Bug Summary

File:src/usr.sbin/nsd/remote.c
Warning:line 449, column 5
Array access (from variable 'ip') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name remote.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/nsd/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I . -I /usr/src/usr.sbin/nsd -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/nsd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/nsd/remote.c
1/*
2 * remote.c - remote control for the NSD 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 * nsd-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
47#ifdef HAVE_SSL
48#ifdef HAVE_OPENSSL_SSL_H1
49#include <openssl/ssl.h>
50#endif
51#ifdef HAVE_OPENSSL_ERR_H1
52#include <openssl/err.h>
53#endif
54#ifdef HAVE_OPENSSL_RAND_H1
55#include <openssl/rand.h>
56#endif
57#endif /* HAVE_SSL */
58#include <ctype.h>
59#include <unistd.h>
60#include <assert.h>
61#include <fcntl.h>
62#include <errno(*__errno()).h>
63#ifndef USE_MINI_EVENT
64# ifdef HAVE_EVENT_H1
65# include <event.h>
66# else
67# include <event2/event.h>
68# include "event2/event_struct.h"
69# include "event2/event_compat.h"
70# endif
71#else
72# include "mini_event.h"
73#endif
74#include "remote.h"
75#include "util.h"
76#include "xfrd.h"
77#include "xfrd-notify.h"
78#include "xfrd-tcp.h"
79#include "nsd.h"
80#include "options.h"
81#include "difffile.h"
82#include "ipc.h"
83
84#ifdef HAVE_SYS_TYPES_H1
85# include <sys/types.h>
86#endif
87#ifdef HAVE_SYS_STAT_H1
88# include <sys/stat.h>
89#endif
90#ifdef HAVE_NETDB_H1
91# include <netdb.h>
92#endif
93#ifdef HAVE_SYS_UN_H1
94# include <sys/un.h>
95#endif
96#ifndef AF_LOCAL1
97#define AF_LOCAL1 AF_UNIX1
98#endif
99
100/** number of seconds timeout on incoming remote control handshake */
101#define REMOTE_CONTROL_TCP_TIMEOUT120 120
102
103/** repattern to master or slave */
104#define REPAT_SLAVE1 1
105#define REPAT_MASTER2 2
106
107/** if you want zero to be inhibited in stats output.
108 * it omits zeroes for types that have no acronym and unused-rcodes */
109const int inhibit_zero = 1;
110
111/**
112 * a busy control command connection, SSL state
113 * Defined here to keep the definition private, and keep SSL out of the .h
114 */
115struct rc_state {
116 /** the next item in list */
117 struct rc_state* next, *prev;
118 /* if the event was added to the event_base */
119 int event_added;
120 /** the commpoint */
121 struct event c;
122 /** timeout for this state */
123 struct timeval tval;
124 /** in the handshake part */
125 enum { rc_none, rc_hs_read, rc_hs_write } shake_state;
126#ifdef HAVE_SSL
127 /** the ssl state */
128 SSL* ssl;
129#endif
130 /** file descriptor */
131 int fd;
132 /** the rc this is part of */
133 struct daemon_remote* rc;
134 /** stats list next item */
135 struct rc_state* stats_next;
136};
137
138/**
139 * list of events for accepting connections
140 */
141struct acceptlist {
142 struct acceptlist* next;
143 int event_added;
144 struct event c;
145 char* ident;
146 struct daemon_remote* rc;
147};
148
149/**
150 * The remote control state.
151 */
152struct daemon_remote {
153 /** the master process for this remote control */
154 struct xfrd_state* xfrd;
155 /** commpoints for accepting remote control connections */
156 struct acceptlist* accept_list;
157 /* if certificates are used */
158 int use_cert;
159 /** number of active commpoints that are handling remote control */
160 int active;
161 /** max active commpoints */
162 int max_active;
163 /** current commpoints busy; double linked, malloced */
164 struct rc_state* busy_list;
165 /** last time stats was reported */
166 struct timeval stats_time, boot_time;
167#ifdef HAVE_SSL
168 /** the SSL context for creating new SSL streams */
169 SSL_CTX* ctx;
170#endif
171};
172
173/**
174 * Connection to print to, either SSL or plain over fd
175 */
176struct remote_stream {
177#ifdef HAVE_SSL
178 /** SSL structure, nonNULL if using SSL */
179 SSL* ssl;
180#endif
181 /** file descriptor for plain transfer */
182 int fd;
183};
184typedef struct remote_stream RES;
185
186/**
187 * Print fixed line of text over ssl connection in blocking mode
188 * @param res: print to
189 * @param text: the text.
190 * @return false on connection failure.
191 */
192static int ssl_print_text(RES* res, const char* text);
193
194/**
195 * printf style printing to the ssl connection
196 * @param res: the RES connection to print to. Blocking.
197 * @param format: printf style format string.
198 * @return success or false on a network failure.
199 */
200static int ssl_printf(RES* res, const char* format, ...)
201 ATTR_FORMAT(printf, 2, 3)__attribute__ ((format (printf, 2, 3)));
202
203/**
204 * Read until \n is encountered
205 * If stream signals EOF, the string up to then is returned (without \n).
206 * @param res: the RES connection to read from. blocking.
207 * @param buf: buffer to read to.
208 * @param max: size of buffer.
209 * @return false on connection failure.
210 */
211static int ssl_read_line(RES* res, char* buf, size_t max);
212
213/** perform the accept of a new remote control connection */
214static void
215remote_accept_callback(int fd, short event, void* arg);
216
217/** perform remote control */
218static void
219remote_control_callback(int fd, short event, void* arg);
220
221#ifdef BIND8_STATS
222/* process the statistics and output them */
223static void process_stats(RES* ssl, xfrd_state_type* xfrd, int peek);
224#endif
225
226/** ---- end of private defines ---- **/
227
228#ifdef HAVE_SSL
229/** log ssl crypto err */
230static void
231log_crypto_err(const char* str)
232{
233 /* error:[error code]:[library name]:[function name]:[reason string] */
234 char buf[128];
235 unsigned long e;
236 ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
237 log_msg(LOG_ERR3, "%s crypto %s", str, buf);
238 while( (e=ERR_get_error()) ) {
239 ERR_error_string_n(e, buf, sizeof(buf));
240 log_msg(LOG_ERR3, "and additionally crypto %s", buf);
241 }
242}
243#endif /* HAVE_SSL */
244
245#ifdef BIND8_STATS
246/** subtract timers and the values do not overflow or become negative */
247static void
248timeval_subtract(struct timeval* d, const struct timeval* end,
249 const struct timeval* start)
250{
251#ifndef S_SPLINT_S
252 time_t end_usec = end->tv_usec;
253 d->tv_sec = end->tv_sec - start->tv_sec;
254 if(end_usec < start->tv_usec) {
255 end_usec += 1000000;
256 d->tv_sec--;
257 }
258 d->tv_usec = end_usec - start->tv_usec;
259#endif
260}
261#endif /* BIND8_STATS */
262
263#ifdef HAVE_SSL
264static int
265remote_setup_ctx(struct daemon_remote* rc, struct nsd_options* cfg)
266{
267 char* s_cert = cfg->server_cert_file;
268 char* s_key = cfg->server_key_file;
269 rc->ctx = server_tls_ctx_setup(s_key, s_cert, s_cert);
270 if(!rc->ctx) {
271 log_msg(LOG_ERR3, "could not setup remote control TLS context");
272 return 0;
273 }
274 return 1;
275}
276#endif /* HAVE_SSL */
277
278struct daemon_remote*
279daemon_remote_create(struct nsd_options* cfg)
280{
281 struct daemon_remote* rc = (struct daemon_remote*)xalloc_zero(
282 sizeof(*rc));
283 rc->max_active = 10;
284 assert(cfg->control_enable)((void)0);
285
286 if(options_remote_is_address(cfg)) {
1
Assuming the condition is false
2
Taking false branch
287#ifdef HAVE_SSL
288 if(!remote_setup_ctx(rc, cfg)) {
289 daemon_remote_delete(rc);
290 return NULL((void *)0);
291 }
292 rc->use_cert = 1;
293#else
294 log_msg(LOG_ERR3, "Could not setup remote control: NSD was compiled without SSL.");
295#endif /* HAVE_SSL */
296 } else {
297 struct ip_address_option* o;
298#ifdef HAVE_SSL
299 rc->ctx = NULL((void *)0);
300#endif
301 rc->use_cert = 0;
302 for(o = cfg->control_interface; o; o = o->next) {
4
Loop condition is false. Execution continues on line 309
303 if(o->address && o->address[0] != '/')
3
Assuming field 'address' is null
304 log_msg(LOG_WARNING4, "control-interface %s is not using TLS, but plain transfer, because first control-interface in config file is a local socket (starts with a /).", o->address);
305 }
306 }
307
308 /* and try to open the ports */
309 if(!daemon_remote_open_ports(rc, cfg)) {
5
Calling 'daemon_remote_open_ports'
310 log_msg(LOG_ERR3, "could not open remote control port");
311 daemon_remote_delete(rc);
312 return NULL((void *)0);
313 }
314
315 if(gettimeofday(&rc->boot_time, NULL((void *)0)) == -1)
316 log_msg(LOG_ERR3, "gettimeofday: %s", strerror(errno(*__errno())));
317 rc->stats_time = rc->boot_time;
318
319 return rc;
320}
321
322void daemon_remote_close(struct daemon_remote* rc)
323{
324 struct rc_state* p, *np;
325 struct acceptlist* h, *nh;
326 if(!rc) return;
327
328 /* close listen sockets */
329 h = rc->accept_list;
330 while(h) {
331 nh = h->next;
332 if(h->event_added)
333 event_del(&h->c);
334 close(h->c.ev_fd);
335 free(h->ident);
336 free(h);
337 h = nh;
338 }
339 rc->accept_list = NULL((void *)0);
340
341 /* close busy connection sockets */
342 p = rc->busy_list;
343 while(p) {
344 np = p->next;
345 if(p->event_added)
346 event_del(&p->c);
347#ifdef HAVE_SSL
348 if(p->ssl)
349 SSL_free(p->ssl);
350#endif
351 close(p->c.ev_fd);
352 free(p);
353 p = np;
354 }
355 rc->busy_list = NULL((void *)0);
356 rc->active = 0;
357}
358
359void daemon_remote_delete(struct daemon_remote* rc)
360{
361 if(!rc) return;
362 daemon_remote_close(rc);
363#ifdef HAVE_SSL
364 if(rc->ctx) {
365 SSL_CTX_free(rc->ctx);
366 }
367#endif
368 free(rc);
369}
370
371static int
372create_tcp_accept_sock(struct addrinfo* addr, int* noproto)
373{
374#if defined(SO_REUSEADDR0x0004) || (defined(INET6) && (defined(IPV6_V6ONLY27) || defined(IPV6_USE_MIN_MTU42) || defined(IPV6_MTU)))
375 int on = 1;
376#endif
377 int s;
378 *noproto = 0;
379 if ((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
380#if defined(INET6)
381 if (addr->ai_family == AF_INET624 &&
382 errno(*__errno()) == EAFNOSUPPORT47) {
383 *noproto = 1;
384 log_msg(LOG_WARNING4, "fallback to TCP4, no IPv6: not supported");
385 return -1;
386 }
387#endif /* INET6 */
388 log_msg(LOG_ERR3, "can't create a socket: %s", strerror(errno(*__errno())));
389 return -1;
390 }
391#ifdef SO_REUSEADDR0x0004
392 if (setsockopt(s, SOL_SOCKET0xffff, SO_REUSEADDR0x0004, &on, sizeof(on)) < 0) {
393 log_msg(LOG_ERR3, "setsockopt(..., SO_REUSEADDR, ...) failed: %s", strerror(errno(*__errno())));
394 }
395#endif /* SO_REUSEADDR */
396#if defined(INET6) && defined(IPV6_V6ONLY27)
397 if (addr->ai_family == AF_INET624 &&
398 setsockopt(s, IPPROTO_IPV641, IPV6_V6ONLY27, &on, sizeof(on)) < 0)
399 {
400 log_msg(LOG_ERR3, "setsockopt(..., IPV6_V6ONLY, ...) failed: %s", strerror(errno(*__errno())));
401 close(s);
402 return -1;
403 }
404#endif
405 /* set it nonblocking */
406 /* (StevensUNP p463), if tcp listening socket is blocking, then
407 it may block in accept, even if select() says readable. */
408 if (fcntl(s, F_SETFL4, O_NONBLOCK0x0004) == -1) {
409 log_msg(LOG_ERR3, "cannot fcntl tcp: %s", strerror(errno(*__errno())));
410 }
411 /* Bind it... */
412 if (bind(s, (struct sockaddr *)addr->ai_addr, addr->ai_addrlen) != 0) {
413 log_msg(LOG_ERR3, "can't bind tcp socket: %s", strerror(errno(*__errno())));
414 close(s);
415 return -1;
416 }
417 /* Listen to it... */
418 if (listen(s, TCP_BACKLOG_REMOTE16) == -1) {
419 log_msg(LOG_ERR3, "can't listen: %s", strerror(errno(*__errno())));
420 close(s);
421 return -1;
422 }
423 return s;
424}
425
426/**
427 * Add and open a new control port
428 * @param rc: rc with result list.
429 * @param ip: ip str
430 * @param nr: port nr
431 * @param noproto_is_err: if lack of protocol support is an error.
432 * @return false on failure.
433 */
434static int
435add_open(struct daemon_remote* rc, struct nsd_options* cfg, const char* ip,
436 int nr, int noproto_is_err)
437{
438 struct addrinfo hints;
439 struct addrinfo* res;
440 struct acceptlist* hl;
441 int noproto = 0;
442 int fd, r;
443 char port[15];
444 snprintf(port, sizeof(port), "%d", nr);
445 port[sizeof(port)-1]=0;
446 memset(&hints, 0, sizeof(hints));
447 assert(ip)((void)0);
448
449 if(ip[0] == '/') {
10
Array access (from variable 'ip') results in a null pointer dereference
450 /* This looks like a local socket */
451 fd = create_local_accept_sock(ip, &noproto);
452 /*
453 * Change socket ownership and permissions so users other
454 * than root can access it provided they are in the same
455 * group as the user we run as.
456 */
457 if(fd != -1) {
458#ifdef HAVE_CHOWN1
459 if(chmod(ip, (mode_t)(S_IRUSR0000400 | S_IWUSR0000200 | S_IRGRP0000040 | S_IWGRP0000020)) == -1) {
460 VERBOSITY(3, (LOG_INFO, "cannot chmod control socket %s: %s", ip, strerror(errno)))do { if ((3) <= verbosity) { log_msg (6, "cannot chmod control socket %s: %s"
, ip, strerror((*__errno()))) ; } } while (0)
;
461 }
462 if (cfg->username && cfg->username[0] &&
463 nsd.uid != (uid_t)-1) {
464 if(chown(ip, nsd.uid, nsd.gid) == -1)
465 VERBOSITY(2, (LOG_INFO, "cannot chown %u.%u %s: %s",do { if ((2) <= verbosity) { log_msg (6, "cannot chown %u.%u %s: %s"
, (unsigned)nsd.uid, (unsigned)nsd.gid, ip, strerror((*__errno
()))) ; } } while (0)
466 (unsigned)nsd.uid, (unsigned)nsd.gid,do { if ((2) <= verbosity) { log_msg (6, "cannot chown %u.%u %s: %s"
, (unsigned)nsd.uid, (unsigned)nsd.gid, ip, strerror((*__errno
()))) ; } } while (0)
467 ip, strerror(errno)))do { if ((2) <= verbosity) { log_msg (6, "cannot chown %u.%u %s: %s"
, (unsigned)nsd.uid, (unsigned)nsd.gid, ip, strerror((*__errno
()))) ; } } while (0)
;
468 }
469#else
470 (void)cfg;
471#endif
472 }
473 } else {
474 hints.ai_socktype = SOCK_STREAM1;
475 hints.ai_flags = AI_PASSIVE1 | AI_NUMERICHOST4;
476 /* if we had no interface ip name, "default" is what we
477 * would do getaddrinfo for. */
478 if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
479 log_msg(LOG_ERR3, "control interface %s:%s getaddrinfo: %s %s",
480 ip, port, gai_strerror(r),
481#ifdef EAI_SYSTEM-11
482 r==EAI_SYSTEM-11?(char*)strerror(errno(*__errno())):""
483#else
484 ""
485#endif
486 );
487 return 0;
488 }
489
490 /* open fd */
491 fd = create_tcp_accept_sock(res, &noproto);
492 freeaddrinfo(res);
493 }
494
495 if(fd == -1 && noproto) {
496 if(!noproto_is_err)
497 return 1; /* return success, but do nothing */
498 log_msg(LOG_ERR3, "cannot open control interface %s %d : "
499 "protocol not supported", ip, nr);
500 return 0;
501 }
502 if(fd == -1) {
503 log_msg(LOG_ERR3, "cannot open control interface %s %d", ip, nr);
504 return 0;
505 }
506
507 /* alloc */
508 hl = (struct acceptlist*)xalloc_zero(sizeof(*hl));
509 hl->rc = rc;
510 hl->ident = strdup(ip);
511 if(!hl->ident) {
512 log_msg(LOG_ERR3, "malloc failure");
513 close(fd);
514 free(hl);
515 return 0;
516 }
517 hl->next = rc->accept_list;
518 rc->accept_list = hl;
519
520 hl->c.ev_fd = fd;
521 hl->event_added = 0;
522 return 1;
523}
524
525int
526daemon_remote_open_ports(struct daemon_remote* rc, struct nsd_options* cfg)
527{
528 assert(cfg->control_enable && cfg->control_port)((void)0);
529 if(cfg->control_interface
5.1
Field 'control_interface' is non-null
) {
6
Taking true branch
530 ip_address_option_type* p;
531 for(p = cfg->control_interface; p; p = p->next) {
7
Loop condition is true. Entering loop body
532 if(!add_open(rc, cfg, p->address, cfg->control_port, 1)) {
8
Passing null pointer value via 3rd parameter 'ip'
9
Calling 'add_open'
533 return 0;
534 }
535 }
536 } else {
537 /* defaults */
538 if(cfg->do_ip6 && !add_open(rc, cfg, "::1", cfg->control_port, 0)) {
539 return 0;
540 }
541 if(cfg->do_ip4 &&
542 !add_open(rc, cfg, "127.0.0.1", cfg->control_port, 1)) {
543 return 0;
544 }
545 }
546 return 1;
547}
548
549void
550daemon_remote_attach(struct daemon_remote* rc, struct xfrd_state* xfrd)
551{
552 int fd;
553 struct acceptlist* p;
554 if(!rc) return;
555 rc->xfrd = xfrd;
556 for(p = rc->accept_list; p; p = p->next) {
557 /* add event */
558 fd = p->c.ev_fd;
559 memset(&p->c, 0, sizeof(p->c));
560 event_set(&p->c, fd, EV_PERSIST0x10|EV_READ0x02, remote_accept_callback,
561 p);
562 if(event_base_set(xfrd->event_base, &p->c) != 0)
563 log_msg(LOG_ERR3, "remote: cannot set event_base");
564 if(event_add(&p->c, NULL((void *)0)) != 0)
565 log_msg(LOG_ERR3, "remote: cannot add event");
566 p->event_added = 1;
567 }
568}
569
570static void
571remote_accept_callback(int fd, short event, void* arg)
572{
573 struct acceptlist *hl = (struct acceptlist*)arg;
574 struct daemon_remote *rc = hl->rc;
575#ifdef INET6
576 struct sockaddr_storage addr;
577#else
578 struct sockaddr_in addr;
579#endif
580 socklen_t addrlen;
581 int newfd;
582 struct rc_state* n;
583
584 if (!(event & EV_READ0x02)) {
585 return;
586 }
587
588 /* perform the accept */
589 addrlen = sizeof(addr);
590#ifndef HAVE_ACCEPT41
591 newfd = accept(fd, (struct sockaddr*)&addr, &addrlen);
592#else
593 newfd = accept4(fd, (struct sockaddr*)&addr, &addrlen, SOCK_NONBLOCK0x4000);
594#endif
595 if(newfd == -1) {
596 if ( errno(*__errno()) != EINTR4
597 && errno(*__errno()) != EWOULDBLOCK35
598#ifdef ECONNABORTED53
599 && errno(*__errno()) != ECONNABORTED53
600#endif /* ECONNABORTED */
601#ifdef EPROTO95
602 && errno(*__errno()) != EPROTO95
603#endif /* EPROTO */
604 ) {
605 log_msg(LOG_ERR3, "accept failed: %s", strerror(errno(*__errno())));
606 }
607 return;
608 }
609
610 /* create new commpoint unless we are servicing already */
611 if(rc->active >= rc->max_active) {
612 log_msg(LOG_WARNING4, "drop incoming remote control: "
613 "too many connections");
614 close_exit:
615 close(newfd);
616 return;
617 }
618
619#ifndef HAVE_ACCEPT41
620 if (fcntl(newfd, F_SETFL4, O_NONBLOCK0x0004) == -1) {
621 log_msg(LOG_ERR3, "fcntl failed: %s", strerror(errno(*__errno())));
622 goto close_exit;
623 }
624#endif
625
626 /* setup state to service the remote control command */
627 n = (struct rc_state*)calloc(1, sizeof(*n));
628 if(!n) {
629 log_msg(LOG_ERR3, "out of memory");
630 goto close_exit;
631 }
632
633 n->tval.tv_sec = REMOTE_CONTROL_TCP_TIMEOUT120;
634 n->tval.tv_usec = 0L;
635 n->fd = newfd;
636
637 memset(&n->c, 0, sizeof(n->c));
638 event_set(&n->c, newfd, EV_PERSIST0x10|EV_TIMEOUT0x01|EV_READ0x02,
639 remote_control_callback, n);
640 if(event_base_set(xfrd->event_base, &n->c) != 0) {
641 log_msg(LOG_ERR3, "remote_accept: cannot set event_base");
642 free(n);
643 goto close_exit;
644 }
645 if(event_add(&n->c, &n->tval) != 0) {
646 log_msg(LOG_ERR3, "remote_accept: cannot add event");
647 free(n);
648 goto close_exit;
649 }
650 n->event_added = 1;
651
652 if(2 <= verbosity) {
653 if(hl->ident && hl->ident[0] == '/') {
654 VERBOSITY(2, (LOG_INFO, "new control connection from %s", hl->ident))do { if ((2) <= verbosity) { log_msg (6, "new control connection from %s"
, hl->ident) ; } } while (0)
;
655 } else {
656 char s[128];
657 addr2str(&addr, s, sizeof(s));
658 VERBOSITY(2, (LOG_INFO, "new control connection from %s", s))do { if ((2) <= verbosity) { log_msg (6, "new control connection from %s"
, s) ; } } while (0)
;
659 }
660 }
661
662#ifdef HAVE_SSL
663 if(rc->ctx) {
664 n->shake_state = rc_hs_read;
665 n->ssl = SSL_new(rc->ctx);
666 if(!n->ssl) {
667 log_crypto_err("could not SSL_new");
668 event_del(&n->c);
669 free(n);
670 goto close_exit;
671 }
672 SSL_set_accept_state(n->ssl);
673 (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY)SSL_ctrl((n->ssl),33,(0x00000004L),((void *)0));
674 if(!SSL_set_fd(n->ssl, newfd)) {
675 log_crypto_err("could not SSL_set_fd");
676 event_del(&n->c);
677 SSL_free(n->ssl);
678 free(n);
679 goto close_exit;
680 }
681 } else {
682 n->ssl = NULL((void *)0);
683 }
684#endif /* HAVE_SSL */
685
686 n->rc = rc;
687 n->stats_next = NULL((void *)0);
688 n->prev = NULL((void *)0);
689 n->next = rc->busy_list;
690 if(n->next) n->next->prev = n;
691 rc->busy_list = n;
692 rc->active ++;
693
694 /* perform the first nonblocking read already, for windows,
695 * so it can return wouldblock. could be faster too. */
696 remote_control_callback(newfd, EV_READ0x02, n);
697}
698
699/** delete from list */
700static void
701state_list_remove_elem(struct rc_state** list, struct rc_state* todel)
702{
703 if(todel->prev) todel->prev->next = todel->next;
704 else *list = todel->next;
705 if(todel->next) todel->next->prev = todel->prev;
706}
707
708/** decrease active count and remove commpoint from busy list */
709static void
710clean_point(struct daemon_remote* rc, struct rc_state* s)
711{
712 state_list_remove_elem(&rc->busy_list, s);
713 rc->active --;
714 if(s->event_added)
715 event_del(&s->c);
716#ifdef HAVE_SSL
717 if(s->ssl) {
718 SSL_shutdown(s->ssl);
719 SSL_free(s->ssl);
720 }
721#endif /* HAVE_SSL */
722 close(s->c.ev_fd);
723 free(s);
724}
725
726static int
727ssl_print_text(RES* res, const char* text)
728{
729 if(!res)
730 return 0;
731#ifdef HAVE_SSL
732 if(res->ssl) {
733 int r;
734 ERR_clear_error();
735 if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) {
736 if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN6) {
737 VERBOSITY(2, (LOG_WARNING, "in SSL_write, peer "do { if ((2) <= verbosity) { log_msg (4, "in SSL_write, peer "
"closed connection") ; } } while (0)
738 "closed connection"))do { if ((2) <= verbosity) { log_msg (4, "in SSL_write, peer "
"closed connection") ; } } while (0)
;
739 return 0;
740 }
741 log_crypto_err("could not SSL_write");
742 return 0;
743 }
744 } else {
745#endif /* HAVE_SSL */
746 if(write_socket(res->fd, text, strlen(text)) <= 0) {
747 log_msg(LOG_ERR3, "could not write: %s",
748 strerror(errno(*__errno())));
749 return 0;
750 }
751#ifdef HAVE_SSL
752 }
753#endif /* HAVE_SSL */
754 return 1;
755}
756
757/** print text over the ssl connection */
758static int
759ssl_print_vmsg(RES* ssl, const char* format, va_list args)
760{
761 char msg[1024];
762 vsnprintf(msg, sizeof(msg), format, args);
763 return ssl_print_text(ssl, msg);
764}
765
766/** printf style printing to the ssl connection */
767static int
768ssl_printf(RES* ssl, const char* format, ...)
769{
770 va_list args;
771 int ret;
772 va_start(args, format)__builtin_va_start((args), format);
773 ret = ssl_print_vmsg(ssl, format, args);
774 va_end(args)__builtin_va_end((args));
775 return ret;
776}
777
778static int
779ssl_read_line(RES* res, char* buf, size_t max)
780{
781 size_t len = 0;
782 if(!res)
783 return 0;
784 while(len < max) {
785 buf[len] = 0; /* terminate for safety and please checkers */
786 /* this byte is written if we read a byte from the input */
787#ifdef HAVE_SSL
788 if(res->ssl) {
789 int r;
790 ERR_clear_error();
791 if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) {
792 if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN6) {
793 buf[len] = 0;
794 return 1;
795 }
796 log_crypto_err("could not SSL_read");
797 return 0;
798 }
799 } else {
800#endif /* HAVE_SSL */
801 while(1) {
802 ssize_t rr = read(res->fd, buf+len, 1);
803 if(rr <= 0) {
804 if(rr == 0) {
805 buf[len] = 0;
806 return 1;
807 }
808 if(errno(*__errno()) == EINTR4 || errno(*__errno()) == EAGAIN35)
809 continue;
810 log_msg(LOG_ERR3, "could not read: %s",
811 strerror(errno(*__errno())));
812 return 0;
813 }
814 break;
815 }
816#ifdef HAVE_SSL
817 }
818#endif /* HAVE_SSL */
819 if(buf[len] == '\n') {
820 /* return string without \n */
821 buf[len] = 0;
822 return 1;
823 }
824 len++;
825 }
826 buf[max-1] = 0;
827 log_msg(LOG_ERR3, "control line too long (%d): %s", (int)max, buf);
828 return 0;
829}
830
831/** skip whitespace, return new pointer into string */
832static char*
833skipwhite(char* str)
834{
835 /* EOS \0 is not a space */
836 while( isspace((unsigned char)*str) )
837 str++;
838 return str;
839}
840
841/** send the OK to the control client */
842static void
843send_ok(RES* ssl)
844{
845 (void)ssl_printf(ssl, "ok\n");
846}
847
848/** get zone argument (if any) or NULL, false on error */
849static int
850get_zone_arg(RES* ssl, xfrd_state_type* xfrd, char* arg,
851 struct zone_options** zo)
852{
853 const dname_type* dname;
854 if(!arg[0]) {
855 /* no argument present, return NULL */
856 *zo = NULL((void *)0);
857 return 1;
858 }
859 dname = dname_parse(xfrd->region, arg);
860 if(!dname) {
861 (void)ssl_printf(ssl, "error cannot parse zone name '%s'\n", arg);
862 *zo = NULL((void *)0);
863 return 0;
864 }
865 *zo = zone_options_find(xfrd->nsd->options, dname);
866 region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
867 if(!*zo) {
868 (void)ssl_printf(ssl, "error zone %s not configured\n", arg);
869 return 0;
870 }
871 return 1;
872}
873
874/** do the stop command */
875static void
876do_stop(RES* ssl, xfrd_state_type* xfrd)
877{
878 xfrd->need_to_send_shutdown = 1;
879
880 if(!(xfrd->ipc_handler_flags&EV_WRITE0x04)) {
881 ipc_xfrd_set_listening(xfrd, EV_PERSIST0x10|EV_READ0x02|EV_WRITE0x04);
882 }
883
884 send_ok(ssl);
885}
886
887/** do the log_reopen command, it only needs reload_now */
888static void
889do_log_reopen(RES* ssl, xfrd_state_type* xfrd)
890{
891 xfrd_set_reload_now(xfrd);
892 send_ok(ssl);
893}
894
895/** do the reload command */
896static void
897do_reload(RES* ssl, xfrd_state_type* xfrd, char* arg)
898{
899 struct zone_options* zo;
900 if(!get_zone_arg(ssl, xfrd, arg, &zo))
901 return;
902 task_new_check_zonefiles(xfrd->nsd->task[xfrd->nsd->mytask],
903 xfrd->last_task, zo?(const dname_type*)zo->node.key:NULL((void *)0));
904 xfrd_set_reload_now(xfrd);
905 send_ok(ssl);
906}
907
908/** do the write command */
909static void
910do_write(RES* ssl, xfrd_state_type* xfrd, char* arg)
911{
912 struct zone_options* zo;
913 if(!get_zone_arg(ssl, xfrd, arg, &zo))
914 return;
915 task_new_write_zonefiles(xfrd->nsd->task[xfrd->nsd->mytask],
916 xfrd->last_task, zo?(const dname_type*)zo->node.key:NULL((void *)0));
917 xfrd_set_reload_now(xfrd);
918 send_ok(ssl);
919}
920
921/** do the notify command */
922static void
923do_notify(RES* ssl, xfrd_state_type* xfrd, char* arg)
924{
925 struct zone_options* zo;
926 if(!get_zone_arg(ssl, xfrd, arg, &zo))
927 return;
928 if(zo) {
929 struct notify_zone* n = (struct notify_zone*)rbtree_search(
930 xfrd->notify_zones, (const dname_type*)zo->node.key);
931 if(n) {
932 xfrd_notify_start(n, xfrd);
933 send_ok(ssl);
934 } else {
935 (void)ssl_printf(ssl, "error zone does not have notify\n");
936 }
937 } else {
938 struct notify_zone* n;
939 RBTREE_FOR(n, struct notify_zone*, xfrd->notify_zones)for(n=(struct notify_zone*)rbtree_first(xfrd->notify_zones
); (rbnode_type*)n != &rbtree_null_node; n = (struct notify_zone
*)rbtree_next((rbnode_type*)n))
{
940 xfrd_notify_start(n, xfrd);
941 }
942 send_ok(ssl);
943 }
944}
945
946/** do the transfer command */
947static void
948do_transfer(RES* ssl, xfrd_state_type* xfrd, char* arg)
949{
950 struct zone_options* zo;
951 xfrd_zone_type* zone;
952 if(!get_zone_arg(ssl, xfrd, arg, &zo))
953 return;
954 if(zo) {
955 zone = (xfrd_zone_type*)rbtree_search(xfrd->zones, (const
956 dname_type*)zo->node.key);
957 if(zone) {
958 xfrd_handle_notify_and_start_xfr(zone, NULL((void *)0));
959 send_ok(ssl);
960 } else {
961 (void)ssl_printf(ssl, "error zone not slave\n");
962 }
963 } else {
964 RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones)for(zone=(xfrd_zone_type*)rbtree_first(xfrd->zones); (rbnode_type
*)zone != &rbtree_null_node; zone = (xfrd_zone_type*)rbtree_next
((rbnode_type*)zone))
{
965 xfrd_handle_notify_and_start_xfr(zone, NULL((void *)0));
966 }
967 (void)ssl_printf(ssl, "ok, %lu zones\n", (unsigned long)xfrd->zones->count);
968 }
969}
970
971/** force transfer a zone */
972static void
973force_transfer_zone(xfrd_zone_type* zone)
974{
975 /* if in TCP transaction, stop it immediately. */
976 if(zone->tcp_conn != -1)
977 xfrd_tcp_release(xfrd->tcp_set, zone);
978 else if(zone->zone_handler.ev_fd != -1)
979 xfrd_udp_release(zone);
980 /* pretend we not longer have it and force any
981 * zone to be downloaded (even same serial, w AXFR) */
982 zone->soa_disk_acquired = 0;
983 zone->soa_nsd_acquired = 0;
984 xfrd_handle_notify_and_start_xfr(zone, NULL((void *)0));
985}
986
987/** do the force transfer command */
988static void
989do_force_transfer(RES* ssl, xfrd_state_type* xfrd, char* arg)
990{
991 struct zone_options* zo;
992 xfrd_zone_type* zone;
993 if(!get_zone_arg(ssl, xfrd, arg, &zo))
994 return;
995 if(zo) {
996 zone = (xfrd_zone_type*)rbtree_search(xfrd->zones, (const
997 dname_type*)zo->node.key);
998 if(zone) {
999 force_transfer_zone(zone);
1000 send_ok(ssl);
1001 } else {
1002 (void)ssl_printf(ssl, "error zone not slave\n");
1003 }
1004 } else {
1005 RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones)for(zone=(xfrd_zone_type*)rbtree_first(xfrd->zones); (rbnode_type
*)zone != &rbtree_null_node; zone = (xfrd_zone_type*)rbtree_next
((rbnode_type*)zone))
{
1006 force_transfer_zone(zone);
1007 }
1008 (void)ssl_printf(ssl, "ok, %lu zones\n", (unsigned long)xfrd->zones->count);
1009 }
1010}
1011
1012static int
1013print_soa_status(RES* ssl, const char* str, xfrd_soa_type* soa, time_t acq)
1014{
1015 if(acq) {
1016 if(!ssl_printf(ssl, " %s: \"%u since %s\"\n", str,
1017 (unsigned)ntohl(soa->serial)(__uint32_t)(__builtin_constant_p(soa->serial) ? (__uint32_t
)(((__uint32_t)(soa->serial) & 0xff) << 24 | ((__uint32_t
)(soa->serial) & 0xff00) << 8 | ((__uint32_t)(soa
->serial) & 0xff0000) >> 8 | ((__uint32_t)(soa->
serial) & 0xff000000) >> 24) : __swap32md(soa->serial
))
, xfrd_pretty_time(acq)))
1018 return 0;
1019 } else {
1020 if(!ssl_printf(ssl, " %s: none\n", str))
1021 return 0;
1022 }
1023 return 1;
1024}
1025
1026/** print zonestatus for one domain */
1027static int
1028print_zonestatus(RES* ssl, xfrd_state_type* xfrd, struct zone_options* zo)
1029{
1030 xfrd_zone_type* xz = (xfrd_zone_type*)rbtree_search(xfrd->zones,
1031 (const dname_type*)zo->node.key);
1032 struct notify_zone* nz = (struct notify_zone*)rbtree_search(
1033 xfrd->notify_zones, (const dname_type*)zo->node.key);
1034 if(!ssl_printf(ssl, "zone: %s\n", zo->name))
1035 return 0;
1036 if(!zo->part_of_config) {
1037 if(!ssl_printf(ssl, " pattern: %s\n", zo->pattern->pname))
1038 return 0;
1039 }
1040 if(nz) {
1041 if(nz->is_waiting) {
1042 if(!ssl_printf(ssl, " notify: \"waiting-for-fd\"\n"))
1043 return 0;
1044 } else if(nz->notify_send_enable || nz->notify_send6_enable) {
1045 int i;
1046 if(!ssl_printf(ssl, " notify: \"send"))
1047 return 0;
1048 for(i=0; i<NOTIFY_CONCURRENT_MAX16; i++) {
1049 if(!nz->pkts[i].dest) continue;
1050 if(!ssl_printf(ssl, " %s",
1051 nz->pkts[i].dest->ip_address_spec))
1052 return 0;
1053 }
1054 if(!ssl_printf(ssl, " with serial %u\"\n",
1055 (unsigned)ntohl(nz->current_soa->serial)(__uint32_t)(__builtin_constant_p(nz->current_soa->serial
) ? (__uint32_t)(((__uint32_t)(nz->current_soa->serial)
& 0xff) << 24 | ((__uint32_t)(nz->current_soa->
serial) & 0xff00) << 8 | ((__uint32_t)(nz->current_soa
->serial) & 0xff0000) >> 8 | ((__uint32_t)(nz->
current_soa->serial) & 0xff000000) >> 24) : __swap32md
(nz->current_soa->serial))
))
1056 return 0;
1057 }
1058 }
1059 if(!xz) {
1060 if(!ssl_printf(ssl, " state: master\n"))
1061 return 0;
1062 return 1;
1063 }
1064 if(!ssl_printf(ssl, " state: %s\n",
1065 (xz->state == xfrd_zone_ok)?"ok":(
1066 (xz->state == xfrd_zone_expired)?"expired":"refreshing")))
1067 return 0;
1068 if(!print_soa_status(ssl, "served-serial", &xz->soa_nsd,
1069 xz->soa_nsd_acquired))
1070 return 0;
1071 if(!print_soa_status(ssl, "commit-serial", &xz->soa_disk,
1072 xz->soa_disk_acquired))
1073 return 0;
1074 if(xz->round_num != -1) {
1075 if(!print_soa_status(ssl, "notified-serial", &xz->soa_notified,
1076 xz->soa_notified_acquired))
1077 return 0;
1078 } else if(xz->event_added) {
1079 if(!ssl_printf(ssl, "\twait: \"%lu sec between attempts\"\n",
1080 (unsigned long)xz->timeout.tv_sec))
1081 return 0;
1082 }
1083
1084 /* UDP */
1085 if(xz->udp_waiting) {
1086 if(!ssl_printf(ssl, " transfer: \"waiting-for-UDP-fd\"\n"))
1087 return 0;
1088 } else if(xz->zone_handler.ev_fd != -1 && xz->tcp_conn == -1) {
1089 if(!ssl_printf(ssl, " transfer: \"sent UDP to %s\"\n",
1090 xz->master->ip_address_spec))
1091 return 0;
1092 }
1093
1094 /* TCP */
1095 if(xz->tcp_waiting) {
1096 if(!ssl_printf(ssl, " transfer: \"waiting-for-TCP-fd\"\n"))
1097 return 0;
1098 } else if(xz->tcp_conn != -1) {
1099 if(!ssl_printf(ssl, " transfer: \"TCP connected to %s\"\n",
1100 xz->master->ip_address_spec))
1101 return 0;
1102 }
1103
1104 return 1;
1105}
1106
1107/** do the zonestatus command */
1108static void
1109do_zonestatus(RES* ssl, xfrd_state_type* xfrd, char* arg)
1110{
1111 struct zone_options* zo;
1112 if(!get_zone_arg(ssl, xfrd, arg, &zo))
1113 return;
1114 if(zo) (void)print_zonestatus(ssl, xfrd, zo);
1115 else {
1116 RBTREE_FOR(zo, struct zone_options*,for(zo=(struct zone_options*)rbtree_first(xfrd->nsd->options
->zone_options); (rbnode_type*)zo != &rbtree_null_node
; zo = (struct zone_options*)rbtree_next((rbnode_type*)zo))
1117 xfrd->nsd->options->zone_options)for(zo=(struct zone_options*)rbtree_first(xfrd->nsd->options
->zone_options); (rbnode_type*)zo != &rbtree_null_node
; zo = (struct zone_options*)rbtree_next((rbnode_type*)zo))
{
1118 if(!print_zonestatus(ssl, xfrd, zo))
1119 return;
1120 }
1121 }
1122}
1123
1124/** do the verbosity command */
1125static void
1126do_verbosity(RES* ssl, char* str)
1127{
1128 int val = atoi(str);
1129 if(strcmp(str, "") == 0) {
1130 (void)ssl_printf(ssl, "verbosity %d\n", verbosity);
1131 return;
1132 }
1133 if(val == 0 && strcmp(str, "0") != 0) {
1134 (void)ssl_printf(ssl, "error in verbosity number syntax: %s\n", str);
1135 return;
1136 }
1137 verbosity = val;
1138 task_new_set_verbosity(xfrd->nsd->task[xfrd->nsd->mytask],
1139 xfrd->last_task, val);
1140 xfrd_set_reload_now(xfrd);
1141 send_ok(ssl);
1142}
1143
1144/** find second argument, modifies string */
1145static int
1146find_arg2(RES* ssl, char* arg, char** arg2)
1147{
1148 char* as = strrchr(arg, ' ');
1149 if(as) {
1150 as[0]=0;
1151 *arg2 = as+1;
1152 while(isspace((unsigned char)*as) && as > arg)
1153 as--;
1154 as[0]=0;
1155 return 1;
1156 }
1157 *arg2 = NULL((void *)0);
1158 (void)ssl_printf(ssl, "error could not find next argument "
1159 "after %s\n", arg);
1160 return 0;
1161}
1162
1163/** find second and third arguments, modifies string,
1164 * does not print error for missing arg3 so that if it does not find an
1165 * arg3, the caller can use two arguments. */
1166static int
1167find_arg3(RES* ssl, char* arg, char** arg2, char** arg3)
1168{
1169 if(find_arg2(ssl, arg, arg2)) {
1170 char* as;
1171 *arg3 = *arg2;
1172 as = strrchr(arg, ' ');
1173 if(as) {
1174 as[0]=0;
1175 *arg2 = as+1;
1176 while(isspace((unsigned char)*as) && as > arg)
1177 as--;
1178 as[0]=0;
1179 return 1;
1180 }
1181 }
1182 *arg3 = NULL((void *)0);
1183 return 0;
1184}
1185
1186/** do the status command */
1187static void
1188do_status(RES* ssl, xfrd_state_type* xfrd)
1189{
1190 if(!ssl_printf(ssl, "version: %s\n", PACKAGE_VERSION"4.8.0"))
1191 return;
1192 if(!ssl_printf(ssl, "verbosity: %d\n", verbosity))
1193 return;
1194#ifdef RATELIMIT
1195 if(!ssl_printf(ssl, "ratelimit: %d\n",
1196 (int)xfrd->nsd->options->rrl_ratelimit))
1197 return;
1198#else
1199 (void)xfrd;
1200#endif
1201}
1202
1203/** do the stats command */
1204static void
1205do_stats(RES* ssl, xfrd_state_type* xfrd, int peek)
1206{
1207#ifdef BIND8_STATS
1208 process_stats(ssl, xfrd, peek);
1209#else
1210 (void)xfrd; (void)peek;
1211 (void)ssl_printf(ssl, "error no stats enabled at compile time\n");
1212#endif /* BIND8_STATS */
1213}
1214
1215/** see if we have more zonestatistics entries and it has to be incremented */
1216static void
1217zonestat_inc_ifneeded(xfrd_state_type* xfrd)
1218{
1219#ifdef USE_ZONE_STATS
1220 if(xfrd->nsd->options->zonestatnames->count != xfrd->zonestat_safe)
1221 task_new_zonestat_inc(xfrd->nsd->task[xfrd->nsd->mytask],
1222 xfrd->last_task,
1223 xfrd->nsd->options->zonestatnames->count);
1224#else
1225 (void)xfrd;
1226#endif /* USE_ZONE_STATS */
1227}
1228
1229/** perform the changezone command for one zone */
1230static int
1231perform_changezone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1232{
1233 const dname_type* dname;
1234 struct zone_options* zopt;
1235 char* arg2 = NULL((void *)0);
1236 if(!find_arg2(ssl, arg, &arg2))
1237 return 0;
1238
1239 /* if we add it to the xfrd now, then xfrd could download AXFR and
1240 * store it and the NSD-reload would see it in the difffile before
1241 * it sees the add-config task.
1242 */
1243 /* thus: AXFRs and IXFRs must store the pattern name in the
1244 * difffile, so that it can be added when the AXFR or IXFR is seen.
1245 */
1246
1247 /* check that the pattern exists */
1248 if(!rbtree_search(xfrd->nsd->options->patterns, arg2)) {
1249 (void)ssl_printf(ssl, "error pattern %s does not exist\n",
1250 arg2);
1251 return 0;
1252 }
1253
1254 dname = dname_parse(xfrd->region, arg);
1255 if(!dname) {
1256 (void)ssl_printf(ssl, "error cannot parse zone name\n");
1257 return 0;
1258 }
1259
1260 /* see if zone is a duplicate */
1261 if( (zopt=zone_options_find(xfrd->nsd->options, dname)) ) {
1262 if(zopt->part_of_config) {
1263 (void)ssl_printf(ssl, "error zone defined in nsd.conf, "
1264 "cannot delete it in this manner: remove it from "
1265 "nsd.conf yourself and repattern\n");
1266 region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1267 dname = NULL((void *)0);
1268 return 0;
1269 }
1270 /* found the zone, now delete it */
1271 /* create deletion task */
1272 /* this deletion task is processed before the addition task,
1273 * that is created below, in the same reload process, causing
1274 * a seamless change from one to the other, with no downtime
1275 * for the zone. */
1276 task_new_del_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1277 xfrd->last_task, dname);
1278 xfrd_set_reload_now(xfrd);
1279 /* delete it in xfrd */
1280 if(zone_is_slave(zopt)) {
1281 xfrd_del_slave_zone(xfrd, dname);
1282 }
1283 xfrd_del_notify(xfrd, dname);
1284 /* delete from config */
1285 zone_list_del(xfrd->nsd->options, zopt);
1286 } else {
1287 (void)ssl_printf(ssl, "zone %s did not exist, creating", arg);
1288 }
1289 region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1290 dname = NULL((void *)0);
1291
1292 /* add to zonelist and adds to config in memory */
1293 zopt = zone_list_add(xfrd->nsd->options, arg, arg2);
1294 if(!zopt) {
1295 /* also dname parse error here */
1296 (void)ssl_printf(ssl, "error could not add zonelist entry\n");
1297 return 0;
1298 }
1299 /* make addzone task and schedule reload */
1300 task_new_add_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1301 xfrd->last_task, arg, arg2,
1302 getzonestatid(xfrd->nsd->options, zopt));
1303 zonestat_inc_ifneeded(xfrd);
1304 xfrd_set_reload_now(xfrd);
1305 /* add to xfrd - notify (for master and slaves) */
1306 init_notify_send(xfrd->notify_zones, xfrd->region, zopt);
1307 /* add to xfrd - slave */
1308 if(zone_is_slave(zopt)) {
1309 xfrd_init_slave_zone(xfrd, zopt);
1310 }
1311 return 1;
1312}
1313
1314/** perform the addzone command for one zone */
1315static int
1316perform_addzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1317{
1318 const dname_type* dname;
1319 struct zone_options* zopt;
1320 char* arg2 = NULL((void *)0);
1321 if(!find_arg2(ssl, arg, &arg2))
1322 return 0;
1323
1324 /* if we add it to the xfrd now, then xfrd could download AXFR and
1325 * store it and the NSD-reload would see it in the difffile before
1326 * it sees the add-config task.
1327 */
1328 /* thus: AXFRs and IXFRs must store the pattern name in the
1329 * difffile, so that it can be added when the AXFR or IXFR is seen.
1330 */
1331
1332 /* check that the pattern exists */
1333 if(!rbtree_search(xfrd->nsd->options->patterns, arg2)) {
1334 (void)ssl_printf(ssl, "error pattern %s does not exist\n",
1335 arg2);
1336 return 0;
1337 }
1338
1339 dname = dname_parse(xfrd->region, arg);
1340 if(!dname) {
1341 (void)ssl_printf(ssl, "error cannot parse zone name\n");
1342 return 0;
1343 }
1344
1345 /* see if zone is a duplicate */
1346 if( zone_options_find(xfrd->nsd->options, dname) ) {
1347 region_recycle(xfrd->region, (void*)dname,
1348 dname_total_size(dname));
1349 (void)ssl_printf(ssl, "zone %s already exists\n", arg);
1350 return 1;
1351 }
1352 region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1353 dname = NULL((void *)0);
1354
1355 /* add to zonelist and adds to config in memory */
1356 zopt = zone_list_add(xfrd->nsd->options, arg, arg2);
1357 if(!zopt) {
1358 /* also dname parse error here */
1359 (void)ssl_printf(ssl, "error could not add zonelist entry\n");
1360 return 0;
1361 }
1362 /* make addzone task and schedule reload */
1363 task_new_add_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1364 xfrd->last_task, arg, arg2,
1365 getzonestatid(xfrd->nsd->options, zopt));
1366 zonestat_inc_ifneeded(xfrd);
1367 xfrd_set_reload_now(xfrd);
1368 /* add to xfrd - notify (for master and slaves) */
1369 init_notify_send(xfrd->notify_zones, xfrd->region, zopt);
1370 /* add to xfrd - slave */
1371 if(zone_is_slave(zopt)) {
1372 xfrd_init_slave_zone(xfrd, zopt);
1373 }
1374 return 1;
1375}
1376
1377/** perform the delzone command for one zone */
1378static int
1379perform_delzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1380{
1381 const dname_type* dname;
1382 struct zone_options* zopt;
1383
1384 dname = dname_parse(xfrd->region, arg);
1385 if(!dname) {
1386 (void)ssl_printf(ssl, "error cannot parse zone name\n");
1387 return 0;
1388 }
1389
1390 /* see if we have the zone in question */
1391 zopt = zone_options_find(xfrd->nsd->options, dname);
1392 if(!zopt) {
1393 region_recycle(xfrd->region, (void*)dname,
1394 dname_total_size(dname));
1395 /* nothing to do */
1396 (void)ssl_printf(ssl, "warning zone %s not present\n", arg);
1397 return 0;
1398 }
1399
1400 /* see if it can be deleted */
1401 if(zopt->part_of_config) {
1402 region_recycle(xfrd->region, (void*)dname,
1403 dname_total_size(dname));
1404 (void)ssl_printf(ssl, "error zone defined in nsd.conf, "
1405 "cannot delete it in this manner: remove it from "
1406 "nsd.conf yourself and repattern\n");
1407 return 0;
1408 }
1409
1410 /* create deletion task */
1411 task_new_del_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1412 xfrd->last_task, dname);
1413 xfrd_set_reload_now(xfrd);
1414 /* delete it in xfrd */
1415 if(zone_is_slave(zopt)) {
1416 xfrd_del_slave_zone(xfrd, dname);
1417 }
1418 xfrd_del_notify(xfrd, dname);
1419 /* delete from config */
1420 zone_list_del(xfrd->nsd->options, zopt);
1421
1422 region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1423 return 1;
1424}
1425
1426/** do the addzone command */
1427static void
1428do_addzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1429{
1430 if(!perform_addzone(ssl, xfrd, arg))
1431 return;
1432 send_ok(ssl);
1433}
1434
1435/** do the delzone command */
1436static void
1437do_delzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1438{
1439 if(!perform_delzone(ssl, xfrd, arg))
1440 return;
1441 send_ok(ssl);
1442}
1443
1444/** do the changezone command */
1445static void
1446do_changezone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1447{
1448 if(!perform_changezone(ssl, xfrd, arg))
1449 return;
1450 send_ok(ssl);
1451}
1452
1453/** do the addzones command */
1454static void
1455do_addzones(RES* ssl, xfrd_state_type* xfrd)
1456{
1457 char buf[2048];
1458 int num = 0;
1459 while(ssl_read_line(ssl, buf, sizeof(buf))) {
1460 if(buf[0] == 0x04 && buf[1] == 0)
1461 break; /* end of transmission */
1462 if(!perform_addzone(ssl, xfrd, buf)) {
1463 if(!ssl_printf(ssl, "error for input line '%s'\n",
1464 buf))
1465 return;
1466 } else {
1467 if(!ssl_printf(ssl, "added: %s\n", buf))
1468 return;
1469 num++;
1470 }
1471 }
1472 (void)ssl_printf(ssl, "added %d zones\n", num);
1473}
1474
1475/** do the delzones command */
1476static void
1477do_delzones(RES* ssl, xfrd_state_type* xfrd)
1478{
1479 char buf[2048];
1480 int num = 0;
1481 while(ssl_read_line(ssl, buf, sizeof(buf))) {
1482 if(buf[0] == 0x04 && buf[1] == 0)
1483 break; /* end of transmission */
1484 if(!perform_delzone(ssl, xfrd, buf)) {
1485 if(!ssl_printf(ssl, "error for input line '%s'\n",
1486 buf))
1487 return;
1488 } else {
1489 if(!ssl_printf(ssl, "removed: %s\n", buf))
1490 return;
1491 num++;
1492 }
1493 }
1494 (void)ssl_printf(ssl, "deleted %d zones\n", num);
1495}
1496
1497
1498/** remove TSIG key from config and add task so that reload does too */
1499static void remove_key(xfrd_state_type* xfrd, const char* kname)
1500{
1501 /* add task before deletion because the name string could be deleted */
1502 task_new_del_key(xfrd->nsd->task[xfrd->nsd->mytask], xfrd->last_task,
1503 kname);
1504 key_options_remove(xfrd->nsd->options, kname);
1505 xfrd_set_reload_now(xfrd); /* this is executed when the current control
1506 command ends, thus the entire config changes are bunched up */
1507}
1508
1509/** add TSIG key to config and add task so that reload does too */
1510static void add_key(xfrd_state_type* xfrd, struct key_options* k)
1511{
1512 key_options_add_modify(xfrd->nsd->options, k);
1513 task_new_add_key(xfrd->nsd->task[xfrd->nsd->mytask], xfrd->last_task,
1514 k);
1515 xfrd_set_reload_now(xfrd);
1516}
1517
1518/** check if keys have changed */
1519static void repat_keys(xfrd_state_type* xfrd, struct nsd_options* newopt)
1520{
1521 struct nsd_options* oldopt = xfrd->nsd->options;
1522 struct key_options* k;
1523 /* find deleted keys */
1524 k = (struct key_options*)rbtree_first(oldopt->keys);
1525 while((rbnode_type*)k != RBTREE_NULL&rbtree_null_node) {
1526 struct key_options* next = (struct key_options*)rbtree_next(
1527 (rbnode_type*)k);
1528 if(!key_options_find(newopt, k->name))
1529 remove_key(xfrd, k->name);
1530 k = next;
1531 }
1532 /* find added or changed keys */
1533 RBTREE_FOR(k, struct key_options*, newopt->keys)for(k=(struct key_options*)rbtree_first(newopt->keys); (rbnode_type
*)k != &rbtree_null_node; k = (struct key_options*)rbtree_next
((rbnode_type*)k))
{
1534 struct key_options* origk = key_options_find(oldopt, k->name);
1535 if(!origk)
1536 add_key(xfrd, k);
1537 else if(!key_options_equal(k, origk))
1538 add_key(xfrd, k);
1539 }
1540}
1541
1542/** find zone given the implicit pattern */
1543static const dname_type*
1544parse_implicit_name(xfrd_state_type* xfrd,const char* pname)
1545{
1546 if(strncmp(pname, PATTERN_IMPLICIT_MARKER"_implicit_",
1547 strlen(PATTERN_IMPLICIT_MARKER"_implicit_")) != 0)
1548 return NULL((void *)0);
1549 return dname_parse(xfrd->region, pname +
1550 strlen(PATTERN_IMPLICIT_MARKER"_implicit_"));
1551}
1552
1553/** remove cfgzone and add task so that reload does too */
1554static void
1555remove_cfgzone(xfrd_state_type* xfrd, const char* pname)
1556{
1557 /* dname and find the zone for the implicit pattern */
1558 struct zone_options* zopt = NULL((void *)0);
1559 const dname_type* dname = parse_implicit_name(xfrd, pname);
1560 if(!dname) {
1561 /* should have a parseable name, but it did not */
1562 return;
1563 }
1564
1565 /* find the zone entry for the implicit pattern */
1566 zopt = zone_options_find(xfrd->nsd->options, dname);
1567 if(!zopt) {
1568 /* this should not happen; implicit pattern has zone entry */
1569 region_recycle(xfrd->region, (void*)dname,
1570 dname_total_size(dname));
1571 return;
1572 }
1573
1574 /* create deletion task */
1575 task_new_del_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1576 xfrd->last_task, dname);
1577 xfrd_set_reload_now(xfrd);
1578 /* delete it in xfrd */
1579 if(zone_is_slave(zopt)) {
1580 xfrd_del_slave_zone(xfrd, dname);
1581 }
1582 xfrd_del_notify(xfrd, dname);
1583
1584 /* delete from zoneoptions */
1585 zone_options_delete(xfrd->nsd->options, zopt);
1586
1587 /* recycle parsed dname */
1588 region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1589}
1590
1591/** add cfgzone and add task so that reload does too */
1592static void
1593add_cfgzone(xfrd_state_type* xfrd, const char* pname)
1594{
1595 /* add to our zonelist */
1596 struct zone_options* zopt = zone_options_create(
1597 xfrd->nsd->options->region);
1598 if(!zopt)
1599 return;
1600 zopt->part_of_config = 1;
1601 zopt->name = region_strdup(xfrd->nsd->options->region,
1602 pname + strlen(PATTERN_IMPLICIT_MARKER"_implicit_"));
1603 zopt->pattern = pattern_options_find(xfrd->nsd->options, pname);
1604 if(!zopt->name || !zopt->pattern)
1605 return;
1606 if(!nsd_options_insert_zone(xfrd->nsd->options, zopt)) {
1607 log_msg(LOG_ERR3, "bad domain name or duplicate zone '%s' "
1608 "pattern %s", zopt->name, pname);
1609 }
1610
1611 /* make addzone task and schedule reload */
1612 task_new_add_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1613 xfrd->last_task, zopt->name, pname,
1614 getzonestatid(xfrd->nsd->options, zopt));
1615 /* zonestat_inc is done after the entire config file has been done */
1616 xfrd_set_reload_now(xfrd);
1617 /* add to xfrd - notify (for master and slaves) */
1618 init_notify_send(xfrd->notify_zones, xfrd->region, zopt);
1619 /* add to xfrd - slave */
1620 if(zone_is_slave(zopt)) {
1621 xfrd_init_slave_zone(xfrd, zopt);
1622 }
1623}
1624
1625/** remove pattern and add task so that reload does too */
1626static void
1627remove_pat(xfrd_state_type* xfrd, const char* name)
1628{
1629 /* add task before deletion, because name-string could be deleted */
1630 task_new_del_pattern(xfrd->nsd->task[xfrd->nsd->mytask],
1631 xfrd->last_task, name);
1632 pattern_options_remove(xfrd->nsd->options, name);
1633 xfrd_set_reload_now(xfrd);
1634}
1635
1636/** add pattern and add task so that reload does too */
1637static void
1638add_pat(xfrd_state_type* xfrd, struct pattern_options* p)
1639{
1640 pattern_options_add_modify(xfrd->nsd->options, p);
1641 task_new_add_pattern(xfrd->nsd->task[xfrd->nsd->mytask],
1642 xfrd->last_task, p);
1643 xfrd_set_reload_now(xfrd);
1644}
1645
1646/** interrupt zones that are using changed or removed patterns */
1647static void
1648repat_interrupt_zones(xfrd_state_type* xfrd, struct nsd_options* newopt)
1649{
1650 /* if masterlist changed:
1651 * interrupt slave zone (UDP or TCP) transfers.
1652 * slave zones reset master to start of list.
1653 */
1654 xfrd_zone_type* xz;
1655 struct notify_zone* nz;
1656 RBTREE_FOR(xz, xfrd_zone_type*, xfrd->zones)for(xz=(xfrd_zone_type*)rbtree_first(xfrd->zones); (rbnode_type
*)xz != &rbtree_null_node; xz = (xfrd_zone_type*)rbtree_next
((rbnode_type*)xz))
{
1657 struct pattern_options* oldp = xz->zone_options->pattern;
1658 struct pattern_options* newp = pattern_options_find(newopt,
1659 oldp->pname);
1660 if(!newp || !acl_list_equal(oldp->request_xfr,
1661 newp->request_xfr)) {
1662 /* interrupt transfer */
1663 if(xz->tcp_conn != -1) {
1664 xfrd_tcp_release(xfrd->tcp_set, xz);
1665 xfrd_set_refresh_now(xz);
1666 } else if(xz->zone_handler.ev_fd != -1) {
1667 xfrd_udp_release(xz);
1668 xfrd_set_refresh_now(xz);
1669 }
1670 xz->master = 0;
1671 xz->master_num = 0;
1672 xz->next_master = -1;
1673 xz->round_num = -1; /* fresh set of retries */
1674 }
1675 }
1676 /* if notify list changed:
1677 * interrupt notify that is busy.
1678 * reset notify to start of list. (clear all other reset_notify)
1679 */
1680 RBTREE_FOR(nz, struct notify_zone*, xfrd->notify_zones)for(nz=(struct notify_zone*)rbtree_first(xfrd->notify_zones
); (rbnode_type*)nz != &rbtree_null_node; nz = (struct notify_zone
*)rbtree_next((rbnode_type*)nz))
{
1681 struct pattern_options* oldp = nz->options->pattern;
1682 struct pattern_options* newp = pattern_options_find(newopt,
1683 oldp->pname);
1684 if(!newp || !acl_list_equal(oldp->notify, newp->notify)) {
1685 /* interrupt notify */
1686 if(nz->notify_send_enable) {
1687 notify_disable(nz);
1688 /* set to restart the notify after the
1689 * pattern has been changed. */
1690 nz->notify_restart = 2;
1691 } else {
1692 nz->notify_restart = 1;
1693 }
1694 } else {
1695 nz->notify_restart = 0;
1696 }
1697 }
1698}
1699
1700/** for notify, after the pattern changes, restart the affected notifies */
1701static void
1702repat_interrupt_notify_start(xfrd_state_type* xfrd)
1703{
1704 struct notify_zone* nz;
1705 RBTREE_FOR(nz, struct notify_zone*, xfrd->notify_zones)for(nz=(struct notify_zone*)rbtree_first(xfrd->notify_zones
); (rbnode_type*)nz != &rbtree_null_node; nz = (struct notify_zone
*)rbtree_next((rbnode_type*)nz))
{
1706 if(nz->notify_restart) {
1707 if(nz->notify_current)
1708 nz->notify_current = nz->options->pattern->notify;
1709 if(nz->notify_restart == 2) {
1710 if(nz->notify_restart)
1711 xfrd_notify_start(nz, xfrd);
1712 }
1713 }
1714 }
1715}
1716
1717/** check if patterns have changed */
1718static void
1719repat_patterns(xfrd_state_type* xfrd, struct nsd_options* newopt)
1720{
1721 /* zones that use changed patterns must have:
1722 * - their AXFR/IXFR interrupted: try again, acl may have changed.
1723 * if the old master/key still exists, OK, fix master-numptrs and
1724 * keep going. Otherwise, stop xfer and reset TSIG.
1725 * - send NOTIFY reset to start of NOTIFY list (and TSIG reset).
1726 */
1727 struct nsd_options* oldopt = xfrd->nsd->options;
1728 struct pattern_options* p;
1729 int search_zones = 0;
1730
1731 repat_interrupt_zones(xfrd, newopt);
1732 /* find deleted patterns */
1733 p = (struct pattern_options*)rbtree_first(oldopt->patterns);
1734 while((rbnode_type*)p != RBTREE_NULL&rbtree_null_node) {
1735 struct pattern_options* next = (struct pattern_options*)
1736 rbtree_next((rbnode_type*)p);
1737 if(!pattern_options_find(newopt, p->pname)) {
1738 if(p->implicit) {
1739 /* first remove its zone */
1740 VERBOSITY(1, (LOG_INFO, "zone removed from config: %s", p->pname + strlen(PATTERN_IMPLICIT_MARKER)))do { if ((1) <= verbosity) { log_msg (6, "zone removed from config: %s"
, p->pname + strlen("_implicit_")) ; } } while (0)
;
1741 remove_cfgzone(xfrd, p->pname);
1742 }
1743 remove_pat(xfrd, p->pname);
1744 }
1745 p = next;
1746 }
1747 /* find added or changed patterns */
1748 RBTREE_FOR(p, struct pattern_options*, newopt->patterns)for(p=(struct pattern_options*)rbtree_first(newopt->patterns
); (rbnode_type*)p != &rbtree_null_node; p = (struct pattern_options
*)rbtree_next((rbnode_type*)p))
{
1749 struct pattern_options* origp = pattern_options_find(oldopt,
1750 p->pname);
1751 if(!origp) {
1752 /* no zones can use it, no zone_interrupt needed */
1753 add_pat(xfrd, p);
1754 if(p->implicit) {
1755 VERBOSITY(1, (LOG_INFO, "zone added to config: %s", p->pname + strlen(PATTERN_IMPLICIT_MARKER)))do { if ((1) <= verbosity) { log_msg (6, "zone added to config: %s"
, p->pname + strlen("_implicit_")) ; } } while (0)
;
1756 add_cfgzone(xfrd, p->pname);
1757 }
1758 } else if(!pattern_options_equal(p, origp)) {
1759 uint8_t newstate = 0;
1760 if (p->request_xfr && !origp->request_xfr) {
1761 newstate = REPAT_SLAVE1;
1762 } else if (!p->request_xfr && origp->request_xfr) {
1763 newstate = REPAT_MASTER2;
1764 }
1765 add_pat(xfrd, p);
1766 if (p->implicit && newstate) {
1767 const dname_type* dname =
1768 parse_implicit_name(xfrd, p->pname);
1769 if (dname) {
1770 if (newstate == REPAT_SLAVE1) {
1771 struct zone_options* zopt =
1772 zone_options_find(
1773 oldopt, dname);
1774 if (zopt) {
1775 xfrd_init_slave_zone(
1776 xfrd, zopt);
1777 }
1778 } else if (newstate == REPAT_MASTER2) {
1779 xfrd_del_slave_zone(xfrd,
1780 dname);
1781 }
1782 region_recycle(xfrd->region,
1783 (void*)dname,
1784 dname_total_size(dname));
1785 }
1786 } else if(!p->implicit && newstate) {
1787 /* search all zones with this pattern */
1788 search_zones = 1;
1789 origp->xfrd_flags = newstate;
1790 }
1791 }
1792 }
1793 if (search_zones) {
1794 struct zone_options* zone_opt;
1795 /* search in oldopt because 1) it contains zonelist zones,
1796 * and 2) you need oldopt(existing) to call xfrd_init */
1797 RBTREE_FOR(zone_opt, struct zone_options*, oldopt->zone_options)for(zone_opt=(struct zone_options*)rbtree_first(oldopt->zone_options
); (rbnode_type*)zone_opt != &rbtree_null_node; zone_opt =
(struct zone_options*)rbtree_next((rbnode_type*)zone_opt))
{
1798 struct pattern_options* oldp = zone_opt->pattern;
1799 if (!oldp->implicit) {
1800 if (oldp->xfrd_flags == REPAT_SLAVE1) {
1801 /* xfrd needs stable reference so get
1802 * it from the oldopt(modified) tree */
1803 xfrd_init_slave_zone(xfrd, zone_opt);
1804 } else if (oldp->xfrd_flags == REPAT_MASTER2) {
1805 xfrd_del_slave_zone(xfrd,
1806 (const dname_type*)
1807 zone_opt->node.key);
1808 }
1809 oldp->xfrd_flags = 0;
1810 }
1811 }
1812 }
1813 repat_interrupt_notify_start(xfrd);
1814}
1815
1816/** true if options are different that can be set via repat. */
1817static int
1818repat_options_changed(xfrd_state_type* xfrd, struct nsd_options* newopt)
1819{
1820#ifdef RATELIMIT
1821 if(xfrd->nsd->options->rrl_ratelimit != newopt->rrl_ratelimit)
1822 return 1;
1823 if(xfrd->nsd->options->rrl_whitelist_ratelimit != newopt->rrl_whitelist_ratelimit)
1824 return 1;
1825 if(xfrd->nsd->options->rrl_slip != newopt->rrl_slip)
1826 return 1;
1827#else
1828 (void)xfrd; (void)newopt;
1829#endif
1830 return 0;
1831}
1832
1833/** check if global options have changed */
1834static void
1835repat_options(xfrd_state_type* xfrd, struct nsd_options* newopt)
1836{
1837 if(repat_options_changed(xfrd, newopt)) {
1838 /* update our options */
1839#ifdef RATELIMIT
1840 xfrd->nsd->options->rrl_ratelimit = newopt->rrl_ratelimit;
1841 xfrd->nsd->options->rrl_whitelist_ratelimit = newopt->rrl_whitelist_ratelimit;
1842 xfrd->nsd->options->rrl_slip = newopt->rrl_slip;
1843#endif
1844 task_new_opt_change(xfrd->nsd->task[xfrd->nsd->mytask],
1845 xfrd->last_task, newopt);
1846 xfrd_set_reload_now(xfrd);
1847 }
1848}
1849
1850/** print errors over ssl, gets pointer-to-pointer to ssl, so it can set
1851 * the pointer to NULL on failure and stop printing */
1852static void
1853print_ssl_cfg_err(void* arg, const char* str)
1854{
1855 RES** ssl = (RES**)arg;
1856 if(!*ssl) return;
1857 if(!ssl_printf(*ssl, "%s", str))
1858 *ssl = NULL((void *)0); /* failed, stop printing */
1859}
1860
1861/** do the repattern command: reread config file and apply keys, patterns */
1862static void
1863do_repattern(RES* ssl, xfrd_state_type* xfrd)
1864{
1865 region_type* region = region_create(xalloc, free);
1866 struct nsd_options* opt;
1867 const char* cfgfile = xfrd->nsd->options->configfile;
1868
1869 /* check chroot and configfile, if possible to reread */
1870 if(xfrd->nsd->chrootdir) {
1871 size_t l = strlen(xfrd->nsd->chrootdir);
1872 while(l>0 && xfrd->nsd->chrootdir[l-1] == '/')
1873 --l;
1874 if(strncmp(xfrd->nsd->chrootdir, cfgfile, l) != 0) {
1875 (void)ssl_printf(ssl, "error %s is not relative to %s: "
1876 "chroot prevents reread of config\n",
1877 cfgfile, xfrd->nsd->chrootdir);
1878 region_destroy(region);
1879 return;
1880 }
1881 cfgfile += l;
1882 }
1883
1884 (void)ssl_printf(ssl, "reconfig start, read %s\n", cfgfile);
1885 opt = nsd_options_create(region);
1886 if(!parse_options_file(opt, cfgfile, &print_ssl_cfg_err, &ssl)) {
1887 /* error already printed */
1888 region_destroy(region);
1889 return;
1890 }
1891 /* check for differences in TSIG keys and patterns, and apply,
1892 * first the keys, so that pattern->keyptr can be set right. */
1893 repat_keys(xfrd, opt);
1894 repat_patterns(xfrd, opt);
1895 repat_options(xfrd, opt);
1896 zonestat_inc_ifneeded(xfrd);
1897 send_ok(ssl);
1898 region_destroy(region);
1899}
1900
1901/** do the serverpid command: printout pid of server process */
1902static void
1903do_serverpid(RES* ssl, xfrd_state_type* xfrd)
1904{
1905 (void)ssl_printf(ssl, "%u\n", (unsigned)xfrd->reload_pid);
1906}
1907
1908/** do the print_tsig command: printout tsig info */
1909static void
1910do_print_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
1911{
1912 if(*arg == '\0') {
1913 struct key_options* key;
1914 RBTREE_FOR(key, struct key_options*, xfrd->nsd->options->keys)for(key=(struct key_options*)rbtree_first(xfrd->nsd->options
->keys); (rbnode_type*)key != &rbtree_null_node; key =
(struct key_options*)rbtree_next((rbnode_type*)key))
{
1915 if(!ssl_printf(ssl, "key: name: \"%s\" secret: \"%s\" algorithm: %s\n", key->name, key->secret, key->algorithm))
1916 return;
1917 }
1918 return;
1919 } else {
1920 struct key_options* key_opts = key_options_find(xfrd->nsd->options, arg);
1921 if(!key_opts) {
1922 (void)ssl_printf(ssl, "error: no such key with name: %s\n", arg);
1923 return;
1924 } else {
1925 (void)ssl_printf(ssl, "key: name: \"%s\" secret: \"%s\" algorithm: %s\n", arg, key_opts->secret, key_opts->algorithm);
1926 }
1927 }
1928}
1929
1930/** do the update_tsig command: change existing tsig to new secret */
1931static void
1932do_update_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
1933{
1934 struct region* region = xfrd->nsd->options->region;
1935 char* arg2 = NULL((void *)0);
1936 uint8_t data[65536]; /* 64K */
1937 struct key_options* key_opt;
1938
1939 if(*arg == '\0') {
1940 (void)ssl_printf(ssl, "error: missing argument (keyname)\n");
1941 return;
1942 }
1943 if(!find_arg2(ssl, arg, &arg2)) {
1944 (void)ssl_printf(ssl, "error: missing argument (secret)\n");
1945 return;
1946 }
1947 key_opt = key_options_find(xfrd->nsd->options, arg);
1948 if(!key_opt) {
1949 (void)ssl_printf(ssl, "error: no such key with name: %s\n", arg);
1950 memset(arg2, 0xdd, strlen(arg2));
1951 return;
1952 }
1953 if(__b64_pton(arg2, data, sizeof(data)) == -1) {
1954 (void)ssl_printf(ssl, "error: the secret: %s is not in b64 format\n", arg2);
1955 memset(data, 0xdd, sizeof(data)); /* wipe secret */
1956 memset(arg2, 0xdd, strlen(arg2));
1957 return;
1958 }
1959 log_msg(LOG_INFO6, "changing secret provided with the key: %s with old secret %s and algo: %s\n", arg, key_opt->secret, key_opt->algorithm);
1960 if(key_opt->secret) {
1961 /* wipe old secret */
1962 memset(key_opt->secret, 0xdd, strlen(key_opt->secret));
1963 region_recycle(region, key_opt->secret,
1964 strlen(key_opt->secret)+1);
1965 }
1966 key_opt->secret = region_strdup(region, arg2);
1967 log_msg(LOG_INFO6, "the key: %s has new secret %s and algorithm: %s\n", arg, key_opt->secret, key_opt->algorithm);
1968 /* wipe secret from temp parse buffer */
1969 memset(arg2, 0xdd, strlen(arg2));
1970 memset(data, 0xdd, sizeof(data));
1971
1972 key_options_desetup(region, key_opt);
1973 key_options_setup(region, key_opt);
1974 task_new_add_key(xfrd->nsd->task[xfrd->nsd->mytask], xfrd->last_task,
1975 key_opt);
1976 xfrd_set_reload_now(xfrd);
1977
1978 send_ok(ssl);
1979}
1980
1981/** do the add tsig command, add new key with name, secret and algo given */
1982static void
1983do_add_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
1984{
1985 char* arg2 = NULL((void *)0);
1986 char* arg3 = NULL((void *)0);
1987 uint8_t data[65536]; /* 64KB */
1988 uint8_t dname[MAXDOMAINLEN255+1];
1989 char algo[256];
1990 region_type* region = xfrd->nsd->options->region;
1991 struct key_options* new_key_opt;
1992
1993 if(*arg == '\0') {
1994 (void)ssl_printf(ssl, "error: missing argument (keyname)\n");
1995 return;
1996 }
1997 if(!find_arg3(ssl, arg, &arg2, &arg3)) {
1998 strlcpy(algo, "hmac-sha256", sizeof(algo));
1999 } else {
2000 strlcpy(algo, arg3, sizeof(algo));
2001 }
2002 if(!arg2) {
2003 (void)ssl_printf(ssl, "error: missing argument (secret)\n");
2004 return;
2005 }
2006 if(key_options_find(xfrd->nsd->options, arg)) {
2007 (void)ssl_printf(ssl, "error: key %s already exists\n", arg);
2008 memset(arg2, 0xdd, strlen(arg2));
2009 return;
2010 }
2011 if(__b64_pton(arg2, data, sizeof(data)) == -1) {
2012 (void)ssl_printf(ssl, "error: the secret: %s is not in b64 format\n", arg2);
2013 memset(data, 0xdd, sizeof(data)); /* wipe secret */
2014 memset(arg2, 0xdd, strlen(arg2));
2015 return;
2016 }
2017 memset(data, 0xdd, sizeof(data)); /* wipe secret from temp buffer */
2018 if(!dname_parse_wire(dname, arg)) {
2019 (void)ssl_printf(ssl, "error: could not parse key name: %s\n", arg);
2020 memset(arg2, 0xdd, strlen(arg2));
2021 return;
2022 }
2023 if(tsig_get_algorithm_by_name(algo) == NULL((void *)0)) {
2024 (void)ssl_printf(ssl, "error: unknown algorithm: %s\n", algo);
2025 memset(arg2, 0xdd, strlen(arg2));
2026 return;
2027 }
2028 log_msg(LOG_INFO6, "adding key with name: %s and secret: %s with algo: %s\n", arg, arg2, algo);
2029 new_key_opt = key_options_create(region);
2030 new_key_opt->name = region_strdup(region, arg);
2031 new_key_opt->secret = region_strdup(region, arg2);
2032 new_key_opt->algorithm = region_strdup(region, algo);
2033 add_key(xfrd, new_key_opt);
2034
2035 /* wipe secret from temp buffer */
2036 memset(arg2, 0xdd, strlen(arg2));
2037 send_ok(ssl);
2038}
2039
2040/** set acl entries to use the given TSIG key */
2041static void
2042zopt_set_acl_to_tsig(struct acl_options* acl, struct region* region,
2043 const char* key_name, struct key_options* key_opt)
2044{
2045 while(acl) {
2046 if(acl->blocked) {
2047 acl = acl->next;
2048 continue;
2049 }
2050 acl->nokey = 0;
2051 if(acl->key_name)
2052 region_recycle(region, (void*)acl->key_name,
2053 strlen(acl->key_name)+1);
2054 acl->key_name = region_strdup(region, key_name);
2055 acl->key_options = key_opt;
2056 acl = acl->next;
2057 }
2058}
2059
2060/** do the assoc_tsig command: associate the zone to use the tsig name */
2061static void
2062do_assoc_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
2063{
2064 region_type* region = xfrd->nsd->options->region;
2065 char* arg2 = NULL((void *)0);
2066 struct zone_options* zone;
2067 struct key_options* key_opt;
2068
2069 if(*arg == '\0') {
2070 (void)ssl_printf(ssl, "error: missing argument (zonename)\n");
2071 return;
2072 }
2073 if(!find_arg2(ssl, arg, &arg2)) {
2074 (void)ssl_printf(ssl, "error: missing argument (keyname)\n");
2075 return;
2076 }
2077
2078 if(!get_zone_arg(ssl, xfrd, arg, &zone))
2079 return;
2080 if(!zone) {
2081 (void)ssl_printf(ssl, "error: missing argument (zone)\n");
2082 return;
2083 }
2084 key_opt = key_options_find(xfrd->nsd->options, arg2);
2085 if(!key_opt) {
2086 (void)ssl_printf(ssl, "error: key: %s does not exist\n", arg2);
2087 return;
2088 }
2089
2090 zopt_set_acl_to_tsig(zone->pattern->allow_notify, region, arg2,
2091 key_opt);
2092 zopt_set_acl_to_tsig(zone->pattern->notify, region, arg2, key_opt);
2093 zopt_set_acl_to_tsig(zone->pattern->request_xfr, region, arg2,
2094 key_opt);
2095 zopt_set_acl_to_tsig(zone->pattern->provide_xfr, region, arg2,
2096 key_opt);
2097 zopt_set_acl_to_tsig(zone->pattern->allow_query, region, arg2,
2098 key_opt);
2099
2100 task_new_add_pattern(xfrd->nsd->task[xfrd->nsd->mytask],
2101 xfrd->last_task, zone->pattern);
2102 xfrd_set_reload_now(xfrd);
2103
2104 send_ok(ssl);
2105}
2106
2107/** see if TSIG key is used in the acl */
2108static int
2109acl_contains_tsig_key(struct acl_options* acl, const char* name)
2110{
2111 while(acl) {
2112 if(acl->key_name && strcmp(acl->key_name, name) == 0)
2113 return 1;
2114 acl = acl->next;
2115 }
2116 return 0;
2117}
2118
2119/** do the del_tsig command, remove an (unused) tsig */
2120static void
2121do_del_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg) {
2122 int used_key = 0;
2123 struct zone_options* zone;
2124 struct key_options* key_opt;
2125
2126 if(*arg == '\0') {
2127 (void)ssl_printf(ssl, "error: missing argument (keyname)\n");
2128 return;
2129 }
2130 key_opt = key_options_find(xfrd->nsd->options, arg);
2131 if(!key_opt) {
2132 (void)ssl_printf(ssl, "key %s does not exist, nothing to be deleted\n", arg);
2133 return;
2134 }
2135 RBTREE_FOR(zone, struct zone_options*, xfrd->nsd->options->zone_options)for(zone=(struct zone_options*)rbtree_first(xfrd->nsd->
options->zone_options); (rbnode_type*)zone != &rbtree_null_node
; zone = (struct zone_options*)rbtree_next((rbnode_type*)zone
))
2136 {
2137 if(acl_contains_tsig_key(zone->pattern->allow_notify, arg) ||
2138 acl_contains_tsig_key(zone->pattern->notify, arg) ||
2139 acl_contains_tsig_key(zone->pattern->request_xfr, arg) ||
2140 acl_contains_tsig_key(zone->pattern->provide_xfr, arg) ||
2141 acl_contains_tsig_key(zone->pattern->allow_query, arg)) {
2142 if(!ssl_printf(ssl, "zone %s uses key %s\n",
2143 zone->name, arg))
2144 return;
2145 used_key = 1;
2146 break;
2147 }
2148 }
2149
2150 if(used_key) {
2151 (void)ssl_printf(ssl, "error: key: %s is in use and cannot be deleted\n", arg);
2152 return;
2153 } else {
2154 remove_key(xfrd, arg);
2155 log_msg(LOG_INFO6, "key: %s is successfully deleted\n", arg);
2156 }
2157
2158 send_ok(ssl);
2159}
2160
2161/* returns `0` on failure */
2162static int
2163cookie_secret_file_dump(RES* ssl, nsd_type const* nsd) {
2164 char const* secret_file = nsd->options->cookie_secret_file;
2165 char secret_hex[NSD_COOKIE_SECRET_SIZE16 * 2 + 1];
2166 FILE* f;
2167 size_t i;
2168 assert( secret_file != NULL )((void)0);
2169
2170 /* open write only and truncate */
2171 if((f = fopen(secret_file, "w")) == NULL((void *)0) ) {
2172 (void)ssl_printf(ssl, "unable to open cookie secret file %s: %s",
2173 secret_file, strerror(errno(*__errno())));
2174 return 0;
2175 }
2176 for(i = 0; i < nsd->cookie_count; i++) {
2177 struct cookie_secret const* cs = &nsd->cookie_secrets[i];
2178 ssize_t const len = hex_ntop(cs->cookie_secret, NSD_COOKIE_SECRET_SIZE16,
2179 secret_hex, sizeof(secret_hex));
2180 (void)len; /* silence unused variable warning with -DNDEBUG */
2181 assert( len == NSD_COOKIE_SECRET_SIZE * 2 )((void)0);
2182 secret_hex[NSD_COOKIE_SECRET_SIZE16 * 2] = '\0';
2183 fprintf(f, "%s\n", secret_hex);
2184 }
2185 explicit_bzero(secret_hex, sizeof(secret_hex));
2186 fclose(f);
2187 return 1;
2188}
2189
2190static void
2191do_activate_cookie_secret(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2192 nsd_type* nsd = xrfd->nsd;
2193 (void)arg;
2194
2195 if(nsd->cookie_count <= 1 ) {
2196 (void)ssl_printf(ssl, "error: no staging cookie secret to activate\n");
2197 return;
2198 }
2199 if(!nsd->options->cookie_secret_file || !nsd->options->cookie_secret_file[0]) {
2200 (void)ssl_printf(ssl, "error: no cookie secret file configured\n");
2201 return;
2202 }
2203 if(!cookie_secret_file_dump(ssl, nsd)) {
2204 (void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
2205 nsd->options->cookie_secret_file);
2206 return;
2207 }
2208 activate_cookie_secret(nsd);
2209 (void)cookie_secret_file_dump(ssl, nsd);
2210 task_new_activate_cookie_secret(xfrd->nsd->task[xfrd->nsd->mytask],
2211 xfrd->last_task);
2212 xfrd_set_reload_now(xfrd);
2213 send_ok(ssl);
2214}
2215
2216static void
2217do_drop_cookie_secret(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2218 nsd_type* nsd = xrfd->nsd;
2219 (void)arg;
2220
2221 if(nsd->cookie_count <= 1 ) {
2222 (void)ssl_printf(ssl, "error: can not drop the currently active cookie secret\n");
2223 return;
2224 }
2225 if(!nsd->options->cookie_secret_file || !nsd->options->cookie_secret_file[0]) {
2226 (void)ssl_printf(ssl, "error: no cookie secret file configured\n");
2227 return;
2228 }
2229 if(!cookie_secret_file_dump(ssl, nsd)) {
2230 (void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
2231 nsd->options->cookie_secret_file);
2232 return;
2233 }
2234 drop_cookie_secret(nsd);
2235 (void)cookie_secret_file_dump(ssl, nsd);
2236 task_new_drop_cookie_secret(xfrd->nsd->task[xfrd->nsd->mytask],
2237 xfrd->last_task);
2238 xfrd_set_reload_now(xfrd);
2239 send_ok(ssl);
2240}
2241
2242static void
2243do_add_cookie_secret(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2244 nsd_type* nsd = xrfd->nsd;
2245 uint8_t secret[NSD_COOKIE_SECRET_SIZE16];
2246
2247 if(*arg == '\0') {
2248 (void)ssl_printf(ssl, "error: missing argument (cookie_secret)\n");
2249 return;
2250 }
2251 if(strlen(arg) != 32) {
2252 explicit_bzero(arg, strlen(arg));
2253 (void)ssl_printf(ssl, "invalid cookie secret: invalid argument length\n");
2254 (void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
2255 return;
2256 }
2257 if(hex_pton(arg, secret, NSD_COOKIE_SECRET_SIZE16) != NSD_COOKIE_SECRET_SIZE16 ) {
2258 explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE16);
2259 explicit_bzero(arg, strlen(arg));
2260 (void)ssl_printf(ssl, "invalid cookie secret: parse error\n");
2261 (void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
2262 return;
2263 }
2264 if(!nsd->options->cookie_secret_file || !nsd->options->cookie_secret_file[0]) {
2265 explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE16);
2266 explicit_bzero(arg, strlen(arg));
2267 (void)ssl_printf(ssl, "error: no cookie secret file configured\n");
2268 return;
2269 }
2270 if(!cookie_secret_file_dump(ssl, nsd)) {
2271 explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE16);
2272 explicit_bzero(arg, strlen(arg));
2273 (void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
2274 nsd->options->cookie_secret_file);
2275 return;
2276 }
2277 add_cookie_secret(nsd, secret);
2278 explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE16);
2279 (void)cookie_secret_file_dump(ssl, nsd);
2280 task_new_add_cookie_secret(xfrd->nsd->task[xfrd->nsd->mytask],
2281 xfrd->last_task, arg);
2282 explicit_bzero(arg, strlen(arg));
2283 xfrd_set_reload_now(xfrd);
2284 send_ok(ssl);
2285}
2286
2287static void
2288do_print_cookie_secrets(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2289 nsd_type* nsd = xrfd->nsd;
2290 char secret_hex[NSD_COOKIE_SECRET_SIZE16 * 2 + 1];
2291 int i;
2292 (void)arg;
2293
2294 /* (void)ssl_printf(ssl, "cookie_secret_count=%zu\n", nsd->cookie_count); */
2295 for(i = 0; (size_t)i < nsd->cookie_count; i++) {
2296 struct cookie_secret const* cs = &nsd->cookie_secrets[i];
2297 ssize_t const len = hex_ntop(cs->cookie_secret, NSD_COOKIE_SECRET_SIZE16,
2298 secret_hex, sizeof(secret_hex));
2299 (void)len; /* silence unused variable warning with -DNDEBUG */
2300 assert( len == NSD_COOKIE_SECRET_SIZE * 2 )((void)0);
2301 secret_hex[NSD_COOKIE_SECRET_SIZE16 * 2] = '\0';
2302 if (i == 0)
2303 (void)ssl_printf(ssl, "active : %s\n", secret_hex);
2304 else if (nsd->cookie_count == 2)
2305 (void)ssl_printf(ssl, "staging: %s\n", secret_hex);
2306 else
2307 (void)ssl_printf(ssl, "staging[%d]: %s\n", i, secret_hex);
2308 }
2309 explicit_bzero(secret_hex, sizeof(secret_hex));
2310}
2311
2312/** check for name with end-of-string, space or tab after it */
2313static int
2314cmdcmp(char* p, const char* cmd, size_t len)
2315{
2316 return strncmp(p,cmd,len)==0 && (p[len]==0||p[len]==' '||p[len]=='\t');
2317}
2318
2319/** execute a remote control command */
2320static void
2321execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
2322{
2323 char* p = skipwhite(cmd);
2324 /* compare command */
2325 if(cmdcmp(p, "stop", 4)) {
2326 do_stop(ssl, rc->xfrd);
2327 } else if(cmdcmp(p, "reload", 6)) {
2328 do_reload(ssl, rc->xfrd, skipwhite(p+6));
2329 } else if(cmdcmp(p, "write", 5)) {
2330 do_write(ssl, rc->xfrd, skipwhite(p+5));
2331 } else if(cmdcmp(p, "status", 6)) {
2332 do_status(ssl, rc->xfrd);
2333 } else if(cmdcmp(p, "stats_noreset", 13)) {
2334 do_stats(ssl, rc->xfrd, 1);
2335 } else if(cmdcmp(p, "stats", 5)) {
2336 do_stats(ssl, rc->xfrd, 0);
2337 } else if(cmdcmp(p, "log_reopen", 10)) {
2338 do_log_reopen(ssl, rc->xfrd);
2339 } else if(cmdcmp(p, "addzone", 7)) {
2340 do_addzone(ssl, rc->xfrd, skipwhite(p+7));
2341 } else if(cmdcmp(p, "delzone", 7)) {
2342 do_delzone(ssl, rc->xfrd, skipwhite(p+7));
2343 } else if(cmdcmp(p, "changezone", 10)) {
2344 do_changezone(ssl, rc->xfrd, skipwhite(p+10));
2345 } else if(cmdcmp(p, "addzones", 8)) {
2346 do_addzones(ssl, rc->xfrd);
2347 } else if(cmdcmp(p, "delzones", 8)) {
2348 do_delzones(ssl, rc->xfrd);
2349 } else if(cmdcmp(p, "notify", 6)) {
2350 do_notify(ssl, rc->xfrd, skipwhite(p+6));
2351 } else if(cmdcmp(p, "transfer", 8)) {
2352 do_transfer(ssl, rc->xfrd, skipwhite(p+8));
2353 } else if(cmdcmp(p, "force_transfer", 14)) {
2354 do_force_transfer(ssl, rc->xfrd, skipwhite(p+14));
2355 } else if(cmdcmp(p, "zonestatus", 10)) {
2356 do_zonestatus(ssl, rc->xfrd, skipwhite(p+10));
2357 } else if(cmdcmp(p, "verbosity", 9)) {
2358 do_verbosity(ssl, skipwhite(p+9));
2359 } else if(cmdcmp(p, "repattern", 9)) {
2360 do_repattern(ssl, rc->xfrd);
2361 } else if(cmdcmp(p, "reconfig", 8)) {
2362 do_repattern(ssl, rc->xfrd);
2363 } else if(cmdcmp(p, "serverpid", 9)) {
2364 do_serverpid(ssl, rc->xfrd);
2365 } else if(cmdcmp(p, "print_tsig", 10)) {
2366 do_print_tsig(ssl, rc->xfrd, skipwhite(p+10));
2367 } else if(cmdcmp(p, "update_tsig", 11)) {
2368 do_update_tsig(ssl, rc->xfrd, skipwhite(p+11));
2369 } else if(cmdcmp(p, "add_tsig", 8)) {
2370 do_add_tsig(ssl, rc->xfrd, skipwhite(p+8));
2371 } else if(cmdcmp(p, "assoc_tsig", 10)) {
2372 do_assoc_tsig(ssl, rc->xfrd, skipwhite(p+10));
2373 } else if(cmdcmp(p, "del_tsig", 8)) {
2374 do_del_tsig(ssl, rc->xfrd, skipwhite(p+8));
2375 } else if(cmdcmp(p, "add_cookie_secret", 17)) {
2376 do_add_cookie_secret(ssl, rc->xfrd, skipwhite(p+17));
2377 } else if(cmdcmp(p, "drop_cookie_secret", 18)) {
2378 do_drop_cookie_secret(ssl, rc->xfrd, skipwhite(p+18));
2379 } else if(cmdcmp(p, "print_cookie_secrets", 20)) {
2380 do_print_cookie_secrets(ssl, rc->xfrd, skipwhite(p+20));
2381 } else if(cmdcmp(p, "activate_cookie_secret", 22)) {
2382 do_activate_cookie_secret(ssl, rc->xfrd, skipwhite(p+22));
2383 } else {
2384 (void)ssl_printf(ssl, "error unknown command '%s'\n", p);
2385 }
2386}
2387
2388/** handle remote control request */
2389static void
2390handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
2391{
2392 int r;
2393 char pre[10];
2394 char magic[8];
2395 char buf[1024];
2396 if (fcntl(s->c.ev_fd, F_SETFL4, 0) == -1) { /* set blocking */
2397 log_msg(LOG_ERR3, "cannot fcntl rc: %s", strerror(errno(*__errno())));
2398 }
2399
2400 /* try to read magic UBCT[version]_space_ string */
2401#ifdef HAVE_SSL
2402 if(res->ssl) {
2403 ERR_clear_error();
2404 if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) {
2405 if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN6)
2406 return;
2407 log_crypto_err("could not SSL_read");
2408 return;
2409 }
2410 } else {
2411#endif /* HAVE_SSL */
2412 while(1) {
2413 ssize_t rr = read(res->fd, magic, sizeof(magic)-1);
2414 if(rr <= 0) {
2415 if(rr == 0) return;
2416 if(errno(*__errno()) == EINTR4 || errno(*__errno()) == EAGAIN35)
2417 continue;
2418 log_msg(LOG_ERR3, "could not read: %s", strerror(errno(*__errno())));
2419 return;
2420 }
2421 r = (int)rr;
2422 break;
2423 }
2424#ifdef HAVE_SSL
2425 }
2426#endif /* HAVE_SSL */
2427 magic[7] = 0;
2428 if( r != 7 || strncmp(magic, "NSDCT", 5) != 0) {
2429 VERBOSITY(2, (LOG_INFO, "control connection has bad header"))do { if ((2) <= verbosity) { log_msg (6, "control connection has bad header"
) ; } } while (0)
;
2430 /* probably wrong tool connected, ignore it completely */
2431 return;
2432 }
2433
2434 /* read the command line */
2435 if(!ssl_read_line(res, buf, sizeof(buf))) {
2436 return;
2437 }
2438 snprintf(pre, sizeof(pre), "NSDCT%d ", NSD_CONTROL_VERSION1);
2439 if(strcmp(magic, pre) != 0) {
2440 VERBOSITY(2, (LOG_INFO, "control connection had bad "do { if ((2) <= verbosity) { log_msg (6, "control connection had bad "
"version %s, cmd: %s", magic, buf) ; } } while (0)
2441 "version %s, cmd: %s", magic, buf))do { if ((2) <= verbosity) { log_msg (6, "control connection had bad "
"version %s, cmd: %s", magic, buf) ; } } while (0)
;
2442 (void)ssl_printf(res, "error version mismatch\n");
2443 return;
2444 }
2445 /* always log control commands */
2446 VERBOSITY(0, (LOG_INFO, "control cmd: %s", buf))do { if ((0) <= verbosity) { log_msg (6, "control cmd: %s"
, buf) ; } } while (0)
;
2447
2448 /* figure out what to do */
2449 execute_cmd(rc, res, buf);
2450}
2451
2452#ifdef HAVE_SSL
2453/** handle SSL_do_handshake changes to the file descriptor to wait for later */
2454static void
2455remote_handshake_later(struct daemon_remote* rc, struct rc_state* s, int fd,
2456 int r, int r2)
2457{
2458 if(r2 == SSL_ERROR_WANT_READ2) {
2459 if(s->shake_state == rc_hs_read) {
2460 /* try again later */
2461 return;
2462 }
2463 s->shake_state = rc_hs_read;
2464 event_del(&s->c);
2465 memset(&s->c, 0, sizeof(s->c));
2466 event_set(&s->c, fd, EV_PERSIST0x10|EV_TIMEOUT0x01|EV_READ0x02,
2467 remote_control_callback, s);
2468 if(event_base_set(xfrd->event_base, &s->c) != 0)
2469 log_msg(LOG_ERR3, "remote_accept: cannot set event_base");
2470 if(event_add(&s->c, &s->tval) != 0)
2471 log_msg(LOG_ERR3, "remote_accept: cannot add event");
2472 return;
2473 } else if(r2 == SSL_ERROR_WANT_WRITE3) {
2474 if(s->shake_state == rc_hs_write) {
2475 /* try again later */
2476 return;
2477 }
2478 s->shake_state = rc_hs_write;
2479 event_del(&s->c);
2480 memset(&s->c, 0, sizeof(s->c));
2481 event_set(&s->c, fd, EV_PERSIST0x10|EV_TIMEOUT0x01|EV_WRITE0x04,
2482 remote_control_callback, s);
2483 if(event_base_set(xfrd->event_base, &s->c) != 0)
2484 log_msg(LOG_ERR3, "remote_accept: cannot set event_base");
2485 if(event_add(&s->c, &s->tval) != 0)
2486 log_msg(LOG_ERR3, "remote_accept: cannot add event");
2487 return;
2488 } else {
2489 if(r == 0)
2490 log_msg(LOG_ERR3, "remote control connection closed prematurely");
2491 log_crypto_err("remote control failed ssl");
2492 clean_point(rc, s);
2493 }
2494}
2495#endif /* HAVE_SSL */
2496
2497static void
2498remote_control_callback(int fd, short event, void* arg)
2499{
2500 RES res;
2501 struct rc_state* s = (struct rc_state*)arg;
2502 struct daemon_remote* rc = s->rc;
2503 if( (event&EV_TIMEOUT0x01) ) {
2504 log_msg(LOG_ERR3, "remote control timed out");
2505 clean_point(rc, s);
2506 return;
2507 }
2508#ifdef HAVE_SSL
2509 if(s->ssl) {
2510 /* (continue to) setup the SSL connection */
2511 int r;
2512 ERR_clear_error();
2513 r = SSL_do_handshake(s->ssl);
2514 if(r != 1) {
2515 int r2 = SSL_get_error(s->ssl, r);
2516 remote_handshake_later(rc, s, fd, r, r2);
2517 return;
2518 }
2519 s->shake_state = rc_none;
2520 }
2521#endif /* HAVE_SSL */
2522
2523 /* once handshake has completed, check authentication */
2524 if (!rc->use_cert) {
2525 VERBOSITY(3, (LOG_INFO, "unauthenticated remote control connection"))do { if ((3) <= verbosity) { log_msg (6, "unauthenticated remote control connection"
) ; } } while (0)
;
2526#ifdef HAVE_SSL
2527 } else if(SSL_get_verify_result(s->ssl) == X509_V_OK0) {
2528 X509* x = SSL_get_peer_certificate(s->ssl);
2529 if(!x) {
2530 VERBOSITY(2, (LOG_INFO, "remote control connection "do { if ((2) <= verbosity) { log_msg (6, "remote control connection "
"provided no client certificate") ; } } while (0)
2531 "provided no client certificate"))do { if ((2) <= verbosity) { log_msg (6, "remote control connection "
"provided no client certificate") ; } } while (0)
;
2532 clean_point(rc, s);
2533 return;
2534 }
2535 VERBOSITY(3, (LOG_INFO, "remote control connection authenticated"))do { if ((3) <= verbosity) { log_msg (6, "remote control connection authenticated"
) ; } } while (0)
;
2536 X509_free(x);
2537#endif /* HAVE_SSL */
2538 } else {
2539 VERBOSITY(2, (LOG_INFO, "remote control connection failed to "do { if ((2) <= verbosity) { log_msg (6, "remote control connection failed to "
"authenticate with client certificate") ; } } while (0)
2540 "authenticate with client certificate"))do { if ((2) <= verbosity) { log_msg (6, "remote control connection failed to "
"authenticate with client certificate") ; } } while (0)
;
2541 clean_point(rc, s);
2542 return;
2543 }
2544
2545 /* if OK start to actually handle the request */
2546#ifdef HAVE_SSL
2547 res.ssl = s->ssl;
2548#endif /* HAVE_SSL */
2549 res.fd = fd;
2550 handle_req(rc, s, &res);
2551
2552 VERBOSITY(3, (LOG_INFO, "remote control operation completed"))do { if ((3) <= verbosity) { log_msg (6, "remote control operation completed"
) ; } } while (0)
;
2553 clean_point(rc, s);
2554}
2555
2556#ifdef BIND8_STATS
2557static const char*
2558opcode2str(int o)
2559{
2560 switch(o) {
2561 case OPCODE_QUERY0: return "QUERY";
2562 case OPCODE_IQUERY1: return "IQUERY";
2563 case OPCODE_STATUS2: return "STATUS";
2564 case OPCODE_NOTIFY4: return "NOTIFY";
2565 case OPCODE_UPDATE5: return "UPDATE";
2566 default: return "OTHER";
2567 }
2568}
2569
2570/** print long number */
2571static int
2572print_longnum(RES* ssl, char* desc, uint64_t x)
2573{
2574 if(x > (uint64_t)1024*1024*1024) {
2575 /* more than a Gb */
2576 size_t front = (size_t)(x / (uint64_t)1000000);
2577 size_t back = (size_t)(x % (uint64_t)1000000);
2578 return ssl_printf(ssl, "%s%lu%6.6lu\n", desc,
2579 (unsigned long)front, (unsigned long)back);
2580 } else {
2581 return ssl_printf(ssl, "%s%lu\n", desc, (unsigned long)x);
2582 }
2583}
2584
2585/* print one block of statistics. n is name and d is delimiter */
2586static void
2587print_stat_block(RES* ssl, char* n, char* d, struct nsdst* st)
2588{
2589 const char* rcstr[] = {"NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN",
2590 "NOTIMP", "REFUSED", "YXDOMAIN", "YXRRSET", "NXRRSET", "NOTAUTH",
2591 "NOTZONE", "RCODE11", "RCODE12", "RCODE13", "RCODE14", "RCODE15",
2592 "BADVERS"
2593 };
2594 size_t i;
2595 for(i=0; i<= 255; i++) {
2596 if(inhibit_zero && st->qtype[i] == 0 &&
2597 strncmp(rrtype_to_string(i), "TYPE", 4) == 0)
2598 continue;
2599 if(!ssl_printf(ssl, "%s%snum.type.%s=%lu\n", n, d,
2600 rrtype_to_string(i), (unsigned long)st->qtype[i]))
2601 return;
2602 }
2603
2604 /* opcode */
2605 for(i=0; i<6; i++) {
2606 if(inhibit_zero && st->opcode[i] == 0 && i != OPCODE_QUERY0)
2607 continue;
2608 if(!ssl_printf(ssl, "%s%snum.opcode.%s=%lu\n", n, d,
2609 opcode2str(i), (unsigned long)st->opcode[i]))
2610 return;
2611 }
2612
2613 /* qclass */
2614 for(i=0; i<4; i++) {
2615 if(inhibit_zero && st->qclass[i] == 0 && i != CLASS_IN1)
2616 continue;
2617 if(!ssl_printf(ssl, "%s%snum.class.%s=%lu\n", n, d,
2618 rrclass_to_string(i), (unsigned long)st->qclass[i]))
2619 return;
2620 }
2621
2622 /* rcode */
2623 for(i=0; i<17; i++) {
2624 if(inhibit_zero && st->rcode[i] == 0 &&
2625 i > RCODE_YXDOMAIN6) /* NSD does not use larger */
2626 continue;
2627 if(!ssl_printf(ssl, "%s%snum.rcode.%s=%lu\n", n, d, rcstr[i],
2628 (unsigned long)st->rcode[i]))
2629 return;
2630 }
2631
2632 /* edns */
2633 if(!ssl_printf(ssl, "%s%snum.edns=%lu\n", n, d, (unsigned long)st->edns))
2634 return;
2635
2636 /* ednserr */
2637 if(!ssl_printf(ssl, "%s%snum.ednserr=%lu\n", n, d,
2638 (unsigned long)st->ednserr))
2639 return;
2640
2641 /* qudp */
2642 if(!ssl_printf(ssl, "%s%snum.udp=%lu\n", n, d, (unsigned long)st->qudp))
2643 return;
2644 /* qudp6 */
2645 if(!ssl_printf(ssl, "%s%snum.udp6=%lu\n", n, d, (unsigned long)st->qudp6))
2646 return;
2647 /* ctcp */
2648 if(!ssl_printf(ssl, "%s%snum.tcp=%lu\n", n, d, (unsigned long)st->ctcp))
2649 return;
2650 /* ctcp6 */
2651 if(!ssl_printf(ssl, "%s%snum.tcp6=%lu\n", n, d, (unsigned long)st->ctcp6))
2652 return;
2653 /* ctls */
2654 if(!ssl_printf(ssl, "%s%snum.tls=%lu\n", n, d, (unsigned long)st->ctls))
2655 return;
2656 /* ctls6 */
2657 if(!ssl_printf(ssl, "%s%snum.tls6=%lu\n", n, d, (unsigned long)st->ctls6))
2658 return;
2659
2660 /* nona */
2661 if(!ssl_printf(ssl, "%s%snum.answer_wo_aa=%lu\n", n, d,
2662 (unsigned long)st->nona))
2663 return;
2664
2665 /* rxerr */
2666 if(!ssl_printf(ssl, "%s%snum.rxerr=%lu\n", n, d, (unsigned long)st->rxerr))
2667 return;
2668
2669 /* txerr */
2670 if(!ssl_printf(ssl, "%s%snum.txerr=%lu\n", n, d, (unsigned long)st->txerr))
2671 return;
2672
2673 /* number of requested-axfr, number of times axfr served to clients */
2674 if(!ssl_printf(ssl, "%s%snum.raxfr=%lu\n", n, d, (unsigned long)st->raxfr))
2675 return;
2676
2677 /* number of requested-ixfr, number of times ixfr served to clients */
2678 if(!ssl_printf(ssl, "%s%snum.rixfr=%lu\n", n, d, (unsigned long)st->rixfr))
2679 return;
2680
2681 /* truncated */
2682 if(!ssl_printf(ssl, "%s%snum.truncated=%lu\n", n, d,
2683 (unsigned long)st->truncated))
2684 return;
2685
2686 /* dropped */
2687 if(!ssl_printf(ssl, "%s%snum.dropped=%lu\n", n, d,
2688 (unsigned long)st->dropped))
2689 return;
2690}
2691
2692#ifdef USE_ZONE_STATS
2693static void
2694resize_zonestat(xfrd_state_type* xfrd, size_t num)
2695{
2696 struct nsdst** a = xalloc_array_zero(num, sizeof(struct nsdst*));
2697 if(xfrd->zonestat_clear_num != 0)
2698 memcpy(a, xfrd->zonestat_clear, xfrd->zonestat_clear_num
2699 * sizeof(struct nsdst*));
2700 free(xfrd->zonestat_clear);
2701 xfrd->zonestat_clear = a;
2702 xfrd->zonestat_clear_num = num;
2703}
2704
2705static void
2706zonestat_print(RES* ssl, xfrd_state_type* xfrd, int clear,
2707 struct nsdst** zonestats)
2708{
2709 struct zonestatname* n;
2710 struct nsdst stat0, stat1;
2711 RBTREE_FOR(n, struct zonestatname*, xfrd->nsd->options->zonestatnames)for(n=(struct zonestatname*)rbtree_first(xfrd->nsd->options
->zonestatnames); (rbnode_type*)n != &rbtree_null_node
; n = (struct zonestatname*)rbtree_next((rbnode_type*)n))
{
2712 char* name = (char*)n->node.key;
2713 if(n->id >= xfrd->zonestat_safe)
2714 continue; /* newly allocated and reload has not yet
2715 done and replied with new size */
2716 if(name == NULL((void *)0) || name[0]==0)
2717 continue; /* empty name, do not output */
2718 /* the statistics are stored in two blocks, during reload
2719 * the newly forked processes get the other block to use,
2720 * these blocks are mmapped and are currently in use to
2721 * add statistics to */
2722 memcpy(&stat0, &zonestats[0][n->id], sizeof(stat0));
2723 memcpy(&stat1, &zonestats[1][n->id], sizeof(stat1));
2724 stats_add(&stat0, &stat1);
2725
2726 /* save a copy of current (cumulative) stats in stat1 */
2727 memcpy(&stat1, &stat0, sizeof(stat1));
2728 /* subtract last total of stats that was 'cleared' */
2729 if(n->id < xfrd->zonestat_clear_num &&
2730 xfrd->zonestat_clear[n->id])
2731 stats_subtract(&stat0, xfrd->zonestat_clear[n->id]);
2732 if(clear) {
2733 /* extend storage array if needed */
2734 if(n->id >= xfrd->zonestat_clear_num) {
2735 if(n->id+1 < xfrd->nsd->options->zonestatnames->count)
2736 resize_zonestat(xfrd, xfrd->nsd->options->zonestatnames->count);
2737 else
2738 resize_zonestat(xfrd, n->id+1);
2739 }
2740 if(!xfrd->zonestat_clear[n->id])
2741 xfrd->zonestat_clear[n->id] = xalloc(
2742 sizeof(struct nsdst));
2743 /* store last total of stats */
2744 memcpy(xfrd->zonestat_clear[n->id], &stat1,
2745 sizeof(struct nsdst));
2746 }
2747
2748 /* stat0 contains the details that we want to print */
2749 if(!ssl_printf(ssl, "%s%snum.queries=%lu\n", name, ".",
2750 (unsigned long)(stat0.qudp + stat0.qudp6 + stat0.ctcp +
2751 stat0.ctcp6 + stat0.ctls + stat0.ctls6)))
2752 return;
2753 print_stat_block(ssl, name, ".", &stat0);
2754 }
2755}
2756#endif /* USE_ZONE_STATS */
2757
2758static void
2759print_stats(RES* ssl, xfrd_state_type* xfrd, struct timeval* now, int clear,
2760 struct nsdst* st, struct nsdst** zonestats)
2761{
2762 size_t i;
2763 stc_type total = 0;
2764 struct timeval elapsed, uptime;
2765
2766 /* per CPU and total */
2767 for(i=0; i<xfrd->nsd->child_count; i++) {
2768 if(!ssl_printf(ssl, "server%d.queries=%lu\n", (int)i,
2769 (unsigned long)xfrd->nsd->children[i].query_count))
2770 return;
2771 total += xfrd->nsd->children[i].query_count;
2772 }
2773 if(!ssl_printf(ssl, "num.queries=%lu\n", (unsigned long)total))
2774 return;
2775
2776 /* time elapsed and uptime (in seconds) */
2777 timeval_subtract(&uptime, now, &xfrd->nsd->rc->boot_time);
2778 timeval_subtract(&elapsed, now, &xfrd->nsd->rc->stats_time);
2779 if(!ssl_printf(ssl, "time.boot=%lu.%6.6lu\n",
2780 (unsigned long)uptime.tv_sec, (unsigned long)uptime.tv_usec))
2781 return;
2782 if(!ssl_printf(ssl, "time.elapsed=%lu.%6.6lu\n",
2783 (unsigned long)elapsed.tv_sec, (unsigned long)elapsed.tv_usec))
2784 return;
2785
2786 /* mem info, database on disksize */
2787 if(!print_longnum(ssl, "size.db.disk=", st->db_disk))
2788 return;
2789 if(!print_longnum(ssl, "size.db.mem=", st->db_mem))
2790 return;
2791 if(!print_longnum(ssl, "size.xfrd.mem=", region_get_mem(xfrd->region)))
2792 return;
2793 if(!print_longnum(ssl, "size.config.disk=",
2794 xfrd->nsd->options->zonelist_off))
2795 return;
2796 if(!print_longnum(ssl, "size.config.mem=", region_get_mem(
2797 xfrd->nsd->options->region)))
2798 return;
2799 print_stat_block(ssl, "", "", st);
2800
2801 /* zone statistics */
2802 if(!ssl_printf(ssl, "zone.master=%lu\n",
2803 (unsigned long)(xfrd->notify_zones->count - xfrd->zones->count)))
2804 return;
2805 if(!ssl_printf(ssl, "zone.slave=%lu\n", (unsigned long)xfrd->zones->count))
2806 return;
2807#ifdef USE_ZONE_STATS
2808 zonestat_print(ssl, xfrd, clear, zonestats); /* per-zone statistics */
2809#else
2810 (void)clear; (void)zonestats;
2811#endif
2812}
2813
2814/* allocate stats temp arrays, for taking a coherent snapshot of the
2815 * statistics values at that time. */
2816static void
2817process_stats_alloc(xfrd_state_type* xfrd, struct nsdst** stats,
2818 struct nsdst** zonestats)
2819{
2820 *stats = xmallocarray(xfrd->nsd->child_count*2, sizeof(struct nsdst));
2821#ifdef USE_ZONE_STATS
2822 zonestats[0] = xmallocarray(xfrd->zonestat_safe, sizeof(struct nsdst));
2823 zonestats[1] = xmallocarray(xfrd->zonestat_safe, sizeof(struct nsdst));
2824#else
2825 (void)zonestats;
2826#endif
2827}
2828
2829/* grab a copy of the statistics, at this particular time. */
2830static void
2831process_stats_grab(xfrd_state_type* xfrd, struct timeval* stattime,
2832 struct nsdst* stats, struct nsdst** zonestats)
2833{
2834 if(gettimeofday(stattime, NULL((void *)0)) == -1)
2835 log_msg(LOG_ERR3, "gettimeofday: %s", strerror(errno(*__errno())));
2836 memcpy(stats, xfrd->nsd->stat_map,
2837 xfrd->nsd->child_count*2*sizeof(struct nsdst));
2838#ifdef USE_ZONE_STATS
2839 memcpy(zonestats[0], xfrd->nsd->zonestat[0],
2840 xfrd->zonestat_safe*sizeof(struct nsdst));
2841 memcpy(zonestats[1], xfrd->nsd->zonestat[1],
2842 xfrd->zonestat_safe*sizeof(struct nsdst));
2843#else
2844 (void)zonestats;
2845#endif
2846}
2847
2848/* add the old and new processes stat values into the first part of the
2849 * array of stats */
2850static void
2851process_stats_add_old_new(xfrd_state_type* xfrd, struct nsdst* stats)
2852{
2853 size_t i;
2854 uint64_t dbd = stats[0].db_disk;
2855 uint64_t dbm = stats[0].db_mem;
2856 /* The old and new server processes have separate stat blocks,
2857 * and these are added up together. This results in the statistics
2858 * values per server-child. The reload task briefly forks both
2859 * old and new server processes. */
2860 for(i=0; i<xfrd->nsd->child_count; i++) {
2861 stats_add(&stats[i], &stats[xfrd->nsd->child_count+i]);
2862 }
2863 stats[0].db_disk = dbd;
2864 stats[0].db_mem = dbm;
2865}
2866
2867/* manage clearing of stats, a cumulative count of cleared statistics */
2868static void
2869process_stats_manage_clear(xfrd_state_type* xfrd, struct nsdst* stats,
2870 int peek)
2871{
2872 struct nsdst st;
2873 size_t i;
2874 if(peek) {
2875 /* Subtract the earlier resetted values from the numbers,
2876 * but do not reset the values that are retrieved now. */
2877 if(!xfrd->stat_clear)
2878 return; /* nothing to subtract */
2879 for(i=0; i<xfrd->nsd->child_count; i++) {
2880 /* subtract cumulative count that has been reset */
2881 stats_subtract(&stats[i], &xfrd->stat_clear[i]);
2882 }
2883 return;
2884 }
2885 if(!xfrd->stat_clear)
2886 xfrd->stat_clear = region_alloc_zero(xfrd->region,
2887 sizeof(struct nsdst)*xfrd->nsd->child_count);
2888 for(i=0; i<xfrd->nsd->child_count; i++) {
2889 /* store cumulative count copy */
2890 memcpy(&st, &stats[i], sizeof(st));
2891 /* subtract cumulative count that has been reset */
2892 stats_subtract(&stats[i], &xfrd->stat_clear[i]);
2893 /* store cumulative count in the cleared value array */
2894 memcpy(&xfrd->stat_clear[i], &st, sizeof(st));
2895 }
2896}
2897
2898/* add up the statistics to get the total over the server children. */
2899static void
2900process_stats_add_total(xfrd_state_type* xfrd, struct nsdst* total,
2901 struct nsdst* stats)
2902{
2903 size_t i;
2904 /* copy over the first one, with also the nonadded values. */
2905 memcpy(total, &stats[0], sizeof(*total));
2906 xfrd->nsd->children[0].query_count = stats[0].qudp + stats[0].qudp6
2907 + stats[0].ctcp + stats[0].ctcp6 + stats[0].ctls
2908 + stats[0].ctls6;
2909 for(i=1; i<xfrd->nsd->child_count; i++) {
2910 stats_add(total, &stats[i]);
2911 xfrd->nsd->children[i].query_count = stats[i].qudp
2912 + stats[i].qudp6 + stats[i].ctcp + stats[i].ctcp6
2913 + stats[i].ctls + stats[i].ctls6;
2914 }
2915}
2916
2917/* process the statistics and output them */
2918static void
2919process_stats(RES* ssl, xfrd_state_type* xfrd, int peek)
2920{
2921 struct timeval stattime;
2922 struct nsdst* stats, *zonestats[2], total;
2923
2924 process_stats_alloc(xfrd, &stats, zonestats);
2925 process_stats_grab(xfrd, &stattime, stats, zonestats);
2926 process_stats_add_old_new(xfrd, stats);
2927 process_stats_manage_clear(xfrd, stats, peek);
2928 process_stats_add_total(xfrd, &total, stats);
2929 print_stats(ssl, xfrd, &stattime, !peek, &total, zonestats);
2930 xfrd->nsd->rc->stats_time = stattime;
2931
2932 free(stats);
2933#ifdef USE_ZONE_STATS
2934 free(zonestats[0]);
2935 free(zonestats[1]);
2936#endif
2937
2938 VERBOSITY(3, (LOG_INFO, "remote control stats printed"))do { if ((3) <= verbosity) { log_msg (6, "remote control stats printed"
) ; } } while (0)
;
2939}
2940#endif /* BIND8_STATS */
2941
2942int
2943create_local_accept_sock(const char *path, int* noproto)
2944{
2945#ifdef HAVE_SYS_UN_H1
2946 int s;
2947 struct sockaddr_un usock;
2948
2949 VERBOSITY(3, (LOG_INFO, "creating unix socket %s", path))do { if ((3) <= verbosity) { log_msg (6, "creating unix socket %s"
, path) ; } } while (0)
;
2950#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN1
2951 /* this member exists on BSDs, not Linux */
2952 usock.sun_len = (unsigned)sizeof(usock);
2953#endif
2954 usock.sun_family = AF_LOCAL1;
2955 /* length is 92-108, 104 on FreeBSD */
2956 (void)strlcpy(usock.sun_path, path, sizeof(usock.sun_path));
2957
2958 if ((s = socket(AF_LOCAL1, SOCK_STREAM1, 0)) == -1) {
2959 log_msg(LOG_ERR3, "Cannot create local socket %s (%s)",
2960 path, strerror(errno(*__errno())));
2961 return -1;
2962 }
2963
2964 if (unlink(path) && errno(*__errno()) != ENOENT2) {
2965 /* The socket already exists and cannot be removed */
2966 log_msg(LOG_ERR3, "Cannot remove old local socket %s (%s)",
2967 path, strerror(errno(*__errno())));
2968 goto err;
2969 }
2970
2971 if (bind(s, (struct sockaddr *)&usock,
2972 (socklen_t)sizeof(struct sockaddr_un)) == -1) {
2973 log_msg(LOG_ERR3, "Cannot bind local socket %s (%s)",
2974 path, strerror(errno(*__errno())));
2975 goto err;
2976 }
2977
2978 if (fcntl(s, F_SETFL4, O_NONBLOCK0x0004) == -1) {
2979 log_msg(LOG_ERR3, "Cannot set non-blocking mode");
2980 goto err;
2981 }
2982
2983 if (listen(s, TCP_BACKLOG256) == -1) {
2984 log_msg(LOG_ERR3, "can't listen: %s", strerror(errno(*__errno())));
2985 goto err;
2986 }
2987
2988 (void)noproto; /*unused*/
2989 return s;
2990
2991err:
2992 close(s);
2993 return -1;
2994
2995#else
2996 (void)path;
2997 log_msg(LOG_ERR3, "Local sockets are not supported");
2998 *noproto = 1;
2999 return -1;
3000#endif
3001}