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.37 2020/12/21 11:41:08 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 { "199.9.14.201", AF_INET }, /* b.root-servers.net */ 120 { "2001:500:200::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 { 26946, "DEVICEID" }, /* Brian Hartvigsen */ 1278 }; 1279 1280 #define N_EDNS_OPTNAMES (sizeof(optnames) / sizeof(optnames[0])) 1281 1282 void 1283 save_opt(dig_lookup_t *lookup, char *code, char *value) { 1284 isc_result_t result; 1285 uint32_t num = 0; 1286 isc_buffer_t b; 1287 int found = 0; 1288 unsigned int i; 1289 const char *errstr; 1290 1291 if (lookup->ednsoptscnt >= EDNSOPT_OPTIONS) 1292 fatal("too many ednsopts"); 1293 1294 for (i = 0; i < N_EDNS_OPTNAMES; i++) { 1295 if (strcasecmp(code, optnames[i].name) == 0) { 1296 num = optnames[i].code; 1297 found = 1; 1298 break; 1299 } 1300 } 1301 1302 if (!found) { 1303 num = strtonum(code, 0, 65535, &errstr); 1304 if (errstr != NULL) 1305 fatal("edns code point is %s: '%s'", errstr, code); 1306 } 1307 1308 if (lookup->ednsopts == NULL) { 1309 cloneopts(lookup, NULL); 1310 } 1311 1312 if (lookup->ednsopts[lookup->ednsoptscnt].value != NULL) 1313 free(lookup->ednsopts[lookup->ednsoptscnt].value); 1314 1315 lookup->ednsopts[lookup->ednsoptscnt].code = num; 1316 lookup->ednsopts[lookup->ednsoptscnt].length = 0; 1317 lookup->ednsopts[lookup->ednsoptscnt].value = NULL; 1318 1319 if (value != NULL) { 1320 char *buf; 1321 buf = malloc(strlen(value)/2 + 1); 1322 if (buf == NULL) 1323 fatal("out of memory"); 1324 isc_buffer_init(&b, buf, (unsigned int) strlen(value)/2 + 1); 1325 result = isc_hex_decodestring(value, &b); 1326 check_result(result, "isc_hex_decodestring"); 1327 lookup->ednsopts[lookup->ednsoptscnt].value = 1328 isc_buffer_base(&b); 1329 lookup->ednsopts[lookup->ednsoptscnt].length = 1330 isc_buffer_usedlength(&b); 1331 } 1332 1333 lookup->ednsoptscnt++; 1334 } 1335 1336 /*% 1337 * Add EDNS0 option record to a message. Currently, the only supported 1338 * options are UDP buffer size, the DO bit, and EDNS options 1339 * (e.g., NSID, SIT, client-subnet) 1340 */ 1341 static void 1342 add_opt(dns_message_t *msg, uint16_t udpsize, uint16_t edns, 1343 unsigned int flags, dns_ednsopt_t *opts, size_t count) 1344 { 1345 dns_rdataset_t *rdataset = NULL; 1346 isc_result_t result; 1347 1348 debug("add_opt()"); 1349 result = dns_message_buildopt(msg, &rdataset, edns, udpsize, flags, 1350 opts, count); 1351 check_result(result, "dns_message_buildopt"); 1352 result = dns_message_setopt(msg, rdataset); 1353 check_result(result, "dns_message_setopt"); 1354 } 1355 1356 /*% 1357 * Add a question section to a message, asking for the specified name, 1358 * type, and class. 1359 */ 1360 static void 1361 add_question(dns_message_t *message, dns_name_t *name, 1362 dns_rdataclass_t rdclass, dns_rdatatype_t rdtype) 1363 { 1364 dns_rdataset_t *rdataset; 1365 isc_result_t result; 1366 1367 debug("add_question()"); 1368 rdataset = NULL; 1369 result = dns_message_gettemprdataset(message, &rdataset); 1370 check_result(result, "dns_message_gettemprdataset()"); 1371 dns_rdataset_makequestion(rdataset, rdclass, rdtype); 1372 ISC_LIST_APPEND(name->list, rdataset, link); 1373 } 1374 1375 /*% 1376 * Check if we're done with all the queued lookups, which is true iff 1377 * all sockets, sends, and recvs are accounted for (counters == 0), 1378 * and the lookup list is empty. 1379 * If we are done, pass control back out to dighost_shutdown() (which is 1380 * part of dig.c, host.c, or nslookup.c) to either shutdown the system as 1381 * a whole or reseed the lookup list. 1382 */ 1383 static void 1384 check_if_done(void) { 1385 debug("check_if_done()"); 1386 debug("list %s", ISC_LIST_EMPTY(lookup_list) ? "empty" : "full"); 1387 if (ISC_LIST_EMPTY(lookup_list) && current_lookup == NULL && 1388 sendcount == 0) { 1389 INSIST(sockcount == 0); 1390 INSIST(recvcount == 0); 1391 debug("shutting down"); 1392 dighost_shutdown(); 1393 } 1394 } 1395 1396 /*% 1397 * Clear out a query when we're done with it. WARNING: This routine 1398 * WILL invalidate the query pointer. 1399 */ 1400 static void 1401 clear_query(dig_query_t *query) { 1402 dig_lookup_t *lookup; 1403 1404 REQUIRE(query != NULL); 1405 1406 debug("clear_query(%p)", query); 1407 1408 if (query->timer != NULL) 1409 isc_timer_detach(&query->timer); 1410 lookup = query->lookup; 1411 1412 if (lookup->current_query == query) 1413 lookup->current_query = NULL; 1414 1415 if (ISC_LINK_LINKED(query, link)) 1416 ISC_LIST_UNLINK(lookup->q, query, link); 1417 if (ISC_LINK_LINKED(query, clink)) 1418 ISC_LIST_UNLINK(lookup->connecting, query, clink); 1419 if (ISC_LINK_LINKED(&query->recvbuf, link)) 1420 ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf, 1421 link); 1422 if (ISC_LINK_LINKED(&query->lengthbuf, link)) 1423 ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf, 1424 link); 1425 INSIST(query->recvspace != NULL); 1426 1427 if (query->sock != NULL) { 1428 isc_socket_detach(&query->sock); 1429 sockcount--; 1430 debug("sockcount=%d", sockcount); 1431 } 1432 free(query->recvspace); 1433 isc_buffer_invalidate(&query->recvbuf); 1434 isc_buffer_invalidate(&query->lengthbuf); 1435 if (query->waiting_senddone) 1436 query->pending_free = 1; 1437 else 1438 free(query); 1439 } 1440 1441 /*% 1442 * Try and clear out a lookup if we're done with it. Return 1 if 1443 * the lookup was successfully cleared. If 1 is returned, the 1444 * lookup pointer has been invalidated. 1445 */ 1446 static int 1447 try_clear_lookup(dig_lookup_t *lookup) { 1448 dig_query_t *q; 1449 1450 REQUIRE(lookup != NULL); 1451 1452 debug("try_clear_lookup(%p)", lookup); 1453 1454 if (ISC_LIST_HEAD(lookup->q) != NULL || 1455 ISC_LIST_HEAD(lookup->connecting) != NULL) 1456 { 1457 if (debugging) { 1458 q = ISC_LIST_HEAD(lookup->q); 1459 while (q != NULL) { 1460 debug("query to %s still pending", q->servname); 1461 q = ISC_LIST_NEXT(q, link); 1462 } 1463 1464 q = ISC_LIST_HEAD(lookup->connecting); 1465 while (q != NULL) { 1466 debug("query to %s still connecting", 1467 q->servname); 1468 q = ISC_LIST_NEXT(q, clink); 1469 } 1470 } 1471 return (0); 1472 } 1473 1474 /* 1475 * At this point, we know there are no queries on the lookup, 1476 * so can make it go away also. 1477 */ 1478 destroy_lookup(lookup); 1479 return (1); 1480 } 1481 1482 void 1483 destroy_lookup(dig_lookup_t *lookup) { 1484 dig_server_t *s; 1485 void *ptr; 1486 1487 debug("destroy"); 1488 s = ISC_LIST_HEAD(lookup->my_server_list); 1489 while (s != NULL) { 1490 debug("freeing server %p belonging to %p", s, lookup); 1491 ptr = s; 1492 s = ISC_LIST_NEXT(s, link); 1493 ISC_LIST_DEQUEUE(lookup->my_server_list, 1494 (dig_server_t *)ptr, link); 1495 free(ptr); 1496 } 1497 if (lookup->sendmsg != NULL) 1498 dns_message_destroy(&lookup->sendmsg); 1499 if (lookup->querysig != NULL) { 1500 debug("freeing buffer %p", lookup->querysig); 1501 isc_buffer_free(&lookup->querysig); 1502 } 1503 if (lookup->sendspace != NULL) 1504 free(lookup->sendspace); 1505 1506 if (lookup->tsigctx != NULL) 1507 dst_context_destroy(&lookup->tsigctx); 1508 1509 if (lookup->ecs_addr != NULL) 1510 free(lookup->ecs_addr); 1511 1512 if (lookup->ednsopts != NULL) { 1513 size_t i; 1514 for (i = 0; i < EDNSOPT_OPTIONS; i++) { 1515 if (lookup->ednsopts[i].value != NULL) 1516 free(lookup->ednsopts[i].value); 1517 } 1518 free(lookup->ednsopts); 1519 } 1520 1521 free(lookup); 1522 } 1523 1524 /*% 1525 * If we can, start the next lookup in the queue running. 1526 * This assumes that the lookup on the head of the queue hasn't been 1527 * started yet. It also removes the lookup from the head of the queue, 1528 * setting the current_lookup pointer pointing to it. 1529 */ 1530 void 1531 start_lookup(void) { 1532 debug("start_lookup()"); 1533 if (cancel_now) 1534 return; 1535 1536 /* 1537 * If there's a current lookup running, we really shouldn't get 1538 * here. 1539 */ 1540 INSIST(current_lookup == NULL); 1541 1542 current_lookup = ISC_LIST_HEAD(lookup_list); 1543 /* 1544 * Put the current lookup somewhere so cancel_all can find it 1545 */ 1546 if (current_lookup != NULL) { 1547 ISC_LIST_DEQUEUE(lookup_list, current_lookup, link); 1548 if (setup_lookup(current_lookup)) 1549 do_lookup(current_lookup); 1550 else if (next_origin(current_lookup)) 1551 check_next_lookup(current_lookup); 1552 } else { 1553 check_if_done(); 1554 } 1555 } 1556 1557 /*% 1558 * If we can, clear the current lookup and start the next one running. 1559 * This calls try_clear_lookup, so may invalidate the lookup pointer. 1560 */ 1561 static void 1562 check_next_lookup(dig_lookup_t *lookup) { 1563 1564 INSIST(!free_now); 1565 1566 debug("check_next_lookup(%p)", lookup); 1567 1568 if (ISC_LIST_HEAD(lookup->q) != NULL) { 1569 debug("still have a worker"); 1570 return; 1571 } 1572 if (try_clear_lookup(lookup)) { 1573 current_lookup = NULL; 1574 start_lookup(); 1575 } 1576 } 1577 1578 /*% 1579 * Create and queue a new lookup as a followup to the current lookup, 1580 * based on the supplied message and section. This is used in trace and 1581 * name server search modes to start a new lookup using servers from 1582 * NS records in a reply. Returns the number of followup lookups made. 1583 */ 1584 static int 1585 followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) 1586 { 1587 dig_lookup_t *lookup = NULL; 1588 dig_server_t *srv = NULL; 1589 dns_rdataset_t *rdataset = NULL; 1590 dns_rdata_t rdata = DNS_RDATA_INIT; 1591 dns_name_t *name = NULL; 1592 isc_result_t result; 1593 int success = 0; 1594 int numLookups = 0; 1595 int num; 1596 isc_result_t lresult, addresses_result; 1597 char bad_namestr[DNS_NAME_FORMATSIZE]; 1598 dns_name_t *domain; 1599 int horizontal = 0, bad = 0; 1600 1601 INSIST(!free_now); 1602 1603 debug("following up %s", query->lookup->textname); 1604 1605 addresses_result = ISC_R_SUCCESS; 1606 bad_namestr[0] = '\0'; 1607 for (result = dns_message_firstname(msg, section); 1608 result == ISC_R_SUCCESS; 1609 result = dns_message_nextname(msg, section)) { 1610 name = NULL; 1611 dns_message_currentname(msg, section, &name); 1612 1613 if (section == DNS_SECTION_AUTHORITY) { 1614 rdataset = NULL; 1615 result = dns_message_findtype(name, dns_rdatatype_soa, 1616 0, &rdataset); 1617 if (result == ISC_R_SUCCESS) 1618 return (0); 1619 } 1620 rdataset = NULL; 1621 result = dns_message_findtype(name, dns_rdatatype_ns, 0, 1622 &rdataset); 1623 if (result != ISC_R_SUCCESS) 1624 continue; 1625 1626 debug("found NS set"); 1627 1628 if (query->lookup->trace && !query->lookup->trace_root) { 1629 dns_namereln_t namereln; 1630 unsigned int nlabels; 1631 int order; 1632 1633 domain = dns_fixedname_name(&query->lookup->fdomain); 1634 namereln = dns_name_fullcompare(name, domain, 1635 &order, &nlabels); 1636 if (namereln == dns_namereln_equal) { 1637 if (!horizontal) 1638 printf(";; BAD (HORIZONTAL) REFERRAL\n"); 1639 horizontal = 1; 1640 } else if (namereln != dns_namereln_subdomain) { 1641 if (!bad) 1642 printf(";; BAD REFERRAL\n"); 1643 bad = 1; 1644 continue; 1645 } 1646 } 1647 1648 for (result = dns_rdataset_first(rdataset); 1649 result == ISC_R_SUCCESS; 1650 result = dns_rdataset_next(rdataset)) { 1651 char namestr[DNS_NAME_FORMATSIZE]; 1652 dns_rdata_ns_t ns; 1653 1654 if (query->lookup->trace_root && 1655 query->lookup->nsfound >= MXSERV) 1656 break; 1657 1658 dns_rdataset_current(rdataset, &rdata); 1659 1660 query->lookup->nsfound++; 1661 result = dns_rdata_tostruct_ns(&rdata, &ns); 1662 check_result(result, "dns_rdata_tostruct_ns"); 1663 dns_name_format(&ns.name, namestr, sizeof(namestr)); 1664 dns_rdata_freestruct_ns(&ns); 1665 1666 /* Initialize lookup if we've not yet */ 1667 debug("found NS %s", namestr); 1668 if (!success) { 1669 success = 1; 1670 lookup_counter++; 1671 lookup = requeue_lookup(query->lookup, 1672 0); 1673 cancel_lookup(query->lookup); 1674 lookup->doing_xfr = 0; 1675 if (!lookup->trace_root && 1676 section == DNS_SECTION_ANSWER) 1677 lookup->trace = 0; 1678 else 1679 lookup->trace = query->lookup->trace; 1680 lookup->ns_search_only = 1681 query->lookup->ns_search_only; 1682 lookup->trace_root = 0; 1683 if (lookup->ns_search_only) 1684 lookup->recurse = 0; 1685 domain = dns_fixedname_name(&lookup->fdomain); 1686 dns_name_copy(name, domain, NULL); 1687 } 1688 debug("adding server %s", namestr); 1689 num = getaddresses(lookup, namestr, &lresult); 1690 if (lresult != ISC_R_SUCCESS) { 1691 printf("couldn't get address for '%s': %s\n", 1692 namestr, isc_result_totext(lresult)); 1693 if (addresses_result == ISC_R_SUCCESS) { 1694 addresses_result = lresult; 1695 strlcpy(bad_namestr, namestr, 1696 sizeof(bad_namestr)); 1697 } 1698 } 1699 numLookups += num; 1700 dns_rdata_reset(&rdata); 1701 } 1702 } 1703 if (numLookups == 0 && addresses_result != ISC_R_SUCCESS) { 1704 fatal("couldn't get address for '%s': %s", 1705 bad_namestr, isc_result_totext(result)); 1706 } 1707 1708 if (lookup == NULL && 1709 section == DNS_SECTION_ANSWER && 1710 (query->lookup->trace || query->lookup->ns_search_only)) 1711 return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY)); 1712 1713 /* 1714 * Randomize the order the nameserver will be tried. 1715 */ 1716 if (numLookups > 1) { 1717 uint32_t i, j; 1718 dig_serverlist_t my_server_list; 1719 dig_server_t *next; 1720 1721 ISC_LIST_INIT(my_server_list); 1722 1723 i = numLookups; 1724 for (srv = ISC_LIST_HEAD(lookup->my_server_list); 1725 srv != NULL; 1726 srv = ISC_LIST_HEAD(lookup->my_server_list)) { 1727 INSIST(i > 0); 1728 j = arc4random_uniform(i); 1729 next = ISC_LIST_NEXT(srv, link); 1730 while (j-- > 0 && next != NULL) { 1731 srv = next; 1732 next = ISC_LIST_NEXT(srv, link); 1733 } 1734 ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link); 1735 ISC_LIST_APPEND(my_server_list, srv, link); 1736 i--; 1737 } 1738 ISC_LIST_APPENDLIST(lookup->my_server_list, 1739 my_server_list, link); 1740 } 1741 1742 return (numLookups); 1743 } 1744 1745 /*% 1746 * Create and queue a new lookup using the next origin from the search 1747 * list, read in setup_system(). 1748 * 1749 * Return 1 iff there was another searchlist entry. 1750 */ 1751 static int 1752 next_origin(dig_lookup_t *oldlookup) { 1753 dig_lookup_t *newlookup; 1754 dig_searchlist_t *search; 1755 dns_fixedname_t fixed; 1756 dns_name_t *name; 1757 isc_result_t result; 1758 1759 INSIST(!free_now); 1760 1761 debug("next_origin()"); 1762 debug("following up %s", oldlookup->textname); 1763 1764 if (!usesearch) 1765 /* 1766 * We're not using a search list, so don't even think 1767 * about finding the next entry. 1768 */ 1769 return (0); 1770 1771 /* 1772 * Check for a absolute name or ndots being met. 1773 */ 1774 dns_fixedname_init(&fixed); 1775 name = dns_fixedname_name(&fixed); 1776 result = dns_name_fromstring2(name, oldlookup->textname, NULL, 0); 1777 if (result == ISC_R_SUCCESS && 1778 (dns_name_isabsolute(name) || 1779 (int)dns_name_countlabels(name) > ndots)) 1780 return (0); 1781 1782 if (oldlookup->origin == NULL && !oldlookup->need_search) 1783 /* 1784 * Then we just did rootorg; there's nothing left. 1785 */ 1786 return (0); 1787 if (oldlookup->origin == NULL && oldlookup->need_search) { 1788 newlookup = requeue_lookup(oldlookup, 1); 1789 newlookup->origin = ISC_LIST_HEAD(search_list); 1790 newlookup->need_search = 0; 1791 } else { 1792 search = ISC_LIST_NEXT(oldlookup->origin, link); 1793 if (search == NULL && oldlookup->done_as_is) 1794 return (0); 1795 newlookup = requeue_lookup(oldlookup, 1); 1796 newlookup->origin = search; 1797 } 1798 cancel_lookup(oldlookup); 1799 return (1); 1800 } 1801 1802 /*% 1803 * Insert an SOA record into the sendmessage in a lookup. Used for 1804 * creating IXFR queries. 1805 */ 1806 static void 1807 insert_soa(dig_lookup_t *lookup) { 1808 isc_result_t result; 1809 dns_rdata_soa_t soa; 1810 dns_rdata_t *rdata = NULL; 1811 dns_rdatalist_t *rdatalist = NULL; 1812 dns_rdataset_t *rdataset = NULL; 1813 dns_name_t *soaname = NULL; 1814 1815 debug("insert_soa()"); 1816 soa.serial = lookup->ixfr_serial; 1817 soa.refresh = 0; 1818 soa.retry = 0; 1819 soa.expire = 0; 1820 soa.minimum = 0; 1821 soa.common.rdclass = lookup->rdclass; 1822 soa.common.rdtype = dns_rdatatype_soa; 1823 1824 dns_name_init(&soa.origin, NULL); 1825 dns_name_init(&soa.contact, NULL); 1826 1827 dns_name_clone(dns_rootname, &soa.origin); 1828 dns_name_clone(dns_rootname, &soa.contact); 1829 1830 isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore, 1831 sizeof(lookup->rdatastore)); 1832 1833 result = dns_message_gettemprdata(lookup->sendmsg, &rdata); 1834 check_result(result, "dns_message_gettemprdata"); 1835 1836 result = dns_rdata_fromstruct_soa(rdata, lookup->rdclass, 1837 dns_rdatatype_soa, &soa, 1838 &lookup->rdatabuf); 1839 check_result(result, "isc_rdata_fromstruct_soa"); 1840 1841 result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist); 1842 check_result(result, "dns_message_gettemprdatalist"); 1843 1844 result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset); 1845 check_result(result, "dns_message_gettemprdataset"); 1846 1847 dns_rdatalist_init(rdatalist); 1848 rdatalist->type = dns_rdatatype_soa; 1849 rdatalist->rdclass = lookup->rdclass; 1850 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 1851 1852 dns_rdatalist_tordataset(rdatalist, rdataset); 1853 1854 result = dns_message_gettempname(lookup->sendmsg, &soaname); 1855 check_result(result, "dns_message_gettempname"); 1856 dns_name_init(soaname, NULL); 1857 dns_name_clone(lookup->name, soaname); 1858 ISC_LIST_INIT(soaname->list); 1859 ISC_LIST_APPEND(soaname->list, rdataset, link); 1860 dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY); 1861 } 1862 1863 static void 1864 compute_cookie(unsigned char *clientcookie, size_t len) { 1865 /* XXXMPA need to fix, should be per server. */ 1866 INSIST(len >= 8U); 1867 memmove(clientcookie, cookie_secret, 8); 1868 } 1869 1870 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 1871 static void 1872 populate_root_hints(void) 1873 { 1874 dig_server_t *newsrv; 1875 size_t i; 1876 1877 if (!ISC_LIST_EMPTY(root_hints_server_list)) 1878 return; 1879 1880 for (i = 0; i < nitems(root_hints); i++) { 1881 if (!have_ipv4 && root_hints[i].af == AF_INET) 1882 continue; 1883 if (!have_ipv6 && root_hints[i].af == AF_INET6) 1884 continue; 1885 newsrv = make_server(root_hints[i].ns, root_hints[i].ns); 1886 ISC_LINK_INIT(newsrv, link); 1887 ISC_LIST_ENQUEUE(root_hints_server_list, newsrv, link); 1888 } 1889 } 1890 #undef nitems 1891 1892 /*% 1893 * Setup the supplied lookup structure, making it ready to start sending 1894 * queries to servers. Create and initialize the message to be sent as 1895 * well as the query structures and buffer space for the replies. If the 1896 * server list is empty, clone it from the system default list. 1897 */ 1898 int 1899 setup_lookup(dig_lookup_t *lookup) { 1900 isc_result_t result; 1901 uint32_t id; 1902 unsigned int len; 1903 dig_server_t *serv; 1904 dig_query_t *query; 1905 isc_buffer_t b; 1906 dns_compress_t cctx; 1907 char store[MXNAME]; 1908 char ecsbuf[20]; 1909 char sitbuf[256]; 1910 1911 REQUIRE(lookup != NULL); 1912 INSIST(!free_now); 1913 1914 debug("setup_lookup(%p)", lookup); 1915 1916 result = dns_message_create(DNS_MESSAGE_INTENTRENDER, 1917 &lookup->sendmsg); 1918 check_result(result, "dns_message_create"); 1919 1920 if (lookup->new_search) { 1921 debug("resetting lookup counter."); 1922 lookup_counter = 0; 1923 } 1924 1925 if (ISC_LIST_EMPTY(lookup->my_server_list)) { 1926 if (lookup->trace && lookup->trace_root) { 1927 populate_root_hints(); 1928 clone_server_list(root_hints_server_list, 1929 &lookup->my_server_list); 1930 } else { 1931 debug("cloning server list"); 1932 clone_server_list(server_list, 1933 &lookup->my_server_list); 1934 } 1935 } 1936 result = dns_message_gettempname(lookup->sendmsg, &lookup->name); 1937 check_result(result, "dns_message_gettempname"); 1938 dns_name_init(lookup->name, NULL); 1939 1940 isc_buffer_init(&lookup->namebuf, lookup->name_space, 1941 sizeof(lookup->name_space)); 1942 isc_buffer_init(&lookup->onamebuf, lookup->oname_space, 1943 sizeof(lookup->oname_space)); 1944 1945 /* 1946 * If the name has too many dots, force the origin to be NULL 1947 * (which produces an absolute lookup). Otherwise, take the origin 1948 * we have if there's one in the struct already. If it's NULL, 1949 * take the first entry in the searchlist iff either usesearch 1950 * is TRUE or we got a domain line in the resolv.conf file. 1951 */ 1952 if (lookup->new_search) { 1953 if ((count_dots(lookup->textname) >= ndots) || !usesearch) { 1954 lookup->origin = NULL; /* Force abs lookup */ 1955 lookup->done_as_is = 1; 1956 lookup->need_search = usesearch; 1957 } else if (lookup->origin == NULL && usesearch) { 1958 lookup->origin = ISC_LIST_HEAD(search_list); 1959 lookup->need_search = 0; 1960 } 1961 } 1962 1963 if (lookup->origin != NULL) { 1964 debug("trying origin %s", lookup->origin->origin); 1965 result = dns_message_gettempname(lookup->sendmsg, 1966 &lookup->oname); 1967 check_result(result, "dns_message_gettempname"); 1968 dns_name_init(lookup->oname, NULL); 1969 /* XXX Helper funct to conv char* to name? */ 1970 len = (unsigned int) strlen(lookup->origin->origin); 1971 isc_buffer_init(&b, lookup->origin->origin, len); 1972 isc_buffer_add(&b, len); 1973 result = dns_name_fromtext(lookup->oname, &b, dns_rootname, 1974 0, &lookup->onamebuf); 1975 if (result != ISC_R_SUCCESS) { 1976 dns_message_puttempname(lookup->sendmsg, 1977 &lookup->name); 1978 dns_message_puttempname(lookup->sendmsg, 1979 &lookup->oname); 1980 fatal("'%s' is not in legal name syntax (%s)", 1981 lookup->origin->origin, 1982 isc_result_totext(result)); 1983 } 1984 if (lookup->trace && lookup->trace_root) { 1985 dns_name_clone(dns_rootname, lookup->name); 1986 } else { 1987 dns_fixedname_t fixed; 1988 dns_name_t *name; 1989 1990 dns_fixedname_init(&fixed); 1991 name = dns_fixedname_name(&fixed); 1992 len = (unsigned int) strlen(lookup->textname); 1993 isc_buffer_init(&b, lookup->textname, len); 1994 isc_buffer_add(&b, len); 1995 result = dns_name_fromtext(name, &b, NULL, 0, NULL); 1996 if (result == ISC_R_SUCCESS && 1997 !dns_name_isabsolute(name)) 1998 result = dns_name_concatenate(name, 1999 lookup->oname, 2000 lookup->name, 2001 &lookup->namebuf); 2002 else if (result == ISC_R_SUCCESS) 2003 result = dns_name_copy(name, lookup->name, 2004 &lookup->namebuf); 2005 if (result != ISC_R_SUCCESS) { 2006 dns_message_puttempname(lookup->sendmsg, 2007 &lookup->name); 2008 dns_message_puttempname(lookup->sendmsg, 2009 &lookup->oname); 2010 if (result == DNS_R_NAMETOOLONG) 2011 return (0); 2012 fatal("'%s' is not in legal name syntax (%s)", 2013 lookup->textname, 2014 isc_result_totext(result)); 2015 } 2016 } 2017 dns_message_puttempname(lookup->sendmsg, &lookup->oname); 2018 } else 2019 { 2020 debug("using root origin"); 2021 if (lookup->trace && lookup->trace_root) 2022 dns_name_clone(dns_rootname, lookup->name); 2023 else { 2024 len = (unsigned int) strlen(lookup->textname); 2025 isc_buffer_init(&b, lookup->textname, len); 2026 isc_buffer_add(&b, len); 2027 result = dns_name_fromtext(lookup->name, &b, 2028 dns_rootname, 0, 2029 &lookup->namebuf); 2030 } 2031 if (result != ISC_R_SUCCESS) { 2032 dns_message_puttempname(lookup->sendmsg, 2033 &lookup->name); 2034 fatal("'%s' is not a legal name " 2035 "(%s)", lookup->textname, 2036 isc_result_totext(result)); 2037 } 2038 } 2039 dns_name_format(lookup->name, store, sizeof(store)); 2040 dighost_trying(store, lookup); 2041 INSIST(dns_name_isabsolute(lookup->name)); 2042 2043 id = arc4random(); 2044 lookup->sendmsg->id = (unsigned short)id & 0xFFFF; 2045 lookup->sendmsg->opcode = lookup->opcode; 2046 lookup->msgcounter = 0; 2047 /* 2048 * If this is a trace request, completely disallow recursion, since 2049 * it's meaningless for traces. 2050 */ 2051 if (lookup->trace || (lookup->ns_search_only && !lookup->trace_root)) 2052 lookup->recurse = 0; 2053 2054 if (lookup->recurse && 2055 lookup->rdtype != dns_rdatatype_axfr && 2056 lookup->rdtype != dns_rdatatype_ixfr) { 2057 debug("recursive query"); 2058 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_RD; 2059 } 2060 2061 /* XXX aaflag */ 2062 if (lookup->aaonly) { 2063 debug("AA query"); 2064 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AA; 2065 } 2066 2067 if (lookup->adflag) { 2068 debug("AD query"); 2069 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AD; 2070 } 2071 2072 if (lookup->cdflag) { 2073 debug("CD query"); 2074 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_CD; 2075 } 2076 2077 dns_message_addname(lookup->sendmsg, lookup->name, 2078 DNS_SECTION_QUESTION); 2079 2080 if (lookup->trace && lookup->trace_root) { 2081 lookup->qrdtype = lookup->rdtype; 2082 lookup->rdtype = dns_rdatatype_ns; 2083 } 2084 2085 if ((lookup->rdtype == dns_rdatatype_axfr) || 2086 (lookup->rdtype == dns_rdatatype_ixfr)) { 2087 /* 2088 * Force TCP mode if we're doing an axfr. 2089 */ 2090 if (lookup->rdtype == dns_rdatatype_axfr) { 2091 lookup->doing_xfr = 1; 2092 lookup->tcp_mode = 1; 2093 } else if (lookup->tcp_mode) { 2094 lookup->doing_xfr = 1; 2095 } 2096 } 2097 2098 add_question(lookup->sendmsg, lookup->name, lookup->rdclass, 2099 lookup->rdtype); 2100 2101 /* add_soa */ 2102 if (lookup->rdtype == dns_rdatatype_ixfr) 2103 insert_soa(lookup); 2104 2105 /* XXX Insist this? */ 2106 lookup->tsigctx = NULL; 2107 lookup->querysig = NULL; 2108 if (tsigkey != NULL) { 2109 debug("initializing keys"); 2110 result = dns_message_settsigkey(lookup->sendmsg, tsigkey); 2111 check_result(result, "dns_message_settsigkey"); 2112 } 2113 2114 lookup->sendspace = malloc(COMMSIZE); 2115 if (lookup->sendspace == NULL) 2116 fatal("memory allocation failure"); 2117 2118 result = dns_compress_init(&cctx, -1); 2119 check_result(result, "dns_compress_init"); 2120 2121 debug("starting to render the message"); 2122 isc_buffer_init(&lookup->renderbuf, lookup->sendspace, COMMSIZE); 2123 result = dns_message_renderbegin(lookup->sendmsg, &cctx, 2124 &lookup->renderbuf); 2125 check_result(result, "dns_message_renderbegin"); 2126 if (lookup->udpsize > 0 || lookup->dnssec || 2127 lookup->edns > -1 || lookup->ecs_addr != NULL) 2128 { 2129 #define MAXOPTS (EDNSOPT_OPTIONS + DNS_EDNSOPTIONS) 2130 dns_ednsopt_t opts[MAXOPTS]; 2131 unsigned int flags; 2132 unsigned int i = 0; 2133 2134 if (lookup->udpsize == 0) 2135 lookup->udpsize = 4096; 2136 if (lookup->edns < 0) 2137 lookup->edns = 0; 2138 2139 if (lookup->nsid) { 2140 INSIST(i < MAXOPTS); 2141 opts[i].code = DNS_OPT_NSID; 2142 opts[i].length = 0; 2143 opts[i].value = NULL; 2144 i++; 2145 } 2146 2147 if (lookup->ecs_addr != NULL) { 2148 uint8_t addr[16]; 2149 uint16_t family; 2150 uint32_t plen; 2151 struct sockaddr *sa; 2152 struct sockaddr_in *sin; 2153 struct sockaddr_in6 *sin6; 2154 size_t addrl; 2155 2156 sa = (struct sockaddr *)lookup->ecs_addr; 2157 plen = lookup->ecs_plen; 2158 2159 /* Round up prefix len to a multiple of 8 */ 2160 addrl = (plen + 7) / 8; 2161 2162 INSIST(i < MAXOPTS); 2163 opts[i].code = DNS_OPT_CLIENT_SUBNET; 2164 opts[i].length = (uint16_t) addrl + 4; 2165 check_result(result, "isc_buffer_allocate"); 2166 2167 /* 2168 * XXXMUKS: According to RFC7871, "If there is 2169 * no ADDRESS set, i.e., SOURCE PREFIX-LENGTH is 2170 * set to 0, then FAMILY SHOULD be set to the 2171 * transport over which the query is sent." 2172 * 2173 * However, at this point we don't know what 2174 * transport(s) we'll be using, so we can't 2175 * set the value now. For now, we're using 2176 * IPv4 as the default the +subnet option 2177 * used an IPv4 prefix, or for +subnet=0, 2178 * and IPv6 if the +subnet option used an 2179 * IPv6 prefix. 2180 * 2181 * (For future work: preserve the offset into 2182 * the buffer where the family field is; 2183 * that way we can update it in send_udp() 2184 * or send_tcp_connect() once we know 2185 * what it outght to be.) 2186 */ 2187 switch (sa->sa_family) { 2188 case AF_UNSPEC: 2189 INSIST(plen == 0); 2190 family = 1; 2191 break; 2192 case AF_INET: 2193 INSIST(plen <= 32); 2194 family = 1; 2195 sin = (struct sockaddr_in *) sa; 2196 memmove(addr, &sin->sin_addr, addrl); 2197 break; 2198 case AF_INET6: 2199 INSIST(plen <= 128); 2200 family = 2; 2201 sin6 = (struct sockaddr_in6 *) sa; 2202 memmove(addr, &sin6->sin6_addr, addrl); 2203 break; 2204 default: 2205 INSIST(0); 2206 } 2207 2208 isc_buffer_init(&b, ecsbuf, sizeof(ecsbuf)); 2209 /* family */ 2210 isc_buffer_putuint16(&b, family); 2211 /* source prefix-length */ 2212 isc_buffer_putuint8(&b, plen); 2213 /* scope prefix-length */ 2214 isc_buffer_putuint8(&b, 0); 2215 2216 /* address */ 2217 if (addrl > 0) { 2218 /* Mask off last address byte */ 2219 if ((plen % 8) != 0) 2220 addr[addrl - 1] &= 2221 ~0U << (8 - (plen % 8)); 2222 isc_buffer_putmem(&b, addr, 2223 (unsigned)addrl); 2224 } 2225 2226 opts[i].value = (uint8_t *) ecsbuf; 2227 i++; 2228 } 2229 2230 if (lookup->sit) { 2231 INSIST(i < MAXOPTS); 2232 opts[i].code = DNS_OPT_COOKIE; 2233 if (lookup->sitvalue != NULL) { 2234 isc_buffer_init(&b, sitbuf, sizeof(sitbuf)); 2235 result = isc_hex_decodestring(lookup->sitvalue, 2236 &b); 2237 check_result(result, "isc_hex_decodestring"); 2238 opts[i].value = isc_buffer_base(&b); 2239 opts[i].length = isc_buffer_usedlength(&b); 2240 } else { 2241 compute_cookie(cookie, sizeof(cookie)); 2242 opts[i].length = 8; 2243 opts[i].value = cookie; 2244 } 2245 i++; 2246 } 2247 2248 if (lookup->expire) { 2249 INSIST(i < MAXOPTS); 2250 opts[i].code = DNS_OPT_EXPIRE; 2251 opts[i].length = 0; 2252 opts[i].value = NULL; 2253 i++; 2254 } 2255 2256 if (lookup->ednsoptscnt != 0) { 2257 INSIST(i + lookup->ednsoptscnt <= MAXOPTS); 2258 memmove(&opts[i], lookup->ednsopts, 2259 sizeof(dns_ednsopt_t) * lookup->ednsoptscnt); 2260 i += lookup->ednsoptscnt; 2261 } 2262 2263 flags = lookup->ednsflags; 2264 flags &= ~DNS_MESSAGEEXTFLAG_DO; 2265 if (lookup->dnssec) 2266 flags |= DNS_MESSAGEEXTFLAG_DO; 2267 add_opt(lookup->sendmsg, lookup->udpsize, 2268 lookup->edns, flags, opts, i); 2269 } 2270 2271 result = dns_message_rendersection(lookup->sendmsg, 2272 DNS_SECTION_QUESTION); 2273 check_result(result, "dns_message_rendersection"); 2274 result = dns_message_rendersection(lookup->sendmsg, 2275 DNS_SECTION_AUTHORITY); 2276 check_result(result, "dns_message_rendersection"); 2277 result = dns_message_renderend(lookup->sendmsg); 2278 check_result(result, "dns_message_renderend"); 2279 debug("done rendering"); 2280 2281 dns_compress_invalidate(&cctx); 2282 2283 /* 2284 * Force TCP mode if the request is larger than 512 bytes. 2285 */ 2286 if (isc_buffer_usedlength(&lookup->renderbuf) > 512) 2287 lookup->tcp_mode = 1; 2288 2289 lookup->pending = 0; 2290 2291 for (serv = ISC_LIST_HEAD(lookup->my_server_list); 2292 serv != NULL; 2293 serv = ISC_LIST_NEXT(serv, link)) { 2294 query = malloc(sizeof(dig_query_t)); 2295 if (query == NULL) 2296 fatal("memory allocation failure in %s:%d", 2297 __FILE__, __LINE__); 2298 debug("create query %p linked to lookup %p", 2299 query, lookup); 2300 query->lookup = lookup; 2301 query->timer = NULL; 2302 query->waiting_connect = 0; 2303 query->waiting_senddone = 0; 2304 query->pending_free = 0; 2305 query->recv_made = 0; 2306 query->first_pass = 1; 2307 query->first_soa_rcvd = 0; 2308 query->second_rr_rcvd = 0; 2309 query->first_repeat_rcvd = 0; 2310 query->warn_id = 1; 2311 query->timedout = 0; 2312 query->first_rr_serial = 0; 2313 query->second_rr_serial = 0; 2314 query->servname = serv->servername; 2315 query->userarg = serv->userarg; 2316 query->rr_count = 0; 2317 query->msg_count = 0; 2318 query->byte_count = 0; 2319 query->ixfr_axfr = 0; 2320 ISC_LIST_INIT(query->recvlist); 2321 ISC_LIST_INIT(query->lengthlist); 2322 query->sock = NULL; 2323 query->recvspace = malloc(COMMSIZE); 2324 if (query->recvspace == NULL) 2325 fatal("memory allocation failure"); 2326 2327 isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); 2328 isc_buffer_init(&query->lengthbuf, query->lengthspace, 2); 2329 isc_buffer_init(&query->slbuf, query->slspace, 2); 2330 query->sendbuf = lookup->renderbuf; 2331 2332 ISC_LINK_INIT(query, clink); 2333 ISC_LINK_INIT(query, link); 2334 ISC_LIST_ENQUEUE(lookup->q, query, link); 2335 } 2336 2337 /* XXX qrflag, print_query, etc... */ 2338 if (!ISC_LIST_EMPTY(lookup->q) && qr) { 2339 extrabytes = 0; 2340 dighost_printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg, 2341 1); 2342 } 2343 return (1); 2344 } 2345 2346 /*% 2347 * Event handler for send completion. Track send counter, and clear out 2348 * the query if the send was canceled. 2349 */ 2350 static void 2351 send_done(isc_task_t *_task, isc_event_t *event) { 2352 isc_socketevent_t *sevent = (isc_socketevent_t *)event; 2353 isc_buffer_t *b = NULL; 2354 dig_query_t *query, *next; 2355 dig_lookup_t *l; 2356 2357 REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); 2358 2359 UNUSED(_task); 2360 2361 debug("send_done()"); 2362 sendcount--; 2363 debug("sendcount=%d", sendcount); 2364 INSIST(sendcount >= 0); 2365 2366 for (b = ISC_LIST_HEAD(sevent->bufferlist); 2367 b != NULL; 2368 b = ISC_LIST_HEAD(sevent->bufferlist)) { 2369 ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); 2370 free(b); 2371 } 2372 2373 query = event->ev_arg; 2374 query->waiting_senddone = 0; 2375 l = query->lookup; 2376 2377 if (l->ns_search_only && !l->trace_root && !l->tcp_mode) { 2378 debug("sending next, since searching"); 2379 next = ISC_LIST_NEXT(query, link); 2380 if (next != NULL) 2381 send_udp(next); 2382 } 2383 2384 isc_event_free(&event); 2385 2386 if (query->pending_free) 2387 free(query); 2388 2389 check_if_done(); 2390 } 2391 2392 /*% 2393 * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding 2394 * IO sockets. The cancel handlers should take care of cleaning up the 2395 * query and lookup structures 2396 */ 2397 static void 2398 cancel_lookup(dig_lookup_t *lookup) { 2399 dig_query_t *query, *next; 2400 2401 debug("cancel_lookup()"); 2402 query = ISC_LIST_HEAD(lookup->q); 2403 while (query != NULL) { 2404 next = ISC_LIST_NEXT(query, link); 2405 if (query->sock != NULL) { 2406 isc_socket_cancel(query->sock, global_task, 2407 ISC_SOCKCANCEL_ALL); 2408 check_if_done(); 2409 } else { 2410 clear_query(query); 2411 } 2412 query = next; 2413 } 2414 lookup->pending = 0; 2415 lookup->retries = 0; 2416 } 2417 2418 static void 2419 bringup_timer(dig_query_t *query, unsigned int default_timeout) { 2420 dig_lookup_t *l; 2421 unsigned int local_timeout; 2422 isc_result_t result; 2423 2424 debug("bringup_timer()"); 2425 /* 2426 * If the timer already exists, that means we're calling this 2427 * a second time (for a retry). Don't need to recreate it, 2428 * just reset it. 2429 */ 2430 l = query->lookup; 2431 if (ISC_LINK_LINKED(query, link) && ISC_LIST_NEXT(query, link) != NULL) 2432 local_timeout = SERVER_TIMEOUT; 2433 else { 2434 if (timeout == 0) 2435 local_timeout = default_timeout; 2436 else 2437 local_timeout = timeout; 2438 } 2439 debug("have local timeout of %d", local_timeout); 2440 l->interval.tv_sec = local_timeout; 2441 l->interval.tv_nsec = 0; 2442 if (query->timer != NULL) 2443 isc_timer_detach(&query->timer); 2444 result = isc_timer_create(timermgr, 2445 &l->interval, global_task, connect_timeout, 2446 query, &query->timer); 2447 check_result(result, "isc_timer_create"); 2448 } 2449 2450 static void 2451 force_timeout(dig_query_t *query) { 2452 isc_event_t *event; 2453 2454 debug("force_timeout ()"); 2455 event = isc_event_allocate(query, ISC_TIMEREVENT_IDLE, 2456 connect_timeout, query, 2457 sizeof(isc_event_t)); 2458 if (event == NULL) { 2459 fatal("isc_event_allocate: %s", 2460 isc_result_totext(ISC_R_NOMEMORY)); 2461 } 2462 isc_task_send(global_task, &event); 2463 2464 /* 2465 * The timer may have expired if, for example, get_address() takes 2466 * long time and the timer was running on a different thread. 2467 * We need to cancel the possible timeout event not to confuse 2468 * ourselves due to the duplicate events. 2469 */ 2470 if (query->timer != NULL) 2471 isc_timer_detach(&query->timer); 2472 } 2473 2474 static void 2475 connect_done(isc_task_t *task, isc_event_t *event); 2476 2477 /*% 2478 * Unlike send_udp, this can't be called multiple times with the same 2479 * query. When we retry TCP, we requeue the whole lookup, which should 2480 * start anew. 2481 */ 2482 static void 2483 send_tcp_connect(dig_query_t *query) { 2484 isc_result_t result; 2485 dig_query_t *next; 2486 dig_lookup_t *l; 2487 2488 debug("send_tcp_connect(%p)", query); 2489 2490 l = query->lookup; 2491 query->waiting_connect = 1; 2492 query->lookup->current_query = query; 2493 result = get_address(query->servname, port, &query->sockaddr); 2494 if (result != ISC_R_SUCCESS) { 2495 /* 2496 * This servname doesn't have an address. Try the next server 2497 * by triggering an immediate 'timeout' (we lie, but the effect 2498 * is the same). 2499 */ 2500 force_timeout(query); 2501 return; 2502 } 2503 2504 if (specified_source && 2505 (isc_sockaddr_pf(&query->sockaddr) != 2506 isc_sockaddr_pf(&bind_address))) { 2507 printf(";; Skipping server %s, incompatible " 2508 "address family\n", query->servname); 2509 query->waiting_connect = 0; 2510 if (ISC_LINK_LINKED(query, link)) 2511 next = ISC_LIST_NEXT(query, link); 2512 else 2513 next = NULL; 2514 l = query->lookup; 2515 clear_query(query); 2516 if (next == NULL) { 2517 printf(";; No acceptable nameservers\n"); 2518 check_next_lookup(l); 2519 return; 2520 } 2521 send_tcp_connect(next); 2522 return; 2523 } 2524 2525 INSIST(query->sock == NULL); 2526 2527 if (keep != NULL && isc_sockaddr_equal(&keepaddr, &query->sockaddr)) { 2528 sockcount++; 2529 isc_socket_attach(keep, &query->sock); 2530 query->waiting_connect = 0; 2531 launch_next_query(query, 1); 2532 goto search; 2533 } 2534 2535 result = isc_socket_create(socketmgr, 2536 isc_sockaddr_pf(&query->sockaddr), 2537 isc_sockettype_tcp, &query->sock); 2538 check_result(result, "isc_socket_create"); 2539 sockcount++; 2540 debug("sockcount=%d", sockcount); 2541 if (specified_source) 2542 result = isc_socket_bind(query->sock, &bind_address, 2543 ISC_SOCKET_REUSEADDRESS); 2544 else { 2545 if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) && 2546 have_ipv4) 2547 isc_sockaddr_any(&bind_any); 2548 else 2549 isc_sockaddr_any6(&bind_any); 2550 result = isc_socket_bind(query->sock, &bind_any, 0); 2551 } 2552 check_result(result, "isc_socket_bind"); 2553 bringup_timer(query, TCP_TIMEOUT); 2554 result = isc_socket_connect(query->sock, &query->sockaddr, 2555 global_task, connect_done, query); 2556 check_result(result, "isc_socket_connect"); 2557 search: 2558 /* 2559 * If we're at the endgame of a nameserver search, we need to 2560 * immediately bring up all the queries. Do it here. 2561 */ 2562 if (l->ns_search_only && !l->trace_root) { 2563 debug("sending next, since searching"); 2564 if (ISC_LINK_LINKED(query, link)) { 2565 next = ISC_LIST_NEXT(query, link); 2566 ISC_LIST_DEQUEUE(l->q, query, link); 2567 } else 2568 next = NULL; 2569 ISC_LIST_ENQUEUE(l->connecting, query, clink); 2570 if (next != NULL) 2571 send_tcp_connect(next); 2572 } 2573 } 2574 2575 static isc_buffer_t * 2576 clone_buffer(isc_buffer_t *source) { 2577 isc_buffer_t *buffer; 2578 buffer = malloc(sizeof(*buffer)); 2579 if (buffer == NULL) 2580 fatal("memory allocation failure in %s:%d", 2581 __FILE__, __LINE__); 2582 *buffer = *source; 2583 return (buffer); 2584 } 2585 2586 /*% 2587 * Send a UDP packet to the remote nameserver, possible starting the 2588 * recv action as well. Also make sure that the timer is running and 2589 * is properly reset. 2590 */ 2591 static void 2592 send_udp(dig_query_t *query) { 2593 dig_lookup_t *l = NULL; 2594 isc_result_t result; 2595 isc_buffer_t *sendbuf; 2596 2597 debug("send_udp(%p)", query); 2598 2599 l = query->lookup; 2600 bringup_timer(query, UDP_TIMEOUT); 2601 l->current_query = query; 2602 debug("working on lookup %p, query %p", query->lookup, query); 2603 if (!query->recv_made) { 2604 /* XXX Check the sense of this, need assertion? */ 2605 query->waiting_connect = 0; 2606 result = get_address(query->servname, port, &query->sockaddr); 2607 if (result != ISC_R_SUCCESS) { 2608 /* This servname doesn't have an address. */ 2609 force_timeout(query); 2610 return; 2611 } 2612 2613 result = isc_socket_create(socketmgr, 2614 isc_sockaddr_pf(&query->sockaddr), 2615 isc_sockettype_udp, &query->sock); 2616 check_result(result, "isc_socket_create"); 2617 sockcount++; 2618 debug("sockcount=%d", sockcount); 2619 if (specified_source) { 2620 result = isc_socket_bind(query->sock, &bind_address, 2621 ISC_SOCKET_REUSEADDRESS); 2622 } else { 2623 isc_sockaddr_anyofpf(&bind_any, 2624 isc_sockaddr_pf(&query->sockaddr)); 2625 result = isc_socket_bind(query->sock, &bind_any, 0); 2626 } 2627 check_result(result, "isc_socket_bind"); 2628 2629 query->recv_made = 1; 2630 ISC_LINK_INIT(&query->recvbuf, link); 2631 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, 2632 link); 2633 debug("recving with lookup=%p, query=%p, sock=%p", 2634 query->lookup, query, query->sock); 2635 result = isc_socket_recvv(query->sock, &query->recvlist, 1, 2636 global_task, recv_done, query); 2637 check_result(result, "isc_socket_recvv"); 2638 recvcount++; 2639 debug("recvcount=%d", recvcount); 2640 } 2641 ISC_LIST_INIT(query->sendlist); 2642 sendbuf = clone_buffer(&query->sendbuf); 2643 ISC_LIST_ENQUEUE(query->sendlist, sendbuf, link); 2644 debug("sending a request"); 2645 clock_gettime(CLOCK_MONOTONIC, &query->time_sent); 2646 INSIST(query->sock != NULL); 2647 query->waiting_senddone = 1; 2648 result = isc_socket_sendtov2(query->sock, &query->sendlist, 2649 global_task, send_done, query, 2650 &query->sockaddr, NULL, 2651 ISC_SOCKFLAG_NORETRY); 2652 check_result(result, "isc_socket_sendtov"); 2653 sendcount++; 2654 } 2655 2656 /*% 2657 * IO timeout handler, used for both connect and recv timeouts. If 2658 * retries are still allowed, either resend the UDP packet or queue a 2659 * new TCP lookup. Otherwise, cancel the lookup. 2660 */ 2661 static void 2662 connect_timeout(isc_task_t *task, isc_event_t *event) { 2663 dig_lookup_t *l = NULL; 2664 dig_query_t *query = NULL, *cq; 2665 2666 UNUSED(task); 2667 REQUIRE(event->ev_type == ISC_TIMEREVENT_IDLE); 2668 2669 debug("connect_timeout()"); 2670 2671 query = event->ev_arg; 2672 l = query->lookup; 2673 isc_event_free(&event); 2674 2675 INSIST(!free_now); 2676 2677 if ((query != NULL) && (query->lookup->current_query != NULL) && 2678 ISC_LINK_LINKED(query->lookup->current_query, link) && 2679 (ISC_LIST_NEXT(query->lookup->current_query, link) != NULL)) { 2680 debug("trying next server..."); 2681 cq = query->lookup->current_query; 2682 if (!l->tcp_mode) 2683 send_udp(ISC_LIST_NEXT(cq, link)); 2684 else { 2685 if (query->sock != NULL) 2686 isc_socket_cancel(query->sock, NULL, 2687 ISC_SOCKCANCEL_ALL); 2688 send_tcp_connect(ISC_LIST_NEXT(cq, link)); 2689 } 2690 return; 2691 } 2692 2693 if (l->tcp_mode && query->sock != NULL) { 2694 query->timedout = 1; 2695 isc_socket_cancel(query->sock, NULL, ISC_SOCKCANCEL_ALL); 2696 } 2697 2698 if (l->retries > 1) { 2699 if (!l->tcp_mode) { 2700 l->retries--; 2701 debug("resending UDP request to first server"); 2702 send_udp(ISC_LIST_HEAD(l->q)); 2703 } else { 2704 debug("making new TCP request, %d tries left", 2705 l->retries); 2706 l->retries--; 2707 requeue_lookup(l, 1); 2708 cancel_lookup(l); 2709 check_next_lookup(l); 2710 } 2711 } else { 2712 if (!l->ns_search_only) { 2713 fputs(l->cmdline, stdout); 2714 printf(";; connection timed out; no servers could be " 2715 "reached\n"); 2716 } 2717 cancel_lookup(l); 2718 check_next_lookup(l); 2719 if (exitcode < 9) 2720 exitcode = 9; 2721 } 2722 } 2723 2724 /*% 2725 * Event handler for the TCP recv which gets the length header of TCP 2726 * packets. Start the next recv of length bytes. 2727 */ 2728 static void 2729 tcp_length_done(isc_task_t *task, isc_event_t *event) { 2730 isc_socketevent_t *sevent; 2731 isc_buffer_t *b = NULL; 2732 isc_result_t result; 2733 dig_query_t *query = NULL; 2734 dig_lookup_t *l, *n; 2735 uint16_t length; 2736 2737 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); 2738 INSIST(!free_now); 2739 2740 UNUSED(task); 2741 2742 debug("tcp_length_done()"); 2743 2744 sevent = (isc_socketevent_t *)event; 2745 query = event->ev_arg; 2746 2747 recvcount--; 2748 INSIST(recvcount >= 0); 2749 2750 b = ISC_LIST_HEAD(sevent->bufferlist); 2751 INSIST(b == &query->lengthbuf); 2752 ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); 2753 2754 if (sevent->result == ISC_R_CANCELED) { 2755 isc_event_free(&event); 2756 l = query->lookup; 2757 clear_query(query); 2758 check_next_lookup(l); 2759 return; 2760 } 2761 if (sevent->result != ISC_R_SUCCESS) { 2762 char sockstr[ISC_SOCKADDR_FORMATSIZE]; 2763 isc_sockaddr_format(&query->sockaddr, sockstr, 2764 sizeof(sockstr)); 2765 printf(";; communications error to %s: %s\n", 2766 sockstr, isc_result_totext(sevent->result)); 2767 if (keep != NULL) 2768 isc_socket_detach(&keep); 2769 l = query->lookup; 2770 isc_socket_detach(&query->sock); 2771 sockcount--; 2772 debug("sockcount=%d", sockcount); 2773 INSIST(sockcount >= 0); 2774 if (sevent->result == ISC_R_EOF && l->eoferr == 0U) { 2775 n = requeue_lookup(l, 1); 2776 n->eoferr++; 2777 } 2778 isc_event_free(&event); 2779 clear_query(query); 2780 cancel_lookup(l); 2781 check_next_lookup(l); 2782 return; 2783 } 2784 length = isc_buffer_getuint16(b); 2785 if (length == 0) { 2786 isc_event_free(&event); 2787 launch_next_query(query, 0); 2788 return; 2789 } 2790 2791 /* 2792 * Even though the buffer was already init'ed, we need 2793 * to redo it now, to force the length we want. 2794 */ 2795 isc_buffer_invalidate(&query->recvbuf); 2796 isc_buffer_init(&query->recvbuf, query->recvspace, length); 2797 ENSURE(ISC_LIST_EMPTY(query->recvlist)); 2798 ISC_LINK_INIT(&query->recvbuf, link); 2799 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link); 2800 debug("recving with lookup=%p, query=%p", query->lookup, query); 2801 result = isc_socket_recvv(query->sock, &query->recvlist, length, task, 2802 recv_done, query); 2803 check_result(result, "isc_socket_recvv"); 2804 recvcount++; 2805 debug("resubmitted recv request with length %d, recvcount=%d", 2806 length, recvcount); 2807 isc_event_free(&event); 2808 } 2809 2810 /*% 2811 * For transfers that involve multiple recvs (XFR's in particular), 2812 * launch the next recv. 2813 */ 2814 static void 2815 launch_next_query(dig_query_t *query, int include_question) { 2816 isc_result_t result; 2817 dig_lookup_t *l; 2818 isc_buffer_t *buffer; 2819 2820 INSIST(!free_now); 2821 2822 debug("launch_next_query()"); 2823 2824 if (!query->lookup->pending) { 2825 debug("ignoring launch_next_query because !pending"); 2826 isc_socket_detach(&query->sock); 2827 sockcount--; 2828 debug("sockcount=%d", sockcount); 2829 INSIST(sockcount >= 0); 2830 query->waiting_connect = 0; 2831 l = query->lookup; 2832 clear_query(query); 2833 check_next_lookup(l); 2834 return; 2835 } 2836 2837 isc_buffer_clear(&query->slbuf); 2838 isc_buffer_clear(&query->lengthbuf); 2839 isc_buffer_putuint16(&query->slbuf, (uint16_t) query->sendbuf.used); 2840 ISC_LIST_INIT(query->sendlist); 2841 ISC_LINK_INIT(&query->slbuf, link); 2842 if (!query->first_soa_rcvd) { 2843 buffer = clone_buffer(&query->slbuf); 2844 ISC_LIST_ENQUEUE(query->sendlist, buffer, link); 2845 if (include_question) { 2846 buffer = clone_buffer(&query->sendbuf); 2847 ISC_LIST_ENQUEUE(query->sendlist, buffer, link); 2848 } 2849 } 2850 2851 ISC_LINK_INIT(&query->lengthbuf, link); 2852 ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link); 2853 2854 result = isc_socket_recvv(query->sock, &query->lengthlist, 0, 2855 global_task, tcp_length_done, query); 2856 check_result(result, "isc_socket_recvv"); 2857 recvcount++; 2858 debug("recvcount=%d", recvcount); 2859 if (!query->first_soa_rcvd) { 2860 debug("sending a request in launch_next_query"); 2861 clock_gettime(CLOCK_MONOTONIC, &query->time_sent); 2862 query->waiting_senddone = 1; 2863 result = isc_socket_sendv(query->sock, &query->sendlist, 2864 global_task, send_done, query); 2865 check_result(result, "isc_socket_sendv"); 2866 sendcount++; 2867 debug("sendcount=%d", sendcount); 2868 } 2869 query->waiting_connect = 0; 2870 return; 2871 } 2872 2873 /*% 2874 * Event handler for TCP connect complete. Make sure the connection was 2875 * successful, then pass into launch_next_query to actually send the 2876 * question. 2877 */ 2878 static void 2879 connect_done(isc_task_t *task, isc_event_t *event) { 2880 char sockstr[ISC_SOCKADDR_FORMATSIZE]; 2881 isc_socketevent_t *sevent = NULL; 2882 dig_query_t *query = NULL, *next; 2883 dig_lookup_t *l; 2884 2885 UNUSED(task); 2886 2887 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); 2888 INSIST(!free_now); 2889 2890 debug("connect_done()"); 2891 2892 sevent = (isc_socketevent_t *)event; 2893 query = sevent->ev_arg; 2894 2895 INSIST(query->waiting_connect); 2896 2897 query->waiting_connect = 0; 2898 2899 if (sevent->result == ISC_R_CANCELED) { 2900 debug("in cancel handler"); 2901 isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr)); 2902 if (query->timedout) 2903 printf(";; Connection to %s(%s) for %s failed: %s.\n", 2904 sockstr, query->servname, 2905 query->lookup->textname, 2906 isc_result_totext(ISC_R_TIMEDOUT)); 2907 isc_socket_detach(&query->sock); 2908 INSIST(sockcount > 0); 2909 sockcount--; 2910 debug("sockcount=%d", sockcount); 2911 query->waiting_connect = 0; 2912 isc_event_free(&event); 2913 l = query->lookup; 2914 clear_query(query); 2915 check_next_lookup(l); 2916 return; 2917 } 2918 if (sevent->result != ISC_R_SUCCESS) { 2919 2920 debug("unsuccessful connection: %s", 2921 isc_result_totext(sevent->result)); 2922 isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr)); 2923 if (sevent->result != ISC_R_CANCELED) 2924 printf(";; Connection to %s(%s) for %s failed: " 2925 "%s.\n", sockstr, 2926 query->servname, query->lookup->textname, 2927 isc_result_totext(sevent->result)); 2928 isc_socket_detach(&query->sock); 2929 INSIST(sockcount > 0); 2930 sockcount--; 2931 /* XXX Clean up exitcodes */ 2932 if (exitcode < 9) 2933 exitcode = 9; 2934 debug("sockcount=%d", sockcount); 2935 query->waiting_connect = 0; 2936 isc_event_free(&event); 2937 l = query->lookup; 2938 if ((l->current_query != NULL) && 2939 (ISC_LINK_LINKED(l->current_query, link))) 2940 next = ISC_LIST_NEXT(l->current_query, link); 2941 else 2942 next = NULL; 2943 clear_query(query); 2944 if (next != NULL) { 2945 bringup_timer(next, TCP_TIMEOUT); 2946 send_tcp_connect(next); 2947 } else 2948 check_next_lookup(l); 2949 return; 2950 } 2951 if (keep_open) { 2952 if (keep != NULL) 2953 isc_socket_detach(&keep); 2954 isc_socket_attach(query->sock, &keep); 2955 keepaddr = query->sockaddr; 2956 } 2957 launch_next_query(query, 1); 2958 isc_event_free(&event); 2959 } 2960 2961 /*% 2962 * Check if the ongoing XFR needs more data before it's complete, using 2963 * the semantics of IXFR and AXFR protocols. Much of the complexity of 2964 * this routine comes from determining when an IXFR is complete. 2965 * 0 means more data is on the way, and the recv has been issued. 2966 */ 2967 static int 2968 check_for_more_data(dig_query_t *query, dns_message_t *msg, 2969 isc_socketevent_t *sevent) 2970 { 2971 dns_rdataset_t *rdataset = NULL; 2972 dns_rdata_t rdata = DNS_RDATA_INIT; 2973 dns_rdata_soa_t soa; 2974 uint32_t ixfr_serial = query->lookup->ixfr_serial, serial; 2975 isc_result_t result; 2976 int ixfr = query->lookup->rdtype == dns_rdatatype_ixfr; 2977 int axfr = query->lookup->rdtype == dns_rdatatype_axfr; 2978 2979 if (ixfr) 2980 axfr = query->ixfr_axfr; 2981 2982 debug("check_for_more_data()"); 2983 2984 /* 2985 * By the time we're in this routine, we know we're doing 2986 * either an AXFR or IXFR. If there's no second_rr_type, 2987 * then we don't yet know which kind of answer we got back 2988 * from the server. Here, we're going to walk through the 2989 * rr's in the message, acting as necessary whenever we hit 2990 * an SOA rr. 2991 */ 2992 2993 query->msg_count++; 2994 query->byte_count += sevent->n; 2995 result = dns_message_firstname(msg, DNS_SECTION_ANSWER); 2996 if (result != ISC_R_SUCCESS) { 2997 puts("; Transfer failed."); 2998 return (1); 2999 } 3000 do { 3001 dns_name_t *name; 3002 name = NULL; 3003 dns_message_currentname(msg, DNS_SECTION_ANSWER, 3004 &name); 3005 for (rdataset = ISC_LIST_HEAD(name->list); 3006 rdataset != NULL; 3007 rdataset = ISC_LIST_NEXT(rdataset, link)) { 3008 result = dns_rdataset_first(rdataset); 3009 if (result != ISC_R_SUCCESS) 3010 continue; 3011 do { 3012 query->rr_count++; 3013 dns_rdata_reset(&rdata); 3014 dns_rdataset_current(rdataset, &rdata); 3015 /* 3016 * If this is the first rr, make sure 3017 * it's an SOA 3018 */ 3019 if ((!query->first_soa_rcvd) && 3020 (rdata.type != dns_rdatatype_soa)) { 3021 puts("; Transfer failed. " 3022 "Didn't start with SOA answer."); 3023 return (1); 3024 } 3025 if ((!query->second_rr_rcvd) && 3026 (rdata.type != dns_rdatatype_soa)) { 3027 query->second_rr_rcvd = 1; 3028 query->second_rr_serial = 0; 3029 debug("got the second rr as nonsoa"); 3030 axfr = query->ixfr_axfr = 1; 3031 goto next_rdata; 3032 } 3033 3034 /* 3035 * If the record is anything except an SOA 3036 * now, just continue on... 3037 */ 3038 if (rdata.type != dns_rdatatype_soa) 3039 goto next_rdata; 3040 3041 /* Now we have an SOA. Work with it. */ 3042 debug("got an SOA"); 3043 result = dns_rdata_tostruct_soa(&rdata, &soa); 3044 check_result(result, "dns_rdata_tostruct_soa"); 3045 serial = soa.serial; 3046 dns_rdata_freestruct_soa(&soa); 3047 if (!query->first_soa_rcvd) { 3048 query->first_soa_rcvd = 1; 3049 query->first_rr_serial = serial; 3050 debug("this is the first serial %u", 3051 serial); 3052 if (ixfr && isc_serial_ge(ixfr_serial, 3053 serial)) { 3054 debug("got up to date " 3055 "response"); 3056 goto doexit; 3057 } 3058 goto next_rdata; 3059 } 3060 if (axfr) { 3061 debug("doing axfr, got second SOA"); 3062 goto doexit; 3063 } 3064 if (!query->second_rr_rcvd) { 3065 if (query->first_rr_serial == serial) { 3066 debug("doing ixfr, got " 3067 "empty zone"); 3068 goto doexit; 3069 } 3070 debug("this is the second serial %u", 3071 serial); 3072 query->second_rr_rcvd = 1; 3073 query->second_rr_serial = serial; 3074 goto next_rdata; 3075 } 3076 /* 3077 * If we get to this point, we're doing an 3078 * IXFR and have to start really looking 3079 * at serial numbers. 3080 */ 3081 if (query->first_rr_serial == serial) { 3082 debug("got a match for ixfr"); 3083 if (!query->first_repeat_rcvd) { 3084 query->first_repeat_rcvd = 3085 1; 3086 goto next_rdata; 3087 } 3088 debug("done with ixfr"); 3089 goto doexit; 3090 } 3091 debug("meaningless soa %u", serial); 3092 next_rdata: 3093 result = dns_rdataset_next(rdataset); 3094 } while (result == ISC_R_SUCCESS); 3095 } 3096 result = dns_message_nextname(msg, DNS_SECTION_ANSWER); 3097 } while (result == ISC_R_SUCCESS); 3098 launch_next_query(query, 0); 3099 return (0); 3100 doexit: 3101 dighost_received(sevent->n, &sevent->address, query); 3102 return (1); 3103 } 3104 3105 static void 3106 process_sit(dig_lookup_t *l, dns_message_t *msg, 3107 isc_buffer_t *optbuf, size_t optlen) 3108 { 3109 char bb[256]; 3110 isc_buffer_t hexbuf; 3111 size_t len; 3112 const unsigned char *sit; 3113 int copysit; 3114 isc_result_t result; 3115 3116 if (l->sitvalue != NULL) { 3117 isc_buffer_init(&hexbuf, bb, sizeof(bb)); 3118 result = isc_hex_decodestring(l->sitvalue, &hexbuf); 3119 check_result(result, "isc_hex_decodestring"); 3120 sit = isc_buffer_base(&hexbuf); 3121 len = isc_buffer_usedlength(&hexbuf); 3122 copysit = 0; 3123 } else { 3124 sit = cookie; 3125 len = sizeof(cookie); 3126 copysit = 1; 3127 } 3128 3129 INSIST(msg->sitok == 0 && msg->sitbad == 0); 3130 if (optlen >= len && optlen >= 8U) { 3131 if (timingsafe_bcmp(isc_buffer_current(optbuf), sit, 8) == 0) { 3132 msg->sitok = 1; 3133 } else { 3134 printf(";; Warning: SIT client cookie mismatch\n"); 3135 msg->sitbad = 1; 3136 copysit = 0; 3137 } 3138 } else { 3139 printf(";; Warning: SIT bad token (too short)\n"); 3140 msg->sitbad = 1; 3141 copysit = 0; 3142 } 3143 if (copysit) { 3144 isc_region_t r; 3145 3146 r.base = isc_buffer_current(optbuf); 3147 r.length = (unsigned int)optlen; 3148 isc_buffer_init(&hexbuf, sitvalue, sizeof(sitvalue)); 3149 result = isc_hex_totext(&r, 2, "", &hexbuf); 3150 check_result(result, "isc_hex_totext"); 3151 if (isc_buffer_availablelength(&hexbuf) > 0) { 3152 isc_buffer_putuint8(&hexbuf, 0); 3153 l->sitvalue = sitvalue; 3154 } 3155 } 3156 isc_buffer_forward(optbuf, (unsigned int)optlen); 3157 } 3158 3159 static void 3160 process_opt(dig_lookup_t *l, dns_message_t *msg) { 3161 dns_rdata_t rdata; 3162 isc_result_t result; 3163 isc_buffer_t optbuf; 3164 uint16_t optcode, optlen; 3165 dns_rdataset_t *opt = msg->opt; 3166 int seen_cookie = 0; 3167 3168 result = dns_rdataset_first(opt); 3169 if (result == ISC_R_SUCCESS) { 3170 dns_rdata_init(&rdata); 3171 dns_rdataset_current(opt, &rdata); 3172 isc_buffer_init(&optbuf, rdata.data, rdata.length); 3173 isc_buffer_add(&optbuf, rdata.length); 3174 while (isc_buffer_remaininglength(&optbuf) >= 4) { 3175 optcode = isc_buffer_getuint16(&optbuf); 3176 optlen = isc_buffer_getuint16(&optbuf); 3177 switch (optcode) { 3178 case DNS_OPT_COOKIE: 3179 /* 3180 * Only process the first cookie option. 3181 */ 3182 if (seen_cookie) { 3183 isc_buffer_forward(&optbuf, optlen); 3184 break; 3185 } 3186 process_sit(l, msg, &optbuf, optlen); 3187 seen_cookie = 1; 3188 break; 3189 default: 3190 isc_buffer_forward(&optbuf, optlen); 3191 break; 3192 } 3193 } 3194 } 3195 } 3196 3197 static int 3198 ednsvers(dns_rdataset_t *opt) { 3199 return ((opt->ttl >> 16) & 0xff); 3200 } 3201 3202 /*% 3203 * Event handler for recv complete. Perform whatever actions are necessary, 3204 * based on the specifics of the user's request. 3205 */ 3206 static void 3207 recv_done(isc_task_t *task, isc_event_t *event) { 3208 isc_socketevent_t *sevent = NULL; 3209 dig_query_t *query = NULL; 3210 isc_buffer_t *b = NULL; 3211 dns_message_t *msg = NULL; 3212 isc_result_t result; 3213 dig_lookup_t *n, *l; 3214 int docancel = 0; 3215 int match = 1; 3216 unsigned int parseflags; 3217 dns_messageid_t id; 3218 unsigned int msgflags; 3219 int newedns; 3220 3221 UNUSED(task); 3222 INSIST(!free_now); 3223 3224 debug("recv_done()"); 3225 3226 recvcount--; 3227 debug("recvcount=%d", recvcount); 3228 INSIST(recvcount >= 0); 3229 3230 query = event->ev_arg; 3231 clock_gettime(CLOCK_MONOTONIC, &query->time_recv); 3232 debug("lookup=%p, query=%p", query->lookup, query); 3233 3234 l = query->lookup; 3235 3236 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); 3237 sevent = (isc_socketevent_t *)event; 3238 3239 b = ISC_LIST_HEAD(sevent->bufferlist); 3240 INSIST(b == &query->recvbuf); 3241 ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); 3242 3243 if ((l->tcp_mode) && (query->timer != NULL)) 3244 isc_timer_touch(query->timer); 3245 if ((!l->pending && !l->ns_search_only) || cancel_now) { 3246 debug("no longer pending. Got %s", 3247 isc_result_totext(sevent->result)); 3248 query->waiting_connect = 0; 3249 3250 isc_event_free(&event); 3251 clear_query(query); 3252 check_next_lookup(l); 3253 return; 3254 } 3255 3256 if (sevent->result != ISC_R_SUCCESS) { 3257 if (sevent->result == ISC_R_CANCELED) { 3258 debug("in recv cancel handler"); 3259 query->waiting_connect = 0; 3260 } else { 3261 printf(";; communications error: %s\n", 3262 isc_result_totext(sevent->result)); 3263 if (keep != NULL) 3264 isc_socket_detach(&keep); 3265 isc_socket_detach(&query->sock); 3266 sockcount--; 3267 debug("sockcount=%d", sockcount); 3268 INSIST(sockcount >= 0); 3269 } 3270 if (sevent->result == ISC_R_EOF && l->eoferr == 0U) { 3271 n = requeue_lookup(l, 1); 3272 n->eoferr++; 3273 } 3274 isc_event_free(&event); 3275 clear_query(query); 3276 cancel_lookup(l); 3277 check_next_lookup(l); 3278 return; 3279 } 3280 3281 if (!l->tcp_mode && 3282 !isc_sockaddr_compare(&sevent->address, &query->sockaddr, 3283 ISC_SOCKADDR_CMPADDR| 3284 ISC_SOCKADDR_CMPPORT| 3285 ISC_SOCKADDR_CMPSCOPE| 3286 ISC_SOCKADDR_CMPSCOPEZERO)) { 3287 char buf1[ISC_SOCKADDR_FORMATSIZE]; 3288 char buf2[ISC_SOCKADDR_FORMATSIZE]; 3289 struct sockaddr_storage any; 3290 3291 if (isc_sockaddr_pf(&query->sockaddr) == AF_INET) 3292 isc_sockaddr_any(&any); 3293 else 3294 isc_sockaddr_any6(&any); 3295 3296 /* 3297 * We don't expect a match when the packet is 3298 * sent to 0.0.0.0, :: or to a multicast addresses. 3299 * XXXMPA broadcast needs to be handled here as well. 3300 */ 3301 if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) && 3302 !isc_sockaddr_ismulticast(&query->sockaddr)) || 3303 isc_sockaddr_getport(&query->sockaddr) != 3304 isc_sockaddr_getport(&sevent->address)) { 3305 isc_sockaddr_format(&sevent->address, buf1, 3306 sizeof(buf1)); 3307 isc_sockaddr_format(&query->sockaddr, buf2, 3308 sizeof(buf2)); 3309 printf(";; reply from unexpected source: %s," 3310 " expected %s\n", buf1, buf2); 3311 match = 0; 3312 } 3313 } 3314 3315 result = dns_message_peekheader(b, &id, &msgflags); 3316 if (result != ISC_R_SUCCESS || l->sendmsg->id != id) { 3317 match = 0; 3318 if (l->tcp_mode) { 3319 int fail = 1; 3320 if (result == ISC_R_SUCCESS) { 3321 if (!query->first_soa_rcvd || 3322 query->warn_id) 3323 printf(";; %s: ID mismatch: " 3324 "expected ID %u, got %u\n", 3325 query->first_soa_rcvd ? 3326 "WARNING" : "ERROR", 3327 l->sendmsg->id, id); 3328 if (query->first_soa_rcvd) 3329 fail = 0; 3330 query->warn_id = 0; 3331 } else 3332 printf(";; ERROR: short " 3333 "(< header size) message\n"); 3334 if (fail) { 3335 isc_event_free(&event); 3336 clear_query(query); 3337 cancel_lookup(l); 3338 check_next_lookup(l); 3339 return; 3340 } 3341 match = 1; 3342 } else if (result == ISC_R_SUCCESS) 3343 printf(";; Warning: ID mismatch: " 3344 "expected ID %u, got %u\n", l->sendmsg->id, id); 3345 else 3346 printf(";; Warning: short " 3347 "(< header size) message received\n"); 3348 } 3349 3350 if (result == ISC_R_SUCCESS && (msgflags & DNS_MESSAGEFLAG_QR) == 0) 3351 printf(";; Warning: query response not set\n"); 3352 3353 if (!match) 3354 goto udp_mismatch; 3355 3356 result = dns_message_create(DNS_MESSAGE_INTENTPARSE, &msg); 3357 check_result(result, "dns_message_create"); 3358 3359 if (tsigkey != NULL) { 3360 if (l->querysig == NULL) { 3361 debug("getting initial querysig"); 3362 result = dns_message_getquerytsig(l->sendmsg, 3363 &l->querysig); 3364 check_result(result, "dns_message_getquerytsig"); 3365 } 3366 result = dns_message_setquerytsig(msg, l->querysig); 3367 check_result(result, "dns_message_setquerytsig"); 3368 result = dns_message_settsigkey(msg, tsigkey); 3369 check_result(result, "dns_message_settsigkey"); 3370 msg->tsigctx = l->tsigctx; 3371 l->tsigctx = NULL; 3372 if (l->msgcounter != 0) 3373 msg->tcp_continuation = 1; 3374 l->msgcounter++; 3375 } 3376 3377 debug("before parse starts"); 3378 parseflags = 0; 3379 if (l->besteffort) { 3380 parseflags |= DNS_MESSAGEPARSE_BESTEFFORT; 3381 parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION; 3382 } 3383 result = dns_message_parse(msg, b, parseflags); 3384 if (result == DNS_R_RECOVERABLE) { 3385 printf(";; Warning: Message parser reports malformed " 3386 "message packet.\n"); 3387 result = ISC_R_SUCCESS; 3388 } 3389 if (result != ISC_R_SUCCESS) { 3390 printf(";; Got bad packet: %s\n", isc_result_totext(result)); 3391 hex_dump(b); 3392 query->waiting_connect = 0; 3393 dns_message_destroy(&msg); 3394 isc_event_free(&event); 3395 clear_query(query); 3396 cancel_lookup(l); 3397 check_next_lookup(l); 3398 return; 3399 } 3400 if (msg->counts[DNS_SECTION_QUESTION] != 0) { 3401 match = 1; 3402 for (result = dns_message_firstname(msg, DNS_SECTION_QUESTION); 3403 result == ISC_R_SUCCESS && match; 3404 result = dns_message_nextname(msg, DNS_SECTION_QUESTION)) { 3405 dns_name_t *name = NULL; 3406 dns_rdataset_t *rdataset; 3407 3408 dns_message_currentname(msg, DNS_SECTION_QUESTION, 3409 &name); 3410 for (rdataset = ISC_LIST_HEAD(name->list); 3411 rdataset != NULL; 3412 rdataset = ISC_LIST_NEXT(rdataset, link)) { 3413 if (l->rdtype != rdataset->type || 3414 l->rdclass != rdataset->rdclass || 3415 !dns_name_equal(l->name, name)) { 3416 char namestr[DNS_NAME_FORMATSIZE]; 3417 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3418 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 3419 dns_name_format(name, namestr, 3420 sizeof(namestr)); 3421 dns_rdatatype_format(rdataset->type, 3422 typebuf, 3423 sizeof(typebuf)); 3424 dns_rdataclass_format(rdataset->rdclass, 3425 classbuf, 3426 sizeof(classbuf)); 3427 printf(";; Question section mismatch: " 3428 "got %s/%s/%s\n", 3429 namestr, typebuf, classbuf); 3430 match = 0; 3431 } 3432 } 3433 } 3434 if (!match) { 3435 dns_message_destroy(&msg); 3436 if (l->tcp_mode) { 3437 isc_event_free(&event); 3438 clear_query(query); 3439 cancel_lookup(l); 3440 check_next_lookup(l); 3441 return; 3442 } else 3443 goto udp_mismatch; 3444 } 3445 } 3446 if (msg->rcode == dns_rcode_badvers && msg->opt != NULL && 3447 (newedns = ednsvers(msg->opt)) < l->edns && l->ednsneg) { 3448 /* 3449 * Add minimum EDNS version required checks here if needed. 3450 */ 3451 if (l->comments) 3452 printf(";; BADVERS, retrying with EDNS version %u.\n", 3453 (unsigned int)newedns); 3454 l->edns = newedns; 3455 n = requeue_lookup(l, 1); 3456 if (l->trace && l->trace_root) 3457 n->rdtype = l->qrdtype; 3458 dns_message_destroy(&msg); 3459 isc_event_free(&event); 3460 clear_query(query); 3461 cancel_lookup(l); 3462 check_next_lookup(l); 3463 return; 3464 } 3465 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 && 3466 !l->ignore && !l->tcp_mode) { 3467 if (l->sitvalue == NULL && l->sit && msg->opt != NULL) 3468 process_opt(l, msg); 3469 if (l->comments) 3470 printf(";; Truncated, retrying in TCP mode.\n"); 3471 n = requeue_lookup(l, 1); 3472 n->tcp_mode = 1; 3473 if (l->trace && l->trace_root) 3474 n->rdtype = l->qrdtype; 3475 dns_message_destroy(&msg); 3476 isc_event_free(&event); 3477 clear_query(query); 3478 cancel_lookup(l); 3479 check_next_lookup(l); 3480 return; 3481 } 3482 if ((msg->rcode == dns_rcode_servfail && !l->servfail_stops) || 3483 (check_ra && (msg->flags & DNS_MESSAGEFLAG_RA) == 0 && l->recurse)) 3484 { 3485 dig_query_t *next = ISC_LIST_NEXT(query, link); 3486 if (l->current_query == query) 3487 l->current_query = NULL; 3488 if (next != NULL) { 3489 debug("sending query %p\n", next); 3490 if (l->tcp_mode) 3491 send_tcp_connect(next); 3492 else 3493 send_udp(next); 3494 } 3495 /* 3496 * If our query is at the head of the list and there 3497 * is no next, we're the only one left, so fall 3498 * through to print the message. 3499 */ 3500 if ((ISC_LIST_HEAD(l->q) != query) || 3501 (ISC_LIST_NEXT(query, link) != NULL)) { 3502 if (l->comments) 3503 printf(";; Got %s from %s, " 3504 "trying next server\n", 3505 msg->rcode == dns_rcode_servfail ? 3506 "SERVFAIL reply" : 3507 "recursion not available", 3508 query->servname); 3509 clear_query(query); 3510 check_next_lookup(l); 3511 dns_message_destroy(&msg); 3512 isc_event_free(&event); 3513 return; 3514 } 3515 } 3516 3517 if (tsigkey != NULL) { 3518 result = dns_tsig_verify(&query->recvbuf, msg); 3519 if (result != ISC_R_SUCCESS) { 3520 printf(";; Couldn't verify signature: %s\n", 3521 isc_result_totext(result)); 3522 validated = 0; 3523 } 3524 l->tsigctx = msg->tsigctx; 3525 msg->tsigctx = NULL; 3526 if (l->querysig != NULL) { 3527 debug("freeing querysig buffer %p", l->querysig); 3528 isc_buffer_free(&l->querysig); 3529 } 3530 result = dns_message_getquerytsig(msg, &l->querysig); 3531 check_result(result,"dns_message_getquerytsig"); 3532 } 3533 3534 extrabytes = isc_buffer_remaininglength(b); 3535 3536 debug("after parse"); 3537 if (l->doing_xfr && l->xfr_q == NULL) { 3538 l->xfr_q = query; 3539 /* 3540 * Once we are in the XFR message, increase 3541 * the timeout to much longer, so brief network 3542 * outages won't cause the XFR to abort 3543 */ 3544 if (timeout != INT_MAX && query->timer != NULL) { 3545 unsigned int local_timeout; 3546 3547 if (timeout == 0) { 3548 if (l->tcp_mode) 3549 local_timeout = TCP_TIMEOUT * 4; 3550 else 3551 local_timeout = UDP_TIMEOUT * 4; 3552 } else { 3553 if (timeout < (INT_MAX / 4)) 3554 local_timeout = timeout * 4; 3555 else 3556 local_timeout = INT_MAX; 3557 } 3558 debug("have local timeout of %d", local_timeout); 3559 l->interval.tv_sec = local_timeout; 3560 l->interval.tv_nsec = 0; 3561 result = isc_timer_reset(query->timer, 3562 &l->interval, 3563 0); 3564 check_result(result, "isc_timer_reset"); 3565 } 3566 } 3567 3568 if (l->sitvalue != NULL) { 3569 if (msg->opt == NULL) 3570 printf(";; expected opt record in response\n"); 3571 else 3572 process_opt(l, msg); 3573 } else if (l->sit && msg->opt != NULL) 3574 process_opt(l, msg); 3575 3576 if (!l->doing_xfr || l->xfr_q == query) { 3577 if (msg->rcode == dns_rcode_nxdomain && 3578 (l->origin != NULL || l->need_search)) { 3579 if (!next_origin(query->lookup) || showsearch) { 3580 dighost_printmessage(query, msg, 1); 3581 dighost_received(b->used, &sevent->address, query); 3582 } 3583 } else if (!l->trace && !l->ns_search_only) { 3584 dighost_printmessage(query, msg, 1); 3585 } else if (l->trace) { 3586 int nl = 0; 3587 int count = msg->counts[DNS_SECTION_ANSWER]; 3588 3589 debug("in TRACE code"); 3590 if (!l->ns_search_only) 3591 dighost_printmessage(query, msg, 1); 3592 3593 l->rdtype = l->qrdtype; 3594 if (l->trace_root || (l->ns_search_only && count > 0)) { 3595 if (!l->trace_root) 3596 l->rdtype = dns_rdatatype_soa; 3597 nl = followup_lookup(msg, query, 3598 DNS_SECTION_ANSWER); 3599 l->trace_root = 0; 3600 } else if (count == 0) 3601 nl = followup_lookup(msg, query, 3602 DNS_SECTION_AUTHORITY); 3603 if (nl == 0) 3604 docancel = 1; 3605 } else { 3606 debug("in NSSEARCH code"); 3607 3608 if (l->trace_root) { 3609 /* 3610 * This is the initial NS query. 3611 */ 3612 int nl; 3613 3614 l->rdtype = dns_rdatatype_soa; 3615 nl = followup_lookup(msg, query, 3616 DNS_SECTION_ANSWER); 3617 if (nl == 0) 3618 docancel = 1; 3619 l->trace_root = 0; 3620 usesearch = 0; 3621 } else 3622 dighost_printmessage(query, msg, 1); 3623 } 3624 } 3625 3626 if (l->pending) 3627 debug("still pending."); 3628 if (l->doing_xfr) { 3629 if (query != l->xfr_q) { 3630 dns_message_destroy(&msg); 3631 isc_event_free(&event); 3632 query->waiting_connect = 0; 3633 return; 3634 } 3635 if (!docancel) 3636 docancel = check_for_more_data(query, msg, sevent); 3637 if (docancel) { 3638 dns_message_destroy(&msg); 3639 clear_query(query); 3640 cancel_lookup(l); 3641 check_next_lookup(l); 3642 } 3643 } else { 3644 3645 if (msg->rcode == dns_rcode_noerror || l->origin == NULL) { 3646 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