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