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