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