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