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