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