Home | History | Annotate | Line # | Download | only in dist
nsd.c revision 1.1.1.1.8.1
      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 #include <login_cap.h>
     25 #endif /* HAVE_SETUSERCONTEXT */
     26 
     27 #include <assert.h>
     28 #include <ctype.h>
     29 #include <errno.h>
     30 #include <fcntl.h>
     31 #include <limits.h>
     32 #include <netdb.h>
     33 #include <pwd.h>
     34 #include <signal.h>
     35 #include <stdarg.h>
     36 #include <stddef.h>
     37 #include <stdio.h>
     38 #include <stdlib.h>
     39 #include <string.h>
     40 #include <time.h>
     41 #include <unistd.h>
     42 
     43 #include "nsd.h"
     44 #include "options.h"
     45 #include "tsig.h"
     46 #include "remote.h"
     47 #include "xfrd-disk.h"
     48 
     49 /* The server handler... */
     50 struct nsd nsd;
     51 static char hostname[MAXHOSTNAMELEN];
     52 extern config_parser_state_type* cfg_parser;
     53 
     54 static void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
     55 
     56 /*
     57  * Print the help text.
     58  *
     59  */
     60 static void
     61 usage (void)
     62 {
     63 	fprintf(stderr, "Usage: nsd [OPTION]...\n");
     64 	fprintf(stderr, "Name Server Daemon.\n\n");
     65 	fprintf(stderr,
     66 		"Supported options:\n"
     67 		"  -4                   Only listen to IPv4 connections.\n"
     68 		"  -6                   Only listen to IPv6 connections.\n"
     69 		"  -a ip-address[@port] Listen to the specified incoming IP address (and port)\n"
     70 		"                       May be specified multiple times).\n"
     71 		"  -c configfile        Read specified configfile instead of %s.\n"
     72 		"  -d                   do not fork as a daemon process.\n"
     73 #ifndef NDEBUG
     74 		"  -F facilities        Specify the debug facilities.\n"
     75 #endif /* NDEBUG */
     76 		"  -f database          Specify the database to load.\n"
     77 		"  -h                   Print this help information.\n"
     78 		, CONFIGFILE);
     79 	fprintf(stderr,
     80 		"  -i identity          Specify the identity when queried for id.server CHAOS TXT.\n"
     81 		"  -I nsid              Specify the NSID. This must be a hex string.\n"
     82 #ifndef NDEBUG
     83 		"  -L level             Specify the debug level.\n"
     84 #endif /* NDEBUG */
     85 		"  -l filename          Specify the log file.\n"
     86 		"  -N server-count      The number of servers to start.\n"
     87 		"  -n tcp-count         The maximum number of TCP connections per server.\n"
     88 		"  -P pidfile           Specify the PID file to write.\n"
     89 		"  -p port              Specify the port to listen to.\n"
     90 		"  -s seconds           Dump statistics every SECONDS seconds.\n"
     91 		"  -t chrootdir         Change root to specified directory on startup.\n"
     92 		);
     93 	fprintf(stderr,
     94 		"  -u user              Change effective uid to the specified user.\n"
     95 		"  -V level             Specify verbosity level.\n"
     96 		"  -v                   Print version information.\n"
     97 		);
     98 	fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
     99 		PACKAGE_VERSION, PACKAGE_BUGREPORT);
    100 }
    101 
    102 /*
    103  * Print the version exit.
    104  *
    105  */
    106 static void
    107 version(void)
    108 {
    109 	fprintf(stderr, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
    110 	fprintf(stderr, "Written by NLnet Labs.\n\n");
    111 	fprintf(stderr,
    112 		"Copyright (C) 2001-2006 NLnet Labs.  This is free software.\n"
    113 		"There is NO warranty; not even for MERCHANTABILITY or FITNESS\n"
    114 		"FOR A PARTICULAR PURPOSE.\n");
    115 	exit(0);
    116 }
    117 
    118 /*
    119  * Something went wrong, give error messages and exit.
    120  *
    121  */
    122 static void
    123 error(const char *format, ...)
    124 {
    125 	va_list args;
    126 	va_start(args, format);
    127 	log_vmsg(LOG_ERR, format, args);
    128 	va_end(args);
    129 	exit(1);
    130 }
    131 
    132 static void
    133 append_trailing_slash(const char** dirname, region_type* region)
    134 {
    135 	int l = strlen(*dirname);
    136 	if (l>0 && (*dirname)[l-1] != '/' && l < 0xffffff) {
    137 		char *dirname_slash = region_alloc(region, l+2);
    138 		memcpy(dirname_slash, *dirname, l+1);
    139 		strlcat(dirname_slash, "/", l+2);
    140 		/* old dirname is leaked, this is only used for chroot, once */
    141 		*dirname = dirname_slash;
    142 	}
    143 }
    144 
    145 static int
    146 file_inside_chroot(const char* fname, const char* chr)
    147 {
    148 	/* true if filename starts with chroot or is not absolute */
    149 	return ((fname && fname[0] && strncmp(fname, chr, strlen(chr)) == 0) ||
    150 		(fname && fname[0] != '/'));
    151 }
    152 
    153 void
    154 get_ip_port_frm_str(const char* arg, const char** hostname,
    155         const char** port)
    156 {
    157         /* parse src[@port] option */
    158         char* delim = NULL;
    159 	if (arg) {
    160 		delim = strchr(arg, '@');
    161 	}
    162 
    163         if (delim) {
    164                 *delim = '\0';
    165                 *port = delim+1;
    166         }
    167         *hostname = arg;
    168 }
    169 
    170 /* append interface to interface array (names, udp, tcp) */
    171 void
    172 add_interface(char*** nodes, struct nsd* nsd, char* ip)
    173 {
    174 	/* realloc the arrays */
    175 	if(nsd->ifs == 0) {
    176 		*nodes = xalloc_zero(sizeof(*nodes));
    177 		nsd->udp = xalloc_zero(sizeof(*nsd->udp));
    178 		nsd->tcp = xalloc_zero(sizeof(*nsd->udp));
    179 	} else {
    180 		region_remove_cleanup(nsd->region, free, *nodes);
    181 		region_remove_cleanup(nsd->region, free, nsd->udp);
    182 		region_remove_cleanup(nsd->region, free, nsd->tcp);
    183 		*nodes = xrealloc(*nodes, (nsd->ifs+1)*sizeof(*nodes));
    184 		nsd->udp = xrealloc(nsd->udp, (nsd->ifs+1)*sizeof(*nsd->udp));
    185 		nsd->tcp = xrealloc(nsd->tcp, (nsd->ifs+1)*sizeof(*nsd->udp));
    186 		(*nodes)[nsd->ifs] = NULL;
    187 		memset(&nsd->udp[nsd->ifs], 0, sizeof(*nsd->udp));
    188 		memset(&nsd->tcp[nsd->ifs], 0, sizeof(*nsd->tcp));
    189 	}
    190 	region_add_cleanup(nsd->region, free, *nodes);
    191 	region_add_cleanup(nsd->region, free, nsd->udp);
    192 	region_add_cleanup(nsd->region, free, nsd->tcp);
    193 
    194 	/* add it */
    195 	(*nodes)[nsd->ifs] = ip;
    196 	++nsd->ifs;
    197 }
    198 
    199 /*
    200  * Fetch the nsd parent process id from the nsd pidfile
    201  *
    202  */
    203 pid_t
    204 readpid(const char *file)
    205 {
    206 	int fd;
    207 	pid_t pid;
    208 	char pidbuf[16];
    209 	char *t;
    210 	int l;
    211 
    212 	if ((fd = open(file, O_RDONLY)) == -1) {
    213 		return -1;
    214 	}
    215 
    216 	if (((l = read(fd, pidbuf, sizeof(pidbuf)))) == -1) {
    217 		close(fd);
    218 		return -1;
    219 	}
    220 
    221 	close(fd);
    222 
    223 	/* Empty pidfile means no pidfile... */
    224 	if (l == 0) {
    225 		errno = ENOENT;
    226 		return -1;
    227 	}
    228 
    229 	pid = (pid_t) strtol(pidbuf, &t, 10);
    230 
    231 	if (*t && *t != '\n') {
    232 		return -1;
    233 	}
    234 	return pid;
    235 }
    236 
    237 /*
    238  * Store the nsd parent process id in the nsd pidfile
    239  *
    240  */
    241 int
    242 writepid(struct nsd *nsd)
    243 {
    244 	FILE * fd;
    245 	char pidbuf[32];
    246 
    247 	snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) nsd->pid);
    248 
    249 	if ((fd = fopen(nsd->pidfile, "w")) ==  NULL ) {
    250 		log_msg(LOG_ERR, "cannot open pidfile %s: %s",
    251 			nsd->pidfile, strerror(errno));
    252 		return -1;
    253 	}
    254 
    255 	if (!write_data(fd, pidbuf, strlen(pidbuf))) {
    256 		log_msg(LOG_ERR, "cannot write pidfile %s: %s",
    257 			nsd->pidfile, strerror(errno));
    258 		fclose(fd);
    259 		return -1;
    260 	}
    261 	fclose(fd);
    262 
    263 	if (chown(nsd->pidfile, nsd->uid, nsd->gid) == -1) {
    264 		log_msg(LOG_ERR, "cannot chown %u.%u %s: %s",
    265 			(unsigned) nsd->uid, (unsigned) nsd->gid,
    266 			nsd->pidfile, strerror(errno));
    267 		return -1;
    268 	}
    269 
    270 	return 0;
    271 }
    272 
    273 void
    274 unlinkpid(const char* file)
    275 {
    276 	int fd = -1;
    277 
    278 	if (file) {
    279 		/* truncate pidfile */
    280 		fd = open(file, O_WRONLY | O_TRUNC, 0644);
    281 		if (fd == -1) {
    282 			/* Truncate the pid file.  */
    283 			log_msg(LOG_ERR, "can not truncate the pid file %s: %s", file, strerror(errno));
    284 		} else
    285 			close(fd);
    286 
    287 		/* unlink pidfile */
    288 		if (unlink(file) == -1)
    289 			log_msg(LOG_WARNING, "failed to unlink pidfile %s: %s",
    290 				file, strerror(errno));
    291 	}
    292 }
    293 
    294 /*
    295  * Incoming signals, set appropriate actions.
    296  *
    297  */
    298 void
    299 sig_handler(int sig)
    300 {
    301 	/* To avoid race cond. We really don't want to use log_msg() in this handler */
    302 
    303 	/* Are we a child server? */
    304 	if (nsd.server_kind != NSD_SERVER_MAIN) {
    305 		switch (sig) {
    306 		case SIGCHLD:
    307 			nsd.signal_hint_child = 1;
    308 			break;
    309 		case SIGALRM:
    310 			break;
    311 		case SIGINT:
    312 		case SIGTERM:
    313 			nsd.signal_hint_quit = 1;
    314 			break;
    315 		case SIGILL:
    316 		case SIGUSR1:	/* Dump stats on SIGUSR1.  */
    317 			nsd.signal_hint_statsusr = 1;
    318 			break;
    319 		default:
    320 			break;
    321 		}
    322 		return;
    323 	}
    324 
    325 	/* We are the main process */
    326 	switch (sig) {
    327 	case SIGCHLD:
    328 		nsd.signal_hint_child = 1;
    329 		return;
    330 	case SIGHUP:
    331 		nsd.signal_hint_reload_hup = 1;
    332 		return;
    333 	case SIGALRM:
    334 		nsd.signal_hint_stats = 1;
    335 		break;
    336 	case SIGILL:
    337 		/*
    338 		 * For backwards compatibility with BIND 8 and older
    339 		 * versions of NSD.
    340 		 */
    341 		nsd.signal_hint_statsusr = 1;
    342 		break;
    343 	case SIGUSR1:
    344 		/* Dump statistics.  */
    345 		nsd.signal_hint_statsusr = 1;
    346 		break;
    347 	case SIGINT:
    348 	case SIGTERM:
    349 	default:
    350 		nsd.signal_hint_shutdown = 1;
    351 		break;
    352 	}
    353 }
    354 
    355 /*
    356  * Statistic output...
    357  *
    358  */
    359 #ifdef BIND8_STATS
    360 void
    361 bind8_stats (struct nsd *nsd)
    362 {
    363 	char buf[MAXSYSLOGMSGLEN];
    364 	char *msg, *t;
    365 	int i, len;
    366 
    367 	/* Current time... */
    368 	time_t now;
    369 	if(!nsd->st.period)
    370 		return;
    371 	time(&now);
    372 
    373 	/* NSTATS */
    374 	t = msg = buf + snprintf(buf, MAXSYSLOGMSGLEN, "NSTATS %lld %lu",
    375 				 (long long) now, (unsigned long) nsd->st.boot);
    376 	for (i = 0; i <= 255; i++) {
    377 		/* How much space left? */
    378 		if ((len = buf + MAXSYSLOGMSGLEN - t) < 32) {
    379 			log_msg(LOG_INFO, "%s", buf);
    380 			t = msg;
    381 			len = buf + MAXSYSLOGMSGLEN - t;
    382 		}
    383 
    384 		if (nsd->st.qtype[i] != 0) {
    385 			t += snprintf(t, len, " %s=%lu", rrtype_to_string(i), nsd->st.qtype[i]);
    386 		}
    387 	}
    388 	if (t > msg)
    389 		log_msg(LOG_INFO, "%s", buf);
    390 
    391 	/* XSTATS */
    392 	/* Only print it if we're in the main daemon or have anything to report... */
    393 	if (nsd->server_kind == NSD_SERVER_MAIN
    394 	    || nsd->st.dropped || nsd->st.raxfr || (nsd->st.qudp + nsd->st.qudp6 - nsd->st.dropped)
    395 	    || nsd->st.txerr || nsd->st.opcode[OPCODE_QUERY] || nsd->st.opcode[OPCODE_IQUERY]
    396 	    || nsd->st.wrongzone || nsd->st.ctcp + nsd->st.ctcp6 || nsd->st.rcode[RCODE_SERVFAIL]
    397 	    || nsd->st.rcode[RCODE_FORMAT] || nsd->st.nona || nsd->st.rcode[RCODE_NXDOMAIN]
    398 	    || nsd->st.opcode[OPCODE_UPDATE]) {
    399 
    400 		log_msg(LOG_INFO, "XSTATS %lld %lu"
    401 			" RR=%lu RNXD=%lu RFwdR=%lu RDupR=%lu RFail=%lu RFErr=%lu RErr=%lu RAXFR=%lu"
    402 			" RLame=%lu ROpts=%lu SSysQ=%lu SAns=%lu SFwdQ=%lu SDupQ=%lu SErr=%lu RQ=%lu"
    403 			" RIQ=%lu RFwdQ=%lu RDupQ=%lu RTCP=%lu SFwdR=%lu SFail=%lu SFErr=%lu SNaAns=%lu"
    404 			" SNXD=%lu RUQ=%lu RURQ=%lu RUXFR=%lu RUUpd=%lu",
    405 			(long long) now, (unsigned long) nsd->st.boot,
    406 			nsd->st.dropped, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0,
    407 			(unsigned long)0, (unsigned long)0, nsd->st.raxfr, (unsigned long)0, (unsigned long)0,
    408 			(unsigned long)0, nsd->st.qudp + nsd->st.qudp6 - nsd->st.dropped, (unsigned long)0,
    409 			(unsigned long)0, nsd->st.txerr,
    410 			nsd->st.opcode[OPCODE_QUERY], nsd->st.opcode[OPCODE_IQUERY], nsd->st.wrongzone,
    411 			(unsigned long)0, nsd->st.ctcp + nsd->st.ctcp6,
    412 			(unsigned long)0, nsd->st.rcode[RCODE_SERVFAIL], nsd->st.rcode[RCODE_FORMAT],
    413 			nsd->st.nona, nsd->st.rcode[RCODE_NXDOMAIN],
    414 			(unsigned long)0, (unsigned long)0, (unsigned long)0, nsd->st.opcode[OPCODE_UPDATE]);
    415 	}
    416 
    417 }
    418 #endif /* BIND8_STATS */
    419 
    420 extern char *optarg;
    421 extern int optind;
    422 
    423 int
    424 main(int argc, char *argv[])
    425 {
    426 	/* Scratch variables... */
    427 	int c;
    428 	pid_t	oldpid;
    429 	size_t i;
    430 	struct sigaction action;
    431 #ifdef HAVE_GETPWNAM
    432 	struct passwd *pwd = NULL;
    433 #endif /* HAVE_GETPWNAM */
    434 
    435 	struct addrinfo hints[2];
    436 	int hints_in_use = 1;
    437 	char** nodes = NULL; /* array of address strings, size nsd.ifs */
    438 	const char *udp_port = 0;
    439 	const char *tcp_port = 0;
    440 
    441 	const char *configfile = CONFIGFILE;
    442 
    443 	char* argv0 = (argv0 = strrchr(argv[0], '/')) ? argv0 + 1 : argv[0];
    444 
    445 	log_init(argv0);
    446 
    447 	/* Initialize the server handler... */
    448 	memset(&nsd, 0, sizeof(struct nsd));
    449 	nsd.region      = region_create(xalloc, free);
    450 	nsd.dbfile	= 0;
    451 	nsd.pidfile	= 0;
    452 	nsd.server_kind = NSD_SERVER_MAIN;
    453 	memset(&hints, 0, sizeof(*hints)*2);
    454 	hints[0].ai_family = DEFAULT_AI_FAMILY;
    455 	hints[0].ai_flags = AI_PASSIVE;
    456 	hints[1].ai_family = DEFAULT_AI_FAMILY;
    457 	hints[1].ai_flags = AI_PASSIVE;
    458 	nsd.identity	= 0;
    459 	nsd.version	= VERSION;
    460 	nsd.username	= 0;
    461 	nsd.chrootdir	= 0;
    462 	nsd.nsid 	= NULL;
    463 	nsd.nsid_len 	= 0;
    464 
    465 	nsd.child_count = 0;
    466 	nsd.maximum_tcp_count = 0;
    467 	nsd.current_tcp_count = 0;
    468 	nsd.grab_ip6_optional = 0;
    469 	nsd.file_rotation_ok = 0;
    470 
    471 	/* Set up our default identity to gethostname(2) */
    472 	if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
    473 		nsd.identity = hostname;
    474 	} else {
    475 		log_msg(LOG_ERR,
    476 			"failed to get the host name: %s - using default identity",
    477 			strerror(errno));
    478 		nsd.identity = IDENTITY;
    479 	}
    480 
    481 	/* Parse the command line... */
    482 	while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v"
    483 #ifndef NDEBUG /* <mattthijs> only when configured with --enable-checking */
    484 		"F:L:"
    485 #endif /* NDEBUG */
    486 		)) != -1) {
    487 		switch (c) {
    488 		case '4':
    489 			hints[0].ai_family = AF_INET;
    490 			break;
    491 		case '6':
    492 #ifdef INET6
    493 			hints[0].ai_family = AF_INET6;
    494 #else /* !INET6 */
    495 			error("IPv6 support not enabled.");
    496 #endif /* INET6 */
    497 			break;
    498 		case 'a':
    499 			add_interface(&nodes, &nsd, optarg);
    500 			break;
    501 		case 'c':
    502 			configfile = optarg;
    503 			break;
    504 		case 'd':
    505 			nsd.debug = 1;
    506 			break;
    507 		case 'f':
    508 			nsd.dbfile = optarg;
    509 			break;
    510 		case 'h':
    511 			usage();
    512 			exit(0);
    513 		case 'i':
    514 			nsd.identity = optarg;
    515 			break;
    516 		case 'I':
    517 			if (nsd.nsid_len != 0) {
    518 				/* can only be given once */
    519 				break;
    520 			}
    521 			if (strncasecmp(optarg, "ascii_", 6) == 0) {
    522 				nsd.nsid = xalloc(strlen(optarg+6));
    523 				nsd.nsid_len = strlen(optarg+6);
    524 				memmove(nsd.nsid, optarg+6, nsd.nsid_len);
    525 			} else {
    526 				if (strlen(optarg) % 2 != 0) {
    527 					error("the NSID must be a hex string of an even length.");
    528 				}
    529 				nsd.nsid = xalloc(strlen(optarg) / 2);
    530 				nsd.nsid_len = strlen(optarg) / 2;
    531 				if (hex_pton(optarg, nsd.nsid, nsd.nsid_len) == -1) {
    532 					error("hex string cannot be parsed '%s' in NSID.", optarg);
    533 				}
    534 			}
    535 			break;
    536 		case 'l':
    537 			nsd.log_filename = optarg;
    538 			break;
    539 		case 'N':
    540 			i = atoi(optarg);
    541 			if (i <= 0) {
    542 				error("number of child servers must be greater than zero.");
    543 			} else {
    544 				nsd.child_count = i;
    545 			}
    546 			break;
    547 		case 'n':
    548 			i = atoi(optarg);
    549 			if (i <= 0) {
    550 				error("number of concurrent TCP connections must greater than zero.");
    551 			} else {
    552 				nsd.maximum_tcp_count = i;
    553 			}
    554 			break;
    555 		case 'P':
    556 			nsd.pidfile = optarg;
    557 			break;
    558 		case 'p':
    559 			if (atoi(optarg) == 0) {
    560 				error("port argument must be numeric.");
    561 			}
    562 			tcp_port = optarg;
    563 			udp_port = optarg;
    564 			break;
    565 		case 's':
    566 #ifdef BIND8_STATS
    567 			nsd.st.period = atoi(optarg);
    568 #else /* !BIND8_STATS */
    569 			error("BIND 8 statistics not enabled.");
    570 #endif /* BIND8_STATS */
    571 			break;
    572 		case 't':
    573 #ifdef HAVE_CHROOT
    574 			nsd.chrootdir = optarg;
    575 #else /* !HAVE_CHROOT */
    576 			error("chroot not supported on this platform.");
    577 #endif /* HAVE_CHROOT */
    578 			break;
    579 		case 'u':
    580 			nsd.username = optarg;
    581 			break;
    582 		case 'V':
    583 			verbosity = atoi(optarg);
    584 			break;
    585 		case 'v':
    586 			version();
    587 			/* version exits */
    588 			break;
    589 #ifndef NDEBUG
    590 		case 'F':
    591 			sscanf(optarg, "%x", &nsd_debug_facilities);
    592 			break;
    593 		case 'L':
    594 			sscanf(optarg, "%d", &nsd_debug_level);
    595 			break;
    596 #endif /* NDEBUG */
    597 		case '?':
    598 		default:
    599 			usage();
    600 			exit(1);
    601 		}
    602 	}
    603 	argc -= optind;
    604 	/* argv += optind; */
    605 
    606 	/* Commandline parse error */
    607 	if (argc != 0) {
    608 		usage();
    609 		exit(1);
    610 	}
    611 
    612 	if (strlen(nsd.identity) > UCHAR_MAX) {
    613 		error("server identity too long (%u characters)",
    614 		      (unsigned) strlen(nsd.identity));
    615 	}
    616 	if(!tsig_init(nsd.region))
    617 		error("init tsig failed");
    618 
    619 	/* Read options */
    620 	nsd.options = nsd_options_create(region_create_custom(xalloc, free,
    621 		DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE,
    622 		DEFAULT_INITIAL_CLEANUP_SIZE, 1));
    623 	if(!parse_options_file(nsd.options, configfile, NULL, NULL)) {
    624 		error("could not read config: %s\n", configfile);
    625 	}
    626 	if(!parse_zone_list_file(nsd.options)) {
    627 		error("could not read zonelist file %s\n",
    628 			nsd.options->zonelistfile);
    629 	}
    630 	if(nsd.options->do_ip4 && !nsd.options->do_ip6) {
    631 		hints[0].ai_family = AF_INET;
    632 	}
    633 #ifdef INET6
    634 	if(nsd.options->do_ip6 && !nsd.options->do_ip4) {
    635 		hints[0].ai_family = AF_INET6;
    636 	}
    637 #endif /* INET6 */
    638 	if(nsd.options->ip_addresses)
    639 	{
    640 		ip_address_option_type* ip = nsd.options->ip_addresses;
    641 		while(ip) {
    642 			add_interface(&nodes, &nsd, ip->address);
    643 			ip = ip->next;
    644 		}
    645 	}
    646 	if (verbosity == 0)
    647 		verbosity = nsd.options->verbosity;
    648 #ifndef NDEBUG
    649 	if (nsd_debug_level > 0 && verbosity == 0)
    650 		verbosity = nsd_debug_level;
    651 #endif /* NDEBUG */
    652 	if(nsd.options->debug_mode) nsd.debug=1;
    653 	if(!nsd.dbfile)
    654 	{
    655 		if(nsd.options->database)
    656 			nsd.dbfile = nsd.options->database;
    657 		else
    658 			nsd.dbfile = DBFILE;
    659 	}
    660 	if(!nsd.pidfile)
    661 	{
    662 		if(nsd.options->pidfile)
    663 			nsd.pidfile = nsd.options->pidfile;
    664 		else
    665 			nsd.pidfile = PIDFILE;
    666 	}
    667 	if(strcmp(nsd.identity, hostname)==0 || strcmp(nsd.identity,IDENTITY)==0)
    668 	{
    669 		if(nsd.options->identity)
    670 			nsd.identity = nsd.options->identity;
    671 	}
    672 	if(nsd.options->version) {
    673 		nsd.version = nsd.options->version;
    674 	}
    675 	if (nsd.options->logfile && !nsd.log_filename) {
    676 		nsd.log_filename = nsd.options->logfile;
    677 	}
    678 	if(nsd.child_count == 0) {
    679 		nsd.child_count = nsd.options->server_count;
    680 	}
    681 #ifdef SO_REUSEPORT
    682 	if(nsd.options->reuseport && nsd.child_count > 1) {
    683 		nsd.reuseport = nsd.child_count;
    684 	}
    685 #endif /* SO_REUSEPORT */
    686 	if(nsd.maximum_tcp_count == 0) {
    687 		nsd.maximum_tcp_count = nsd.options->tcp_count;
    688 	}
    689 	nsd.tcp_timeout = nsd.options->tcp_timeout;
    690 	nsd.tcp_query_count = nsd.options->tcp_query_count;
    691 	nsd.tcp_mss = nsd.options->tcp_mss;
    692 	nsd.outgoing_tcp_mss = nsd.options->outgoing_tcp_mss;
    693 	nsd.ipv4_edns_size = nsd.options->ipv4_edns_size;
    694 	nsd.ipv6_edns_size = nsd.options->ipv6_edns_size;
    695 
    696 	if(udp_port == 0)
    697 	{
    698 		if(nsd.options->port != 0) {
    699 			udp_port = nsd.options->port;
    700 			tcp_port = nsd.options->port;
    701 		} else {
    702 			udp_port = UDP_PORT;
    703 			tcp_port = TCP_PORT;
    704 		}
    705 	}
    706 #ifdef BIND8_STATS
    707 	if(nsd.st.period == 0) {
    708 		nsd.st.period = nsd.options->statistics;
    709 	}
    710 #endif /* BIND8_STATS */
    711 #ifdef HAVE_CHROOT
    712 	if(nsd.chrootdir == 0) nsd.chrootdir = nsd.options->chroot;
    713 #ifdef CHROOTDIR
    714 	/* if still no chrootdir, fallback to default */
    715 	if(nsd.chrootdir == 0) nsd.chrootdir = CHROOTDIR;
    716 #endif /* CHROOTDIR */
    717 #endif /* HAVE_CHROOT */
    718 	if(nsd.username == 0) {
    719 		if(nsd.options->username) nsd.username = nsd.options->username;
    720 		else nsd.username = USER;
    721 	}
    722 	if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
    723 		if(chdir(nsd.options->zonesdir)) {
    724 			error("cannot chdir to '%s': %s",
    725 				nsd.options->zonesdir, strerror(errno));
    726 		}
    727 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
    728 			nsd.options->zonesdir));
    729 	}
    730 
    731 	/* EDNS0 */
    732 	edns_init_data(&nsd.edns_ipv4, nsd.options->ipv4_edns_size);
    733 #if defined(INET6)
    734 #if defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU)
    735 	edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
    736 #else /* no way to set IPV6 MTU, send no bigger than that. */
    737 	if (nsd.options->ipv6_edns_size < IPV6_MIN_MTU)
    738 		edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
    739 	else
    740 		edns_init_data(&nsd.edns_ipv6, IPV6_MIN_MTU);
    741 #endif /* IPV6 MTU) */
    742 #endif /* defined(INET6) */
    743 
    744 	if (nsd.nsid_len == 0 && nsd.options->nsid) {
    745 		if (strlen(nsd.options->nsid) % 2 != 0) {
    746 			error("the NSID must be a hex string of an even length.");
    747 		}
    748 		nsd.nsid = xalloc(strlen(nsd.options->nsid) / 2);
    749 		nsd.nsid_len = strlen(nsd.options->nsid) / 2;
    750 		if (hex_pton(nsd.options->nsid, nsd.nsid, nsd.nsid_len) == -1) {
    751 			error("hex string cannot be parsed '%s' in NSID.", nsd.options->nsid);
    752 		}
    753 	}
    754 	edns_init_nsid(&nsd.edns_ipv4, nsd.nsid_len);
    755 #if defined(INET6)
    756 	edns_init_nsid(&nsd.edns_ipv6, nsd.nsid_len);
    757 #endif /* defined(INET6) */
    758 
    759 	/* Number of child servers to fork.  */
    760 	nsd.children = (struct nsd_child *) region_alloc_array(
    761 		nsd.region, nsd.child_count, sizeof(struct nsd_child));
    762 	for (i = 0; i < nsd.child_count; ++i) {
    763 		nsd.children[i].kind = NSD_SERVER_BOTH;
    764 		nsd.children[i].pid = -1;
    765 		nsd.children[i].child_fd = -1;
    766 		nsd.children[i].parent_fd = -1;
    767 		nsd.children[i].handler = NULL;
    768 		nsd.children[i].need_to_send_STATS = 0;
    769 		nsd.children[i].need_to_send_QUIT = 0;
    770 		nsd.children[i].need_to_exit = 0;
    771 		nsd.children[i].has_exited = 0;
    772 #ifdef  BIND8_STATS
    773 		nsd.children[i].query_count = 0;
    774 #endif
    775 	}
    776 
    777 	nsd.this_child = NULL;
    778 
    779 	/* We need at least one active interface */
    780 	if (nsd.ifs == 0) {
    781 		add_interface(&nodes, &nsd, NULL);
    782 
    783 		/*
    784 		 * With IPv6 we'd like to open two separate sockets,
    785 		 * one for IPv4 and one for IPv6, both listening to
    786 		 * the wildcard address (unless the -4 or -6 flags are
    787 		 * specified).
    788 		 *
    789 		 * However, this is only supported on platforms where
    790 		 * we can turn the socket option IPV6_V6ONLY _on_.
    791 		 * Otherwise we just listen to a single IPv6 socket
    792 		 * and any incoming IPv4 connections will be
    793 		 * automatically mapped to our IPv6 socket.
    794 		 */
    795 #ifdef INET6
    796 		if (hints[0].ai_family == AF_UNSPEC) {
    797 #ifdef IPV6_V6ONLY
    798 			add_interface(&nodes, &nsd, NULL);
    799 			hints[0].ai_family = AF_INET6;
    800 			hints[1].ai_family = AF_INET;
    801 			hints_in_use = 2;
    802 			nsd.grab_ip6_optional = 1;
    803 #else /* !IPV6_V6ONLY */
    804 			hints[0].ai_family = AF_INET6;
    805 #endif	/* IPV6_V6ONLY */
    806 		}
    807 #endif /* INET6 */
    808 	}
    809 
    810 	/* Set up the address info structures with real interface/port data */
    811 	assert(nodes);
    812 	for (i = 0; i < nsd.ifs; ++i) {
    813 		int r;
    814 		const char* node = NULL;
    815 		const char* service = NULL;
    816 		int h = ((hints_in_use == 1)?0:i%hints_in_use);
    817 
    818 		/* We don't perform name-lookups */
    819 		if (nodes[i] != NULL)
    820 			hints[h].ai_flags |= AI_NUMERICHOST;
    821 		get_ip_port_frm_str(nodes[i], &node, &service);
    822 
    823 		hints[h].ai_socktype = SOCK_DGRAM;
    824 		if ((r=getaddrinfo(node, (service?service:udp_port), &hints[h], &nsd.udp[i].addr)) != 0) {
    825 #ifdef INET6
    826 			if(nsd.grab_ip6_optional && hints[0].ai_family == AF_INET6) {
    827 				log_msg(LOG_WARNING, "No IPv6, fallback to IPv4. getaddrinfo: %s",
    828 				r==EAI_SYSTEM?strerror(errno):gai_strerror(r));
    829 				continue;
    830 			}
    831 #endif
    832 			error("cannot parse address '%s': getaddrinfo: %s %s",
    833 				nodes[i]?nodes[i]:"(null)",
    834 				gai_strerror(r),
    835 				r==EAI_SYSTEM?strerror(errno):"");
    836 		}
    837 
    838 		hints[h].ai_socktype = SOCK_STREAM;
    839 		if ((r=getaddrinfo(node, (service?service:tcp_port), &hints[h], &nsd.tcp[i].addr)) != 0) {
    840 			error("cannot parse address '%s': getaddrinfo: %s %s",
    841 				nodes[i]?nodes[i]:"(null)",
    842 				gai_strerror(r),
    843 				r==EAI_SYSTEM?strerror(errno):"");
    844 		}
    845 	}
    846 
    847 	/* Parse the username into uid and gid */
    848 	nsd.gid = getgid();
    849 	nsd.uid = getuid();
    850 #ifdef HAVE_GETPWNAM
    851 	/* Parse the username into uid and gid */
    852 	if (*nsd.username) {
    853 		if (isdigit((unsigned char)*nsd.username)) {
    854 			char *t;
    855 			nsd.uid = strtol(nsd.username, &t, 10);
    856 			if (*t != 0) {
    857 				if (*t != '.' || !isdigit((unsigned char)*++t)) {
    858 					error("-u user or -u uid or -u uid.gid");
    859 				}
    860 				nsd.gid = strtol(t, &t, 10);
    861 			} else {
    862 				/* Lookup the group id in /etc/passwd */
    863 				if ((pwd = getpwuid(nsd.uid)) == NULL) {
    864 					error("user id %u does not exist.", (unsigned) nsd.uid);
    865 				} else {
    866 					nsd.gid = pwd->pw_gid;
    867 				}
    868 			}
    869 		} else {
    870 			/* Lookup the user id in /etc/passwd */
    871 			if ((pwd = getpwnam(nsd.username)) == NULL) {
    872 				error("user '%s' does not exist.", nsd.username);
    873 			} else {
    874 				nsd.uid = pwd->pw_uid;
    875 				nsd.gid = pwd->pw_gid;
    876 			}
    877 		}
    878 	}
    879 	/* endpwent(); */
    880 #endif /* HAVE_GETPWNAM */
    881 
    882 #if defined(HAVE_SSL)
    883 	key_options_tsig_add(nsd.options);
    884 #endif
    885 
    886 	append_trailing_slash(&nsd.options->xfrdir, nsd.options->region);
    887 	/* Check relativity of pathnames to chroot */
    888 	if (nsd.chrootdir && nsd.chrootdir[0]) {
    889 		/* existing chrootdir: append trailing slash for strncmp checking */
    890 		append_trailing_slash(&nsd.chrootdir, nsd.region);
    891 		append_trailing_slash(&nsd.options->zonesdir, nsd.options->region);
    892 
    893 		/* zonesdir must be absolute and within chroot,
    894 		 * all other pathnames may be relative to zonesdir */
    895 		if (strncmp(nsd.options->zonesdir, nsd.chrootdir, strlen(nsd.chrootdir)) != 0) {
    896 			error("zonesdir %s has to be an absolute path that starts with the chroot path %s",
    897 				nsd.options->zonesdir, nsd.chrootdir);
    898 		} else if (!file_inside_chroot(nsd.pidfile, nsd.chrootdir)) {
    899 			error("pidfile %s is not relative to %s: chroot not possible",
    900 				nsd.pidfile, nsd.chrootdir);
    901 		} else if (!file_inside_chroot(nsd.dbfile, nsd.chrootdir)) {
    902 			error("database %s is not relative to %s: chroot not possible",
    903 				nsd.dbfile, nsd.chrootdir);
    904 		} else if (!file_inside_chroot(nsd.options->xfrdfile, nsd.chrootdir)) {
    905 			error("xfrdfile %s is not relative to %s: chroot not possible",
    906 				nsd.options->xfrdfile, nsd.chrootdir);
    907 		} else if (!file_inside_chroot(nsd.options->zonelistfile, nsd.chrootdir)) {
    908 			error("zonelistfile %s is not relative to %s: chroot not possible",
    909 				nsd.options->zonelistfile, nsd.chrootdir);
    910 		} else if (!file_inside_chroot(nsd.options->xfrdir, nsd.chrootdir)) {
    911 			error("xfrdir %s is not relative to %s: chroot not possible",
    912 				nsd.options->xfrdir, nsd.chrootdir);
    913 		}
    914 	}
    915 
    916 	/* Set up the logging */
    917 	log_open(LOG_PID, FACILITY, nsd.log_filename);
    918 	if (!nsd.log_filename)
    919 		log_set_log_function(log_syslog);
    920 	else if (nsd.uid && nsd.gid) {
    921 		if(chown(nsd.log_filename, nsd.uid, nsd.gid) != 0)
    922 			VERBOSITY(2, (LOG_WARNING, "chown %s failed: %s",
    923 				nsd.log_filename, strerror(errno)));
    924 	}
    925 	log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING);
    926 
    927 	/* Do we have a running nsd? */
    928 	if ((oldpid = readpid(nsd.pidfile)) == -1) {
    929 		if (errno != ENOENT) {
    930 			log_msg(LOG_ERR, "can't read pidfile %s: %s",
    931 				nsd.pidfile, strerror(errno));
    932 		}
    933 	} else {
    934 		if (kill(oldpid, 0) == 0 || errno == EPERM) {
    935 			log_msg(LOG_WARNING,
    936 				"%s is already running as %u, continuing",
    937 				argv0, (unsigned) oldpid);
    938 		} else {
    939 			log_msg(LOG_ERR,
    940 				"...stale pid file from process %u",
    941 				(unsigned) oldpid);
    942 		}
    943 	}
    944 
    945 	/* Setup the signal handling... */
    946 	action.sa_handler = sig_handler;
    947 	sigfillset(&action.sa_mask);
    948 	action.sa_flags = 0;
    949 	sigaction(SIGTERM, &action, NULL);
    950 	sigaction(SIGHUP, &action, NULL);
    951 	sigaction(SIGINT, &action, NULL);
    952 	sigaction(SIGILL, &action, NULL);
    953 	sigaction(SIGUSR1, &action, NULL);
    954 	sigaction(SIGALRM, &action, NULL);
    955 	sigaction(SIGCHLD, &action, NULL);
    956 	action.sa_handler = SIG_IGN;
    957 	sigaction(SIGPIPE, &action, NULL);
    958 
    959 	/* Initialize... */
    960 	nsd.mode = NSD_RUN;
    961 	nsd.signal_hint_child = 0;
    962 	nsd.signal_hint_reload = 0;
    963 	nsd.signal_hint_reload_hup = 0;
    964 	nsd.signal_hint_quit = 0;
    965 	nsd.signal_hint_shutdown = 0;
    966 	nsd.signal_hint_stats = 0;
    967 	nsd.signal_hint_statsusr = 0;
    968 	nsd.quit_sync_done = 0;
    969 
    970 	/* Initialize the server... */
    971 	if (server_init(&nsd) != 0) {
    972 		error("server initialization failed, %s could "
    973 			"not be started", argv0);
    974 	}
    975 #if defined(HAVE_SSL)
    976 	if(nsd.options->control_enable) {
    977 		/* read ssl keys while superuser and outside chroot */
    978 		if(!(nsd.rc = daemon_remote_create(nsd.options)))
    979 			error("could not perform remote control setup");
    980 	}
    981 #endif /* HAVE_SSL */
    982 
    983 	/* Unless we're debugging, fork... */
    984 	if (!nsd.debug) {
    985 		int fd;
    986 
    987 		/* Take off... */
    988 		switch ((nsd.pid = fork())) {
    989 		case 0:
    990 			/* Child */
    991 			break;
    992 		case -1:
    993 			error("fork() failed: %s", strerror(errno));
    994 			break;
    995 		default:
    996 			/* Parent is done */
    997 			server_close_all_sockets(nsd.udp, nsd.ifs);
    998 			server_close_all_sockets(nsd.tcp, nsd.ifs);
    999 			exit(0);
   1000 		}
   1001 
   1002 		/* Detach ourselves... */
   1003 		if (setsid() == -1) {
   1004 			error("setsid() failed: %s", strerror(errno));
   1005 		}
   1006 
   1007 		if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
   1008 			(void)dup2(fd, STDIN_FILENO);
   1009 			(void)dup2(fd, STDOUT_FILENO);
   1010 			(void)dup2(fd, STDERR_FILENO);
   1011 			if (fd > 2)
   1012 				(void)close(fd);
   1013 		}
   1014 	}
   1015 
   1016 	/* Get our process id */
   1017 	nsd.pid = getpid();
   1018 
   1019 	/* Set user context */
   1020 #ifdef HAVE_GETPWNAM
   1021 	if (*nsd.username) {
   1022 #ifdef HAVE_SETUSERCONTEXT
   1023 		/* setusercontext does initgroups, setuid, setgid, and
   1024 		 * also resource limits from login config, but we
   1025 		 * still call setresuid, setresgid to be sure to set all uid */
   1026 		if (setusercontext(NULL, pwd, nsd.uid,
   1027 			LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
   1028 			log_msg(LOG_WARNING, "unable to setusercontext %s: %s",
   1029 				nsd.username, strerror(errno));
   1030 #endif /* HAVE_SETUSERCONTEXT */
   1031 	}
   1032 #endif /* HAVE_GETPWNAM */
   1033 
   1034 	/* Chroot */
   1035 #ifdef HAVE_CHROOT
   1036 	if (nsd.chrootdir && nsd.chrootdir[0]) {
   1037 		int l = strlen(nsd.chrootdir)-1; /* ends in trailing slash */
   1038 
   1039 		if (file_inside_chroot(nsd.log_filename, nsd.chrootdir))
   1040 			nsd.file_rotation_ok = 1;
   1041 
   1042 		/* strip chroot from pathnames if they're absolute */
   1043 		nsd.options->zonesdir += l;
   1044 		if (nsd.log_filename){
   1045 			if (nsd.log_filename[0] == '/')
   1046 				nsd.log_filename += l;
   1047 		}
   1048 		if (nsd.pidfile[0] == '/')
   1049 			nsd.pidfile += l;
   1050 		if (nsd.dbfile[0] == '/')
   1051 			nsd.dbfile += l;
   1052 		if (nsd.options->xfrdfile[0] == '/')
   1053 			nsd.options->xfrdfile += l;
   1054 		if (nsd.options->zonelistfile[0] == '/')
   1055 			nsd.options->zonelistfile += l;
   1056 		if (nsd.options->xfrdir[0] == '/')
   1057 			nsd.options->xfrdir += l;
   1058 
   1059 		/* strip chroot from pathnames of "include:" statements
   1060 		 * on subsequent repattern commands */
   1061 		cfg_parser->chroot = nsd.chrootdir;
   1062 
   1063 #ifdef HAVE_TZSET
   1064 		/* set timezone whilst not yet in chroot */
   1065 		tzset();
   1066 #endif
   1067 		if (chroot(nsd.chrootdir)) {
   1068 			error("unable to chroot: %s", strerror(errno));
   1069 		}
   1070 		if (chdir("/")) {
   1071 			error("unable to chdir to chroot: %s", strerror(errno));
   1072 		}
   1073 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed root directory to %s",
   1074 			nsd.chrootdir));
   1075 		/* chdir to zonesdir again after chroot */
   1076 		if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
   1077 			if(chdir(nsd.options->zonesdir)) {
   1078 				error("unable to chdir to '%s': %s",
   1079 					nsd.options->zonesdir, strerror(errno));
   1080 			}
   1081 			DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
   1082 				nsd.options->zonesdir));
   1083 		}
   1084 	}
   1085 	else
   1086 #endif /* HAVE_CHROOT */
   1087 		nsd.file_rotation_ok = 1;
   1088 
   1089 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "file rotation on %s %sabled",
   1090 		nsd.log_filename, nsd.file_rotation_ok?"en":"dis"));
   1091 
   1092 	/* Write pidfile */
   1093 	if (writepid(&nsd) == -1) {
   1094 		log_msg(LOG_ERR, "cannot overwrite the pidfile %s: %s",
   1095 			nsd.pidfile, strerror(errno));
   1096 	}
   1097 
   1098 	/* Drop the permissions */
   1099 #ifdef HAVE_GETPWNAM
   1100 	if (*nsd.username) {
   1101 #ifdef HAVE_INITGROUPS
   1102 		if(initgroups(nsd.username, nsd.gid) != 0)
   1103 			log_msg(LOG_WARNING, "unable to initgroups %s: %s",
   1104 				nsd.username, strerror(errno));
   1105 #endif /* HAVE_INITGROUPS */
   1106 		endpwent();
   1107 
   1108 #ifdef HAVE_SETRESGID
   1109 		if(setresgid(nsd.gid,nsd.gid,nsd.gid) != 0)
   1110 #elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
   1111 			if(setregid(nsd.gid,nsd.gid) != 0)
   1112 #else /* use setgid */
   1113 				if(setgid(nsd.gid) != 0)
   1114 #endif /* HAVE_SETRESGID */
   1115 					error("unable to set group id of %s: %s",
   1116 						nsd.username, strerror(errno));
   1117 
   1118 #ifdef HAVE_SETRESUID
   1119 		if(setresuid(nsd.uid,nsd.uid,nsd.uid) != 0)
   1120 #elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
   1121 			if(setreuid(nsd.uid,nsd.uid) != 0)
   1122 #else /* use setuid */
   1123 				if(setuid(nsd.uid) != 0)
   1124 #endif /* HAVE_SETRESUID */
   1125 					error("unable to set user id of %s: %s",
   1126 						nsd.username, strerror(errno));
   1127 
   1128 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "dropped user privileges, run as %s",
   1129 			nsd.username));
   1130 	}
   1131 #endif /* HAVE_GETPWNAM */
   1132 	xfrd_make_tempdir(&nsd);
   1133 #ifdef USE_ZONE_STATS
   1134 	options_zonestatnames_create(nsd.options);
   1135 	server_zonestat_alloc(&nsd);
   1136 #endif /* USE_ZONE_STATS */
   1137 
   1138 	if(nsd.server_kind == NSD_SERVER_MAIN) {
   1139 		server_prepare_xfrd(&nsd);
   1140 		/* xfrd forks this before reading database, so it does not get
   1141 		 * the memory size of the database */
   1142 		server_start_xfrd(&nsd, 0, 0);
   1143 		/* close zonelistfile in non-xfrd processes */
   1144 		zone_list_close(nsd.options);
   1145 	}
   1146 	if (server_prepare(&nsd) != 0) {
   1147 		unlinkpid(nsd.pidfile);
   1148 		error("server preparation failed, %s could "
   1149 			"not be started", argv0);
   1150 	}
   1151 	if(nsd.server_kind == NSD_SERVER_MAIN) {
   1152 		server_send_soa_xfrd(&nsd, 0);
   1153 	}
   1154 
   1155 	/* Really take off */
   1156 	log_msg(LOG_NOTICE, "%s started (%s), pid %d",
   1157 		argv0, PACKAGE_STRING, (int) nsd.pid);
   1158 
   1159 	if (nsd.server_kind == NSD_SERVER_MAIN) {
   1160 		server_main(&nsd);
   1161 	} else {
   1162 		server_child(&nsd);
   1163 	}
   1164 
   1165 	/* NOTREACH */
   1166 	exit(0);
   1167 }
   1168