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