xref: /openbsd/usr.sbin/nsd/nsd.c (revision bf87c3c0)
1 /*
2  * nsd.c -- nsd(8)
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 
10 #include "config.h"
11 
12 #include <sys/types.h>
13 #include <sys/param.h>
14 #include <sys/socket.h>
15 #include <sys/stat.h>
16 #include <sys/uio.h>
17 #include <sys/wait.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #ifdef HAVE_GRP_H
21 #include <grp.h>
22 #endif /* HAVE_GRP_H */
23 #ifdef HAVE_SETUSERCONTEXT
24 #ifdef HAVE_LOGIN_CAP_H
25 #include <login_cap.h>
26 #endif /* HAVE_LOGIN_CAP_H */
27 #endif /* HAVE_SETUSERCONTEXT */
28 #ifdef HAVE_OPENSSL_RAND_H
29 #include <openssl/rand.h>
30 #endif
31 
32 #include <assert.h>
33 #include <ctype.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <limits.h>
37 #include <netdb.h>
38 #include <pwd.h>
39 #include <signal.h>
40 #include <stdarg.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <time.h>
46 #include <unistd.h>
47 #ifdef HAVE_IFADDRS_H
48 #include <ifaddrs.h>
49 #endif
50 
51 #include "nsd.h"
52 #include "options.h"
53 #include "tsig.h"
54 #include "remote.h"
55 #include "xfrd-disk.h"
56 #include "ipc.h"
57 #ifdef USE_DNSTAP
58 #include "dnstap/dnstap_collector.h"
59 #endif
60 #include "util/proxy_protocol.h"
61 
62 /* The server handler... */
63 struct nsd nsd;
64 static char hostname[MAXHOSTNAMELEN];
65 extern config_parser_state_type* cfg_parser;
66 static void version(void) ATTR_NORETURN;
67 
68 /*
69  * Print the help text.
70  *
71  */
72 static void
usage(void)73 usage (void)
74 {
75 	fprintf(stderr, "Usage: nsd [OPTION]...\n");
76 	fprintf(stderr, "Name Server Daemon.\n\n");
77 	fprintf(stderr,
78 		"Supported options:\n"
79 		"  -4                   Only listen to IPv4 connections.\n"
80 		"  -6                   Only listen to IPv6 connections.\n"
81 		"  -a ip-address[@port] Listen to the specified incoming IP address (and port)\n"
82 		"                       May be specified multiple times).\n"
83 		"  -c configfile        Read specified configfile instead of %s.\n"
84 		"  -d                   do not fork as a daemon process.\n"
85 #ifndef NDEBUG
86 		"  -F facilities        Specify the debug facilities.\n"
87 #endif /* NDEBUG */
88 		"  -h                   Print this help information.\n"
89 		, CONFIGFILE);
90 	fprintf(stderr,
91 		"  -i identity          Specify the identity when queried for id.server CHAOS TXT.\n"
92 		"  -I nsid              Specify the NSID. This must be a hex string.\n"
93 #ifndef NDEBUG
94 		"  -L level             Specify the debug level.\n"
95 #endif /* NDEBUG */
96 		"  -l filename          Specify the log file.\n"
97 		"  -N server-count      The number of servers to start.\n"
98 		"  -n tcp-count         The maximum number of TCP connections per server.\n"
99 		"  -P pidfile           Specify the PID file to write.\n"
100 		"  -p port              Specify the port to listen to.\n"
101 		"  -s seconds           Dump statistics every SECONDS seconds.\n"
102 		"  -t chrootdir         Change root to specified directory on startup.\n"
103 		);
104 	fprintf(stderr,
105 		"  -u user              Change effective uid to the specified user.\n"
106 		"  -V level             Specify verbosity level.\n"
107 		"  -v                   Print version information.\n"
108 		);
109 	fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
110 		PACKAGE_VERSION, PACKAGE_BUGREPORT);
111 }
112 
113 /*
114  * Print the version exit.
115  *
116  */
117 static void
version(void)118 version(void)
119 {
120 	fprintf(stderr, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
121 	fprintf(stderr, "Written by NLnet Labs.\n\n");
122 	fprintf(stderr, "Configure line: %s\n", CONFCMDLINE);
123 #ifdef USE_MINI_EVENT
124 	fprintf(stderr, "Event loop: internal (uses select)\n");
125 #else
126 #  if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
127 	fprintf(stderr, "Event loop: %s %s (uses %s)\n",
128 		"libev",
129 		nsd_event_vs(),
130 		nsd_event_method());
131 #  else
132 	fprintf(stderr, "Event loop: %s %s (uses %s)\n",
133 		"libevent",
134 		nsd_event_vs(),
135 		nsd_event_method());
136 #  endif
137 #endif
138 #ifdef HAVE_SSL
139 	fprintf(stderr, "Linked with %s\n\n",
140 #  ifdef SSLEAY_VERSION
141 		SSLeay_version(SSLEAY_VERSION)
142 #  else
143 		OpenSSL_version(OPENSSL_VERSION)
144 #  endif
145 		);
146 #endif
147 	fprintf(stderr,
148 		"Copyright (C) 2001-2020 NLnet Labs.  This is free software.\n"
149 		"There is NO warranty; not even for MERCHANTABILITY or FITNESS\n"
150 		"FOR A PARTICULAR PURPOSE.\n");
151 	exit(0);
152 }
153 
154 static void
setup_verifier_environment(void)155 setup_verifier_environment(void)
156 {
157 	size_t i;
158 	int ret, ip4, ip6;
159 	char *buf, host[NI_MAXHOST], serv[NI_MAXSERV];
160 	size_t size, cnt = 0;
161 
162 	/* allocate large enough buffer to hold a list of all ip addresses.
163 	   ((" " + INET6_ADDRSTRLEN + "@" + "65535") * n) + "\0" */
164 	size = ((INET6_ADDRSTRLEN + 1 + 5 + 1) * nsd.verify_ifs) + 1;
165 	buf = xalloc(size);
166 
167 	ip4 = ip6 = 0;
168 	for(i = 0; i < nsd.verify_ifs; i++) {
169 		ret = getnameinfo(
170 			(struct sockaddr *)&nsd.verify_udp[i].addr.ai_addr,
171 			nsd.verify_udp[i].addr.ai_addrlen,
172 			host, sizeof(host), serv, sizeof(serv),
173 			NI_NUMERICHOST | NI_NUMERICSERV);
174 		if(ret != 0) {
175 			log_msg(LOG_ERR, "error in getnameinfo: %s",
176 				gai_strerror(ret));
177 			continue;
178 		}
179 		buf[cnt++] = ' ';
180 		cnt += strlcpy(&buf[cnt], host, size - cnt);
181 		assert(cnt < size);
182 		buf[cnt++] = '@';
183 		cnt += strlcpy(&buf[cnt], serv, size - cnt);
184 		assert(cnt < size);
185 #ifdef INET6
186 		if (nsd.verify_udp[i].addr.ai_family == AF_INET6 && !ip6) {
187 			setenv("VERIFY_IPV6_ADDRESS", host, 1);
188 			setenv("VERIFY_IPV6_PORT", serv, 1);
189 			setenv("VERIFY_IP_ADDRESS", host, 1);
190 			setenv("VERIFY_PORT", serv, 1);
191 			ip6 = 1;
192 		} else
193 #endif
194 		if (!ip4) {
195 			assert(nsd.verify_udp[i].addr.ai_family == AF_INET);
196 			setenv("VERIFY_IPV4_ADDRESS", host, 1);
197 			setenv("VERIFY_IPV4_PORT", serv, 1);
198 			if (!ip6) {
199 				setenv("VERIFY_IP_ADDRESS", host, 1);
200 				setenv("VERIFY_PORT", serv, 1);
201 			}
202 			ip4 = 1;
203 		}
204 	}
205 
206 	setenv("VERIFY_IP_ADDRESSES", &buf[1], 1);
207 	free(buf);
208 }
209 
210 static void
copyaddrinfo(struct nsd_addrinfo * dest,struct addrinfo * src)211 copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src)
212 {
213 	dest->ai_flags = src->ai_flags;
214 	dest->ai_family = src->ai_family;
215 	dest->ai_socktype = src->ai_socktype;
216 	dest->ai_addrlen = src->ai_addrlen;
217 	memcpy(&dest->ai_addr, src->ai_addr, src->ai_addrlen);
218 }
219 
220 static void
setup_socket(struct nsd_socket * sock,const char * node,const char * port,struct addrinfo * hints)221 setup_socket(
222 	struct nsd_socket *sock, const char *node, const char *port,
223 	struct addrinfo *hints)
224 {
225 	int ret;
226 	char *host;
227 	char host_buf[sizeof("65535") + INET6_ADDRSTRLEN + 1 /* '\0' */];
228 	const char *service;
229 	struct addrinfo *addr = NULL;
230 
231 	sock->fib = -1;
232 	if(node) {
233 		char *sep;
234 
235 		if (strlcpy(host_buf, node, sizeof(host_buf)) >= sizeof(host_buf)) {
236 			error("cannot parse address '%s': %s", node,
237 			    strerror(ENAMETOOLONG));
238 		}
239 
240 		host = host_buf;
241 		sep = strchr(host_buf, '@');
242 		if(sep != NULL) {
243 			*sep = '\0';
244 			service = sep + 1;
245 		} else {
246 			service = port;
247 		}
248 	} else {
249 		host = NULL;
250 		service = port;
251 	}
252 
253 	if((ret = getaddrinfo(host, service, hints, &addr)) == 0) {
254 		copyaddrinfo(&sock->addr, addr);
255 		freeaddrinfo(addr);
256 	} else {
257 		error("cannot parse address '%s': getaddrinfo: %s %s",
258 		      host ? host : "(null)",
259 		      gai_strerror(ret),
260 		      ret==EAI_SYSTEM ? strerror(errno) : "");
261 	}
262 }
263 
264 static void
figure_socket_servers(struct nsd_socket * sock,struct ip_address_option * ip)265 figure_socket_servers(
266 	struct nsd_socket *sock, struct ip_address_option *ip)
267 {
268 	int i;
269 	struct range_option *server;
270 
271 	sock->servers = xalloc_zero(nsd_bitset_size(nsd.child_count));
272 	region_add_cleanup(nsd.region, free, sock->servers);
273 	nsd_bitset_init(sock->servers, nsd.child_count);
274 
275 	if(!ip || !ip->servers) {
276 		/* every server must listen on this socket */
277 		for(i = 0; i < (int)nsd.child_count; i++) {
278 			nsd_bitset_set(sock->servers, i);
279 		}
280 		return;
281 	}
282 
283 	/* only specific servers must listen on this socket */
284 	for(server = ip->servers; server; server = server->next) {
285 		if(server->first == server->last) {
286 			if(server->first <= 0) {
287 				error("server %d specified for ip-address %s "
288 				      "is invalid; server ranges are 1-based",
289 				      server->first, ip->address);
290 			} else if(server->last > (int)nsd.child_count) {
291 				error("server %d specified for ip-address %s "
292 				      "exceeds number of servers configured "
293 				      "in server-count",
294 				      server->first, ip->address);
295 			}
296 		} else {
297 			/* parse_range must ensure range itself is valid */
298 			assert(server->first < server->last);
299 			if(server->first <= 0) {
300 				error("server range %d-%d specified for "
301 				      "ip-address %s is invalid; server "
302 				      "ranges are 1-based",
303 				      server->first, server->last, ip->address);
304 			} else if(server->last > (int)nsd.child_count) {
305 				error("server range %d-%d specified for "
306 				      "ip-address %s exceeds number of servers "
307 				      "configured in server-count",
308 				      server->first, server->last, ip->address);
309 			}
310 		}
311 		for(i = server->first - 1; i < server->last; i++) {
312 			nsd_bitset_set(sock->servers, i);
313 		}
314 	}
315 }
316 
317 static void
figure_default_sockets(struct nsd_socket ** udp,struct nsd_socket ** tcp,size_t * ifs,const char * node,const char * udp_port,const char * tcp_port,const struct addrinfo * hints)318 figure_default_sockets(
319 	struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs,
320 	const char *node, const char *udp_port, const char *tcp_port,
321 	const struct addrinfo *hints)
322 {
323 	size_t i = 0, n = 1;
324 	struct addrinfo ai[2] = { *hints, *hints };
325 
326 	assert(udp != NULL);
327 	assert(tcp != NULL);
328 	assert(ifs != NULL);
329 
330 	ai[0].ai_socktype = SOCK_DGRAM;
331 	ai[1].ai_socktype = SOCK_STREAM;
332 
333 #ifdef INET6
334 #ifdef IPV6_V6ONLY
335 	if (hints->ai_family == AF_UNSPEC) {
336 		ai[0].ai_family = AF_INET6;
337 		ai[1].ai_family = AF_INET6;
338 		n++;
339 	}
340 #endif /* IPV6_V6ONLY */
341 #endif /* INET6 */
342 
343 	*udp = xalloc_zero((n + 1) * sizeof(struct nsd_socket));
344 	*tcp = xalloc_zero((n + 1) * sizeof(struct nsd_socket));
345 	region_add_cleanup(nsd.region, free, *udp);
346 	region_add_cleanup(nsd.region, free, *tcp);
347 
348 #ifdef INET6
349 	if(hints->ai_family == AF_UNSPEC) {
350 		/*
351 		 * With IPv6 we'd like to open two separate sockets, one for
352 		 * IPv4 and one for IPv6, both listening to the wildcard
353 		 * address (unless the -4 or -6 flags are specified).
354 		 *
355 		 * However, this is only supported on platforms where we can
356 		 * turn the socket option IPV6_V6ONLY _on_. Otherwise we just
357 		 * listen to a single IPv6 socket and any incoming IPv4
358 		 * connections will be automatically mapped to our IPv6
359 		 * socket.
360 		 */
361 #ifdef IPV6_V6ONLY
362 		int r;
363 		struct addrinfo *addrs[2] = { NULL, NULL };
364 
365 		if((r = getaddrinfo(node, udp_port, &ai[0], &addrs[0])) == 0 &&
366 		   (r = getaddrinfo(node, tcp_port, &ai[1], &addrs[1])) == 0)
367 		{
368 			(*udp)[i].flags |= NSD_SOCKET_IS_OPTIONAL;
369 			(*udp)[i].fib = -1;
370 			copyaddrinfo(&(*udp)[i].addr, addrs[0]);
371 			figure_socket_servers(&(*udp)[i], NULL);
372 			(*tcp)[i].flags |= NSD_SOCKET_IS_OPTIONAL;
373 			(*tcp)[i].fib = -1;
374 			copyaddrinfo(&(*tcp)[i].addr, addrs[1]);
375 			figure_socket_servers(&(*tcp)[i], NULL);
376 			i++;
377 		} else {
378 			log_msg(LOG_WARNING, "No IPv6, fallback to IPv4. getaddrinfo: %s",
379 			  r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
380 		}
381 
382 		if(addrs[0])
383 			freeaddrinfo(addrs[0]);
384 		if(addrs[1])
385 			freeaddrinfo(addrs[1]);
386 
387 		ai[0].ai_family = AF_INET;
388 		ai[1].ai_family = AF_INET;
389 #endif /* IPV6_V6ONLY */
390 	}
391 #endif /* INET6 */
392 
393 	*ifs = i + 1;
394 	setup_socket(&(*udp)[i], node, udp_port, &ai[0]);
395 	figure_socket_servers(&(*udp)[i], NULL);
396 	setup_socket(&(*tcp)[i], node, tcp_port, &ai[1]);
397 	figure_socket_servers(&(*tcp)[i], NULL);
398 }
399 
400 #ifdef HAVE_GETIFADDRS
401 static int
find_device(struct nsd_socket * sock,const struct ifaddrs * ifa)402 find_device(
403 	struct nsd_socket *sock,
404 	const struct ifaddrs *ifa)
405 {
406 	for(; ifa != NULL; ifa = ifa->ifa_next) {
407 		if((ifa->ifa_addr == NULL) ||
408 		   (ifa->ifa_addr->sa_family != sock->addr.ai_family) ||
409 		   ((ifa->ifa_flags & IFF_UP) == 0 ||
410 		    (ifa->ifa_flags & IFF_LOOPBACK) != 0 ||
411 		    (ifa->ifa_flags & IFF_RUNNING) == 0))
412 		{
413 			continue;
414 		}
415 
416 #ifdef INET6
417 		if(ifa->ifa_addr->sa_family == AF_INET6) {
418 			struct sockaddr_in6 *sa1, *sa2;
419 			size_t sz = sizeof(struct in6_addr);
420 			sa1 = (struct sockaddr_in6 *)ifa->ifa_addr;
421 			sa2 = (struct sockaddr_in6 *)&sock->addr.ai_addr;
422 			if(memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sz) == 0) {
423 				break;
424 			}
425 		} else
426 #endif
427 		if(ifa->ifa_addr->sa_family == AF_INET) {
428 			struct sockaddr_in *sa1, *sa2;
429 			sa1 = (struct sockaddr_in *)ifa->ifa_addr;
430 			sa2 = (struct sockaddr_in *)&sock->addr.ai_addr;
431 			if(sa1->sin_addr.s_addr == sa2->sin_addr.s_addr) {
432 				break;
433 			}
434 		}
435 	}
436 
437 	if(ifa != NULL) {
438 		size_t len = strlcpy(sock->device, ifa->ifa_name, sizeof(sock->device));
439 		if(len < sizeof(sock->device)) {
440 			char *colon = strchr(sock->device, ':');
441 			if(colon != NULL)
442 				*colon = '\0';
443 			return 1;
444 		}
445 	}
446 
447 	return 0;
448 }
449 #endif /* HAVE_GETIFADDRS */
450 
451 static void
figure_sockets(struct nsd_socket ** udp,struct nsd_socket ** tcp,size_t * ifs,struct ip_address_option * ips,const char * node,const char * udp_port,const char * tcp_port,const struct addrinfo * hints)452 figure_sockets(
453 	struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs,
454 	struct ip_address_option *ips,
455 	const char *node, const char *udp_port, const char *tcp_port,
456 	const struct addrinfo *hints)
457 {
458 	size_t i = 0;
459 	struct addrinfo ai = *hints;
460 	struct ip_address_option *ip;
461 #ifdef HAVE_GETIFADDRS
462 	struct ifaddrs *ifa = NULL;
463 #endif
464 	int bind_device = 0;
465 
466 	if(!ips) {
467 		figure_default_sockets(
468 			udp, tcp, ifs, node, udp_port, tcp_port, hints);
469 		return;
470 	}
471 
472 	*ifs = 0;
473 	for(ip = ips; ip; ip = ip->next) {
474 		(*ifs)++;
475 		bind_device |= (ip->dev != 0);
476 	}
477 
478 #ifdef HAVE_GETIFADDRS
479 	if(bind_device && getifaddrs(&ifa) == -1) {
480 		error("getifaddrs failed: %s", strerror(errno));
481 	}
482 #endif
483 
484 	*udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
485 	*tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
486 	region_add_cleanup(nsd.region, free, *udp);
487 	region_add_cleanup(nsd.region, free, *tcp);
488 
489 	ai.ai_flags |= AI_NUMERICHOST;
490 	for(ip = ips, i = 0; ip; ip = ip->next, i++) {
491 		ai.ai_socktype = SOCK_DGRAM;
492 		setup_socket(&(*udp)[i], ip->address, udp_port, &ai);
493 		figure_socket_servers(&(*udp)[i], ip);
494 		ai.ai_socktype = SOCK_STREAM;
495 		setup_socket(&(*tcp)[i], ip->address, tcp_port, &ai);
496 		figure_socket_servers(&(*tcp)[i], ip);
497 		if(ip->fib != -1) {
498 			(*udp)[i].fib = ip->fib;
499 			(*tcp)[i].fib = ip->fib;
500 		}
501 #ifdef HAVE_GETIFADDRS
502 		if(ip->dev != 0) {
503 			(*udp)[i].flags |= NSD_BIND_DEVICE;
504 			(*tcp)[i].flags |= NSD_BIND_DEVICE;
505 			if(ifa != NULL && (find_device(&(*udp)[i], ifa) == 0 ||
506 			                   find_device(&(*tcp)[i], ifa) == 0))
507 			{
508 				error("cannot find device for ip-address %s",
509 				      ip->address);
510 			}
511 		}
512 #endif
513 	}
514 
515 	assert(i == *ifs);
516 
517 #ifdef HAVE_GETIFADDRS
518 	if(ifa != NULL) {
519 		freeifaddrs(ifa);
520 	}
521 #endif
522 }
523 
524 /* print server affinity for given socket. "*" if socket has no affinity with
525    any specific server, "x-y" if socket has affinity with more than two
526    consecutively numbered servers, "x" if socket has affinity with a specific
527    server number, which is not necessarily just one server. e.g. "1 3" is
528    printed if socket has affinity with servers number one and three, but not
529    server number two. */
530 static ssize_t
print_socket_servers(struct nsd_socket * sock,char * buf,size_t bufsz)531 print_socket_servers(struct nsd_socket *sock, char *buf, size_t bufsz)
532 {
533 	int i, x, y, z, n = (int)(sock->servers->size);
534 	char *sep = "";
535 	size_t off, tot;
536 	ssize_t cnt = 0;
537 
538 	assert(bufsz != 0);
539 
540 	off = tot = 0;
541 	x = y = z = -1;
542 	for (i = 0; i <= n; i++) {
543 		if (i == n || !nsd_bitset_isset(sock->servers, i)) {
544 			cnt = 0;
545 			if (i == n && x == -1) {
546 				assert(y == -1);
547 				assert(z == -1);
548 				cnt = snprintf(buf, bufsz, "-");
549 			} else if (y > z) {
550 				assert(x > z);
551 				if (x == 0 && y == (n - 1)) {
552 					assert(z == -1);
553 					cnt = snprintf(buf+off, bufsz-off,
554 					               "*");
555 				} else if (x == y) {
556 					cnt = snprintf(buf+off, bufsz-off,
557 					               "%s%d", sep, x+1);
558 				} else if (x == (y - 1)) {
559 					cnt = snprintf(buf+off, bufsz-off,
560 					               "%s%d %d", sep, x+1, y+1);
561 				} else {
562 					assert(y > (x + 1));
563 					cnt = snprintf(buf+off, bufsz-off,
564 					               "%s%d-%d", sep, x+1, y+1);
565 				}
566 			}
567 			z = i;
568 			if (cnt > 0) {
569 				tot += (size_t)cnt;
570 				off = (tot < bufsz) ? tot : bufsz - 1;
571 				sep = " ";
572 			} else if (cnt < 0) {
573 				return -1;
574 			}
575 		} else if (x <= z) {
576 			x = y = i;
577 		} else {
578 			assert(x > z);
579 			y = i;
580 		}
581 	}
582 
583 	return tot;
584 }
585 
586 static void
print_sockets(struct nsd_socket * udp,struct nsd_socket * tcp,size_t ifs)587 print_sockets(
588 	struct nsd_socket *udp, struct nsd_socket *tcp, size_t ifs)
589 {
590 	char sockbuf[INET6_ADDRSTRLEN + 6 + 1];
591 	char *serverbuf;
592 	size_t i, serverbufsz, servercnt;
593 	const char *fmt = "listen on ip-address %s (%s) with server(s): %s";
594 	struct nsd_bitset *servers;
595 
596 	if(ifs == 0) {
597 		return;
598 	}
599 
600 	assert(udp != NULL);
601 	assert(tcp != NULL);
602 
603 	servercnt = udp[0].servers->size;
604 	serverbufsz = (((servercnt / 10) * servercnt) + servercnt) + 1;
605 	serverbuf = xalloc(serverbufsz);
606 
607 	/* warn user of unused servers */
608 	servers = xalloc(nsd_bitset_size(servercnt));
609 	nsd_bitset_init(servers, (size_t)servercnt);
610 
611 	for(i = 0; i < ifs; i++) {
612 		assert(udp[i].servers->size == servercnt);
613 		addrport2str((void*)&udp[i].addr.ai_addr, sockbuf, sizeof(sockbuf));
614 		print_socket_servers(&udp[i], serverbuf, serverbufsz);
615 		nsd_bitset_or(servers, servers, udp[i].servers);
616 		VERBOSITY(3, (LOG_NOTICE, fmt, sockbuf, "udp", serverbuf));
617 		assert(tcp[i].servers->size == servercnt);
618 		addrport2str((void*)&tcp[i].addr.ai_addr, sockbuf, sizeof(sockbuf));
619 		print_socket_servers(&tcp[i], serverbuf, serverbufsz);
620 		nsd_bitset_or(servers, servers, tcp[i].servers);
621 		VERBOSITY(3, (LOG_NOTICE, fmt, sockbuf, "tcp", serverbuf));
622 	}
623 
624 
625 	/* warn user of unused servers */
626 	for(i = 0; i < servercnt; i++) {
627 		if(!nsd_bitset_isset(servers, i)) {
628 			log_msg(LOG_WARNING, "server %zu will not listen on "
629 			                     "any specified ip-address", i+1);
630 		}
631 	}
632 	free(serverbuf);
633 	free(servers);
634 }
635 
636 #ifdef HAVE_CPUSET_T
free_cpuset(void * ptr)637 static void free_cpuset(void *ptr)
638 {
639 	cpuset_t *set = (cpuset_t *)ptr;
640 	cpuset_destroy(set);
641 }
642 #endif
643 
644 /*
645  * Fetch the nsd parent process id from the nsd pidfile
646  *
647  */
648 pid_t
readpid(const char * file)649 readpid(const char *file)
650 {
651 	int fd;
652 	pid_t pid;
653 	char pidbuf[16];
654 	char *t;
655 	int l;
656 
657 	if ((fd = open(file, O_RDONLY)) == -1) {
658 		return -1;
659 	}
660 
661 	if (((l = read(fd, pidbuf, sizeof(pidbuf)))) == -1) {
662 		close(fd);
663 		return -1;
664 	}
665 
666 	close(fd);
667 
668 	/* Empty pidfile means no pidfile... */
669 	if (l == 0) {
670 		errno = ENOENT;
671 		return -1;
672 	}
673 
674 	pid = (pid_t) strtol(pidbuf, &t, 10);
675 
676 	if (*t && *t != '\n') {
677 		return -1;
678 	}
679 	return pid;
680 }
681 
682 /*
683  * Store the nsd parent process id in the nsd pidfile
684  *
685  */
686 int
writepid(struct nsd * nsd)687 writepid(struct nsd *nsd)
688 {
689 	int fd;
690 	char pidbuf[32];
691 	size_t count = 0;
692 	if(!nsd->pidfile || !nsd->pidfile[0])
693 		return 0;
694 
695 	snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) nsd->pid);
696 
697 	if((fd = open(nsd->pidfile, O_WRONLY | O_CREAT | O_TRUNC
698 #ifdef O_NOFOLLOW
699 		| O_NOFOLLOW
700 #endif
701 		, 0644)) == -1) {
702 		log_msg(LOG_ERR, "cannot open pidfile %s: %s",
703 			nsd->pidfile, strerror(errno));
704 		return -1;
705 	}
706 
707 	while(count < strlen(pidbuf)) {
708 		ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
709 		if(r == -1) {
710 			if(errno == EAGAIN || errno == EINTR)
711 				continue;
712 			log_msg(LOG_ERR, "cannot write pidfile %s: %s",
713 				nsd->pidfile, strerror(errno));
714 			close(fd);
715 			return -1;
716 		} else if(r == 0) {
717 			log_msg(LOG_ERR, "cannot write any bytes to "
718 				"pidfile %s: write returns 0 bytes written",
719 				nsd->pidfile);
720 			close(fd);
721 			return -1;
722 		}
723 		count += r;
724 	}
725 	close(fd);
726 
727 	if (chown(nsd->pidfile, nsd->uid, nsd->gid) == -1) {
728 		log_msg(LOG_ERR, "cannot chown %u.%u %s: %s",
729 			(unsigned) nsd->uid, (unsigned) nsd->gid,
730 			nsd->pidfile, strerror(errno));
731 		return -1;
732 	}
733 
734 	return 0;
735 }
736 
737 void
unlinkpid(const char * file)738 unlinkpid(const char* file)
739 {
740 	int fd = -1;
741 
742 	if (file && file[0]) {
743 		/* truncate pidfile */
744 		fd = open(file, O_WRONLY | O_TRUNC, 0644);
745 		if (fd == -1) {
746 			/* Truncate the pid file.  */
747 			log_msg(LOG_ERR, "can not truncate the pid file %s: %s", file, strerror(errno));
748 		} else {
749 			close(fd);
750 		}
751 
752 		/* unlink pidfile */
753 		if (unlink(file) == -1) {
754 			/* this unlink may not work if the pidfile is located
755 			 * outside of the chroot/workdir or we no longer
756 			 * have permissions */
757 			VERBOSITY(3, (LOG_WARNING,
758 				"failed to unlink pidfile %s: %s",
759 				file, strerror(errno)));
760 		}
761 	}
762 }
763 
764 /*
765  * Incoming signals, set appropriate actions.
766  *
767  */
768 void
sig_handler(int sig)769 sig_handler(int sig)
770 {
771 	/* To avoid race cond. We really don't want to use log_msg() in this handler */
772 
773 	/* Are we a child server? */
774 	if (nsd.server_kind != NSD_SERVER_MAIN) {
775 		switch (sig) {
776 		case SIGCHLD:
777 			nsd.signal_hint_child = 1;
778 			break;
779 		case SIGALRM:
780 			break;
781 		case SIGINT:
782 		case SIGTERM:
783 			nsd.signal_hint_quit = 1;
784 			break;
785 		case SIGILL:
786 		case SIGUSR1:	/* Dump stats on SIGUSR1.  */
787 			nsd.signal_hint_statsusr = 1;
788 			break;
789 		default:
790 			break;
791 		}
792 		return;
793 	}
794 
795 	/* We are the main process */
796 	switch (sig) {
797 	case SIGCHLD:
798 		nsd.signal_hint_child = 1;
799 		return;
800 	case SIGHUP:
801 		nsd.signal_hint_reload_hup = 1;
802 		return;
803 	case SIGALRM:
804 		nsd.signal_hint_stats = 1;
805 		break;
806 	case SIGILL:
807 		/*
808 		 * For backwards compatibility with BIND 8 and older
809 		 * versions of NSD.
810 		 */
811 		nsd.signal_hint_statsusr = 1;
812 		break;
813 	case SIGUSR1:
814 		/* Dump statistics.  */
815 		nsd.signal_hint_statsusr = 1;
816 		break;
817 	case SIGINT:
818 	case SIGTERM:
819 	default:
820 		nsd.signal_hint_shutdown = 1;
821 		break;
822 	}
823 }
824 
825 /*
826  * Statistic output...
827  *
828  */
829 #ifdef BIND8_STATS
830 void
bind8_stats(struct nsd * nsd)831 bind8_stats (struct nsd *nsd)
832 {
833 	char buf[MAXSYSLOGMSGLEN];
834 	char *msg, *t;
835 	int i, len;
836 	struct nsdst st;
837 
838 	/* Current time... */
839 	time_t now;
840 	if(!nsd->st_period)
841 		return;
842 	time(&now);
843 
844 	memcpy(&st, nsd->st, sizeof(st));
845 	stats_subtract(&st, &nsd->stat_proc);
846 
847 	/* NSTATS */
848 	t = msg = buf + snprintf(buf, MAXSYSLOGMSGLEN, "NSTATS %lld %lu",
849 				 (long long) now, (unsigned long) st.boot);
850 	for (i = 0; i <= 255; i++) {
851 		/* How much space left? */
852 		if ((len = buf + MAXSYSLOGMSGLEN - t) < 32) {
853 			log_msg(LOG_INFO, "%s", buf);
854 			t = msg;
855 			len = buf + MAXSYSLOGMSGLEN - t;
856 		}
857 
858 		if (st.qtype[i] != 0) {
859 			t += snprintf(t, len, " %s=%lu", rrtype_to_string(i), st.qtype[i]);
860 		}
861 	}
862 	if (t > msg)
863 		log_msg(LOG_INFO, "%s", buf);
864 
865 	/* XSTATS */
866 	/* Only print it if we're in the main daemon or have anything to report... */
867 	if (nsd->server_kind == NSD_SERVER_MAIN
868 	    || st.dropped || st.raxfr || st.rixfr || (st.qudp + st.qudp6 - st.dropped)
869 	    || st.txerr || st.opcode[OPCODE_QUERY] || st.opcode[OPCODE_IQUERY]
870 	    || st.wrongzone || st.ctcp + st.ctcp6 || st.rcode[RCODE_SERVFAIL]
871 	    || st.rcode[RCODE_FORMAT] || st.nona || st.rcode[RCODE_NXDOMAIN]
872 	    || st.opcode[OPCODE_UPDATE]) {
873 
874 		log_msg(LOG_INFO, "XSTATS %lld %lu"
875 			" RR=%lu RNXD=%lu RFwdR=%lu RDupR=%lu RFail=%lu RFErr=%lu RErr=%lu RAXFR=%lu RIXFR=%lu"
876 			" RLame=%lu ROpts=%lu SSysQ=%lu SAns=%lu SFwdQ=%lu SDupQ=%lu SErr=%lu RQ=%lu"
877 			" RIQ=%lu RFwdQ=%lu RDupQ=%lu RTCP=%lu SFwdR=%lu SFail=%lu SFErr=%lu SNaAns=%lu"
878 			" SNXD=%lu RUQ=%lu RURQ=%lu RUXFR=%lu RUUpd=%lu",
879 			(long long) now, (unsigned long) st.boot,
880 			st.dropped, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0,
881 			(unsigned long)0, (unsigned long)0, st.raxfr, st.rixfr, (unsigned long)0, (unsigned long)0,
882 			(unsigned long)0, st.qudp + st.qudp6 - st.dropped, (unsigned long)0,
883 			(unsigned long)0, st.txerr,
884 			st.opcode[OPCODE_QUERY], st.opcode[OPCODE_IQUERY], st.wrongzone,
885 			(unsigned long)0, st.ctcp + st.ctcp6,
886 			(unsigned long)0, st.rcode[RCODE_SERVFAIL], st.rcode[RCODE_FORMAT],
887 			st.nona, st.rcode[RCODE_NXDOMAIN],
888 			(unsigned long)0, (unsigned long)0, (unsigned long)0, st.opcode[OPCODE_UPDATE]);
889 	}
890 
891 }
892 #endif /* BIND8_STATS */
893 
894 static
cookie_secret_file_read(nsd_type * nsd)895 int cookie_secret_file_read(nsd_type* nsd) {
896 	char secret[NSD_COOKIE_SECRET_SIZE * 2 + 2/*'\n' and '\0'*/];
897 	char const* file = nsd->options->cookie_secret_file;
898 	FILE* f;
899 	int corrupt = 0;
900 	size_t count;
901 
902 	assert( nsd->options->cookie_secret_file != NULL );
903 	f = fopen(file, "r");
904 	/* a non-existing cookie file is not an error */
905 	if( f == NULL ) { return errno != EPERM; }
906 	/* cookie secret file exists and is readable */
907 	nsd->cookie_count = 0;
908 	for( count = 0; count < NSD_COOKIE_HISTORY_SIZE; count++ ) {
909 		size_t secret_len = 0;
910 		ssize_t decoded_len = 0;
911 		if( fgets(secret, sizeof(secret), f) == NULL ) { break; }
912 		secret_len = strlen(secret);
913 		if( secret_len == 0 ) { break; }
914 		assert( secret_len <= sizeof(secret) );
915 		secret_len = secret[secret_len - 1] == '\n' ? secret_len - 1 : secret_len;
916 		if( secret_len != NSD_COOKIE_SECRET_SIZE * 2 ) { corrupt++; break; }
917 		/* needed for `hex_pton`; stripping potential `\n` */
918 		secret[secret_len] = '\0';
919 		decoded_len = hex_pton(secret, nsd->cookie_secrets[count].cookie_secret,
920 		                       NSD_COOKIE_SECRET_SIZE);
921 		if( decoded_len != NSD_COOKIE_SECRET_SIZE ) { corrupt++; break; }
922 		nsd->cookie_count++;
923 	}
924 	fclose(f);
925 	return corrupt == 0;
926 }
927 
928 extern char *optarg;
929 extern int optind;
930 
931 int
main(int argc,char * argv[])932 main(int argc, char *argv[])
933 {
934 	/* Scratch variables... */
935 	int c;
936 	pid_t	oldpid;
937 	size_t i;
938 	struct sigaction action;
939 #ifdef HAVE_GETPWNAM
940 	struct passwd *pwd = NULL;
941 #endif /* HAVE_GETPWNAM */
942 
943 	struct ip_address_option *ip;
944 	struct addrinfo hints;
945 	const char *udp_port = 0;
946 	const char *tcp_port = 0;
947 	const char *verify_port = 0;
948 
949 	const char *configfile = CONFIGFILE;
950 
951 	char* argv0 = (argv0 = strrchr(argv[0], '/')) ? argv0 + 1 : argv[0];
952 
953 	log_init(argv0);
954 
955 	/* Initialize the server handler... */
956 	memset(&nsd, 0, sizeof(struct nsd));
957 	nsd.region      = region_create(xalloc, free);
958 	nsd.pidfile	= 0;
959 	nsd.server_kind = NSD_SERVER_MAIN;
960 	memset(&hints, 0, sizeof(hints));
961 	hints.ai_family = DEFAULT_AI_FAMILY;
962 	hints.ai_flags = AI_PASSIVE;
963 	nsd.identity	= 0;
964 	nsd.version	= VERSION;
965 	nsd.username	= 0;
966 	nsd.chrootdir	= 0;
967 	nsd.nsid 	= NULL;
968 	nsd.nsid_len 	= 0;
969 	nsd.cookie_count = 0;
970 
971 	nsd.child_count = 0;
972 	nsd.maximum_tcp_count = 0;
973 	nsd.current_tcp_count = 0;
974 	nsd.file_rotation_ok = 0;
975 
976 	nsd.do_answer_cookie = 1;
977 
978 	/* Set up our default identity to gethostname(2) */
979 	if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
980 		nsd.identity = hostname;
981 	} else {
982 		log_msg(LOG_ERR,
983 			"failed to get the host name: %s - using default identity",
984 			strerror(errno));
985 		nsd.identity = IDENTITY;
986 	}
987 
988 	/* Create region where options will be stored and set defaults */
989 	nsd.options = nsd_options_create(region_create_custom(xalloc, free,
990 		DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE,
991 		DEFAULT_INITIAL_CLEANUP_SIZE, 1));
992 
993 	/* Parse the command line... */
994 	while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v"
995 #ifndef NDEBUG /* <mattthijs> only when configured with --enable-checking */
996 		"F:L:"
997 #endif /* NDEBUG */
998 		)) != -1) {
999 		switch (c) {
1000 		case '4':
1001 			hints.ai_family = AF_INET;
1002 			break;
1003 		case '6':
1004 #ifdef INET6
1005 			hints.ai_family = AF_INET6;
1006 #else /* !INET6 */
1007 			error("IPv6 support not enabled.");
1008 #endif /* INET6 */
1009 			break;
1010 		case 'a':
1011 			ip = region_alloc_zero(
1012 				nsd.options->region, sizeof(*ip));
1013 			ip->address = region_strdup(
1014 				nsd.options->region, optarg);
1015 			ip->next = nsd.options->ip_addresses;
1016 			nsd.options->ip_addresses = ip;
1017 			break;
1018 		case 'c':
1019 			configfile = optarg;
1020 			break;
1021 		case 'd':
1022 			nsd.debug = 1;
1023 			break;
1024 		case 'f':
1025 			break;
1026 		case 'h':
1027 			usage();
1028 			exit(0);
1029 		case 'i':
1030 			nsd.identity = optarg;
1031 			break;
1032 		case 'I':
1033 			if (nsd.nsid_len != 0) {
1034 				/* can only be given once */
1035 				break;
1036 			}
1037 			if (strncasecmp(optarg, "ascii_", 6) == 0) {
1038 				nsd.nsid = xalloc(strlen(optarg+6));
1039 				nsd.nsid_len = strlen(optarg+6);
1040 				memmove(nsd.nsid, optarg+6, nsd.nsid_len);
1041 			} else {
1042 				if (strlen(optarg) % 2 != 0) {
1043 					error("the NSID must be a hex string of an even length.");
1044 				}
1045 				nsd.nsid = xalloc(strlen(optarg) / 2);
1046 				nsd.nsid_len = strlen(optarg) / 2;
1047 				if (hex_pton(optarg, nsd.nsid, nsd.nsid_len) == -1) {
1048 					error("hex string cannot be parsed '%s' in NSID.", optarg);
1049 				}
1050 			}
1051 			break;
1052 		case 'l':
1053 			nsd.log_filename = optarg;
1054 			break;
1055 		case 'N':
1056 			i = atoi(optarg);
1057 			if (i <= 0) {
1058 				error("number of child servers must be greater than zero.");
1059 			} else {
1060 				nsd.child_count = i;
1061 			}
1062 			break;
1063 		case 'n':
1064 			i = atoi(optarg);
1065 			if (i <= 0) {
1066 				error("number of concurrent TCP connections must greater than zero.");
1067 			} else {
1068 				nsd.maximum_tcp_count = i;
1069 			}
1070 			break;
1071 		case 'P':
1072 			nsd.pidfile = optarg;
1073 			break;
1074 		case 'p':
1075 			if (atoi(optarg) == 0) {
1076 				error("port argument must be numeric.");
1077 			}
1078 			tcp_port = optarg;
1079 			udp_port = optarg;
1080 			break;
1081 		case 's':
1082 #ifdef BIND8_STATS
1083 			nsd.st_period = atoi(optarg);
1084 #else /* !BIND8_STATS */
1085 			error("BIND 8 statistics not enabled.");
1086 #endif /* BIND8_STATS */
1087 			break;
1088 		case 't':
1089 #ifdef HAVE_CHROOT
1090 			nsd.chrootdir = optarg;
1091 #else /* !HAVE_CHROOT */
1092 			error("chroot not supported on this platform.");
1093 #endif /* HAVE_CHROOT */
1094 			break;
1095 		case 'u':
1096 			nsd.username = optarg;
1097 			break;
1098 		case 'V':
1099 			verbosity = atoi(optarg);
1100 			break;
1101 		case 'v':
1102 			version();
1103 			/* version exits */
1104 			break;
1105 #ifndef NDEBUG
1106 		case 'F':
1107 			sscanf(optarg, "%x", &nsd_debug_facilities);
1108 			break;
1109 		case 'L':
1110 			sscanf(optarg, "%d", &nsd_debug_level);
1111 			break;
1112 #endif /* NDEBUG */
1113 		case '?':
1114 		default:
1115 			usage();
1116 			exit(1);
1117 		}
1118 	}
1119 	argc -= optind;
1120 	/* argv += optind; */
1121 
1122 	/* Commandline parse error */
1123 	if (argc != 0) {
1124 		usage();
1125 		exit(1);
1126 	}
1127 
1128 	if (strlen(nsd.identity) > UCHAR_MAX) {
1129 		error("server identity too long (%u characters)",
1130 		      (unsigned) strlen(nsd.identity));
1131 	}
1132 	if(!tsig_init(nsd.region))
1133 		error("init tsig failed");
1134 	pp_init(&write_uint16, &write_uint32);
1135 
1136 	/* Read options */
1137 	if(!parse_options_file(nsd.options, configfile, NULL, NULL, NULL)) {
1138 		error("could not read config: %s\n", configfile);
1139 	}
1140 	if(!parse_zone_list_file(nsd.options)) {
1141 		error("could not read zonelist file %s\n",
1142 			nsd.options->zonelistfile);
1143 	}
1144 	if(nsd.options->do_ip4 && !nsd.options->do_ip6) {
1145 		hints.ai_family = AF_INET;
1146 	}
1147 #ifdef INET6
1148 	if(nsd.options->do_ip6 && !nsd.options->do_ip4) {
1149 		hints.ai_family = AF_INET6;
1150 	}
1151 #endif /* INET6 */
1152 	if (verbosity == 0)
1153 		verbosity = nsd.options->verbosity;
1154 #ifndef NDEBUG
1155 	if (nsd_debug_level > 0 && verbosity == 0)
1156 		verbosity = nsd_debug_level;
1157 #endif /* NDEBUG */
1158 	if(nsd.options->debug_mode) nsd.debug=1;
1159 	if(!nsd.pidfile)
1160 	{
1161 		if(nsd.options->pidfile)
1162 			nsd.pidfile = nsd.options->pidfile;
1163 		else
1164 			nsd.pidfile = PIDFILE;
1165 	}
1166 	if(strcmp(nsd.identity, hostname)==0 || strcmp(nsd.identity,IDENTITY)==0)
1167 	{
1168 		if(nsd.options->identity)
1169 			nsd.identity = nsd.options->identity;
1170 	}
1171 	if(nsd.options->version) {
1172 		nsd.version = nsd.options->version;
1173 	}
1174 	if (nsd.options->logfile && !nsd.log_filename) {
1175 		nsd.log_filename = nsd.options->logfile;
1176 	}
1177 	if(nsd.child_count == 0) {
1178 		nsd.child_count = nsd.options->server_count;
1179 	}
1180 
1181 #ifdef SO_REUSEPORT
1182 	if(nsd.options->reuseport && nsd.child_count > 1) {
1183 		nsd.reuseport = nsd.child_count;
1184 	}
1185 #endif /* SO_REUSEPORT */
1186 	if(nsd.maximum_tcp_count == 0) {
1187 		nsd.maximum_tcp_count = nsd.options->tcp_count;
1188 	}
1189 	nsd.tcp_timeout = nsd.options->tcp_timeout;
1190 	nsd.tcp_query_count = nsd.options->tcp_query_count;
1191 	nsd.tcp_mss = nsd.options->tcp_mss;
1192 	nsd.outgoing_tcp_mss = nsd.options->outgoing_tcp_mss;
1193 	nsd.ipv4_edns_size = nsd.options->ipv4_edns_size;
1194 	nsd.ipv6_edns_size = nsd.options->ipv6_edns_size;
1195 #ifdef HAVE_SSL
1196 	nsd.tls_ctx = NULL;
1197 #endif
1198 
1199 	if(udp_port == 0)
1200 	{
1201 		if(nsd.options->port != 0) {
1202 			udp_port = nsd.options->port;
1203 			tcp_port = nsd.options->port;
1204 		} else {
1205 			udp_port = UDP_PORT;
1206 			tcp_port = TCP_PORT;
1207 		}
1208 	}
1209 	if(nsd.options->verify_port != 0) {
1210 		verify_port = nsd.options->verify_port;
1211 	} else {
1212 		verify_port = VERIFY_PORT;
1213 	}
1214 #ifdef BIND8_STATS
1215 	if(nsd.st_period == 0) {
1216 		nsd.st_period = nsd.options->statistics;
1217 	}
1218 #endif /* BIND8_STATS */
1219 #ifdef HAVE_CHROOT
1220 	if(nsd.chrootdir == 0) nsd.chrootdir = nsd.options->chroot;
1221 #ifdef CHROOTDIR
1222 	/* if still no chrootdir, fallback to default */
1223 	if(nsd.chrootdir == 0) nsd.chrootdir = CHROOTDIR;
1224 #endif /* CHROOTDIR */
1225 #endif /* HAVE_CHROOT */
1226 	if(nsd.username == 0) {
1227 		if(nsd.options->username) nsd.username = nsd.options->username;
1228 		else nsd.username = USER;
1229 	}
1230 	if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
1231 		if(chdir(nsd.options->zonesdir)) {
1232 			error("cannot chdir to '%s': %s",
1233 				nsd.options->zonesdir, strerror(errno));
1234 		}
1235 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
1236 			nsd.options->zonesdir));
1237 	}
1238 
1239 	/* EDNS0 */
1240 	edns_init_data(&nsd.edns_ipv4, nsd.options->ipv4_edns_size);
1241 #if defined(INET6)
1242 #if defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU)
1243 	edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
1244 #else /* no way to set IPV6 MTU, send no bigger than that. */
1245 	if (nsd.options->ipv6_edns_size < IPV6_MIN_MTU)
1246 		edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
1247 	else
1248 		edns_init_data(&nsd.edns_ipv6, IPV6_MIN_MTU);
1249 #endif /* IPV6 MTU) */
1250 #endif /* defined(INET6) */
1251 
1252 	nsd.do_answer_cookie = nsd.options->answer_cookie;
1253 	if (nsd.cookie_count > 0)
1254 		; /* pass */
1255 
1256 	else if (nsd.options->cookie_secret) {
1257 		ssize_t len = hex_pton(nsd.options->cookie_secret,
1258 			nsd.cookie_secrets[0].cookie_secret, NSD_COOKIE_SECRET_SIZE);
1259 		if (len != NSD_COOKIE_SECRET_SIZE ) {
1260 			error("A cookie secret must be a "
1261 			      "128 bit hex string");
1262 		}
1263 		nsd.cookie_count = 1;
1264 	} else {
1265 		size_t j;
1266 		size_t const cookie_secret_len = NSD_COOKIE_SECRET_SIZE;
1267 		/* Calculate a new random secret */
1268 		srandom(getpid() ^ time(NULL));
1269 
1270 		for( j = 0; j < NSD_COOKIE_HISTORY_SIZE; j++) {
1271 #if defined(HAVE_SSL)
1272 			if (!RAND_status()
1273 			    || !RAND_bytes(nsd.cookie_secrets[j].cookie_secret, cookie_secret_len))
1274 #endif
1275 			for (i = 0; i < cookie_secret_len; i++)
1276 				nsd.cookie_secrets[j].cookie_secret[i] = random_generate(256);
1277 		}
1278 		// XXX: all we have is a random cookie, still pretend we have one
1279 		nsd.cookie_count = 1;
1280 	}
1281 
1282 	if (nsd.nsid_len == 0 && nsd.options->nsid) {
1283 		if (strlen(nsd.options->nsid) % 2 != 0) {
1284 			error("the NSID must be a hex string of an even length.");
1285 		}
1286 		nsd.nsid = xalloc(strlen(nsd.options->nsid) / 2);
1287 		nsd.nsid_len = strlen(nsd.options->nsid) / 2;
1288 		if (hex_pton(nsd.options->nsid, nsd.nsid, nsd.nsid_len) == -1) {
1289 			error("hex string cannot be parsed '%s' in NSID.", nsd.options->nsid);
1290 		}
1291 	}
1292 	edns_init_nsid(&nsd.edns_ipv4, nsd.nsid_len);
1293 #if defined(INET6)
1294 	edns_init_nsid(&nsd.edns_ipv6, nsd.nsid_len);
1295 #endif /* defined(INET6) */
1296 
1297 #ifdef HAVE_CPUSET_T
1298 	nsd.use_cpu_affinity = (nsd.options->cpu_affinity != NULL);
1299 	if(nsd.use_cpu_affinity) {
1300 		int ncpus;
1301 		struct cpu_option* opt = nsd.options->cpu_affinity;
1302 
1303 		if((ncpus = number_of_cpus()) == -1) {
1304 			error("cannot retrieve number of cpus: %s",
1305 			      strerror(errno));
1306 		}
1307 		nsd.cpuset = cpuset_create();
1308 		region_add_cleanup(nsd.region, free_cpuset, nsd.cpuset);
1309 		for(; opt; opt = opt->next) {
1310 			assert(opt->cpu >= 0);
1311 			if(opt->cpu >= ncpus) {
1312 				error("invalid cpu %d specified in "
1313 				      "cpu-affinity", opt->cpu);
1314 			}
1315 			cpuset_set((cpuid_t)opt->cpu, nsd.cpuset);
1316 		}
1317 	}
1318 	if(nsd.use_cpu_affinity) {
1319 		int cpu;
1320 		struct cpu_map_option *opt
1321 			= nsd.options->service_cpu_affinity;
1322 
1323 		cpu = -1;
1324 		for(; opt && cpu == -1; opt = opt->next) {
1325 			if(opt->service == -1) {
1326 				cpu = opt->cpu;
1327 				assert(cpu >= 0);
1328 			}
1329 		}
1330 		nsd.xfrd_cpuset = cpuset_create();
1331 		region_add_cleanup(nsd.region, free_cpuset, nsd.xfrd_cpuset);
1332 		if(cpu == -1) {
1333 			cpuset_or(nsd.xfrd_cpuset,
1334 			          nsd.cpuset);
1335 		} else {
1336 			if(!cpuset_isset(cpu, nsd.cpuset)) {
1337 				error("cpu %d specified in xfrd-cpu-affinity "
1338 				      "is not specified in cpu-affinity", cpu);
1339 			}
1340 			cpuset_set((cpuid_t)cpu, nsd.xfrd_cpuset);
1341 		}
1342 	}
1343 #endif /* HAVE_CPUSET_T */
1344 
1345 	/* Number of child servers to fork.  */
1346 	nsd.children = (struct nsd_child *) region_alloc_array(
1347 		nsd.region, nsd.child_count, sizeof(struct nsd_child));
1348 	for (i = 0; i < nsd.child_count; ++i) {
1349 		nsd.children[i].kind = NSD_SERVER_BOTH;
1350 		nsd.children[i].pid = -1;
1351 		nsd.children[i].child_fd = -1;
1352 		nsd.children[i].parent_fd = -1;
1353 		nsd.children[i].handler = NULL;
1354 		nsd.children[i].need_to_send_STATS = 0;
1355 		nsd.children[i].need_to_send_QUIT = 0;
1356 		nsd.children[i].need_to_exit = 0;
1357 		nsd.children[i].has_exited = 0;
1358 #ifdef BIND8_STATS
1359 		nsd.children[i].query_count = 0;
1360 #endif
1361 
1362 #ifdef HAVE_CPUSET_T
1363 		if(nsd.use_cpu_affinity) {
1364 			int cpu, server;
1365 			struct cpu_map_option *opt
1366 				= nsd.options->service_cpu_affinity;
1367 
1368 			cpu = -1;
1369 			server = i+1;
1370 			for(; opt && cpu == -1; opt = opt->next) {
1371 				if(opt->service == server) {
1372 					cpu = opt->cpu;
1373 					assert(cpu >= 0);
1374 				}
1375 			}
1376 			nsd.children[i].cpuset = cpuset_create();
1377 			region_add_cleanup(nsd.region,
1378 			                   free_cpuset,
1379 			                   nsd.children[i].cpuset);
1380 			if(cpu == -1) {
1381 				cpuset_or(nsd.children[i].cpuset,
1382 				          nsd.cpuset);
1383 			} else {
1384 				if(!cpuset_isset((cpuid_t)cpu, nsd.cpuset)) {
1385 					error("cpu %d specified in "
1386 					      "server-%d-cpu-affinity is not "
1387 					      "specified in cpu-affinity",
1388 					      cpu, server);
1389 				}
1390 				cpuset_set(
1391 					(cpuid_t)cpu, nsd.children[i].cpuset);
1392 			}
1393 		}
1394 #endif /* HAVE_CPUSET_T */
1395 	}
1396 
1397 	nsd.this_child = NULL;
1398 
1399 	resolve_interface_names(nsd.options);
1400 	figure_sockets(&nsd.udp, &nsd.tcp, &nsd.ifs,
1401 		nsd.options->ip_addresses, NULL, udp_port, tcp_port, &hints);
1402 
1403 	if(nsd.options->verify_enable) {
1404 		figure_sockets(&nsd.verify_udp, &nsd.verify_tcp, &nsd.verify_ifs,
1405 			nsd.options->verify_ip_addresses, "localhost", verify_port, verify_port, &hints);
1406 		setup_verifier_environment();
1407 	}
1408 
1409 	/* Parse the username into uid and gid */
1410 	nsd.gid = getgid();
1411 	nsd.uid = getuid();
1412 #ifdef HAVE_GETPWNAM
1413 	/* Parse the username into uid and gid */
1414 	if (*nsd.username) {
1415 		if (isdigit((unsigned char)*nsd.username)) {
1416 			char *t;
1417 			nsd.uid = strtol(nsd.username, &t, 10);
1418 			if (*t != 0) {
1419 				if (*t != '.' || !isdigit((unsigned char)*++t)) {
1420 					error("-u user or -u uid or -u uid.gid");
1421 				}
1422 				nsd.gid = strtol(t, &t, 10);
1423 			} else {
1424 				/* Lookup the group id in /etc/passwd */
1425 				if ((pwd = getpwuid(nsd.uid)) == NULL) {
1426 					error("user id %u does not exist.", (unsigned) nsd.uid);
1427 				} else {
1428 					nsd.gid = pwd->pw_gid;
1429 				}
1430 			}
1431 		} else {
1432 			/* Lookup the user id in /etc/passwd */
1433 			if ((pwd = getpwnam(nsd.username)) == NULL) {
1434 				error("user '%s' does not exist.", nsd.username);
1435 			} else {
1436 				nsd.uid = pwd->pw_uid;
1437 				nsd.gid = pwd->pw_gid;
1438 			}
1439 		}
1440 	}
1441 	/* endpwent(); */
1442 #endif /* HAVE_GETPWNAM */
1443 
1444 #if defined(HAVE_SSL)
1445 	key_options_tsig_add(nsd.options);
1446 #endif
1447 
1448 	append_trailing_slash(&nsd.options->xfrdir, nsd.options->region);
1449 	/* Check relativity of pathnames to chroot */
1450 	if (nsd.chrootdir && nsd.chrootdir[0]) {
1451 		/* existing chrootdir: append trailing slash for strncmp checking */
1452 		append_trailing_slash(&nsd.chrootdir, nsd.region);
1453 		append_trailing_slash(&nsd.options->zonesdir, nsd.options->region);
1454 
1455 		/* zonesdir must be absolute and within chroot,
1456 		 * all other pathnames may be relative to zonesdir */
1457 		if (strncmp(nsd.options->zonesdir, nsd.chrootdir, strlen(nsd.chrootdir)) != 0) {
1458 			error("zonesdir %s has to be an absolute path that starts with the chroot path %s",
1459 				nsd.options->zonesdir, nsd.chrootdir);
1460 		} else if (!file_inside_chroot(nsd.pidfile, nsd.chrootdir)) {
1461 			error("pidfile %s is not relative to %s: chroot not possible",
1462 				nsd.pidfile, nsd.chrootdir);
1463 		} else if (!file_inside_chroot(nsd.options->xfrdfile, nsd.chrootdir)) {
1464 			error("xfrdfile %s is not relative to %s: chroot not possible",
1465 				nsd.options->xfrdfile, nsd.chrootdir);
1466 		} else if (!file_inside_chroot(nsd.options->zonelistfile, nsd.chrootdir)) {
1467 			error("zonelistfile %s is not relative to %s: chroot not possible",
1468 				nsd.options->zonelistfile, nsd.chrootdir);
1469 		} else if (!file_inside_chroot(nsd.options->xfrdir, nsd.chrootdir)) {
1470 			error("xfrdir %s is not relative to %s: chroot not possible",
1471 				nsd.options->xfrdir, nsd.chrootdir);
1472 		}
1473 	}
1474 
1475 	/* Set up the logging */
1476 	log_open(LOG_PID, FACILITY, nsd.log_filename);
1477 	if(nsd.options->log_only_syslog)
1478 		log_set_log_function(log_only_syslog);
1479 	else if (!nsd.log_filename)
1480 		log_set_log_function(log_syslog);
1481 	else if (nsd.uid && nsd.gid) {
1482 		if(chown(nsd.log_filename, nsd.uid, nsd.gid) != 0)
1483 			VERBOSITY(2, (LOG_WARNING, "chown %s failed: %s",
1484 				nsd.log_filename, strerror(errno)));
1485 	}
1486 	log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING);
1487 
1488 	/* Do we have a running nsd? */
1489 	if(nsd.pidfile && nsd.pidfile[0]) {
1490 		if ((oldpid = readpid(nsd.pidfile)) == -1) {
1491 			if (errno != ENOENT) {
1492 				log_msg(LOG_ERR, "can't read pidfile %s: %s",
1493 					nsd.pidfile, strerror(errno));
1494 			}
1495 		} else {
1496 			if (kill(oldpid, 0) == 0 || errno == EPERM) {
1497 				log_msg(LOG_WARNING,
1498 					"%s is already running as %u, continuing",
1499 					argv0, (unsigned) oldpid);
1500 			} else {
1501 				log_msg(LOG_ERR,
1502 					"...stale pid file from process %u",
1503 					(unsigned) oldpid);
1504 			}
1505 		}
1506 	}
1507 
1508 #ifdef HAVE_SETPROCTITLE
1509 	setproctitle("main");
1510 #endif
1511 #ifdef HAVE_CPUSET_T
1512 	if(nsd.use_cpu_affinity) {
1513 		set_cpu_affinity(nsd.cpuset);
1514 	}
1515 #endif
1516 
1517 	print_sockets(nsd.udp, nsd.tcp, nsd.ifs);
1518 
1519 	/* Setup the signal handling... */
1520 	action.sa_handler = sig_handler;
1521 	sigfillset(&action.sa_mask);
1522 	action.sa_flags = 0;
1523 	sigaction(SIGTERM, &action, NULL);
1524 	sigaction(SIGHUP, &action, NULL);
1525 	sigaction(SIGINT, &action, NULL);
1526 	sigaction(SIGILL, &action, NULL);
1527 	sigaction(SIGUSR1, &action, NULL);
1528 	sigaction(SIGALRM, &action, NULL);
1529 	sigaction(SIGCHLD, &action, NULL);
1530 	action.sa_handler = SIG_IGN;
1531 	sigaction(SIGPIPE, &action, NULL);
1532 
1533 	/* Initialize... */
1534 	nsd.mode = NSD_RUN;
1535 	nsd.signal_hint_child = 0;
1536 	nsd.signal_hint_reload = 0;
1537 	nsd.signal_hint_reload_hup = 0;
1538 	nsd.signal_hint_quit = 0;
1539 	nsd.signal_hint_shutdown = 0;
1540 	nsd.signal_hint_stats = 0;
1541 	nsd.signal_hint_statsusr = 0;
1542 	nsd.quit_sync_done = 0;
1543 
1544 	/* Initialize the server... */
1545 	if (server_init(&nsd) != 0) {
1546 		error("server initialization failed, %s could "
1547 			"not be started", argv0);
1548 	}
1549 #if defined(HAVE_SSL)
1550 	if(nsd.options->control_enable || (nsd.options->tls_service_key && nsd.options->tls_service_key[0])) {
1551 		perform_openssl_init();
1552 	}
1553 #endif /* HAVE_SSL */
1554 	if(nsd.options->control_enable) {
1555 		/* read ssl keys while superuser and outside chroot */
1556 		if(!(nsd.rc = daemon_remote_create(nsd.options)))
1557 			error("could not perform remote control setup");
1558 	}
1559 #if defined(HAVE_SSL)
1560 	if(nsd.options->tls_service_key && nsd.options->tls_service_key[0]
1561 	   && nsd.options->tls_service_pem && nsd.options->tls_service_pem[0]) {
1562 		if(!(nsd.tls_ctx = server_tls_ctx_create(&nsd, NULL,
1563 			nsd.options->tls_service_ocsp)))
1564 			error("could not set up tls SSL_CTX");
1565 	}
1566 #endif /* HAVE_SSL */
1567 
1568 	if(nsd.options->cookie_secret_file && nsd.options->cookie_secret_file[0]
1569 	   && !cookie_secret_file_read(&nsd) ) {
1570 		log_msg(LOG_ERR, "cookie secret file corrupt or not readable");
1571 	}
1572 
1573 	/* Unless we're debugging, fork... */
1574 	if (!nsd.debug) {
1575 		int fd;
1576 
1577 		/* Take off... */
1578 		switch (fork()) {
1579 		case 0:
1580 			/* Child */
1581 			break;
1582 		case -1:
1583 			error("fork() failed: %s", strerror(errno));
1584 			break;
1585 		default:
1586 			/* Parent is done */
1587 			server_close_all_sockets(nsd.udp, nsd.ifs);
1588 			server_close_all_sockets(nsd.tcp, nsd.ifs);
1589 			exit(0);
1590 		}
1591 
1592 		/* Detach ourselves... */
1593 		if (setsid() == -1) {
1594 			error("setsid() failed: %s", strerror(errno));
1595 		}
1596 
1597 		if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
1598 			(void)dup2(fd, STDIN_FILENO);
1599 			(void)dup2(fd, STDOUT_FILENO);
1600 			(void)dup2(fd, STDERR_FILENO);
1601 			if (fd > 2)
1602 				(void)close(fd);
1603 		}
1604 	}
1605 
1606 	/* Get our process id */
1607 	nsd.pid = getpid();
1608 
1609 	/* Set user context */
1610 #ifdef HAVE_GETPWNAM
1611 	if (*nsd.username) {
1612 #ifdef HAVE_SETUSERCONTEXT
1613 		/* setusercontext does initgroups, setuid, setgid, and
1614 		 * also resource limits from login config, but we
1615 		 * still call setresuid, setresgid to be sure to set all uid */
1616 		if (setusercontext(NULL, pwd, nsd.uid,
1617 			LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
1618 			log_msg(LOG_WARNING, "unable to setusercontext %s: %s",
1619 				nsd.username, strerror(errno));
1620 #endif /* HAVE_SETUSERCONTEXT */
1621 	}
1622 #endif /* HAVE_GETPWNAM */
1623 
1624 	/* Chroot */
1625 #ifdef HAVE_CHROOT
1626 	if (nsd.chrootdir && nsd.chrootdir[0]) {
1627 		int l = strlen(nsd.chrootdir)-1; /* ends in trailing slash */
1628 
1629 		if (file_inside_chroot(nsd.log_filename, nsd.chrootdir))
1630 			nsd.file_rotation_ok = 1;
1631 
1632 		/* strip chroot from pathnames if they're absolute */
1633 		nsd.options->zonesdir += l;
1634 		if (nsd.log_filename){
1635 			if (nsd.log_filename[0] == '/')
1636 				nsd.log_filename += l;
1637 		}
1638 		if (nsd.pidfile && nsd.pidfile[0] == '/')
1639 			nsd.pidfile += l;
1640 		if (nsd.options->xfrdfile[0] == '/')
1641 			nsd.options->xfrdfile += l;
1642 		if (nsd.options->zonelistfile[0] == '/')
1643 			nsd.options->zonelistfile += l;
1644 		if (nsd.options->xfrdir[0] == '/')
1645 			nsd.options->xfrdir += l;
1646 
1647 		/* strip chroot from pathnames of "include:" statements
1648 		 * on subsequent repattern commands */
1649 		cfg_parser->chroot = nsd.chrootdir;
1650 
1651 #ifdef HAVE_TZSET
1652 		/* set timezone whilst not yet in chroot */
1653 		tzset();
1654 #endif
1655 		if (chroot(nsd.chrootdir)) {
1656 			error("unable to chroot: %s", strerror(errno));
1657 		}
1658 		if (chdir("/")) {
1659 			error("unable to chdir to chroot: %s", strerror(errno));
1660 		}
1661 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed root directory to %s",
1662 			nsd.chrootdir));
1663 		/* chdir to zonesdir again after chroot */
1664 		if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
1665 			if(chdir(nsd.options->zonesdir)) {
1666 				error("unable to chdir to '%s': %s",
1667 					nsd.options->zonesdir, strerror(errno));
1668 			}
1669 			DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
1670 				nsd.options->zonesdir));
1671 		}
1672 	}
1673 	else
1674 #endif /* HAVE_CHROOT */
1675 		nsd.file_rotation_ok = 1;
1676 
1677 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "file rotation on %s %sabled",
1678 		nsd.log_filename, nsd.file_rotation_ok?"en":"dis"));
1679 
1680 	/* Write pidfile */
1681 	if (writepid(&nsd) == -1) {
1682 		log_msg(LOG_ERR, "cannot overwrite the pidfile %s: %s",
1683 			nsd.pidfile, strerror(errno));
1684 	}
1685 
1686 	/* Drop the permissions */
1687 #ifdef HAVE_GETPWNAM
1688 	if (*nsd.username) {
1689 #ifdef HAVE_INITGROUPS
1690 		if(initgroups(nsd.username, nsd.gid) != 0)
1691 			log_msg(LOG_WARNING, "unable to initgroups %s: %s",
1692 				nsd.username, strerror(errno));
1693 #endif /* HAVE_INITGROUPS */
1694 		endpwent();
1695 
1696 #ifdef HAVE_SETRESGID
1697 		if(setresgid(nsd.gid,nsd.gid,nsd.gid) != 0)
1698 #elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
1699 			if(setregid(nsd.gid,nsd.gid) != 0)
1700 #else /* use setgid */
1701 				if(setgid(nsd.gid) != 0)
1702 #endif /* HAVE_SETRESGID */
1703 					error("unable to set group id of %s: %s",
1704 						nsd.username, strerror(errno));
1705 
1706 #ifdef HAVE_SETRESUID
1707 		if(setresuid(nsd.uid,nsd.uid,nsd.uid) != 0)
1708 #elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
1709 			if(setreuid(nsd.uid,nsd.uid) != 0)
1710 #else /* use setuid */
1711 				if(setuid(nsd.uid) != 0)
1712 #endif /* HAVE_SETRESUID */
1713 					error("unable to set user id of %s: %s",
1714 						nsd.username, strerror(errno));
1715 
1716 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "dropped user privileges, run as %s",
1717 			nsd.username));
1718 	}
1719 #endif /* HAVE_GETPWNAM */
1720 
1721 	if (pledge("stdio rpath wpath cpath dns inet proc", NULL) == -1)
1722 		error("pledge");
1723 
1724 	xfrd_make_tempdir(&nsd);
1725 #ifdef USE_ZONE_STATS
1726 	options_zonestatnames_create(nsd.options);
1727 	server_zonestat_alloc(&nsd);
1728 #endif /* USE_ZONE_STATS */
1729 #ifdef BIND8_STATS
1730 	server_stat_alloc(&nsd);
1731 #endif /* BIND8_STATS */
1732 	if(nsd.server_kind == NSD_SERVER_MAIN) {
1733 		server_prepare_xfrd(&nsd);
1734 		/* xfrd forks this before reading database, so it does not get
1735 		 * the memory size of the database */
1736 		server_start_xfrd(&nsd, 0, 0);
1737 		/* close zonelistfile in non-xfrd processes */
1738 		zone_list_close(nsd.options);
1739 #ifdef USE_DNSTAP
1740 		if(nsd.options->dnstap_enable) {
1741 			nsd.dt_collector = dt_collector_create(&nsd);
1742 			dt_collector_start(nsd.dt_collector, &nsd);
1743 		}
1744 #endif /* USE_DNSTAP */
1745 	}
1746 	if (server_prepare(&nsd) != 0) {
1747 		unlinkpid(nsd.pidfile);
1748 		error("server preparation failed, %s could "
1749 			"not be started", argv0);
1750 	}
1751 	if(nsd.server_kind == NSD_SERVER_MAIN) {
1752 		server_send_soa_xfrd(&nsd, 0);
1753 	}
1754 
1755 	/* Really take off */
1756 	log_msg(LOG_NOTICE, "%s started (%s), pid %d",
1757 		argv0, PACKAGE_STRING, (int) nsd.pid);
1758 
1759 	if (nsd.server_kind == NSD_SERVER_MAIN) {
1760 		server_main(&nsd);
1761 	} else {
1762 		server_child(&nsd);
1763 	}
1764 
1765 	/* NOTREACH */
1766 	exit(0);
1767 }
1768