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