1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /* $Id: dighost.c,v 1.25 2020/02/25 18:10:17 florian Exp $ */ 18 19 /*! \file 20 * \note 21 * Notice to programmers: Do not use this code as an example of how to 22 * use the ISC library to perform DNS lookups. Dig and Host both operate 23 * on the request level, since they allow fine-tuning of output and are 24 * intended as debugging tools. As a result, they perform many of the 25 * functions which could be better handled using the dns_resolver 26 * functions in most applications. 27 */ 28 29 #include <sys/socket.h> 30 #include <limits.h> 31 #include <locale.h> 32 #include <netdb.h> 33 #include <resolv.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <time.h> 37 #include <stdint.h> 38 39 #include <dns/byaddr.h> 40 #include <dns/fixedname.h> 41 #include <dns/log.h> 42 #include <dns/message.h> 43 #include <dns/name.h> 44 #include <dns/rdata.h> 45 #include <dns/rdataclass.h> 46 #include <dns/rdatalist.h> 47 #include <dns/rdataset.h> 48 #include <dns/rdatatype.h> 49 #include <dns/result.h> 50 #include <dns/tsig.h> 51 52 #include <dst/dst.h> 53 #include <dst/result.h> 54 55 #include <isc/base64.h> 56 #include <isc/hex.h> 57 #include <isc/log.h> 58 #include <isc/netaddr.h> 59 #include <isc/parseint.h> 60 #include <isc/result.h> 61 #include <isc/serial.h> 62 #include <isc/sockaddr.h> 63 #include <isc/task.h> 64 #include <isc/timer.h> 65 #include <isc/types.h> 66 #include <isc/util.h> 67 68 #include <isccfg/namedconf.h> 69 #include <lwres/lwres.h> 70 71 #include "dig.h" 72 73 static lwres_conf_t lwconfdata; 74 static lwres_conf_t *lwconf = &lwconfdata; 75 76 dig_lookuplist_t lookup_list; 77 dig_serverlist_t server_list; 78 dig_serverlist_t root_hints_server_list; 79 dig_searchlistlist_t search_list; 80 81 isc_boolean_t 82 check_ra = ISC_FALSE, 83 have_ipv4 = ISC_TRUE, 84 have_ipv6 = ISC_TRUE, 85 specified_source = ISC_FALSE, 86 free_now = ISC_FALSE, 87 cancel_now = ISC_FALSE, 88 usesearch = ISC_FALSE, 89 showsearch = ISC_FALSE, 90 qr = ISC_FALSE, 91 is_dst_up = ISC_FALSE, 92 keep_open = ISC_FALSE; 93 in_port_t port = 53; 94 unsigned int timeout = 0; 95 unsigned int extrabytes; 96 isc_log_t *lctx = NULL; 97 isc_taskmgr_t *taskmgr = NULL; 98 isc_task_t *global_task = NULL; 99 isc_timermgr_t *timermgr = NULL; 100 isc_socketmgr_t *socketmgr = NULL; 101 isc_sockaddr_t bind_address; 102 isc_sockaddr_t bind_any; 103 int sendcount = 0; 104 int recvcount = 0; 105 int sockcount = 0; 106 int ndots = -1; 107 int tries = 3; 108 int lookup_counter = 0; 109 110 static char sitvalue[256]; 111 112 isc_socket_t *keep = NULL; 113 isc_sockaddr_t keepaddr; 114 115 static const struct { 116 const char *ns; 117 const int af; 118 } root_hints[] = { 119 { "198.41.0.4", AF_INET }, /* a.root-servers.net */ 120 { "2001:503:ba3e::2:30", AF_INET6 }, /* a.root-servers.net */ 121 { "199.9.14.201", AF_INET }, /* b.root-servers.net */ 122 { "2001:500:200::b", AF_INET6 }, /* b.root-servers.net */ 123 { "192.33.4.12", AF_INET }, /* c.root-servers.net */ 124 { "2001:500:2::c", AF_INET6 }, /* c.root-servers.net */ 125 { "199.7.91.13", AF_INET }, /* d.root-servers.net */ 126 { "2001:500:2d::d", AF_INET6 }, /* d.root-servers.net */ 127 { "192.203.230.10", AF_INET }, /* e.root-servers.net */ 128 { "2001:500:a8::e", AF_INET6 }, /* e.root-servers.net */ 129 { "192.5.5.241", AF_INET }, /* f.root-servers.net */ 130 { "2001:500:2f::f", AF_INET6 }, /* f.root-servers.net */ 131 { "192.112.36.4", AF_INET }, /* g.root-servers.net */ 132 { "2001:500:12::d0d", AF_INET6 }, /* g.root-servers.net */ 133 { "198.97.190.53", AF_INET }, /* h.root-servers.net */ 134 { "2001:500:1::53", AF_INET6 }, /* h.root-servers.net */ 135 { "192.36.148.17", AF_INET }, /* i.root-servers.net */ 136 { "2001:7fe::53", AF_INET6 }, /* i.root-servers.net */ 137 { "192.58.128.30", AF_INET }, /* j.root-servers.net */ 138 { "2001:503:c27::2:30", AF_INET6 }, /* j.root-servers.net */ 139 { "193.0.14.129", AF_INET }, /* k.root-servers.net */ 140 { "2001:7fd::1", AF_INET6 }, /* k.root-servers.net */ 141 { "199.7.83.42", AF_INET }, /* l.root-servers.net */ 142 { "2001:500:9f::42", AF_INET6 }, /* l.root-servers.net */ 143 { "202.12.27.33", AF_INET }, /* m.root-servers.net */ 144 { "2001:dc3::35", AF_INET6 } /* m.root-servers.net */ 145 }; 146 147 /*% 148 * Exit Codes: 149 * 150 *\li 0 Everything went well, including things like NXDOMAIN 151 *\li 1 Usage error 152 *\li 7 Got too many RR's or Names 153 *\li 8 Couldn't open batch file 154 *\li 9 No reply from server 155 *\li 10 Internal error 156 */ 157 int exitcode = 0; 158 int fatalexit = 0; 159 char keynametext[MXNAME]; 160 char keyfile[MXNAME] = ""; 161 char keysecret[MXNAME] = ""; 162 unsigned char cookie_secret[33]; 163 unsigned char cookie[8]; 164 dns_name_t *hmacname = NULL; 165 unsigned int digestbits = 0; 166 isc_buffer_t *namebuf = NULL; 167 dns_tsigkey_t *tsigkey = NULL; 168 isc_boolean_t validated = ISC_TRUE; 169 isc_boolean_t debugging = ISC_FALSE; 170 isc_boolean_t debugtiming = ISC_FALSE; 171 char *progname = NULL; 172 dig_lookup_t *current_lookup = NULL; 173 174 #define DIG_MAX_ADDRESSES 20 175 176 /* dynamic callbacks */ 177 178 isc_result_t 179 (*dighost_printmessage)(dig_query_t *query, dns_message_t *msg, 180 isc_boolean_t headers); 181 182 void 183 (*dighost_received)(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query); 184 185 void 186 (*dighost_trying)(char *frm, dig_lookup_t *lookup); 187 188 void 189 (*dighost_shutdown)(void); 190 191 /* forward declarations */ 192 193 static void 194 cancel_lookup(dig_lookup_t *lookup); 195 196 static void 197 recv_done(isc_task_t *task, isc_event_t *event); 198 199 static void 200 send_udp(dig_query_t *query); 201 202 static void 203 connect_timeout(isc_task_t *task, isc_event_t *event); 204 205 static void 206 launch_next_query(dig_query_t *query, isc_boolean_t include_question); 207 208 static void 209 check_next_lookup(dig_lookup_t *lookup); 210 211 static isc_boolean_t 212 next_origin(dig_lookup_t *oldlookup); 213 214 char * 215 next_token(char **stringp, const char *delim) { 216 char *res; 217 218 do { 219 res = strsep(stringp, delim); 220 if (res == NULL) 221 break; 222 } while (*res == '\0'); 223 return (res); 224 } 225 226 static int 227 count_dots(char *string) { 228 char *s; 229 int i = 0; 230 231 s = string; 232 while (*s != '\0') { 233 if (*s == '.') 234 i++; 235 s++; 236 } 237 return (i); 238 } 239 240 static void 241 hex_dump(isc_buffer_t *b) { 242 unsigned int len, i; 243 isc_region_t r; 244 245 isc_buffer_usedregion(b, &r); 246 247 printf("%u bytes\n", r.length); 248 for (len = 0; len < r.length; len++) { 249 printf("%02x ", r.base[len]); 250 if (len % 16 == 15) { 251 fputs(" ", stdout); 252 for (i = len - 15; i <= len; i++) { 253 if (r.base[i] >= '!' && r.base[i] <= '}') 254 putchar(r.base[i]); 255 else 256 putchar('.'); 257 } 258 printf("\n"); 259 } 260 } 261 if (len % 16 != 0) { 262 for (i = len; (i % 16) != 0; i++) 263 fputs(" ", stdout); 264 fputs(" ", stdout); 265 for (i = ((len>>4)<<4); i < len; i++) { 266 if (r.base[i] >= '!' && r.base[i] <= '}') 267 putchar(r.base[i]); 268 else 269 putchar('.'); 270 } 271 printf("\n"); 272 } 273 } 274 275 /*% 276 * Append 'len' bytes of 'text' at '*p', failing with 277 * ISC_R_NOSPACE if that would advance p past 'end'. 278 */ 279 static isc_result_t 280 append(const char *text, size_t len, char **p, char *end) { 281 if (*p + len > end) 282 return (ISC_R_NOSPACE); 283 memmove(*p, text, len); 284 *p += len; 285 return (ISC_R_SUCCESS); 286 } 287 288 static isc_result_t 289 reverse_octets(const char *in, char **p, char *end) { 290 const char *dot = strchr(in, '.'); 291 size_t len; 292 if (dot != NULL) { 293 isc_result_t result; 294 result = reverse_octets(dot + 1, p, end); 295 if (result != ISC_R_SUCCESS) 296 return (result); 297 result = append(".", 1, p, end); 298 if (result != ISC_R_SUCCESS) 299 return (result); 300 len = (int) (dot - in); 301 } else { 302 len = (int) strlen(in); 303 } 304 return (append(in, len, p, end)); 305 } 306 307 isc_result_t 308 get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int, 309 isc_boolean_t strict) 310 { 311 int r; 312 isc_result_t result; 313 isc_netaddr_t addr; 314 315 addr.family = AF_INET6; 316 r = inet_pton(AF_INET6, value, &addr.type.in6); 317 if (r > 0) { 318 /* This is a valid IPv6 address. */ 319 dns_fixedname_t fname; 320 dns_name_t *name; 321 unsigned int options = 0; 322 323 if (ip6_int) 324 options |= DNS_BYADDROPT_IPV6INT; 325 dns_fixedname_init(&fname); 326 name = dns_fixedname_name(&fname); 327 result = dns_byaddr_createptrname2(&addr, options, name); 328 if (result != ISC_R_SUCCESS) 329 return (result); 330 dns_name_format(name, reverse, (unsigned int)len); 331 return (ISC_R_SUCCESS); 332 } else { 333 /* 334 * Not a valid IPv6 address. Assume IPv4. 335 * If 'strict' is not set, construct the 336 * in-addr.arpa name by blindly reversing 337 * octets whether or not they look like integers, 338 * so that this can be used for RFC2317 names 339 * and such. 340 */ 341 char *p = reverse; 342 char *end = reverse + len; 343 if (strict && inet_pton(AF_INET, value, &addr.type.in) != 1) 344 return (DNS_R_BADDOTTEDQUAD); 345 result = reverse_octets(value, &p, end); 346 if (result != ISC_R_SUCCESS) 347 return (result); 348 /* Append .in-addr.arpa. and a terminating NUL. */ 349 result = append(".in-addr.arpa.", 15, &p, end); 350 if (result != ISC_R_SUCCESS) 351 return (result); 352 return (ISC_R_SUCCESS); 353 } 354 } 355 356 void 357 fatal(const char *format, ...) { 358 va_list args; 359 360 fflush(stdout); 361 fprintf(stderr, "%s: ", progname); 362 va_start(args, format); 363 vfprintf(stderr, format, args); 364 va_end(args); 365 fprintf(stderr, "\n"); 366 if (exitcode < 10) 367 exitcode = 10; 368 if (fatalexit != 0) 369 exitcode = fatalexit; 370 exit(exitcode); 371 } 372 373 void 374 debug(const char *format, ...) { 375 va_list args; 376 struct timespec t; 377 378 if (debugging) { 379 fflush(stdout); 380 if (debugtiming) { 381 clock_gettime(CLOCK_MONOTONIC, &t); 382 fprintf(stderr, "%lld.%06ld: ", t.tv_sec, t.tv_nsec / 383 1000); 384 } 385 va_start(args, format); 386 vfprintf(stderr, format, args); 387 va_end(args); 388 fprintf(stderr, "\n"); 389 } 390 } 391 392 void 393 check_result(isc_result_t result, const char *msg) { 394 if (result != ISC_R_SUCCESS) { 395 fatal("%s: %s", msg, isc_result_totext(result)); 396 } 397 } 398 399 /*% 400 * Create a server structure, which is part of the lookup structure. 401 * This is little more than a linked list of servers to query in hopes 402 * of finding the answer the user is looking for 403 */ 404 dig_server_t * 405 make_server(const char *servname, const char *userarg) { 406 dig_server_t *srv; 407 408 REQUIRE(servname != NULL); 409 410 debug("make_server(%s)", servname); 411 srv = malloc(sizeof(struct dig_server)); 412 if (srv == NULL) 413 fatal("memory allocation failure in %s:%d", 414 __FILE__, __LINE__); 415 strlcpy(srv->servername, servname, MXNAME); 416 strlcpy(srv->userarg, userarg, MXNAME); 417 ISC_LINK_INIT(srv, link); 418 return (srv); 419 } 420 421 static int 422 addr2af(int lwresaddrtype) 423 { 424 int af = 0; 425 426 switch (lwresaddrtype) { 427 case LWRES_ADDRTYPE_V4: 428 af = AF_INET; 429 break; 430 431 case LWRES_ADDRTYPE_V6: 432 af = AF_INET6; 433 break; 434 } 435 436 return (af); 437 } 438 439 /*% 440 * Create a copy of the server list from the lwres configuration structure. 441 * The dest list must have already had ISC_LIST_INIT applied. 442 */ 443 static void 444 copy_server_list(lwres_conf_t *confdata, dig_serverlist_t *dest) { 445 dig_server_t *newsrv; 446 char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") + 447 sizeof("%4000000000")]; 448 int af; 449 int i; 450 451 debug("copy_server_list()"); 452 for (i = 0; i < confdata->nsnext; i++) { 453 af = addr2af(confdata->nameservers[i].family); 454 455 if (af == AF_INET && !have_ipv4) 456 continue; 457 if (af == AF_INET6 && !have_ipv6) 458 continue; 459 460 inet_ntop(af, confdata->nameservers[i].address, 461 tmp, sizeof(tmp)); 462 if (af == AF_INET6 && confdata->nameservers[i].zone != 0) { 463 char buf[sizeof("%4000000000")]; 464 snprintf(buf, sizeof(buf), "%%%u", 465 confdata->nameservers[i].zone); 466 strlcat(tmp, buf, sizeof(tmp)); 467 } 468 newsrv = make_server(tmp, tmp); 469 ISC_LINK_INIT(newsrv, link); 470 ISC_LIST_ENQUEUE(*dest, newsrv, link); 471 } 472 } 473 474 void 475 flush_server_list(void) { 476 dig_server_t *s, *ps; 477 478 debug("flush_server_list()"); 479 s = ISC_LIST_HEAD(server_list); 480 while (s != NULL) { 481 ps = s; 482 s = ISC_LIST_NEXT(s, link); 483 ISC_LIST_DEQUEUE(server_list, ps, link); 484 free(ps); 485 } 486 } 487 488 /* this used to be bind9_getaddresses from lib/bind9 */ 489 static isc_result_t 490 get_addresses(const char *hostname, in_port_t dstport, 491 isc_sockaddr_t *addrs, int addrsize, int *addrcount) 492 { 493 struct addrinfo *ai = NULL, *tmpai, hints; 494 int result, i; 495 496 REQUIRE(hostname != NULL); 497 REQUIRE(addrs != NULL); 498 REQUIRE(addrcount != NULL); 499 REQUIRE(addrsize > 0); 500 501 memset(&hints, 0, sizeof(hints)); 502 if (!have_ipv6) 503 hints.ai_family = PF_INET; 504 else if (!have_ipv4) 505 hints.ai_family = PF_INET6; 506 else { 507 hints.ai_family = PF_UNSPEC; 508 hints.ai_flags = AI_ADDRCONFIG; 509 } 510 hints.ai_socktype = SOCK_STREAM; 511 512 result = getaddrinfo(hostname, NULL, &hints, &ai); 513 switch (result) { 514 case 0: 515 break; 516 case EAI_NONAME: 517 case EAI_NODATA: 518 return (ISC_R_NOTFOUND); 519 default: 520 return (ISC_R_FAILURE); 521 } 522 for (tmpai = ai, i = 0; 523 tmpai != NULL && i < addrsize; 524 tmpai = tmpai->ai_next) 525 { 526 if (tmpai->ai_family != AF_INET && 527 tmpai->ai_family != AF_INET6) 528 continue; 529 if (tmpai->ai_family == AF_INET) { 530 struct sockaddr_in *sin; 531 sin = (struct sockaddr_in *)tmpai->ai_addr; 532 isc_sockaddr_fromin(&addrs[i], &sin->sin_addr, dstport); 533 } else { 534 struct sockaddr_in6 *sin6; 535 sin6 = (struct sockaddr_in6 *)tmpai->ai_addr; 536 isc_sockaddr_fromin6(&addrs[i], &sin6->sin6_addr, 537 dstport); 538 } 539 i++; 540 541 } 542 freeaddrinfo(ai); 543 *addrcount = i; 544 if (*addrcount == 0) 545 return (ISC_R_NOTFOUND); 546 else 547 return (ISC_R_SUCCESS); 548 } 549 550 isc_result_t 551 set_nameserver(char *opt) { 552 isc_result_t result; 553 isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES]; 554 isc_netaddr_t netaddr; 555 int count, i; 556 dig_server_t *srv; 557 char tmp[ISC_NETADDR_FORMATSIZE]; 558 559 if (opt == NULL) 560 return ISC_R_NOTFOUND; 561 562 result = get_addresses(opt, 0, sockaddrs, 563 DIG_MAX_ADDRESSES, &count); 564 if (result != ISC_R_SUCCESS) 565 return (result); 566 567 flush_server_list(); 568 569 for (i = 0; i < count; i++) { 570 isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]); 571 isc_netaddr_format(&netaddr, tmp, sizeof(tmp)); 572 srv = make_server(tmp, opt); 573 if (srv == NULL) 574 fatal("memory allocation failure"); 575 ISC_LIST_APPEND(server_list, srv, link); 576 } 577 return (ISC_R_SUCCESS); 578 } 579 580 static isc_result_t 581 add_nameserver(lwres_conf_t *confdata, const char *addr, int af) { 582 583 int i = confdata->nsnext; 584 585 if (confdata->nsnext >= LWRES_CONFMAXNAMESERVERS) 586 return (ISC_R_FAILURE); 587 588 switch (af) { 589 case AF_INET: 590 confdata->nameservers[i].family = LWRES_ADDRTYPE_V4; 591 confdata->nameservers[i].length = sizeof(struct in_addr); 592 break; 593 case AF_INET6: 594 confdata->nameservers[i].family = LWRES_ADDRTYPE_V6; 595 confdata->nameservers[i].length = sizeof(struct in6_addr); 596 break; 597 default: 598 return (ISC_R_FAILURE); 599 } 600 601 if (inet_pton(af, addr, &confdata->nameservers[i].address) == 1) { 602 confdata->nsnext++; 603 return (ISC_R_SUCCESS); 604 } 605 return (ISC_R_FAILURE); 606 } 607 608 /*% 609 * Produce a cloned server list. The dest list must have already had 610 * ISC_LIST_INIT applied. 611 */ 612 void 613 clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) { 614 dig_server_t *srv, *newsrv; 615 616 debug("clone_server_list()"); 617 srv = ISC_LIST_HEAD(src); 618 while (srv != NULL) { 619 newsrv = make_server(srv->servername, srv->userarg); 620 ISC_LINK_INIT(newsrv, link); 621 ISC_LIST_ENQUEUE(*dest, newsrv, link); 622 srv = ISC_LIST_NEXT(srv, link); 623 } 624 } 625 626 /*% 627 * Create an empty lookup structure, which holds all the information needed 628 * to get an answer to a user's question. This structure contains two 629 * linked lists: the server list (servers to query) and the query list 630 * (outstanding queries which have been made to the listed servers). 631 */ 632 dig_lookup_t * 633 make_empty_lookup(void) { 634 dig_lookup_t *looknew; 635 636 debug("make_empty_lookup()"); 637 638 INSIST(!free_now); 639 640 looknew = malloc(sizeof(struct dig_lookup)); 641 if (looknew == NULL) 642 fatal("memory allocation failure in %s:%d", 643 __FILE__, __LINE__); 644 looknew->pending = ISC_TRUE; 645 looknew->textname[0] = 0; 646 looknew->cmdline[0] = 0; 647 looknew->rdtype = dns_rdatatype_a; 648 looknew->qrdtype = dns_rdatatype_a; 649 looknew->rdclass = dns_rdataclass_in; 650 looknew->rdtypeset = ISC_FALSE; 651 looknew->rdclassset = ISC_FALSE; 652 looknew->sendspace = NULL; 653 looknew->sendmsg = NULL; 654 looknew->name = NULL; 655 looknew->oname = NULL; 656 looknew->xfr_q = NULL; 657 looknew->current_query = NULL; 658 looknew->doing_xfr = ISC_FALSE; 659 looknew->ixfr_serial = 0; 660 looknew->trace = ISC_FALSE; 661 looknew->trace_root = ISC_FALSE; 662 looknew->identify = ISC_FALSE; 663 looknew->identify_previous_line = ISC_FALSE; 664 looknew->ignore = ISC_FALSE; 665 looknew->servfail_stops = ISC_TRUE; 666 looknew->besteffort = ISC_TRUE; 667 looknew->dnssec = ISC_FALSE; 668 looknew->ednsflags = 0; 669 looknew->opcode = dns_opcode_query; 670 looknew->expire = ISC_FALSE; 671 looknew->nsid = ISC_FALSE; 672 looknew->idnout = ISC_FALSE; 673 looknew->sit = ISC_FALSE; 674 looknew->udpsize = 0; 675 looknew->edns = -1; 676 looknew->recurse = ISC_TRUE; 677 looknew->aaonly = ISC_FALSE; 678 looknew->adflag = ISC_FALSE; 679 looknew->cdflag = ISC_FALSE; 680 looknew->ns_search_only = ISC_FALSE; 681 looknew->origin = NULL; 682 looknew->tsigctx = NULL; 683 looknew->querysig = NULL; 684 looknew->retries = tries; 685 looknew->nsfound = 0; 686 looknew->tcp_mode = ISC_FALSE; 687 looknew->tcp_mode_set = ISC_FALSE; 688 looknew->ip6_int = ISC_FALSE; 689 looknew->comments = ISC_TRUE; 690 looknew->stats = ISC_TRUE; 691 looknew->section_question = ISC_TRUE; 692 looknew->section_answer = ISC_TRUE; 693 looknew->section_authority = ISC_TRUE; 694 looknew->section_additional = ISC_TRUE; 695 looknew->new_search = ISC_FALSE; 696 looknew->done_as_is = ISC_FALSE; 697 looknew->need_search = ISC_FALSE; 698 looknew->ecs_addr = NULL; 699 looknew->sitvalue = NULL; 700 looknew->ednsopts = NULL; 701 looknew->ednsoptscnt = 0; 702 looknew->ednsneg = ISC_FALSE; 703 looknew->eoferr = 0; 704 dns_fixedname_init(&looknew->fdomain); 705 ISC_LINK_INIT(looknew, link); 706 ISC_LIST_INIT(looknew->q); 707 ISC_LIST_INIT(looknew->connecting); 708 ISC_LIST_INIT(looknew->my_server_list); 709 return (looknew); 710 } 711 712 #define EDNSOPT_OPTIONS 100U 713 714 static void 715 cloneopts(dig_lookup_t *looknew, dig_lookup_t *lookold) { 716 size_t len = sizeof(looknew->ednsopts[0]) * EDNSOPT_OPTIONS; 717 size_t i; 718 looknew->ednsopts = malloc(len); 719 if (looknew->ednsopts == NULL) 720 fatal("out of memory"); 721 for (i = 0; i < EDNSOPT_OPTIONS; i++) { 722 looknew->ednsopts[i].code = 0; 723 looknew->ednsopts[i].length = 0; 724 looknew->ednsopts[i].value = NULL; 725 } 726 looknew->ednsoptscnt = 0; 727 if (lookold == NULL || lookold->ednsopts == NULL) 728 return; 729 730 for (i = 0; i < lookold->ednsoptscnt; i++) { 731 len = lookold->ednsopts[i].length; 732 if (len != 0) { 733 INSIST(lookold->ednsopts[i].value != NULL); 734 looknew->ednsopts[i].value = 735 malloc(len); 736 if (looknew->ednsopts[i].value == NULL) 737 fatal("out of memory"); 738 memmove(looknew->ednsopts[i].value, 739 lookold->ednsopts[i].value, len); 740 } 741 looknew->ednsopts[i].code = lookold->ednsopts[i].code; 742 looknew->ednsopts[i].length = len; 743 } 744 looknew->ednsoptscnt = lookold->ednsoptscnt; 745 } 746 747 /*% 748 * Clone a lookup, perhaps copying the server list. This does not clone 749 * the query list, since it will be regenerated by the setup_lookup() 750 * function, nor does it queue up the new lookup for processing. 751 * Caution: If you don't clone the servers, you MUST clone the server 752 * list separately from somewhere else, or construct it by hand. 753 */ 754 dig_lookup_t * 755 clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { 756 dig_lookup_t *looknew; 757 758 debug("clone_lookup()"); 759 760 INSIST(!free_now); 761 762 looknew = make_empty_lookup(); 763 INSIST(looknew != NULL); 764 strlcpy(looknew->textname, lookold->textname, MXNAME); 765 strlcpy(looknew->cmdline, lookold->cmdline, MXNAME); 766 looknew->textname[MXNAME-1] = 0; 767 looknew->rdtype = lookold->rdtype; 768 looknew->qrdtype = lookold->qrdtype; 769 looknew->rdclass = lookold->rdclass; 770 looknew->rdtypeset = lookold->rdtypeset; 771 looknew->rdclassset = lookold->rdclassset; 772 looknew->doing_xfr = lookold->doing_xfr; 773 looknew->ixfr_serial = lookold->ixfr_serial; 774 looknew->trace = lookold->trace; 775 looknew->trace_root = lookold->trace_root; 776 looknew->identify = lookold->identify; 777 looknew->identify_previous_line = lookold->identify_previous_line; 778 looknew->ignore = lookold->ignore; 779 looknew->servfail_stops = lookold->servfail_stops; 780 looknew->besteffort = lookold->besteffort; 781 looknew->dnssec = lookold->dnssec; 782 looknew->ednsflags = lookold->ednsflags; 783 looknew->opcode = lookold->opcode; 784 looknew->expire = lookold->expire; 785 looknew->nsid = lookold->nsid; 786 looknew->sit = lookold->sit; 787 looknew->sitvalue = lookold->sitvalue; 788 if (lookold->ednsopts != NULL) { 789 cloneopts(looknew, lookold); 790 } else { 791 looknew->ednsopts = NULL; 792 looknew->ednsoptscnt = 0; 793 } 794 looknew->ednsneg = lookold->ednsneg; 795 looknew->idnout = lookold->idnout; 796 looknew->udpsize = lookold->udpsize; 797 looknew->edns = lookold->edns; 798 looknew->recurse = lookold->recurse; 799 looknew->aaonly = lookold->aaonly; 800 looknew->adflag = lookold->adflag; 801 looknew->cdflag = lookold->cdflag; 802 looknew->ns_search_only = lookold->ns_search_only; 803 looknew->tcp_mode = lookold->tcp_mode; 804 looknew->tcp_mode_set = lookold->tcp_mode_set; 805 looknew->comments = lookold->comments; 806 looknew->stats = lookold->stats; 807 looknew->section_question = lookold->section_question; 808 looknew->section_answer = lookold->section_answer; 809 looknew->section_authority = lookold->section_authority; 810 looknew->section_additional = lookold->section_additional; 811 looknew->origin = lookold->origin; 812 looknew->retries = lookold->retries; 813 looknew->tsigctx = NULL; 814 looknew->need_search = lookold->need_search; 815 looknew->done_as_is = lookold->done_as_is; 816 looknew->eoferr = lookold->eoferr; 817 818 if (lookold->ecs_addr != NULL) { 819 size_t len = sizeof(isc_sockaddr_t); 820 looknew->ecs_addr = malloc(len); 821 if (looknew->ecs_addr == NULL) 822 fatal("out of memory"); 823 memmove(looknew->ecs_addr, lookold->ecs_addr, len); 824 } 825 826 dns_name_copy(dns_fixedname_name(&lookold->fdomain), 827 dns_fixedname_name(&looknew->fdomain), NULL); 828 829 if (servers) 830 clone_server_list(lookold->my_server_list, 831 &looknew->my_server_list); 832 return (looknew); 833 } 834 835 /*% 836 * Requeue a lookup for further processing, perhaps copying the server 837 * list. The new lookup structure is returned to the caller, and is 838 * queued for processing. If servers are not cloned in the requeue, they 839 * must be added before allowing the current event to complete, since the 840 * completion of the event may result in the next entry on the lookup 841 * queue getting run. 842 */ 843 dig_lookup_t * 844 requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { 845 dig_lookup_t *looknew; 846 847 debug("requeue_lookup()"); 848 849 lookup_counter++; 850 if (lookup_counter > LOOKUP_LIMIT) 851 fatal("too many lookups"); 852 853 looknew = clone_lookup(lookold, servers); 854 INSIST(looknew != NULL); 855 856 debug("before insertion, init@%p -> %p, new@%p -> %p", 857 lookold, lookold->link.next, looknew, looknew->link.next); 858 ISC_LIST_PREPEND(lookup_list, looknew, link); 859 debug("after insertion, init -> %p, new = %p, new -> %p", 860 lookold, looknew, looknew->link.next); 861 return (looknew); 862 } 863 864 void 865 setup_text_key(void) { 866 isc_result_t result; 867 dns_name_t keyname; 868 isc_buffer_t secretbuf; 869 unsigned int secretsize; 870 unsigned char *secretstore; 871 872 debug("setup_text_key()"); 873 result = isc_buffer_allocate(&namebuf, MXNAME); 874 check_result(result, "isc_buffer_allocate"); 875 dns_name_init(&keyname, NULL); 876 check_result(result, "dns_name_init"); 877 isc_buffer_putstr(namebuf, keynametext); 878 secretsize = (unsigned int) strlen(keysecret) * 3 / 4; 879 secretstore = malloc(secretsize); 880 if (secretstore == NULL) 881 fatal("memory allocation failure in %s:%d", 882 __FILE__, __LINE__); 883 isc_buffer_init(&secretbuf, secretstore, secretsize); 884 result = isc_base64_decodestring(keysecret, &secretbuf); 885 if (result != ISC_R_SUCCESS) 886 goto failure; 887 888 secretsize = isc_buffer_usedlength(&secretbuf); 889 890 if (hmacname == NULL) { 891 result = DST_R_UNSUPPORTEDALG; 892 goto failure; 893 } 894 895 result = dns_name_fromtext(&keyname, namebuf, dns_rootname, 0, namebuf); 896 if (result != ISC_R_SUCCESS) 897 goto failure; 898 899 result = dns_tsigkey_create(&keyname, hmacname, secretstore, 900 (int)secretsize, ISC_FALSE, NULL, 0, 0, 901 &tsigkey); 902 failure: 903 if (result != ISC_R_SUCCESS) 904 printf(";; Couldn't create key %s: %s\n", 905 keynametext, isc_result_totext(result)); 906 else 907 dst_key_setbits(tsigkey->key, digestbits); 908 909 free(secretstore); 910 dns_name_invalidate(&keyname); 911 isc_buffer_free(&namebuf); 912 } 913 914 static isc_result_t 915 parse_uint_helper(uint32_t *uip, const char *value, uint32_t max, 916 const char *desc, int base) { 917 uint32_t n; 918 isc_result_t result = isc_parse_uint32(&n, value, base); 919 if (result == ISC_R_SUCCESS && n > max) 920 result = ISC_R_RANGE; 921 if (result != ISC_R_SUCCESS) { 922 printf("invalid %s '%s': %s\n", desc, 923 value, isc_result_totext(result)); 924 return (result); 925 } 926 *uip = n; 927 return (ISC_R_SUCCESS); 928 } 929 930 isc_result_t 931 parse_uint(uint32_t *uip, const char *value, uint32_t max, 932 const char *desc) { 933 return (parse_uint_helper(uip, value, max, desc, 10)); 934 } 935 936 isc_result_t 937 parse_xint(uint32_t *uip, const char *value, uint32_t max, 938 const char *desc) { 939 return (parse_uint_helper(uip, value, max, desc, 0)); 940 } 941 942 static uint32_t 943 parse_bits(char *arg, const char *desc, uint32_t max) { 944 isc_result_t result; 945 uint32_t tmp; 946 947 result = parse_uint(&tmp, arg, max, desc); 948 if (result != ISC_R_SUCCESS) 949 fatal("couldn't parse digest bits"); 950 tmp = (tmp + 7) & ~0x7U; 951 return (tmp); 952 } 953 954 isc_result_t 955 parse_netprefix(isc_sockaddr_t **sap, const char *value) { 956 isc_result_t result = ISC_R_SUCCESS; 957 isc_sockaddr_t *sa = NULL; 958 struct in_addr in4; 959 struct in6_addr in6; 960 uint32_t prefix_length = 0xffffffff; 961 char *slash = NULL; 962 isc_boolean_t parsed = ISC_FALSE; 963 isc_boolean_t prefix_parsed = ISC_FALSE; 964 char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX/128")]; 965 966 REQUIRE(sap != NULL && *sap == NULL); 967 968 if (strlcpy(buf, value, sizeof(buf)) >= sizeof(buf)) 969 fatal("invalid prefix '%s'\n", value); 970 971 sa = malloc(sizeof(*sa)); 972 if (sa == NULL) 973 fatal("out of memory"); 974 memset(sa, 0, sizeof(*sa)); 975 976 if (strcmp(buf, "0") == 0) { 977 sa->type.sa.sa_family = AF_UNSPEC; 978 prefix_length = 0; 979 goto done; 980 } 981 982 slash = strchr(buf, '/'); 983 if (slash != NULL) { 984 *slash = '\0'; 985 result = isc_parse_uint32(&prefix_length, slash + 1, 10); 986 if (result != ISC_R_SUCCESS) { 987 fatal("invalid prefix length in '%s': %s\n", 988 value, isc_result_totext(result)); 989 } 990 prefix_parsed = ISC_TRUE; 991 } 992 993 if (inet_pton(AF_INET6, buf, &in6) == 1) { 994 parsed = ISC_TRUE; 995 isc_sockaddr_fromin6(sa, &in6, 0); 996 if (prefix_length > 128) 997 prefix_length = 128; 998 } else if (inet_pton(AF_INET, buf, &in4) == 1) { 999 parsed = ISC_TRUE; 1000 isc_sockaddr_fromin(sa, &in4, 0); 1001 if (prefix_length > 32) 1002 prefix_length = 32; 1003 } else if (prefix_parsed) { 1004 int i; 1005 1006 for (i = 0; i < 3 && strlen(buf) < sizeof(buf) - 2; i++) { 1007 strlcat(buf, ".0", sizeof(buf)); 1008 if (inet_pton(AF_INET, buf, &in4) == 1) { 1009 parsed = ISC_TRUE; 1010 isc_sockaddr_fromin(sa, &in4, 0); 1011 break; 1012 } 1013 } 1014 1015 if (prefix_length > 32) 1016 prefix_length = 32; 1017 } 1018 1019 if (!parsed) 1020 fatal("invalid address '%s'", value); 1021 1022 done: 1023 sa->length = prefix_length; 1024 *sap = sa; 1025 1026 return (ISC_R_SUCCESS); 1027 } 1028 1029 /* 1030 * Parse HMAC algorithm specification 1031 */ 1032 void 1033 parse_hmac(const char *hmac) { 1034 char buf[20]; 1035 size_t len; 1036 1037 REQUIRE(hmac != NULL); 1038 1039 len = strlen(hmac); 1040 if (len >= sizeof(buf)) 1041 fatal("unknown key type '%.*s'", (int)len, hmac); 1042 strlcpy(buf, hmac, sizeof(buf)); 1043 1044 digestbits = 0; 1045 1046 if (strcasecmp(buf, "hmac-sha1") == 0) { 1047 hmacname = DNS_TSIG_HMACSHA1_NAME; 1048 digestbits = 0; 1049 } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) { 1050 hmacname = DNS_TSIG_HMACSHA1_NAME; 1051 digestbits = parse_bits(&buf[10], "digest-bits [0..160]", 160); 1052 } else if (strcasecmp(buf, "hmac-sha224") == 0) { 1053 hmacname = DNS_TSIG_HMACSHA224_NAME; 1054 } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) { 1055 hmacname = DNS_TSIG_HMACSHA224_NAME; 1056 digestbits = parse_bits(&buf[12], "digest-bits [0..224]", 224); 1057 } else if (strcasecmp(buf, "hmac-sha256") == 0) { 1058 hmacname = DNS_TSIG_HMACSHA256_NAME; 1059 } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) { 1060 hmacname = DNS_TSIG_HMACSHA256_NAME; 1061 digestbits = parse_bits(&buf[12], "digest-bits [0..256]", 256); 1062 } else if (strcasecmp(buf, "hmac-sha384") == 0) { 1063 hmacname = DNS_TSIG_HMACSHA384_NAME; 1064 } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) { 1065 hmacname = DNS_TSIG_HMACSHA384_NAME; 1066 digestbits = parse_bits(&buf[12], "digest-bits [0..384]", 384); 1067 } else if (strcasecmp(buf, "hmac-sha512") == 0) { 1068 hmacname = DNS_TSIG_HMACSHA512_NAME; 1069 } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) { 1070 hmacname = DNS_TSIG_HMACSHA512_NAME; 1071 digestbits = parse_bits(&buf[12], "digest-bits [0..512]", 512); 1072 } else { 1073 fprintf(stderr, ";; Warning, ignoring " 1074 "invalid TSIG algorithm %s\n", buf); 1075 } 1076 } 1077 1078 /* 1079 * Get a key from a named.conf format keyfile 1080 */ 1081 static isc_result_t 1082 read_confkey(void) { 1083 cfg_parser_t *pctx = NULL; 1084 cfg_obj_t *file = NULL; 1085 const cfg_obj_t *keyobj = NULL; 1086 const cfg_obj_t *secretobj = NULL; 1087 const cfg_obj_t *algorithmobj = NULL; 1088 const char *keyname; 1089 const char *secretstr; 1090 const char *algorithm; 1091 isc_result_t result; 1092 1093 result = cfg_parser_create(NULL, &pctx); 1094 if (result != ISC_R_SUCCESS) 1095 goto cleanup; 1096 1097 result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey, 1098 &file); 1099 if (result != ISC_R_SUCCESS) 1100 goto cleanup; 1101 1102 result = cfg_map_get(file, "key", &keyobj); 1103 if (result != ISC_R_SUCCESS) 1104 goto cleanup; 1105 1106 (void) cfg_map_get(keyobj, "secret", &secretobj); 1107 (void) cfg_map_get(keyobj, "algorithm", &algorithmobj); 1108 if (secretobj == NULL || algorithmobj == NULL) 1109 fatal("key must have algorithm and secret"); 1110 1111 keyname = cfg_obj_asstring(cfg_map_getname(keyobj)); 1112 secretstr = cfg_obj_asstring(secretobj); 1113 algorithm = cfg_obj_asstring(algorithmobj); 1114 1115 strlcpy(keynametext, keyname, sizeof(keynametext)); 1116 strlcpy(keysecret, secretstr, sizeof(keysecret)); 1117 parse_hmac(algorithm); 1118 setup_text_key(); 1119 1120 cleanup: 1121 if (pctx != NULL) { 1122 if (file != NULL) 1123 cfg_obj_destroy(pctx, &file); 1124 cfg_parser_destroy(&pctx); 1125 } 1126 1127 return (result); 1128 } 1129 1130 void 1131 setup_file_key(void) { 1132 isc_result_t result; 1133 1134 debug("setup_file_key()"); 1135 1136 /* Try reading the key as a session.key keyfile */ 1137 result = read_confkey(); 1138 1139 if (result != ISC_R_SUCCESS) 1140 fprintf(stderr, "Couldn't read key from %s: %s\n", 1141 keyfile, isc_result_totext(result)); 1142 } 1143 1144 static dig_searchlist_t * 1145 make_searchlist_entry(char *domain) { 1146 dig_searchlist_t *search; 1147 search = malloc(sizeof(*search)); 1148 if (search == NULL) 1149 fatal("memory allocation failure in %s:%d", 1150 __FILE__, __LINE__); 1151 strlcpy(search->origin, domain, MXNAME); 1152 search->origin[MXNAME-1] = 0; 1153 ISC_LINK_INIT(search, link); 1154 return (search); 1155 } 1156 1157 static void 1158 clear_searchlist(void) { 1159 dig_searchlist_t *search; 1160 while ((search = ISC_LIST_HEAD(search_list)) != NULL) { 1161 ISC_LIST_UNLINK(search_list, search, link); 1162 free(search); 1163 } 1164 } 1165 1166 static void 1167 create_search_list(lwres_conf_t *confdata) { 1168 int i; 1169 dig_searchlist_t *search; 1170 1171 debug("create_search_list()"); 1172 clear_searchlist(); 1173 1174 for (i = 0; i < confdata->searchnxt; i++) { 1175 search = make_searchlist_entry(confdata->search[i]); 1176 ISC_LIST_APPEND(search_list, search, link); 1177 } 1178 } 1179 1180 /*% 1181 * Setup the system as a whole, reading key information and resolv.conf 1182 * settings. 1183 */ 1184 void 1185 setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { 1186 dig_searchlist_t *domain = NULL; 1187 lwres_result_t lwresult; 1188 int lwresflags = 0; 1189 1190 debug("setup_system()"); 1191 1192 if (ipv4only) { 1193 if (have_ipv4) { 1194 isc_net_disableipv6(); 1195 have_ipv6 = ISC_FALSE; 1196 } else { 1197 fatal("can't find IPv4 networking"); 1198 } 1199 } 1200 1201 if (ipv6only) { 1202 if (have_ipv6) { 1203 isc_net_disableipv4(); 1204 have_ipv4 = ISC_FALSE; 1205 } else { 1206 fatal("can't find IPv6 networking"); 1207 } 1208 } 1209 1210 if (have_ipv4) 1211 lwresflags |= LWRES_USEIPV4; 1212 if (have_ipv6) 1213 lwresflags |= LWRES_USEIPV6; 1214 lwres_conf_init(lwconf, lwresflags); 1215 1216 lwresult = lwres_conf_parse(lwconf, _PATH_RESCONF); 1217 if (lwresult != LWRES_R_SUCCESS && lwresult != LWRES_R_NOTFOUND) 1218 fatal("parse of %s failed", _PATH_RESCONF); 1219 1220 /* Make the search list */ 1221 if (lwconf->searchnxt > 0) 1222 create_search_list(lwconf); 1223 else { /* No search list. Use the domain name if any */ 1224 if (lwconf->domainname != NULL) { 1225 domain = make_searchlist_entry(lwconf->domainname); 1226 ISC_LIST_APPEND(search_list, domain, link); 1227 domain = NULL; 1228 } 1229 } 1230 1231 if (ndots == -1) { 1232 ndots = lwconf->ndots; 1233 debug("ndots is %d.", ndots); 1234 } 1235 1236 /* If user doesn't specify server use nameservers from resolv.conf. */ 1237 if (ISC_LIST_EMPTY(server_list)) 1238 copy_server_list(lwconf, &server_list); 1239 1240 /* If we don't find a nameserver fall back to localhost */ 1241 if (ISC_LIST_EMPTY(server_list)) { 1242 if (have_ipv4) { 1243 lwresult = add_nameserver(lwconf, "127.0.0.1", AF_INET); 1244 if (lwresult != ISC_R_SUCCESS) 1245 fatal("add_nameserver failed"); 1246 } 1247 if (have_ipv6) { 1248 lwresult = add_nameserver(lwconf, "::1", AF_INET6); 1249 if (lwresult != ISC_R_SUCCESS) 1250 fatal("add_nameserver failed"); 1251 } 1252 1253 copy_server_list(lwconf, &server_list); 1254 } 1255 1256 if (keyfile[0] != 0) 1257 setup_file_key(); 1258 else if (keysecret[0] != 0) 1259 setup_text_key(); 1260 arc4random_buf(cookie_secret, sizeof(cookie_secret)); 1261 } 1262 1263 /*% 1264 * Override the search list derived from resolv.conf by 'domain'. 1265 */ 1266 void 1267 set_search_domain(char *domain) { 1268 dig_searchlist_t *search; 1269 1270 clear_searchlist(); 1271 search = make_searchlist_entry(domain); 1272 ISC_LIST_APPEND(search_list, search, link); 1273 } 1274 1275 /*% 1276 * Setup the ISC and DNS libraries for use by the system. 1277 */ 1278 void 1279 setup_libs(void) { 1280 isc_result_t result; 1281 isc_logconfig_t *logconfig = NULL; 1282 1283 debug("setup_libs()"); 1284 1285 dns_result_register(); 1286 1287 result = isc_log_create(&lctx, &logconfig); 1288 check_result(result, "isc_log_create"); 1289 1290 isc_log_setcontext(lctx); 1291 dns_log_init(lctx); 1292 dns_log_setcontext(lctx); 1293 1294 result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL); 1295 check_result(result, "isc_log_usechannel"); 1296 1297 isc_log_setdebuglevel(lctx, 0); 1298 1299 result = isc_taskmgr_create(1, 0, &taskmgr); 1300 check_result(result, "isc_taskmgr_create"); 1301 1302 result = isc_task_create(taskmgr, 0, &global_task); 1303 check_result(result, "isc_task_create"); 1304 isc_task_setname(global_task, "dig", NULL); 1305 1306 result = isc_timermgr_create(&timermgr); 1307 check_result(result, "isc_timermgr_create"); 1308 1309 result = isc_socketmgr_create(&socketmgr); 1310 check_result(result, "isc_socketmgr_create"); 1311 1312 check_result(result, "isc_entropy_create"); 1313 1314 result = dst_lib_init(); 1315 check_result(result, "dst_lib_init"); 1316 is_dst_up = ISC_TRUE; 1317 } 1318 1319 typedef struct dig_ednsoptname { 1320 uint32_t code; 1321 const char *name; 1322 } dig_ednsoptname_t; 1323 1324 dig_ednsoptname_t optnames[] = { 1325 { 3, "NSID" }, /* RFC 5001 */ 1326 { 5, "DAU" }, /* RFC 6975 */ 1327 { 6, "DHU" }, /* RFC 6975 */ 1328 { 7, "N3U" }, /* RFC 6975 */ 1329 { 8, "ECS" }, /* RFC 7871 */ 1330 { 9, "EXPIRE" }, /* RFC 7314 */ 1331 { 10, "COOKIE" }, /* RFC 7873 */ 1332 { 11, "KEEPALIVE" }, /* RFC 7828 */ 1333 { 12, "PADDING" }, /* RFC 7830 */ 1334 { 12, "PAD" }, /* shorthand */ 1335 { 13, "CHAIN" }, /* RFC 7901 */ 1336 { 14, "KEY-TAG" }, /* RFC 8145 */ 1337 { 26946, "DEVICEID" }, /* Brian Hartvigsen */ 1338 }; 1339 1340 #define N_EDNS_OPTNAMES (sizeof(optnames) / sizeof(optnames[0])) 1341 1342 void 1343 save_opt(dig_lookup_t *lookup, char *code, char *value) { 1344 isc_result_t result; 1345 uint32_t num = 0; 1346 isc_buffer_t b; 1347 isc_boolean_t found = ISC_FALSE; 1348 unsigned int i; 1349 1350 if (lookup->ednsoptscnt >= EDNSOPT_OPTIONS) 1351 fatal("too many ednsopts"); 1352 1353 for (i = 0; i < N_EDNS_OPTNAMES; i++) { 1354 if (strcasecmp(code, optnames[i].name) == 0) { 1355 num = optnames[i].code; 1356 found = ISC_TRUE; 1357 break; 1358 } 1359 } 1360 1361 if (!found) { 1362 result = parse_uint(&num, code, 65535, "ednsopt"); 1363 if (result != ISC_R_SUCCESS) 1364 fatal("bad edns code point: %s", code); 1365 } 1366 1367 if (lookup->ednsopts == NULL) { 1368 cloneopts(lookup, NULL); 1369 } 1370 1371 if (lookup->ednsopts[lookup->ednsoptscnt].value != NULL) 1372 free(lookup->ednsopts[lookup->ednsoptscnt].value); 1373 1374 lookup->ednsopts[lookup->ednsoptscnt].code = num; 1375 lookup->ednsopts[lookup->ednsoptscnt].length = 0; 1376 lookup->ednsopts[lookup->ednsoptscnt].value = NULL; 1377 1378 if (value != NULL) { 1379 char *buf; 1380 buf = malloc(strlen(value)/2 + 1); 1381 if (buf == NULL) 1382 fatal("out of memory"); 1383 isc_buffer_init(&b, buf, (unsigned int) strlen(value)/2 + 1); 1384 result = isc_hex_decodestring(value, &b); 1385 check_result(result, "isc_hex_decodestring"); 1386 lookup->ednsopts[lookup->ednsoptscnt].value = 1387 isc_buffer_base(&b); 1388 lookup->ednsopts[lookup->ednsoptscnt].length = 1389 isc_buffer_usedlength(&b); 1390 } 1391 1392 lookup->ednsoptscnt++; 1393 } 1394 1395 /*% 1396 * Add EDNS0 option record to a message. Currently, the only supported 1397 * options are UDP buffer size, the DO bit, and EDNS options 1398 * (e.g., NSID, SIT, client-subnet) 1399 */ 1400 static void 1401 add_opt(dns_message_t *msg, uint16_t udpsize, uint16_t edns, 1402 unsigned int flags, dns_ednsopt_t *opts, size_t count) 1403 { 1404 dns_rdataset_t *rdataset = NULL; 1405 isc_result_t result; 1406 1407 debug("add_opt()"); 1408 result = dns_message_buildopt(msg, &rdataset, edns, udpsize, flags, 1409 opts, count); 1410 check_result(result, "dns_message_buildopt"); 1411 result = dns_message_setopt(msg, rdataset); 1412 check_result(result, "dns_message_setopt"); 1413 } 1414 1415 /*% 1416 * Add a question section to a message, asking for the specified name, 1417 * type, and class. 1418 */ 1419 static void 1420 add_question(dns_message_t *message, dns_name_t *name, 1421 dns_rdataclass_t rdclass, dns_rdatatype_t rdtype) 1422 { 1423 dns_rdataset_t *rdataset; 1424 isc_result_t result; 1425 1426 debug("add_question()"); 1427 rdataset = NULL; 1428 result = dns_message_gettemprdataset(message, &rdataset); 1429 check_result(result, "dns_message_gettemprdataset()"); 1430 dns_rdataset_makequestion(rdataset, rdclass, rdtype); 1431 ISC_LIST_APPEND(name->list, rdataset, link); 1432 } 1433 1434 /*% 1435 * Check if we're done with all the queued lookups, which is true iff 1436 * all sockets, sends, and recvs are accounted for (counters == 0), 1437 * and the lookup list is empty. 1438 * If we are done, pass control back out to dighost_shutdown() (which is 1439 * part of dig.c, host.c, or nslookup.c) to either shutdown the system as 1440 * a whole or reseed the lookup list. 1441 */ 1442 static void 1443 check_if_done(void) { 1444 debug("check_if_done()"); 1445 debug("list %s", ISC_LIST_EMPTY(lookup_list) ? "empty" : "full"); 1446 if (ISC_LIST_EMPTY(lookup_list) && current_lookup == NULL && 1447 sendcount == 0) { 1448 INSIST(sockcount == 0); 1449 INSIST(recvcount == 0); 1450 debug("shutting down"); 1451 dighost_shutdown(); 1452 } 1453 } 1454 1455 /*% 1456 * Clear out a query when we're done with it. WARNING: This routine 1457 * WILL invalidate the query pointer. 1458 */ 1459 static void 1460 clear_query(dig_query_t *query) { 1461 dig_lookup_t *lookup; 1462 1463 REQUIRE(query != NULL); 1464 1465 debug("clear_query(%p)", query); 1466 1467 if (query->timer != NULL) 1468 isc_timer_detach(&query->timer); 1469 lookup = query->lookup; 1470 1471 if (lookup->current_query == query) 1472 lookup->current_query = NULL; 1473 1474 if (ISC_LINK_LINKED(query, link)) 1475 ISC_LIST_UNLINK(lookup->q, query, link); 1476 if (ISC_LINK_LINKED(query, clink)) 1477 ISC_LIST_UNLINK(lookup->connecting, query, clink); 1478 if (ISC_LINK_LINKED(&query->recvbuf, link)) 1479 ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf, 1480 link); 1481 if (ISC_LINK_LINKED(&query->lengthbuf, link)) 1482 ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf, 1483 link); 1484 INSIST(query->recvspace != NULL); 1485 1486 if (query->sock != NULL) { 1487 isc_socket_detach(&query->sock); 1488 sockcount--; 1489 debug("sockcount=%d", sockcount); 1490 } 1491 free(query->recvspace); 1492 isc_buffer_invalidate(&query->recvbuf); 1493 isc_buffer_invalidate(&query->lengthbuf); 1494 if (query->waiting_senddone) 1495 query->pending_free = ISC_TRUE; 1496 else 1497 free(query); 1498 } 1499 1500 /*% 1501 * Try and clear out a lookup if we're done with it. Return ISC_TRUE if 1502 * the lookup was successfully cleared. If ISC_TRUE is returned, the 1503 * lookup pointer has been invalidated. 1504 */ 1505 static isc_boolean_t 1506 try_clear_lookup(dig_lookup_t *lookup) { 1507 dig_query_t *q; 1508 1509 REQUIRE(lookup != NULL); 1510 1511 debug("try_clear_lookup(%p)", lookup); 1512 1513 if (ISC_LIST_HEAD(lookup->q) != NULL || 1514 ISC_LIST_HEAD(lookup->connecting) != NULL) 1515 { 1516 if (debugging) { 1517 q = ISC_LIST_HEAD(lookup->q); 1518 while (q != NULL) { 1519 debug("query to %s still pending", q->servname); 1520 q = ISC_LIST_NEXT(q, link); 1521 } 1522 1523 q = ISC_LIST_HEAD(lookup->connecting); 1524 while (q != NULL) { 1525 debug("query to %s still connecting", 1526 q->servname); 1527 q = ISC_LIST_NEXT(q, clink); 1528 } 1529 } 1530 return (ISC_FALSE); 1531 } 1532 1533 /* 1534 * At this point, we know there are no queries on the lookup, 1535 * so can make it go away also. 1536 */ 1537 destroy_lookup(lookup); 1538 return (ISC_TRUE); 1539 } 1540 1541 void 1542 destroy_lookup(dig_lookup_t *lookup) { 1543 dig_server_t *s; 1544 void *ptr; 1545 1546 debug("destroy"); 1547 s = ISC_LIST_HEAD(lookup->my_server_list); 1548 while (s != NULL) { 1549 debug("freeing server %p belonging to %p", s, lookup); 1550 ptr = s; 1551 s = ISC_LIST_NEXT(s, link); 1552 ISC_LIST_DEQUEUE(lookup->my_server_list, 1553 (dig_server_t *)ptr, link); 1554 free(ptr); 1555 } 1556 if (lookup->sendmsg != NULL) 1557 dns_message_destroy(&lookup->sendmsg); 1558 if (lookup->querysig != NULL) { 1559 debug("freeing buffer %p", lookup->querysig); 1560 isc_buffer_free(&lookup->querysig); 1561 } 1562 if (lookup->sendspace != NULL) 1563 free(lookup->sendspace); 1564 1565 if (lookup->tsigctx != NULL) 1566 dst_context_destroy(&lookup->tsigctx); 1567 1568 if (lookup->ecs_addr != NULL) 1569 free(lookup->ecs_addr); 1570 1571 if (lookup->ednsopts != NULL) { 1572 size_t i; 1573 for (i = 0; i < EDNSOPT_OPTIONS; i++) { 1574 if (lookup->ednsopts[i].value != NULL) 1575 free(lookup->ednsopts[i].value); 1576 } 1577 free(lookup->ednsopts); 1578 } 1579 1580 free(lookup); 1581 } 1582 1583 /*% 1584 * If we can, start the next lookup in the queue running. 1585 * This assumes that the lookup on the head of the queue hasn't been 1586 * started yet. It also removes the lookup from the head of the queue, 1587 * setting the current_lookup pointer pointing to it. 1588 */ 1589 void 1590 start_lookup(void) { 1591 debug("start_lookup()"); 1592 if (cancel_now) 1593 return; 1594 1595 /* 1596 * If there's a current lookup running, we really shouldn't get 1597 * here. 1598 */ 1599 INSIST(current_lookup == NULL); 1600 1601 current_lookup = ISC_LIST_HEAD(lookup_list); 1602 /* 1603 * Put the current lookup somewhere so cancel_all can find it 1604 */ 1605 if (current_lookup != NULL) { 1606 ISC_LIST_DEQUEUE(lookup_list, current_lookup, link); 1607 if (setup_lookup(current_lookup)) 1608 do_lookup(current_lookup); 1609 else if (next_origin(current_lookup)) 1610 check_next_lookup(current_lookup); 1611 } else { 1612 check_if_done(); 1613 } 1614 } 1615 1616 /*% 1617 * If we can, clear the current lookup and start the next one running. 1618 * This calls try_clear_lookup, so may invalidate the lookup pointer. 1619 */ 1620 static void 1621 check_next_lookup(dig_lookup_t *lookup) { 1622 1623 INSIST(!free_now); 1624 1625 debug("check_next_lookup(%p)", lookup); 1626 1627 if (ISC_LIST_HEAD(lookup->q) != NULL) { 1628 debug("still have a worker"); 1629 return; 1630 } 1631 if (try_clear_lookup(lookup)) { 1632 current_lookup = NULL; 1633 start_lookup(); 1634 } 1635 } 1636 1637 /*% 1638 * Create and queue a new lookup as a followup to the current lookup, 1639 * based on the supplied message and section. This is used in trace and 1640 * name server search modes to start a new lookup using servers from 1641 * NS records in a reply. Returns the number of followup lookups made. 1642 */ 1643 static int 1644 followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) 1645 { 1646 dig_lookup_t *lookup = NULL; 1647 dig_server_t *srv = NULL; 1648 dns_rdataset_t *rdataset = NULL; 1649 dns_rdata_t rdata = DNS_RDATA_INIT; 1650 dns_name_t *name = NULL; 1651 isc_result_t result; 1652 isc_boolean_t success = ISC_FALSE; 1653 int numLookups = 0; 1654 int num; 1655 isc_result_t lresult, addresses_result; 1656 char bad_namestr[DNS_NAME_FORMATSIZE]; 1657 dns_name_t *domain; 1658 isc_boolean_t horizontal = ISC_FALSE, bad = ISC_FALSE; 1659 1660 INSIST(!free_now); 1661 1662 debug("following up %s", query->lookup->textname); 1663 1664 addresses_result = ISC_R_SUCCESS; 1665 bad_namestr[0] = '\0'; 1666 for (result = dns_message_firstname(msg, section); 1667 result == ISC_R_SUCCESS; 1668 result = dns_message_nextname(msg, section)) { 1669 name = NULL; 1670 dns_message_currentname(msg, section, &name); 1671 1672 if (section == DNS_SECTION_AUTHORITY) { 1673 rdataset = NULL; 1674 result = dns_message_findtype(name, dns_rdatatype_soa, 1675 0, &rdataset); 1676 if (result == ISC_R_SUCCESS) 1677 return (0); 1678 } 1679 rdataset = NULL; 1680 result = dns_message_findtype(name, dns_rdatatype_ns, 0, 1681 &rdataset); 1682 if (result != ISC_R_SUCCESS) 1683 continue; 1684 1685 debug("found NS set"); 1686 1687 if (query->lookup->trace && !query->lookup->trace_root) { 1688 dns_namereln_t namereln; 1689 unsigned int nlabels; 1690 int order; 1691 1692 domain = dns_fixedname_name(&query->lookup->fdomain); 1693 namereln = dns_name_fullcompare(name, domain, 1694 &order, &nlabels); 1695 if (namereln == dns_namereln_equal) { 1696 if (!horizontal) 1697 printf(";; BAD (HORIZONTAL) REFERRAL\n"); 1698 horizontal = ISC_TRUE; 1699 } else if (namereln != dns_namereln_subdomain) { 1700 if (!bad) 1701 printf(";; BAD REFERRAL\n"); 1702 bad = ISC_TRUE; 1703 continue; 1704 } 1705 } 1706 1707 for (result = dns_rdataset_first(rdataset); 1708 result == ISC_R_SUCCESS; 1709 result = dns_rdataset_next(rdataset)) { 1710 char namestr[DNS_NAME_FORMATSIZE]; 1711 dns_rdata_ns_t ns; 1712 1713 if (query->lookup->trace_root && 1714 query->lookup->nsfound >= MXSERV) 1715 break; 1716 1717 dns_rdataset_current(rdataset, &rdata); 1718 1719 query->lookup->nsfound++; 1720 result = dns_rdata_tostruct_ns(&rdata, &ns); 1721 check_result(result, "dns_rdata_tostruct_ns"); 1722 dns_name_format(&ns.name, namestr, sizeof(namestr)); 1723 dns_rdata_freestruct_ns(&ns); 1724 1725 /* Initialize lookup if we've not yet */ 1726 debug("found NS %s", namestr); 1727 if (!success) { 1728 success = ISC_TRUE; 1729 lookup_counter++; 1730 lookup = requeue_lookup(query->lookup, 1731 ISC_FALSE); 1732 cancel_lookup(query->lookup); 1733 lookup->doing_xfr = ISC_FALSE; 1734 if (!lookup->trace_root && 1735 section == DNS_SECTION_ANSWER) 1736 lookup->trace = ISC_FALSE; 1737 else 1738 lookup->trace = query->lookup->trace; 1739 lookup->ns_search_only = 1740 query->lookup->ns_search_only; 1741 lookup->trace_root = ISC_FALSE; 1742 if (lookup->ns_search_only) 1743 lookup->recurse = ISC_FALSE; 1744 domain = dns_fixedname_name(&lookup->fdomain); 1745 dns_name_copy(name, domain, NULL); 1746 } 1747 debug("adding server %s", namestr); 1748 num = getaddresses(lookup, namestr, &lresult); 1749 if (lresult != ISC_R_SUCCESS) { 1750 printf("couldn't get address for '%s': %s\n", 1751 namestr, isc_result_totext(lresult)); 1752 if (addresses_result == ISC_R_SUCCESS) { 1753 addresses_result = lresult; 1754 strlcpy(bad_namestr, namestr, 1755 sizeof(bad_namestr)); 1756 } 1757 } 1758 numLookups += num; 1759 dns_rdata_reset(&rdata); 1760 } 1761 } 1762 if (numLookups == 0 && addresses_result != ISC_R_SUCCESS) { 1763 fatal("couldn't get address for '%s': %s", 1764 bad_namestr, isc_result_totext(result)); 1765 } 1766 1767 if (lookup == NULL && 1768 section == DNS_SECTION_ANSWER && 1769 (query->lookup->trace || query->lookup->ns_search_only)) 1770 return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY)); 1771 1772 /* 1773 * Randomize the order the nameserver will be tried. 1774 */ 1775 if (numLookups > 1) { 1776 uint32_t i, j; 1777 dig_serverlist_t my_server_list; 1778 dig_server_t *next; 1779 1780 ISC_LIST_INIT(my_server_list); 1781 1782 i = numLookups; 1783 for (srv = ISC_LIST_HEAD(lookup->my_server_list); 1784 srv != NULL; 1785 srv = ISC_LIST_HEAD(lookup->my_server_list)) { 1786 INSIST(i > 0); 1787 j = arc4random_uniform(i); 1788 next = ISC_LIST_NEXT(srv, link); 1789 while (j-- > 0 && next != NULL) { 1790 srv = next; 1791 next = ISC_LIST_NEXT(srv, link); 1792 } 1793 ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link); 1794 ISC_LIST_APPEND(my_server_list, srv, link); 1795 i--; 1796 } 1797 ISC_LIST_APPENDLIST(lookup->my_server_list, 1798 my_server_list, link); 1799 } 1800 1801 return (numLookups); 1802 } 1803 1804 /*% 1805 * Create and queue a new lookup using the next origin from the search 1806 * list, read in setup_system(). 1807 * 1808 * Return ISC_TRUE iff there was another searchlist entry. 1809 */ 1810 static isc_boolean_t 1811 next_origin(dig_lookup_t *oldlookup) { 1812 dig_lookup_t *newlookup; 1813 dig_searchlist_t *search; 1814 dns_fixedname_t fixed; 1815 dns_name_t *name; 1816 isc_result_t result; 1817 1818 INSIST(!free_now); 1819 1820 debug("next_origin()"); 1821 debug("following up %s", oldlookup->textname); 1822 1823 if (!usesearch) 1824 /* 1825 * We're not using a search list, so don't even think 1826 * about finding the next entry. 1827 */ 1828 return (ISC_FALSE); 1829 1830 /* 1831 * Check for a absolute name or ndots being met. 1832 */ 1833 dns_fixedname_init(&fixed); 1834 name = dns_fixedname_name(&fixed); 1835 result = dns_name_fromstring2(name, oldlookup->textname, NULL, 0); 1836 if (result == ISC_R_SUCCESS && 1837 (dns_name_isabsolute(name) || 1838 (int)dns_name_countlabels(name) > ndots)) 1839 return (ISC_FALSE); 1840 1841 if (oldlookup->origin == NULL && !oldlookup->need_search) 1842 /* 1843 * Then we just did rootorg; there's nothing left. 1844 */ 1845 return (ISC_FALSE); 1846 if (oldlookup->origin == NULL && oldlookup->need_search) { 1847 newlookup = requeue_lookup(oldlookup, ISC_TRUE); 1848 newlookup->origin = ISC_LIST_HEAD(search_list); 1849 newlookup->need_search = ISC_FALSE; 1850 } else { 1851 search = ISC_LIST_NEXT(oldlookup->origin, link); 1852 if (search == NULL && oldlookup->done_as_is) 1853 return (ISC_FALSE); 1854 newlookup = requeue_lookup(oldlookup, ISC_TRUE); 1855 newlookup->origin = search; 1856 } 1857 cancel_lookup(oldlookup); 1858 return (ISC_TRUE); 1859 } 1860 1861 /*% 1862 * Insert an SOA record into the sendmessage in a lookup. Used for 1863 * creating IXFR queries. 1864 */ 1865 static void 1866 insert_soa(dig_lookup_t *lookup) { 1867 isc_result_t result; 1868 dns_rdata_soa_t soa; 1869 dns_rdata_t *rdata = NULL; 1870 dns_rdatalist_t *rdatalist = NULL; 1871 dns_rdataset_t *rdataset = NULL; 1872 dns_name_t *soaname = NULL; 1873 1874 debug("insert_soa()"); 1875 soa.serial = lookup->ixfr_serial; 1876 soa.refresh = 0; 1877 soa.retry = 0; 1878 soa.expire = 0; 1879 soa.minimum = 0; 1880 soa.common.rdclass = lookup->rdclass; 1881 soa.common.rdtype = dns_rdatatype_soa; 1882 1883 dns_name_init(&soa.origin, NULL); 1884 dns_name_init(&soa.contact, NULL); 1885 1886 dns_name_clone(dns_rootname, &soa.origin); 1887 dns_name_clone(dns_rootname, &soa.contact); 1888 1889 isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore, 1890 sizeof(lookup->rdatastore)); 1891 1892 result = dns_message_gettemprdata(lookup->sendmsg, &rdata); 1893 check_result(result, "dns_message_gettemprdata"); 1894 1895 result = dns_rdata_fromstruct_soa(rdata, lookup->rdclass, 1896 dns_rdatatype_soa, &soa, 1897 &lookup->rdatabuf); 1898 check_result(result, "isc_rdata_fromstruct_soa"); 1899 1900 result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist); 1901 check_result(result, "dns_message_gettemprdatalist"); 1902 1903 result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset); 1904 check_result(result, "dns_message_gettemprdataset"); 1905 1906 dns_rdatalist_init(rdatalist); 1907 rdatalist->type = dns_rdatatype_soa; 1908 rdatalist->rdclass = lookup->rdclass; 1909 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 1910 1911 dns_rdatalist_tordataset(rdatalist, rdataset); 1912 1913 result = dns_message_gettempname(lookup->sendmsg, &soaname); 1914 check_result(result, "dns_message_gettempname"); 1915 dns_name_init(soaname, NULL); 1916 dns_name_clone(lookup->name, soaname); 1917 ISC_LIST_INIT(soaname->list); 1918 ISC_LIST_APPEND(soaname->list, rdataset, link); 1919 dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY); 1920 } 1921 1922 static void 1923 compute_cookie(unsigned char *clientcookie, size_t len) { 1924 /* XXXMPA need to fix, should be per server. */ 1925 INSIST(len >= 8U); 1926 memmove(clientcookie, cookie_secret, 8); 1927 } 1928 1929 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 1930 static void 1931 populate_root_hints(void) 1932 { 1933 dig_server_t *newsrv; 1934 size_t i; 1935 1936 if (!ISC_LIST_EMPTY(root_hints_server_list)) 1937 return; 1938 1939 for (i = 0; i < nitems(root_hints); i++) { 1940 if (!have_ipv4 && root_hints[i].af == AF_INET) 1941 continue; 1942 if (!have_ipv6 && root_hints[i].af == AF_INET6) 1943 continue; 1944 newsrv = make_server(root_hints[i].ns, root_hints[i].ns); 1945 ISC_LINK_INIT(newsrv, link); 1946 ISC_LIST_ENQUEUE(root_hints_server_list, newsrv, link); 1947 } 1948 } 1949 #undef nitems 1950 1951 /*% 1952 * Setup the supplied lookup structure, making it ready to start sending 1953 * queries to servers. Create and initialize the message to be sent as 1954 * well as the query structures and buffer space for the replies. If the 1955 * server list is empty, clone it from the system default list. 1956 */ 1957 isc_boolean_t 1958 setup_lookup(dig_lookup_t *lookup) { 1959 isc_result_t result; 1960 uint32_t id; 1961 unsigned int len; 1962 dig_server_t *serv; 1963 dig_query_t *query; 1964 isc_buffer_t b; 1965 dns_compress_t cctx; 1966 char store[MXNAME]; 1967 char ecsbuf[20]; 1968 char sitbuf[256]; 1969 1970 REQUIRE(lookup != NULL); 1971 INSIST(!free_now); 1972 1973 debug("setup_lookup(%p)", lookup); 1974 1975 result = dns_message_create(DNS_MESSAGE_INTENTRENDER, 1976 &lookup->sendmsg); 1977 check_result(result, "dns_message_create"); 1978 1979 if (lookup->new_search) { 1980 debug("resetting lookup counter."); 1981 lookup_counter = 0; 1982 } 1983 1984 if (ISC_LIST_EMPTY(lookup->my_server_list)) { 1985 if (lookup->trace && lookup->trace_root) { 1986 populate_root_hints(); 1987 clone_server_list(root_hints_server_list, 1988 &lookup->my_server_list); 1989 } else { 1990 debug("cloning server list"); 1991 clone_server_list(server_list, 1992 &lookup->my_server_list); 1993 } 1994 } 1995 result = dns_message_gettempname(lookup->sendmsg, &lookup->name); 1996 check_result(result, "dns_message_gettempname"); 1997 dns_name_init(lookup->name, NULL); 1998 1999 isc_buffer_init(&lookup->namebuf, lookup->name_space, 2000 sizeof(lookup->name_space)); 2001 isc_buffer_init(&lookup->onamebuf, lookup->oname_space, 2002 sizeof(lookup->oname_space)); 2003 2004 /* 2005 * If the name has too many dots, force the origin to be NULL 2006 * (which produces an absolute lookup). Otherwise, take the origin 2007 * we have if there's one in the struct already. If it's NULL, 2008 * take the first entry in the searchlist iff either usesearch 2009 * is TRUE or we got a domain line in the resolv.conf file. 2010 */ 2011 if (lookup->new_search) { 2012 if ((count_dots(lookup->textname) >= ndots) || !usesearch) { 2013 lookup->origin = NULL; /* Force abs lookup */ 2014 lookup->done_as_is = ISC_TRUE; 2015 lookup->need_search = usesearch; 2016 } else if (lookup->origin == NULL && usesearch) { 2017 lookup->origin = ISC_LIST_HEAD(search_list); 2018 lookup->need_search = ISC_FALSE; 2019 } 2020 } 2021 2022 if (lookup->origin != NULL) { 2023 debug("trying origin %s", lookup->origin->origin); 2024 result = dns_message_gettempname(lookup->sendmsg, 2025 &lookup->oname); 2026 check_result(result, "dns_message_gettempname"); 2027 dns_name_init(lookup->oname, NULL); 2028 /* XXX Helper funct to conv char* to name? */ 2029 len = (unsigned int) strlen(lookup->origin->origin); 2030 isc_buffer_init(&b, lookup->origin->origin, len); 2031 isc_buffer_add(&b, len); 2032 result = dns_name_fromtext(lookup->oname, &b, dns_rootname, 2033 0, &lookup->onamebuf); 2034 if (result != ISC_R_SUCCESS) { 2035 dns_message_puttempname(lookup->sendmsg, 2036 &lookup->name); 2037 dns_message_puttempname(lookup->sendmsg, 2038 &lookup->oname); 2039 fatal("'%s' is not in legal name syntax (%s)", 2040 lookup->origin->origin, 2041 isc_result_totext(result)); 2042 } 2043 if (lookup->trace && lookup->trace_root) { 2044 dns_name_clone(dns_rootname, lookup->name); 2045 } else { 2046 dns_fixedname_t fixed; 2047 dns_name_t *name; 2048 2049 dns_fixedname_init(&fixed); 2050 name = dns_fixedname_name(&fixed); 2051 len = (unsigned int) strlen(lookup->textname); 2052 isc_buffer_init(&b, lookup->textname, len); 2053 isc_buffer_add(&b, len); 2054 result = dns_name_fromtext(name, &b, NULL, 0, NULL); 2055 if (result == ISC_R_SUCCESS && 2056 !dns_name_isabsolute(name)) 2057 result = dns_name_concatenate(name, 2058 lookup->oname, 2059 lookup->name, 2060 &lookup->namebuf); 2061 else if (result == ISC_R_SUCCESS) 2062 result = dns_name_copy(name, lookup->name, 2063 &lookup->namebuf); 2064 if (result != ISC_R_SUCCESS) { 2065 dns_message_puttempname(lookup->sendmsg, 2066 &lookup->name); 2067 dns_message_puttempname(lookup->sendmsg, 2068 &lookup->oname); 2069 if (result == DNS_R_NAMETOOLONG) 2070 return (ISC_FALSE); 2071 fatal("'%s' is not in legal name syntax (%s)", 2072 lookup->textname, 2073 isc_result_totext(result)); 2074 } 2075 } 2076 dns_message_puttempname(lookup->sendmsg, &lookup->oname); 2077 } else 2078 { 2079 debug("using root origin"); 2080 if (lookup->trace && lookup->trace_root) 2081 dns_name_clone(dns_rootname, lookup->name); 2082 else { 2083 len = (unsigned int) strlen(lookup->textname); 2084 isc_buffer_init(&b, lookup->textname, len); 2085 isc_buffer_add(&b, len); 2086 result = dns_name_fromtext(lookup->name, &b, 2087 dns_rootname, 0, 2088 &lookup->namebuf); 2089 } 2090 if (result != ISC_R_SUCCESS) { 2091 dns_message_puttempname(lookup->sendmsg, 2092 &lookup->name); 2093 fatal("'%s' is not a legal name " 2094 "(%s)", lookup->textname, 2095 isc_result_totext(result)); 2096 } 2097 } 2098 dns_name_format(lookup->name, store, sizeof(store)); 2099 dighost_trying(store, lookup); 2100 INSIST(dns_name_isabsolute(lookup->name)); 2101 2102 id = arc4random(); 2103 lookup->sendmsg->id = (unsigned short)id & 0xFFFF; 2104 lookup->sendmsg->opcode = lookup->opcode; 2105 lookup->msgcounter = 0; 2106 /* 2107 * If this is a trace request, completely disallow recursion, since 2108 * it's meaningless for traces. 2109 */ 2110 if (lookup->trace || (lookup->ns_search_only && !lookup->trace_root)) 2111 lookup->recurse = ISC_FALSE; 2112 2113 if (lookup->recurse && 2114 lookup->rdtype != dns_rdatatype_axfr && 2115 lookup->rdtype != dns_rdatatype_ixfr) { 2116 debug("recursive query"); 2117 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_RD; 2118 } 2119 2120 /* XXX aaflag */ 2121 if (lookup->aaonly) { 2122 debug("AA query"); 2123 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AA; 2124 } 2125 2126 if (lookup->adflag) { 2127 debug("AD query"); 2128 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AD; 2129 } 2130 2131 if (lookup->cdflag) { 2132 debug("CD query"); 2133 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_CD; 2134 } 2135 2136 dns_message_addname(lookup->sendmsg, lookup->name, 2137 DNS_SECTION_QUESTION); 2138 2139 if (lookup->trace && lookup->trace_root) { 2140 lookup->qrdtype = lookup->rdtype; 2141 lookup->rdtype = dns_rdatatype_ns; 2142 } 2143 2144 if ((lookup->rdtype == dns_rdatatype_axfr) || 2145 (lookup->rdtype == dns_rdatatype_ixfr)) { 2146 /* 2147 * Force TCP mode if we're doing an axfr. 2148 */ 2149 if (lookup->rdtype == dns_rdatatype_axfr) { 2150 lookup->doing_xfr = ISC_TRUE; 2151 lookup->tcp_mode = ISC_TRUE; 2152 } else if (lookup->tcp_mode) { 2153 lookup->doing_xfr = ISC_TRUE; 2154 } 2155 } 2156 2157 add_question(lookup->sendmsg, lookup->name, lookup->rdclass, 2158 lookup->rdtype); 2159 2160 /* add_soa */ 2161 if (lookup->rdtype == dns_rdatatype_ixfr) 2162 insert_soa(lookup); 2163 2164 /* XXX Insist this? */ 2165 lookup->tsigctx = NULL; 2166 lookup->querysig = NULL; 2167 if (tsigkey != NULL) { 2168 debug("initializing keys"); 2169 result = dns_message_settsigkey(lookup->sendmsg, tsigkey); 2170 check_result(result, "dns_message_settsigkey"); 2171 } 2172 2173 lookup->sendspace = malloc(COMMSIZE); 2174 if (lookup->sendspace == NULL) 2175 fatal("memory allocation failure"); 2176 2177 result = dns_compress_init(&cctx, -1); 2178 check_result(result, "dns_compress_init"); 2179 2180 debug("starting to render the message"); 2181 isc_buffer_init(&lookup->renderbuf, lookup->sendspace, COMMSIZE); 2182 result = dns_message_renderbegin(lookup->sendmsg, &cctx, 2183 &lookup->renderbuf); 2184 check_result(result, "dns_message_renderbegin"); 2185 if (lookup->udpsize > 0 || lookup->dnssec || 2186 lookup->edns > -1 || lookup->ecs_addr != NULL) 2187 { 2188 #define MAXOPTS (EDNSOPT_OPTIONS + DNS_EDNSOPTIONS) 2189 dns_ednsopt_t opts[MAXOPTS]; 2190 unsigned int flags; 2191 unsigned int i = 0; 2192 2193 if (lookup->udpsize == 0) 2194 lookup->udpsize = 4096; 2195 if (lookup->edns < 0) 2196 lookup->edns = 0; 2197 2198 if (lookup->nsid) { 2199 INSIST(i < MAXOPTS); 2200 opts[i].code = DNS_OPT_NSID; 2201 opts[i].length = 0; 2202 opts[i].value = NULL; 2203 i++; 2204 } 2205 2206 if (lookup->ecs_addr != NULL) { 2207 uint8_t addr[16]; 2208 uint16_t family; 2209 uint32_t plen; 2210 struct sockaddr *sa; 2211 struct sockaddr_in *sin; 2212 struct sockaddr_in6 *sin6; 2213 size_t addrl; 2214 2215 sa = &lookup->ecs_addr->type.sa; 2216 plen = lookup->ecs_addr->length; 2217 2218 /* Round up prefix len to a multiple of 8 */ 2219 addrl = (plen + 7) / 8; 2220 2221 INSIST(i < MAXOPTS); 2222 opts[i].code = DNS_OPT_CLIENT_SUBNET; 2223 opts[i].length = (uint16_t) addrl + 4; 2224 check_result(result, "isc_buffer_allocate"); 2225 2226 /* 2227 * XXXMUKS: According to RFC7871, "If there is 2228 * no ADDRESS set, i.e., SOURCE PREFIX-LENGTH is 2229 * set to 0, then FAMILY SHOULD be set to the 2230 * transport over which the query is sent." 2231 * 2232 * However, at this point we don't know what 2233 * transport(s) we'll be using, so we can't 2234 * set the value now. For now, we're using 2235 * IPv4 as the default the +subnet option 2236 * used an IPv4 prefix, or for +subnet=0, 2237 * and IPv6 if the +subnet option used an 2238 * IPv6 prefix. 2239 * 2240 * (For future work: preserve the offset into 2241 * the buffer where the family field is; 2242 * that way we can update it in send_udp() 2243 * or send_tcp_connect() once we know 2244 * what it outght to be.) 2245 */ 2246 switch (sa->sa_family) { 2247 case AF_UNSPEC: 2248 INSIST(plen == 0); 2249 family = 1; 2250 break; 2251 case AF_INET: 2252 INSIST(plen <= 32); 2253 family = 1; 2254 sin = (struct sockaddr_in *) sa; 2255 memmove(addr, &sin->sin_addr, addrl); 2256 break; 2257 case AF_INET6: 2258 INSIST(plen <= 128); 2259 family = 2; 2260 sin6 = (struct sockaddr_in6 *) sa; 2261 memmove(addr, &sin6->sin6_addr, addrl); 2262 break; 2263 default: 2264 INSIST(0); 2265 } 2266 2267 isc_buffer_init(&b, ecsbuf, sizeof(ecsbuf)); 2268 /* family */ 2269 isc_buffer_putuint16(&b, family); 2270 /* source prefix-length */ 2271 isc_buffer_putuint8(&b, plen); 2272 /* scope prefix-length */ 2273 isc_buffer_putuint8(&b, 0); 2274 2275 /* address */ 2276 if (addrl > 0) { 2277 /* Mask off last address byte */ 2278 if ((plen % 8) != 0) 2279 addr[addrl - 1] &= 2280 ~0U << (8 - (plen % 8)); 2281 isc_buffer_putmem(&b, addr, 2282 (unsigned)addrl); 2283 } 2284 2285 opts[i].value = (uint8_t *) ecsbuf; 2286 i++; 2287 } 2288 2289 if (lookup->sit) { 2290 INSIST(i < MAXOPTS); 2291 opts[i].code = DNS_OPT_COOKIE; 2292 if (lookup->sitvalue != NULL) { 2293 isc_buffer_init(&b, sitbuf, sizeof(sitbuf)); 2294 result = isc_hex_decodestring(lookup->sitvalue, 2295 &b); 2296 check_result(result, "isc_hex_decodestring"); 2297 opts[i].value = isc_buffer_base(&b); 2298 opts[i].length = isc_buffer_usedlength(&b); 2299 } else { 2300 compute_cookie(cookie, sizeof(cookie)); 2301 opts[i].length = 8; 2302 opts[i].value = cookie; 2303 } 2304 i++; 2305 } 2306 2307 if (lookup->expire) { 2308 INSIST(i < MAXOPTS); 2309 opts[i].code = DNS_OPT_EXPIRE; 2310 opts[i].length = 0; 2311 opts[i].value = NULL; 2312 i++; 2313 } 2314 2315 if (lookup->ednsoptscnt != 0) { 2316 INSIST(i + lookup->ednsoptscnt <= MAXOPTS); 2317 memmove(&opts[i], lookup->ednsopts, 2318 sizeof(dns_ednsopt_t) * lookup->ednsoptscnt); 2319 i += lookup->ednsoptscnt; 2320 } 2321 2322 flags = lookup->ednsflags; 2323 flags &= ~DNS_MESSAGEEXTFLAG_DO; 2324 if (lookup->dnssec) 2325 flags |= DNS_MESSAGEEXTFLAG_DO; 2326 add_opt(lookup->sendmsg, lookup->udpsize, 2327 lookup->edns, flags, opts, i); 2328 } 2329 2330 result = dns_message_rendersection(lookup->sendmsg, 2331 DNS_SECTION_QUESTION); 2332 check_result(result, "dns_message_rendersection"); 2333 result = dns_message_rendersection(lookup->sendmsg, 2334 DNS_SECTION_AUTHORITY); 2335 check_result(result, "dns_message_rendersection"); 2336 result = dns_message_renderend(lookup->sendmsg); 2337 check_result(result, "dns_message_renderend"); 2338 debug("done rendering"); 2339 2340 dns_compress_invalidate(&cctx); 2341 2342 /* 2343 * Force TCP mode if the request is larger than 512 bytes. 2344 */ 2345 if (isc_buffer_usedlength(&lookup->renderbuf) > 512) 2346 lookup->tcp_mode = ISC_TRUE; 2347 2348 lookup->pending = ISC_FALSE; 2349 2350 for (serv = ISC_LIST_HEAD(lookup->my_server_list); 2351 serv != NULL; 2352 serv = ISC_LIST_NEXT(serv, link)) { 2353 query = malloc(sizeof(dig_query_t)); 2354 if (query == NULL) 2355 fatal("memory allocation failure in %s:%d", 2356 __FILE__, __LINE__); 2357 debug("create query %p linked to lookup %p", 2358 query, lookup); 2359 query->lookup = lookup; 2360 query->timer = NULL; 2361 query->waiting_connect = ISC_FALSE; 2362 query->waiting_senddone = ISC_FALSE; 2363 query->pending_free = ISC_FALSE; 2364 query->recv_made = ISC_FALSE; 2365 query->first_pass = ISC_TRUE; 2366 query->first_soa_rcvd = ISC_FALSE; 2367 query->second_rr_rcvd = ISC_FALSE; 2368 query->first_repeat_rcvd = ISC_FALSE; 2369 query->warn_id = ISC_TRUE; 2370 query->timedout = ISC_FALSE; 2371 query->first_rr_serial = 0; 2372 query->second_rr_serial = 0; 2373 query->servname = serv->servername; 2374 query->userarg = serv->userarg; 2375 query->rr_count = 0; 2376 query->msg_count = 0; 2377 query->byte_count = 0; 2378 query->ixfr_axfr = ISC_FALSE; 2379 ISC_LIST_INIT(query->recvlist); 2380 ISC_LIST_INIT(query->lengthlist); 2381 query->sock = NULL; 2382 query->recvspace = malloc(COMMSIZE); 2383 if (query->recvspace == NULL) 2384 fatal("memory allocation failure"); 2385 2386 isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); 2387 isc_buffer_init(&query->lengthbuf, query->lengthspace, 2); 2388 isc_buffer_init(&query->slbuf, query->slspace, 2); 2389 query->sendbuf = lookup->renderbuf; 2390 2391 ISC_LINK_INIT(query, clink); 2392 ISC_LINK_INIT(query, link); 2393 ISC_LIST_ENQUEUE(lookup->q, query, link); 2394 } 2395 2396 /* XXX qrflag, print_query, etc... */ 2397 if (!ISC_LIST_EMPTY(lookup->q) && qr) { 2398 extrabytes = 0; 2399 dighost_printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg, 2400 ISC_TRUE); 2401 } 2402 return (ISC_TRUE); 2403 } 2404 2405 /*% 2406 * Event handler for send completion. Track send counter, and clear out 2407 * the query if the send was canceled. 2408 */ 2409 static void 2410 send_done(isc_task_t *_task, isc_event_t *event) { 2411 isc_socketevent_t *sevent = (isc_socketevent_t *)event; 2412 isc_buffer_t *b = NULL; 2413 dig_query_t *query, *next; 2414 dig_lookup_t *l; 2415 2416 REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); 2417 2418 UNUSED(_task); 2419 2420 debug("send_done()"); 2421 sendcount--; 2422 debug("sendcount=%d", sendcount); 2423 INSIST(sendcount >= 0); 2424 2425 for (b = ISC_LIST_HEAD(sevent->bufferlist); 2426 b != NULL; 2427 b = ISC_LIST_HEAD(sevent->bufferlist)) { 2428 ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); 2429 free(b); 2430 } 2431 2432 query = event->ev_arg; 2433 query->waiting_senddone = ISC_FALSE; 2434 l = query->lookup; 2435 2436 if (l->ns_search_only && !l->trace_root && !l->tcp_mode) { 2437 debug("sending next, since searching"); 2438 next = ISC_LIST_NEXT(query, link); 2439 if (next != NULL) 2440 send_udp(next); 2441 } 2442 2443 isc_event_free(&event); 2444 2445 if (query->pending_free) 2446 free(query); 2447 2448 check_if_done(); 2449 } 2450 2451 /*% 2452 * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding 2453 * IO sockets. The cancel handlers should take care of cleaning up the 2454 * query and lookup structures 2455 */ 2456 static void 2457 cancel_lookup(dig_lookup_t *lookup) { 2458 dig_query_t *query, *next; 2459 2460 debug("cancel_lookup()"); 2461 query = ISC_LIST_HEAD(lookup->q); 2462 while (query != NULL) { 2463 next = ISC_LIST_NEXT(query, link); 2464 if (query->sock != NULL) { 2465 isc_socket_cancel(query->sock, global_task, 2466 ISC_SOCKCANCEL_ALL); 2467 check_if_done(); 2468 } else { 2469 clear_query(query); 2470 } 2471 query = next; 2472 } 2473 lookup->pending = ISC_FALSE; 2474 lookup->retries = 0; 2475 } 2476 2477 static void 2478 bringup_timer(dig_query_t *query, unsigned int default_timeout) { 2479 dig_lookup_t *l; 2480 unsigned int local_timeout; 2481 isc_result_t result; 2482 2483 debug("bringup_timer()"); 2484 /* 2485 * If the timer already exists, that means we're calling this 2486 * a second time (for a retry). Don't need to recreate it, 2487 * just reset it. 2488 */ 2489 l = query->lookup; 2490 if (ISC_LINK_LINKED(query, link) && ISC_LIST_NEXT(query, link) != NULL) 2491 local_timeout = SERVER_TIMEOUT; 2492 else { 2493 if (timeout == 0) 2494 local_timeout = default_timeout; 2495 else 2496 local_timeout = timeout; 2497 } 2498 debug("have local timeout of %d", local_timeout); 2499 l->interval.tv_sec = local_timeout; 2500 l->interval.tv_nsec = 0; 2501 if (query->timer != NULL) 2502 isc_timer_detach(&query->timer); 2503 result = isc_timer_create(timermgr, 2504 &l->interval, global_task, connect_timeout, 2505 query, &query->timer); 2506 check_result(result, "isc_timer_create"); 2507 } 2508 2509 static void 2510 force_timeout(dig_query_t *query) { 2511 isc_event_t *event; 2512 2513 debug("force_timeout ()"); 2514 event = isc_event_allocate(query, ISC_TIMEREVENT_IDLE, 2515 connect_timeout, query, 2516 sizeof(isc_event_t)); 2517 if (event == NULL) { 2518 fatal("isc_event_allocate: %s", 2519 isc_result_totext(ISC_R_NOMEMORY)); 2520 } 2521 isc_task_send(global_task, &event); 2522 2523 /* 2524 * The timer may have expired if, for example, get_address() takes 2525 * long time and the timer was running on a different thread. 2526 * We need to cancel the possible timeout event not to confuse 2527 * ourselves due to the duplicate events. 2528 */ 2529 if (query->timer != NULL) 2530 isc_timer_detach(&query->timer); 2531 } 2532 2533 static void 2534 connect_done(isc_task_t *task, isc_event_t *event); 2535 2536 /*% 2537 * Unlike send_udp, this can't be called multiple times with the same 2538 * query. When we retry TCP, we requeue the whole lookup, which should 2539 * start anew. 2540 */ 2541 static void 2542 send_tcp_connect(dig_query_t *query) { 2543 isc_result_t result; 2544 dig_query_t *next; 2545 dig_lookup_t *l; 2546 2547 debug("send_tcp_connect(%p)", query); 2548 2549 l = query->lookup; 2550 query->waiting_connect = ISC_TRUE; 2551 query->lookup->current_query = query; 2552 result = get_address(query->servname, port, &query->sockaddr); 2553 if (result != ISC_R_SUCCESS) { 2554 /* 2555 * This servname doesn't have an address. Try the next server 2556 * by triggering an immediate 'timeout' (we lie, but the effect 2557 * is the same). 2558 */ 2559 force_timeout(query); 2560 return; 2561 } 2562 2563 if (specified_source && 2564 (isc_sockaddr_pf(&query->sockaddr) != 2565 isc_sockaddr_pf(&bind_address))) { 2566 printf(";; Skipping server %s, incompatible " 2567 "address family\n", query->servname); 2568 query->waiting_connect = ISC_FALSE; 2569 if (ISC_LINK_LINKED(query, link)) 2570 next = ISC_LIST_NEXT(query, link); 2571 else 2572 next = NULL; 2573 l = query->lookup; 2574 clear_query(query); 2575 if (next == NULL) { 2576 printf(";; No acceptable nameservers\n"); 2577 check_next_lookup(l); 2578 return; 2579 } 2580 send_tcp_connect(next); 2581 return; 2582 } 2583 2584 INSIST(query->sock == NULL); 2585 2586 if (keep != NULL && isc_sockaddr_equal(&keepaddr, &query->sockaddr)) { 2587 sockcount++; 2588 isc_socket_attach(keep, &query->sock); 2589 query->waiting_connect = ISC_FALSE; 2590 launch_next_query(query, ISC_TRUE); 2591 goto search; 2592 } 2593 2594 result = isc_socket_create(socketmgr, 2595 isc_sockaddr_pf(&query->sockaddr), 2596 isc_sockettype_tcp, &query->sock); 2597 check_result(result, "isc_socket_create"); 2598 sockcount++; 2599 debug("sockcount=%d", sockcount); 2600 if (specified_source) 2601 result = isc_socket_bind(query->sock, &bind_address, 2602 ISC_SOCKET_REUSEADDRESS); 2603 else { 2604 if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) && 2605 have_ipv4) 2606 isc_sockaddr_any(&bind_any); 2607 else 2608 isc_sockaddr_any6(&bind_any); 2609 result = isc_socket_bind(query->sock, &bind_any, 0); 2610 } 2611 check_result(result, "isc_socket_bind"); 2612 bringup_timer(query, TCP_TIMEOUT); 2613 result = isc_socket_connect(query->sock, &query->sockaddr, 2614 global_task, connect_done, query); 2615 check_result(result, "isc_socket_connect"); 2616 search: 2617 /* 2618 * If we're at the endgame of a nameserver search, we need to 2619 * immediately bring up all the queries. Do it here. 2620 */ 2621 if (l->ns_search_only && !l->trace_root) { 2622 debug("sending next, since searching"); 2623 if (ISC_LINK_LINKED(query, link)) { 2624 next = ISC_LIST_NEXT(query, link); 2625 ISC_LIST_DEQUEUE(l->q, query, link); 2626 } else 2627 next = NULL; 2628 ISC_LIST_ENQUEUE(l->connecting, query, clink); 2629 if (next != NULL) 2630 send_tcp_connect(next); 2631 } 2632 } 2633 2634 static isc_buffer_t * 2635 clone_buffer(isc_buffer_t *source) { 2636 isc_buffer_t *buffer; 2637 buffer = malloc(sizeof(*buffer)); 2638 if (buffer == NULL) 2639 fatal("memory allocation failure in %s:%d", 2640 __FILE__, __LINE__); 2641 *buffer = *source; 2642 return (buffer); 2643 } 2644 2645 /*% 2646 * Send a UDP packet to the remote nameserver, possible starting the 2647 * recv action as well. Also make sure that the timer is running and 2648 * is properly reset. 2649 */ 2650 static void 2651 send_udp(dig_query_t *query) { 2652 dig_lookup_t *l = NULL; 2653 isc_result_t result; 2654 isc_buffer_t *sendbuf; 2655 2656 debug("send_udp(%p)", query); 2657 2658 l = query->lookup; 2659 bringup_timer(query, UDP_TIMEOUT); 2660 l->current_query = query; 2661 debug("working on lookup %p, query %p", query->lookup, query); 2662 if (!query->recv_made) { 2663 /* XXX Check the sense of this, need assertion? */ 2664 query->waiting_connect = ISC_FALSE; 2665 result = get_address(query->servname, port, &query->sockaddr); 2666 if (result != ISC_R_SUCCESS) { 2667 /* This servname doesn't have an address. */ 2668 force_timeout(query); 2669 return; 2670 } 2671 2672 result = isc_socket_create(socketmgr, 2673 isc_sockaddr_pf(&query->sockaddr), 2674 isc_sockettype_udp, &query->sock); 2675 check_result(result, "isc_socket_create"); 2676 sockcount++; 2677 debug("sockcount=%d", sockcount); 2678 if (specified_source) { 2679 result = isc_socket_bind(query->sock, &bind_address, 2680 ISC_SOCKET_REUSEADDRESS); 2681 } else { 2682 isc_sockaddr_anyofpf(&bind_any, 2683 isc_sockaddr_pf(&query->sockaddr)); 2684 result = isc_socket_bind(query->sock, &bind_any, 0); 2685 } 2686 check_result(result, "isc_socket_bind"); 2687 2688 query->recv_made = ISC_TRUE; 2689 ISC_LINK_INIT(&query->recvbuf, link); 2690 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, 2691 link); 2692 debug("recving with lookup=%p, query=%p, sock=%p", 2693 query->lookup, query, query->sock); 2694 result = isc_socket_recvv(query->sock, &query->recvlist, 1, 2695 global_task, recv_done, query); 2696 check_result(result, "isc_socket_recvv"); 2697 recvcount++; 2698 debug("recvcount=%d", recvcount); 2699 } 2700 ISC_LIST_INIT(query->sendlist); 2701 sendbuf = clone_buffer(&query->sendbuf); 2702 ISC_LIST_ENQUEUE(query->sendlist, sendbuf, link); 2703 debug("sending a request"); 2704 clock_gettime(CLOCK_MONOTONIC, &query->time_sent); 2705 INSIST(query->sock != NULL); 2706 query->waiting_senddone = ISC_TRUE; 2707 result = isc_socket_sendtov2(query->sock, &query->sendlist, 2708 global_task, send_done, query, 2709 &query->sockaddr, NULL, 2710 ISC_SOCKFLAG_NORETRY); 2711 check_result(result, "isc_socket_sendtov"); 2712 sendcount++; 2713 } 2714 2715 /*% 2716 * IO timeout handler, used for both connect and recv timeouts. If 2717 * retries are still allowed, either resend the UDP packet or queue a 2718 * new TCP lookup. Otherwise, cancel the lookup. 2719 */ 2720 static void 2721 connect_timeout(isc_task_t *task, isc_event_t *event) { 2722 dig_lookup_t *l = NULL; 2723 dig_query_t *query = NULL, *cq; 2724 2725 UNUSED(task); 2726 REQUIRE(event->ev_type == ISC_TIMEREVENT_IDLE); 2727 2728 debug("connect_timeout()"); 2729 2730 query = event->ev_arg; 2731 l = query->lookup; 2732 isc_event_free(&event); 2733 2734 INSIST(!free_now); 2735 2736 if ((query != NULL) && (query->lookup->current_query != NULL) && 2737 ISC_LINK_LINKED(query->lookup->current_query, link) && 2738 (ISC_LIST_NEXT(query->lookup->current_query, link) != NULL)) { 2739 debug("trying next server..."); 2740 cq = query->lookup->current_query; 2741 if (!l->tcp_mode) 2742 send_udp(ISC_LIST_NEXT(cq, link)); 2743 else { 2744 if (query->sock != NULL) 2745 isc_socket_cancel(query->sock, NULL, 2746 ISC_SOCKCANCEL_ALL); 2747 send_tcp_connect(ISC_LIST_NEXT(cq, link)); 2748 } 2749 return; 2750 } 2751 2752 if (l->tcp_mode && query->sock != NULL) { 2753 query->timedout = ISC_TRUE; 2754 isc_socket_cancel(query->sock, NULL, ISC_SOCKCANCEL_ALL); 2755 } 2756 2757 if (l->retries > 1) { 2758 if (!l->tcp_mode) { 2759 l->retries--; 2760 debug("resending UDP request to first server"); 2761 send_udp(ISC_LIST_HEAD(l->q)); 2762 } else { 2763 debug("making new TCP request, %d tries left", 2764 l->retries); 2765 l->retries--; 2766 requeue_lookup(l, ISC_TRUE); 2767 cancel_lookup(l); 2768 check_next_lookup(l); 2769 } 2770 } else { 2771 if (!l->ns_search_only) { 2772 fputs(l->cmdline, stdout); 2773 printf(";; connection timed out; no servers could be " 2774 "reached\n"); 2775 } 2776 cancel_lookup(l); 2777 check_next_lookup(l); 2778 if (exitcode < 9) 2779 exitcode = 9; 2780 } 2781 } 2782 2783 /*% 2784 * Event handler for the TCP recv which gets the length header of TCP 2785 * packets. Start the next recv of length bytes. 2786 */ 2787 static void 2788 tcp_length_done(isc_task_t *task, isc_event_t *event) { 2789 isc_socketevent_t *sevent; 2790 isc_buffer_t *b = NULL; 2791 isc_result_t result; 2792 dig_query_t *query = NULL; 2793 dig_lookup_t *l, *n; 2794 uint16_t length; 2795 2796 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); 2797 INSIST(!free_now); 2798 2799 UNUSED(task); 2800 2801 debug("tcp_length_done()"); 2802 2803 sevent = (isc_socketevent_t *)event; 2804 query = event->ev_arg; 2805 2806 recvcount--; 2807 INSIST(recvcount >= 0); 2808 2809 b = ISC_LIST_HEAD(sevent->bufferlist); 2810 INSIST(b == &query->lengthbuf); 2811 ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); 2812 2813 if (sevent->result == ISC_R_CANCELED) { 2814 isc_event_free(&event); 2815 l = query->lookup; 2816 clear_query(query); 2817 check_next_lookup(l); 2818 return; 2819 } 2820 if (sevent->result != ISC_R_SUCCESS) { 2821 char sockstr[ISC_SOCKADDR_FORMATSIZE]; 2822 isc_sockaddr_format(&query->sockaddr, sockstr, 2823 sizeof(sockstr)); 2824 printf(";; communications error to %s: %s\n", 2825 sockstr, isc_result_totext(sevent->result)); 2826 if (keep != NULL) 2827 isc_socket_detach(&keep); 2828 l = query->lookup; 2829 isc_socket_detach(&query->sock); 2830 sockcount--; 2831 debug("sockcount=%d", sockcount); 2832 INSIST(sockcount >= 0); 2833 if (sevent->result == ISC_R_EOF && l->eoferr == 0U) { 2834 n = requeue_lookup(l, ISC_TRUE); 2835 n->eoferr++; 2836 } 2837 isc_event_free(&event); 2838 clear_query(query); 2839 cancel_lookup(l); 2840 check_next_lookup(l); 2841 return; 2842 } 2843 length = isc_buffer_getuint16(b); 2844 if (length == 0) { 2845 isc_event_free(&event); 2846 launch_next_query(query, ISC_FALSE); 2847 return; 2848 } 2849 2850 /* 2851 * Even though the buffer was already init'ed, we need 2852 * to redo it now, to force the length we want. 2853 */ 2854 isc_buffer_invalidate(&query->recvbuf); 2855 isc_buffer_init(&query->recvbuf, query->recvspace, length); 2856 ENSURE(ISC_LIST_EMPTY(query->recvlist)); 2857 ISC_LINK_INIT(&query->recvbuf, link); 2858 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link); 2859 debug("recving with lookup=%p, query=%p", query->lookup, query); 2860 result = isc_socket_recvv(query->sock, &query->recvlist, length, task, 2861 recv_done, query); 2862 check_result(result, "isc_socket_recvv"); 2863 recvcount++; 2864 debug("resubmitted recv request with length %d, recvcount=%d", 2865 length, recvcount); 2866 isc_event_free(&event); 2867 } 2868 2869 /*% 2870 * For transfers that involve multiple recvs (XFR's in particular), 2871 * launch the next recv. 2872 */ 2873 static void 2874 launch_next_query(dig_query_t *query, isc_boolean_t include_question) { 2875 isc_result_t result; 2876 dig_lookup_t *l; 2877 isc_buffer_t *buffer; 2878 2879 INSIST(!free_now); 2880 2881 debug("launch_next_query()"); 2882 2883 if (!query->lookup->pending) { 2884 debug("ignoring launch_next_query because !pending"); 2885 isc_socket_detach(&query->sock); 2886 sockcount--; 2887 debug("sockcount=%d", sockcount); 2888 INSIST(sockcount >= 0); 2889 query->waiting_connect = ISC_FALSE; 2890 l = query->lookup; 2891 clear_query(query); 2892 check_next_lookup(l); 2893 return; 2894 } 2895 2896 isc_buffer_clear(&query->slbuf); 2897 isc_buffer_clear(&query->lengthbuf); 2898 isc_buffer_putuint16(&query->slbuf, (uint16_t) query->sendbuf.used); 2899 ISC_LIST_INIT(query->sendlist); 2900 ISC_LINK_INIT(&query->slbuf, link); 2901 if (!query->first_soa_rcvd) { 2902 buffer = clone_buffer(&query->slbuf); 2903 ISC_LIST_ENQUEUE(query->sendlist, buffer, link); 2904 if (include_question) { 2905 buffer = clone_buffer(&query->sendbuf); 2906 ISC_LIST_ENQUEUE(query->sendlist, buffer, link); 2907 } 2908 } 2909 2910 ISC_LINK_INIT(&query->lengthbuf, link); 2911 ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link); 2912 2913 result = isc_socket_recvv(query->sock, &query->lengthlist, 0, 2914 global_task, tcp_length_done, query); 2915 check_result(result, "isc_socket_recvv"); 2916 recvcount++; 2917 debug("recvcount=%d", recvcount); 2918 if (!query->first_soa_rcvd) { 2919 debug("sending a request in launch_next_query"); 2920 clock_gettime(CLOCK_MONOTONIC, &query->time_sent); 2921 query->waiting_senddone = ISC_TRUE; 2922 result = isc_socket_sendv(query->sock, &query->sendlist, 2923 global_task, send_done, query); 2924 check_result(result, "isc_socket_sendv"); 2925 sendcount++; 2926 debug("sendcount=%d", sendcount); 2927 } 2928 query->waiting_connect = ISC_FALSE; 2929 return; 2930 } 2931 2932 /*% 2933 * Event handler for TCP connect complete. Make sure the connection was 2934 * successful, then pass into launch_next_query to actually send the 2935 * question. 2936 */ 2937 static void 2938 connect_done(isc_task_t *task, isc_event_t *event) { 2939 char sockstr[ISC_SOCKADDR_FORMATSIZE]; 2940 isc_socketevent_t *sevent = NULL; 2941 dig_query_t *query = NULL, *next; 2942 dig_lookup_t *l; 2943 2944 UNUSED(task); 2945 2946 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); 2947 INSIST(!free_now); 2948 2949 debug("connect_done()"); 2950 2951 sevent = (isc_socketevent_t *)event; 2952 query = sevent->ev_arg; 2953 2954 INSIST(query->waiting_connect); 2955 2956 query->waiting_connect = ISC_FALSE; 2957 2958 if (sevent->result == ISC_R_CANCELED) { 2959 debug("in cancel handler"); 2960 isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr)); 2961 if (query->timedout) 2962 printf(";; Connection to %s(%s) for %s failed: %s.\n", 2963 sockstr, query->servname, 2964 query->lookup->textname, 2965 isc_result_totext(ISC_R_TIMEDOUT)); 2966 isc_socket_detach(&query->sock); 2967 INSIST(sockcount > 0); 2968 sockcount--; 2969 debug("sockcount=%d", sockcount); 2970 query->waiting_connect = ISC_FALSE; 2971 isc_event_free(&event); 2972 l = query->lookup; 2973 clear_query(query); 2974 check_next_lookup(l); 2975 return; 2976 } 2977 if (sevent->result != ISC_R_SUCCESS) { 2978 2979 debug("unsuccessful connection: %s", 2980 isc_result_totext(sevent->result)); 2981 isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr)); 2982 if (sevent->result != ISC_R_CANCELED) 2983 printf(";; Connection to %s(%s) for %s failed: " 2984 "%s.\n", sockstr, 2985 query->servname, query->lookup->textname, 2986 isc_result_totext(sevent->result)); 2987 isc_socket_detach(&query->sock); 2988 INSIST(sockcount > 0); 2989 sockcount--; 2990 /* XXX Clean up exitcodes */ 2991 if (exitcode < 9) 2992 exitcode = 9; 2993 debug("sockcount=%d", sockcount); 2994 query->waiting_connect = ISC_FALSE; 2995 isc_event_free(&event); 2996 l = query->lookup; 2997 if ((l->current_query != NULL) && 2998 (ISC_LINK_LINKED(l->current_query, link))) 2999 next = ISC_LIST_NEXT(l->current_query, link); 3000 else 3001 next = NULL; 3002 clear_query(query); 3003 if (next != NULL) { 3004 bringup_timer(next, TCP_TIMEOUT); 3005 send_tcp_connect(next); 3006 } else 3007 check_next_lookup(l); 3008 return; 3009 } 3010 if (keep_open) { 3011 if (keep != NULL) 3012 isc_socket_detach(&keep); 3013 isc_socket_attach(query->sock, &keep); 3014 keepaddr = query->sockaddr; 3015 } 3016 launch_next_query(query, ISC_TRUE); 3017 isc_event_free(&event); 3018 } 3019 3020 /*% 3021 * Check if the ongoing XFR needs more data before it's complete, using 3022 * the semantics of IXFR and AXFR protocols. Much of the complexity of 3023 * this routine comes from determining when an IXFR is complete. 3024 * ISC_FALSE means more data is on the way, and the recv has been issued. 3025 */ 3026 static isc_boolean_t 3027 check_for_more_data(dig_query_t *query, dns_message_t *msg, 3028 isc_socketevent_t *sevent) 3029 { 3030 dns_rdataset_t *rdataset = NULL; 3031 dns_rdata_t rdata = DNS_RDATA_INIT; 3032 dns_rdata_soa_t soa; 3033 uint32_t ixfr_serial = query->lookup->ixfr_serial, serial; 3034 isc_result_t result; 3035 isc_boolean_t ixfr = query->lookup->rdtype == dns_rdatatype_ixfr; 3036 isc_boolean_t axfr = query->lookup->rdtype == dns_rdatatype_axfr; 3037 3038 if (ixfr) 3039 axfr = query->ixfr_axfr; 3040 3041 debug("check_for_more_data()"); 3042 3043 /* 3044 * By the time we're in this routine, we know we're doing 3045 * either an AXFR or IXFR. If there's no second_rr_type, 3046 * then we don't yet know which kind of answer we got back 3047 * from the server. Here, we're going to walk through the 3048 * rr's in the message, acting as necessary whenever we hit 3049 * an SOA rr. 3050 */ 3051 3052 query->msg_count++; 3053 query->byte_count += sevent->n; 3054 result = dns_message_firstname(msg, DNS_SECTION_ANSWER); 3055 if (result != ISC_R_SUCCESS) { 3056 puts("; Transfer failed."); 3057 return (ISC_TRUE); 3058 } 3059 do { 3060 dns_name_t *name; 3061 name = NULL; 3062 dns_message_currentname(msg, DNS_SECTION_ANSWER, 3063 &name); 3064 for (rdataset = ISC_LIST_HEAD(name->list); 3065 rdataset != NULL; 3066 rdataset = ISC_LIST_NEXT(rdataset, link)) { 3067 result = dns_rdataset_first(rdataset); 3068 if (result != ISC_R_SUCCESS) 3069 continue; 3070 do { 3071 query->rr_count++; 3072 dns_rdata_reset(&rdata); 3073 dns_rdataset_current(rdataset, &rdata); 3074 /* 3075 * If this is the first rr, make sure 3076 * it's an SOA 3077 */ 3078 if ((!query->first_soa_rcvd) && 3079 (rdata.type != dns_rdatatype_soa)) { 3080 puts("; Transfer failed. " 3081 "Didn't start with SOA answer."); 3082 return (ISC_TRUE); 3083 } 3084 if ((!query->second_rr_rcvd) && 3085 (rdata.type != dns_rdatatype_soa)) { 3086 query->second_rr_rcvd = ISC_TRUE; 3087 query->second_rr_serial = 0; 3088 debug("got the second rr as nonsoa"); 3089 axfr = query->ixfr_axfr = ISC_TRUE; 3090 goto next_rdata; 3091 } 3092 3093 /* 3094 * If the record is anything except an SOA 3095 * now, just continue on... 3096 */ 3097 if (rdata.type != dns_rdatatype_soa) 3098 goto next_rdata; 3099 3100 /* Now we have an SOA. Work with it. */ 3101 debug("got an SOA"); 3102 result = dns_rdata_tostruct_soa(&rdata, &soa); 3103 check_result(result, "dns_rdata_tostruct_soa"); 3104 serial = soa.serial; 3105 dns_rdata_freestruct_soa(&soa); 3106 if (!query->first_soa_rcvd) { 3107 query->first_soa_rcvd = ISC_TRUE; 3108 query->first_rr_serial = serial; 3109 debug("this is the first serial %u", 3110 serial); 3111 if (ixfr && isc_serial_ge(ixfr_serial, 3112 serial)) { 3113 debug("got up to date " 3114 "response"); 3115 goto doexit; 3116 } 3117 goto next_rdata; 3118 } 3119 if (axfr) { 3120 debug("doing axfr, got second SOA"); 3121 goto doexit; 3122 } 3123 if (!query->second_rr_rcvd) { 3124 if (query->first_rr_serial == serial) { 3125 debug("doing ixfr, got " 3126 "empty zone"); 3127 goto doexit; 3128 } 3129 debug("this is the second serial %u", 3130 serial); 3131 query->second_rr_rcvd = ISC_TRUE; 3132 query->second_rr_serial = serial; 3133 goto next_rdata; 3134 } 3135 /* 3136 * If we get to this point, we're doing an 3137 * IXFR and have to start really looking 3138 * at serial numbers. 3139 */ 3140 if (query->first_rr_serial == serial) { 3141 debug("got a match for ixfr"); 3142 if (!query->first_repeat_rcvd) { 3143 query->first_repeat_rcvd = 3144 ISC_TRUE; 3145 goto next_rdata; 3146 } 3147 debug("done with ixfr"); 3148 goto doexit; 3149 } 3150 debug("meaningless soa %u", serial); 3151 next_rdata: 3152 result = dns_rdataset_next(rdataset); 3153 } while (result == ISC_R_SUCCESS); 3154 } 3155 result = dns_message_nextname(msg, DNS_SECTION_ANSWER); 3156 } while (result == ISC_R_SUCCESS); 3157 launch_next_query(query, ISC_FALSE); 3158 return (ISC_FALSE); 3159 doexit: 3160 dighost_received(sevent->n, &sevent->address, query); 3161 return (ISC_TRUE); 3162 } 3163 3164 static void 3165 process_sit(dig_lookup_t *l, dns_message_t *msg, 3166 isc_buffer_t *optbuf, size_t optlen) 3167 { 3168 char bb[256]; 3169 isc_buffer_t hexbuf; 3170 size_t len; 3171 const unsigned char *sit; 3172 isc_boolean_t copysit; 3173 isc_result_t result; 3174 3175 if (l->sitvalue != NULL) { 3176 isc_buffer_init(&hexbuf, bb, sizeof(bb)); 3177 result = isc_hex_decodestring(l->sitvalue, &hexbuf); 3178 check_result(result, "isc_hex_decodestring"); 3179 sit = isc_buffer_base(&hexbuf); 3180 len = isc_buffer_usedlength(&hexbuf); 3181 copysit = ISC_FALSE; 3182 } else { 3183 sit = cookie; 3184 len = sizeof(cookie); 3185 copysit = ISC_TRUE; 3186 } 3187 3188 INSIST(msg->sitok == 0 && msg->sitbad == 0); 3189 if (optlen >= len && optlen >= 8U) { 3190 if (timingsafe_bcmp(isc_buffer_current(optbuf), sit, 8) == 0) { 3191 msg->sitok = 1; 3192 } else { 3193 printf(";; Warning: SIT client cookie mismatch\n"); 3194 msg->sitbad = 1; 3195 copysit = ISC_FALSE; 3196 } 3197 } else { 3198 printf(";; Warning: SIT bad token (too short)\n"); 3199 msg->sitbad = 1; 3200 copysit = ISC_FALSE; 3201 } 3202 if (copysit) { 3203 isc_region_t r; 3204 3205 r.base = isc_buffer_current(optbuf); 3206 r.length = (unsigned int)optlen; 3207 isc_buffer_init(&hexbuf, sitvalue, sizeof(sitvalue)); 3208 result = isc_hex_totext(&r, 2, "", &hexbuf); 3209 check_result(result, "isc_hex_totext"); 3210 if (isc_buffer_availablelength(&hexbuf) > 0) { 3211 isc_buffer_putuint8(&hexbuf, 0); 3212 l->sitvalue = sitvalue; 3213 } 3214 } 3215 isc_buffer_forward(optbuf, (unsigned int)optlen); 3216 } 3217 3218 static void 3219 process_opt(dig_lookup_t *l, dns_message_t *msg) { 3220 dns_rdata_t rdata; 3221 isc_result_t result; 3222 isc_buffer_t optbuf; 3223 uint16_t optcode, optlen; 3224 dns_rdataset_t *opt = msg->opt; 3225 isc_boolean_t seen_cookie = ISC_FALSE; 3226 3227 result = dns_rdataset_first(opt); 3228 if (result == ISC_R_SUCCESS) { 3229 dns_rdata_init(&rdata); 3230 dns_rdataset_current(opt, &rdata); 3231 isc_buffer_init(&optbuf, rdata.data, rdata.length); 3232 isc_buffer_add(&optbuf, rdata.length); 3233 while (isc_buffer_remaininglength(&optbuf) >= 4) { 3234 optcode = isc_buffer_getuint16(&optbuf); 3235 optlen = isc_buffer_getuint16(&optbuf); 3236 switch (optcode) { 3237 case DNS_OPT_COOKIE: 3238 /* 3239 * Only process the first cookie option. 3240 */ 3241 if (seen_cookie) { 3242 isc_buffer_forward(&optbuf, optlen); 3243 break; 3244 } 3245 process_sit(l, msg, &optbuf, optlen); 3246 seen_cookie = ISC_TRUE; 3247 break; 3248 default: 3249 isc_buffer_forward(&optbuf, optlen); 3250 break; 3251 } 3252 } 3253 } 3254 } 3255 3256 static int 3257 ednsvers(dns_rdataset_t *opt) { 3258 return ((opt->ttl >> 16) & 0xff); 3259 } 3260 3261 /*% 3262 * Event handler for recv complete. Perform whatever actions are necessary, 3263 * based on the specifics of the user's request. 3264 */ 3265 static void 3266 recv_done(isc_task_t *task, isc_event_t *event) { 3267 isc_socketevent_t *sevent = NULL; 3268 dig_query_t *query = NULL; 3269 isc_buffer_t *b = NULL; 3270 dns_message_t *msg = NULL; 3271 isc_result_t result; 3272 dig_lookup_t *n, *l; 3273 isc_boolean_t docancel = ISC_FALSE; 3274 isc_boolean_t match = ISC_TRUE; 3275 unsigned int parseflags; 3276 dns_messageid_t id; 3277 unsigned int msgflags; 3278 int newedns; 3279 3280 UNUSED(task); 3281 INSIST(!free_now); 3282 3283 debug("recv_done()"); 3284 3285 recvcount--; 3286 debug("recvcount=%d", recvcount); 3287 INSIST(recvcount >= 0); 3288 3289 query = event->ev_arg; 3290 clock_gettime(CLOCK_MONOTONIC, &query->time_recv); 3291 debug("lookup=%p, query=%p", query->lookup, query); 3292 3293 l = query->lookup; 3294 3295 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); 3296 sevent = (isc_socketevent_t *)event; 3297 3298 b = ISC_LIST_HEAD(sevent->bufferlist); 3299 INSIST(b == &query->recvbuf); 3300 ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); 3301 3302 if ((l->tcp_mode) && (query->timer != NULL)) 3303 isc_timer_touch(query->timer); 3304 if ((!l->pending && !l->ns_search_only) || cancel_now) { 3305 debug("no longer pending. Got %s", 3306 isc_result_totext(sevent->result)); 3307 query->waiting_connect = ISC_FALSE; 3308 3309 isc_event_free(&event); 3310 clear_query(query); 3311 check_next_lookup(l); 3312 return; 3313 } 3314 3315 if (sevent->result != ISC_R_SUCCESS) { 3316 if (sevent->result == ISC_R_CANCELED) { 3317 debug("in recv cancel handler"); 3318 query->waiting_connect = ISC_FALSE; 3319 } else { 3320 printf(";; communications error: %s\n", 3321 isc_result_totext(sevent->result)); 3322 if (keep != NULL) 3323 isc_socket_detach(&keep); 3324 isc_socket_detach(&query->sock); 3325 sockcount--; 3326 debug("sockcount=%d", sockcount); 3327 INSIST(sockcount >= 0); 3328 } 3329 if (sevent->result == ISC_R_EOF && l->eoferr == 0U) { 3330 n = requeue_lookup(l, ISC_TRUE); 3331 n->eoferr++; 3332 } 3333 isc_event_free(&event); 3334 clear_query(query); 3335 cancel_lookup(l); 3336 check_next_lookup(l); 3337 return; 3338 } 3339 3340 if (!l->tcp_mode && 3341 !isc_sockaddr_compare(&sevent->address, &query->sockaddr, 3342 ISC_SOCKADDR_CMPADDR| 3343 ISC_SOCKADDR_CMPPORT| 3344 ISC_SOCKADDR_CMPSCOPE| 3345 ISC_SOCKADDR_CMPSCOPEZERO)) { 3346 char buf1[ISC_SOCKADDR_FORMATSIZE]; 3347 char buf2[ISC_SOCKADDR_FORMATSIZE]; 3348 isc_sockaddr_t any; 3349 3350 if (isc_sockaddr_pf(&query->sockaddr) == AF_INET) 3351 isc_sockaddr_any(&any); 3352 else 3353 isc_sockaddr_any6(&any); 3354 3355 /* 3356 * We don't expect a match when the packet is 3357 * sent to 0.0.0.0, :: or to a multicast addresses. 3358 * XXXMPA broadcast needs to be handled here as well. 3359 */ 3360 if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) && 3361 !isc_sockaddr_ismulticast(&query->sockaddr)) || 3362 isc_sockaddr_getport(&query->sockaddr) != 3363 isc_sockaddr_getport(&sevent->address)) { 3364 isc_sockaddr_format(&sevent->address, buf1, 3365 sizeof(buf1)); 3366 isc_sockaddr_format(&query->sockaddr, buf2, 3367 sizeof(buf2)); 3368 printf(";; reply from unexpected source: %s," 3369 " expected %s\n", buf1, buf2); 3370 match = ISC_FALSE; 3371 } 3372 } 3373 3374 result = dns_message_peekheader(b, &id, &msgflags); 3375 if (result != ISC_R_SUCCESS || l->sendmsg->id != id) { 3376 match = ISC_FALSE; 3377 if (l->tcp_mode) { 3378 isc_boolean_t fail = ISC_TRUE; 3379 if (result == ISC_R_SUCCESS) { 3380 if (!query->first_soa_rcvd || 3381 query->warn_id) 3382 printf(";; %s: ID mismatch: " 3383 "expected ID %u, got %u\n", 3384 query->first_soa_rcvd ? 3385 "WARNING" : "ERROR", 3386 l->sendmsg->id, id); 3387 if (query->first_soa_rcvd) 3388 fail = ISC_FALSE; 3389 query->warn_id = ISC_FALSE; 3390 } else 3391 printf(";; ERROR: short " 3392 "(< header size) message\n"); 3393 if (fail) { 3394 isc_event_free(&event); 3395 clear_query(query); 3396 cancel_lookup(l); 3397 check_next_lookup(l); 3398 return; 3399 } 3400 match = ISC_TRUE; 3401 } else if (result == ISC_R_SUCCESS) 3402 printf(";; Warning: ID mismatch: " 3403 "expected ID %u, got %u\n", l->sendmsg->id, id); 3404 else 3405 printf(";; Warning: short " 3406 "(< header size) message received\n"); 3407 } 3408 3409 if (result == ISC_R_SUCCESS && (msgflags & DNS_MESSAGEFLAG_QR) == 0) 3410 printf(";; Warning: query response not set\n"); 3411 3412 if (!match) 3413 goto udp_mismatch; 3414 3415 result = dns_message_create(DNS_MESSAGE_INTENTPARSE, &msg); 3416 check_result(result, "dns_message_create"); 3417 3418 if (tsigkey != NULL) { 3419 if (l->querysig == NULL) { 3420 debug("getting initial querysig"); 3421 result = dns_message_getquerytsig(l->sendmsg, 3422 &l->querysig); 3423 check_result(result, "dns_message_getquerytsig"); 3424 } 3425 result = dns_message_setquerytsig(msg, l->querysig); 3426 check_result(result, "dns_message_setquerytsig"); 3427 result = dns_message_settsigkey(msg, tsigkey); 3428 check_result(result, "dns_message_settsigkey"); 3429 msg->tsigctx = l->tsigctx; 3430 l->tsigctx = NULL; 3431 if (l->msgcounter != 0) 3432 msg->tcp_continuation = 1; 3433 l->msgcounter++; 3434 } 3435 3436 debug("before parse starts"); 3437 parseflags = 0; 3438 if (l->besteffort) { 3439 parseflags |= DNS_MESSAGEPARSE_BESTEFFORT; 3440 parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION; 3441 } 3442 result = dns_message_parse(msg, b, parseflags); 3443 if (result == DNS_R_RECOVERABLE) { 3444 printf(";; Warning: Message parser reports malformed " 3445 "message packet.\n"); 3446 result = ISC_R_SUCCESS; 3447 } 3448 if (result != ISC_R_SUCCESS) { 3449 printf(";; Got bad packet: %s\n", isc_result_totext(result)); 3450 hex_dump(b); 3451 query->waiting_connect = ISC_FALSE; 3452 dns_message_destroy(&msg); 3453 isc_event_free(&event); 3454 clear_query(query); 3455 cancel_lookup(l); 3456 check_next_lookup(l); 3457 return; 3458 } 3459 if (msg->counts[DNS_SECTION_QUESTION] != 0) { 3460 match = ISC_TRUE; 3461 for (result = dns_message_firstname(msg, DNS_SECTION_QUESTION); 3462 result == ISC_R_SUCCESS && match; 3463 result = dns_message_nextname(msg, DNS_SECTION_QUESTION)) { 3464 dns_name_t *name = NULL; 3465 dns_rdataset_t *rdataset; 3466 3467 dns_message_currentname(msg, DNS_SECTION_QUESTION, 3468 &name); 3469 for (rdataset = ISC_LIST_HEAD(name->list); 3470 rdataset != NULL; 3471 rdataset = ISC_LIST_NEXT(rdataset, link)) { 3472 if (l->rdtype != rdataset->type || 3473 l->rdclass != rdataset->rdclass || 3474 !dns_name_equal(l->name, name)) { 3475 char namestr[DNS_NAME_FORMATSIZE]; 3476 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3477 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 3478 dns_name_format(name, namestr, 3479 sizeof(namestr)); 3480 dns_rdatatype_format(rdataset->type, 3481 typebuf, 3482 sizeof(typebuf)); 3483 dns_rdataclass_format(rdataset->rdclass, 3484 classbuf, 3485 sizeof(classbuf)); 3486 printf(";; Question section mismatch: " 3487 "got %s/%s/%s\n", 3488 namestr, typebuf, classbuf); 3489 match = ISC_FALSE; 3490 } 3491 } 3492 } 3493 if (!match) { 3494 dns_message_destroy(&msg); 3495 if (l->tcp_mode) { 3496 isc_event_free(&event); 3497 clear_query(query); 3498 cancel_lookup(l); 3499 check_next_lookup(l); 3500 return; 3501 } else 3502 goto udp_mismatch; 3503 } 3504 } 3505 if (msg->rcode == dns_rcode_badvers && msg->opt != NULL && 3506 (newedns = ednsvers(msg->opt)) < l->edns && l->ednsneg) { 3507 /* 3508 * Add minimum EDNS version required checks here if needed. 3509 */ 3510 if (l->comments) 3511 printf(";; BADVERS, retrying with EDNS version %u.\n", 3512 (unsigned int)newedns); 3513 l->edns = newedns; 3514 n = requeue_lookup(l, ISC_TRUE); 3515 if (l->trace && l->trace_root) 3516 n->rdtype = l->qrdtype; 3517 dns_message_destroy(&msg); 3518 isc_event_free(&event); 3519 clear_query(query); 3520 cancel_lookup(l); 3521 check_next_lookup(l); 3522 return; 3523 } 3524 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 && 3525 !l->ignore && !l->tcp_mode) { 3526 if (l->sitvalue == NULL && l->sit && msg->opt != NULL) 3527 process_opt(l, msg); 3528 if (l->comments) 3529 printf(";; Truncated, retrying in TCP mode.\n"); 3530 n = requeue_lookup(l, ISC_TRUE); 3531 n->tcp_mode = ISC_TRUE; 3532 if (l->trace && l->trace_root) 3533 n->rdtype = l->qrdtype; 3534 dns_message_destroy(&msg); 3535 isc_event_free(&event); 3536 clear_query(query); 3537 cancel_lookup(l); 3538 check_next_lookup(l); 3539 return; 3540 } 3541 if ((msg->rcode == dns_rcode_servfail && !l->servfail_stops) || 3542 (check_ra && (msg->flags & DNS_MESSAGEFLAG_RA) == 0 && l->recurse)) 3543 { 3544 dig_query_t *next = ISC_LIST_NEXT(query, link); 3545 if (l->current_query == query) 3546 l->current_query = NULL; 3547 if (next != NULL) { 3548 debug("sending query %p\n", next); 3549 if (l->tcp_mode) 3550 send_tcp_connect(next); 3551 else 3552 send_udp(next); 3553 } 3554 /* 3555 * If our query is at the head of the list and there 3556 * is no next, we're the only one left, so fall 3557 * through to print the message. 3558 */ 3559 if ((ISC_LIST_HEAD(l->q) != query) || 3560 (ISC_LIST_NEXT(query, link) != NULL)) { 3561 if (l->comments) 3562 printf(";; Got %s from %s, " 3563 "trying next server\n", 3564 msg->rcode == dns_rcode_servfail ? 3565 "SERVFAIL reply" : 3566 "recursion not available", 3567 query->servname); 3568 clear_query(query); 3569 check_next_lookup(l); 3570 dns_message_destroy(&msg); 3571 isc_event_free(&event); 3572 return; 3573 } 3574 } 3575 3576 if (tsigkey != NULL) { 3577 result = dns_tsig_verify(&query->recvbuf, msg); 3578 if (result != ISC_R_SUCCESS) { 3579 printf(";; Couldn't verify signature: %s\n", 3580 isc_result_totext(result)); 3581 validated = ISC_FALSE; 3582 } 3583 l->tsigctx = msg->tsigctx; 3584 msg->tsigctx = NULL; 3585 if (l->querysig != NULL) { 3586 debug("freeing querysig buffer %p", l->querysig); 3587 isc_buffer_free(&l->querysig); 3588 } 3589 result = dns_message_getquerytsig(msg, &l->querysig); 3590 check_result(result,"dns_message_getquerytsig"); 3591 } 3592 3593 extrabytes = isc_buffer_remaininglength(b); 3594 3595 debug("after parse"); 3596 if (l->doing_xfr && l->xfr_q == NULL) { 3597 l->xfr_q = query; 3598 /* 3599 * Once we are in the XFR message, increase 3600 * the timeout to much longer, so brief network 3601 * outages won't cause the XFR to abort 3602 */ 3603 if (timeout != INT_MAX && query->timer != NULL) { 3604 unsigned int local_timeout; 3605 3606 if (timeout == 0) { 3607 if (l->tcp_mode) 3608 local_timeout = TCP_TIMEOUT * 4; 3609 else 3610 local_timeout = UDP_TIMEOUT * 4; 3611 } else { 3612 if (timeout < (INT_MAX / 4)) 3613 local_timeout = timeout * 4; 3614 else 3615 local_timeout = INT_MAX; 3616 } 3617 debug("have local timeout of %d", local_timeout); 3618 l->interval.tv_sec = local_timeout; 3619 l->interval.tv_nsec = 0; 3620 result = isc_timer_reset(query->timer, 3621 &l->interval, 3622 ISC_FALSE); 3623 check_result(result, "isc_timer_reset"); 3624 } 3625 } 3626 3627 if (l->sitvalue != NULL) { 3628 if (msg->opt == NULL) 3629 printf(";; expected opt record in response\n"); 3630 else 3631 process_opt(l, msg); 3632 } else if (l->sit && msg->opt != NULL) 3633 process_opt(l, msg); 3634 3635 if (!l->doing_xfr || l->xfr_q == query) { 3636 if (msg->rcode == dns_rcode_nxdomain && 3637 (l->origin != NULL || l->need_search)) { 3638 if (!next_origin(query->lookup) || showsearch) { 3639 dighost_printmessage(query, msg, ISC_TRUE); 3640 dighost_received(b->used, &sevent->address, query); 3641 } 3642 } else if (!l->trace && !l->ns_search_only) { 3643 dighost_printmessage(query, msg, ISC_TRUE); 3644 } else if (l->trace) { 3645 int nl = 0; 3646 int count = msg->counts[DNS_SECTION_ANSWER]; 3647 3648 debug("in TRACE code"); 3649 if (!l->ns_search_only) 3650 dighost_printmessage(query, msg, ISC_TRUE); 3651 3652 l->rdtype = l->qrdtype; 3653 if (l->trace_root || (l->ns_search_only && count > 0)) { 3654 if (!l->trace_root) 3655 l->rdtype = dns_rdatatype_soa; 3656 nl = followup_lookup(msg, query, 3657 DNS_SECTION_ANSWER); 3658 l->trace_root = ISC_FALSE; 3659 } else if (count == 0) 3660 nl = followup_lookup(msg, query, 3661 DNS_SECTION_AUTHORITY); 3662 if (nl == 0) 3663 docancel = ISC_TRUE; 3664 } else { 3665 debug("in NSSEARCH code"); 3666 3667 if (l->trace_root) { 3668 /* 3669 * This is the initial NS query. 3670 */ 3671 int nl; 3672 3673 l->rdtype = dns_rdatatype_soa; 3674 nl = followup_lookup(msg, query, 3675 DNS_SECTION_ANSWER); 3676 if (nl == 0) 3677 docancel = ISC_TRUE; 3678 l->trace_root = ISC_FALSE; 3679 usesearch = ISC_FALSE; 3680 } else 3681 dighost_printmessage(query, msg, ISC_TRUE); 3682 } 3683 } 3684 3685 if (l->pending) 3686 debug("still pending."); 3687 if (l->doing_xfr) { 3688 if (query != l->xfr_q) { 3689 dns_message_destroy(&msg); 3690 isc_event_free(&event); 3691 query->waiting_connect = ISC_FALSE; 3692 return; 3693 } 3694 if (!docancel) 3695 docancel = check_for_more_data(query, msg, sevent); 3696 if (docancel) { 3697 dns_message_destroy(&msg); 3698 clear_query(query); 3699 cancel_lookup(l); 3700 check_next_lookup(l); 3701 } 3702 } else { 3703 3704 if (msg->rcode == dns_rcode_noerror || l->origin == NULL) { 3705 3706 dighost_received(b->used, &sevent->address, query); 3707 } 3708 3709 if (!query->lookup->ns_search_only) 3710 query->lookup->pending = ISC_FALSE; 3711 if (!query->lookup->ns_search_only || 3712 query->lookup->trace_root || docancel) { 3713 dns_message_destroy(&msg); 3714 3715 cancel_lookup(l); 3716 } 3717 clear_query(query); 3718 check_next_lookup(l); 3719 } 3720 if (msg != NULL) { 3721 dns_message_destroy(&msg); 3722 } 3723 isc_event_free(&event); 3724 return; 3725 3726 udp_mismatch: 3727 isc_buffer_invalidate(&query->recvbuf); 3728 isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); 3729 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link); 3730 result = isc_socket_recvv(query->sock, &query->recvlist, 1, 3731 global_task, recv_done, query); 3732 check_result(result, "isc_socket_recvv"); 3733 recvcount++; 3734 isc_event_free(&event); 3735 return; 3736 } 3737 3738 /*% 3739 * Turn a name into an address, using system-supplied routines. This is 3740 * used in looking up server names, etc... and needs to use system-supplied 3741 * routines, since they may be using a non-DNS system for these lookups. 3742 */ 3743 isc_result_t 3744 get_address(char *host, in_port_t myport, isc_sockaddr_t *sockaddr) { 3745 int count; 3746 isc_result_t result; 3747 3748 result = get_addresses(host, myport, sockaddr, 1, &count); 3749 if (result != ISC_R_SUCCESS) 3750 return (result); 3751 3752 INSIST(count == 1); 3753 3754 return (ISC_R_SUCCESS); 3755 } 3756 3757 int 3758 getaddresses(dig_lookup_t *lookup, const char *host, isc_result_t *resultp) { 3759 isc_result_t result; 3760 isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES]; 3761 isc_netaddr_t netaddr; 3762 int count, i; 3763 dig_server_t *srv; 3764 char tmp[ISC_NETADDR_FORMATSIZE]; 3765 3766 result = get_addresses(host, 0, sockaddrs, 3767 DIG_MAX_ADDRESSES, &count); 3768 if (resultp != NULL) 3769 *resultp = result; 3770 if (result != ISC_R_SUCCESS) { 3771 if (resultp == NULL) 3772 fatal("couldn't get address for '%s': %s", 3773 host, isc_result_totext(result)); 3774 return (0); 3775 } 3776 3777 for (i = 0; i < count; i++) { 3778 isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]); 3779 isc_netaddr_format(&netaddr, tmp, sizeof(tmp)); 3780 srv = make_server(tmp, host); 3781 ISC_LIST_APPEND(lookup->my_server_list, srv, link); 3782 } 3783 3784 return (count); 3785 } 3786 3787 /*% 3788 * Initiate either a TCP or UDP lookup 3789 */ 3790 void 3791 do_lookup(dig_lookup_t *lookup) { 3792 dig_query_t *query; 3793 3794 REQUIRE(lookup != NULL); 3795 3796 debug("do_lookup()"); 3797 lookup->pending = ISC_TRUE; 3798 query = ISC_LIST_HEAD(lookup->q); 3799 if (query != NULL) { 3800 if (lookup->tcp_mode) 3801 send_tcp_connect(query); 3802 else 3803 send_udp(query); 3804 } 3805 } 3806 3807 /*% 3808 * Start everything in action upon task startup. 3809 */ 3810 void 3811 onrun_callback(isc_task_t *task, isc_event_t *event) { 3812 UNUSED(task); 3813 3814 isc_event_free(&event); 3815 start_lookup(); 3816 } 3817 3818 /*% 3819 * Make everything on the lookup queue go away. Mainly used by the 3820 * SIGINT handler. 3821 */ 3822 void 3823 cancel_all(void) { 3824 dig_lookup_t *l, *n; 3825 dig_query_t *q, *nq; 3826 3827 debug("cancel_all()"); 3828 3829 if (free_now) { 3830 return; 3831 } 3832 cancel_now = ISC_TRUE; 3833 if (current_lookup != NULL) { 3834 for (q = ISC_LIST_HEAD(current_lookup->q); 3835 q != NULL; 3836 q = nq) 3837 { 3838 nq = ISC_LIST_NEXT(q, link); 3839 debug("canceling pending query %p, belonging to %p", 3840 q, current_lookup); 3841 if (q->sock != NULL) 3842 isc_socket_cancel(q->sock, NULL, 3843 ISC_SOCKCANCEL_ALL); 3844 else 3845 clear_query(q); 3846 } 3847 for (q = ISC_LIST_HEAD(current_lookup->connecting); 3848 q != NULL; 3849 q = nq) 3850 { 3851 nq = ISC_LIST_NEXT(q, clink); 3852 debug("canceling connecting query %p, belonging to %p", 3853 q, current_lookup); 3854 if (q->sock != NULL) 3855 isc_socket_cancel(q->sock, NULL, 3856 ISC_SOCKCANCEL_ALL); 3857 else 3858 clear_query(q); 3859 } 3860 } 3861 l = ISC_LIST_HEAD(lookup_list); 3862 while (l != NULL) { 3863 n = ISC_LIST_NEXT(l, link); 3864 ISC_LIST_DEQUEUE(lookup_list, l, link); 3865 try_clear_lookup(l); 3866 l = n; 3867 } 3868 } 3869 3870 /*% 3871 * Destroy all of the libs we are using, and get everything ready for a 3872 * clean shutdown. 3873 */ 3874 void 3875 destroy_libs(void) { 3876 3877 if (keep != NULL) 3878 isc_socket_detach(&keep); 3879 debug("destroy_libs()"); 3880 if (global_task != NULL) { 3881 debug("freeing task"); 3882 isc_task_detach(&global_task); 3883 } 3884 /* 3885 * The taskmgr_destroy() call blocks until all events are cleared 3886 * from the task. 3887 */ 3888 if (taskmgr != NULL) { 3889 debug("freeing taskmgr"); 3890 isc_taskmgr_destroy(&taskmgr); 3891 } 3892 REQUIRE(sockcount == 0); 3893 REQUIRE(recvcount == 0); 3894 REQUIRE(sendcount == 0); 3895 3896 INSIST(ISC_LIST_HEAD(lookup_list) == NULL); 3897 INSIST(current_lookup == NULL); 3898 INSIST(!free_now); 3899 3900 free_now = ISC_TRUE; 3901 3902 lwres_conf_clear(lwconf); 3903 3904 flush_server_list(); 3905 3906 clear_searchlist(); 3907 3908 if (socketmgr != NULL) { 3909 debug("freeing socketmgr"); 3910 isc_socketmgr_destroy(&socketmgr); 3911 } 3912 if (timermgr != NULL) { 3913 debug("freeing timermgr"); 3914 isc_timermgr_destroy(&timermgr); 3915 } 3916 if (tsigkey != NULL) { 3917 debug("freeing key %p", tsigkey); 3918 dns_tsigkey_detach(&tsigkey); 3919 } 3920 if (namebuf != NULL) 3921 isc_buffer_free(&namebuf); 3922 3923 if (is_dst_up) { 3924 debug("destroy DST lib"); 3925 dst_lib_destroy(); 3926 is_dst_up = ISC_FALSE; 3927 } 3928 3929 debug("Removing log context"); 3930 isc_log_destroy(&lctx); 3931 3932 } 3933 3934