2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: dighost.c,v 1.221.2.22 2004/04/15 06:53:18 marka Exp $ */
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.
35 #include <dns/byaddr.h>
36 #include <dns/fixedname.h>
37 #include <dns/message.h>
39 #include <dns/rdata.h>
40 #include <dns/rdataclass.h>
41 #include <dns/rdatalist.h>
42 #include <dns/rdataset.h>
43 #include <dns/rdatastruct.h>
44 #include <dns/rdatatype.h>
45 #include <dns/result.h>
51 #include <isc/base64.h>
52 #include <isc/entropy.h>
54 #include <isc/netaddr.h>
55 #include <isc/netdb.h>
56 #include <isc/print.h>
57 #include <isc/random.h>
58 #include <isc/result.h>
59 #include <isc/string.h>
61 #include <isc/timer.h>
62 #include <isc/types.h>
68 #ifdef HAVE_GETADDRINFO
69 #ifdef HAVE_GAISTRERROR
70 #define USE_GETADDRINFO
75 #ifndef USE_GETADDRINFO
76 #ifndef ISC_PLATFORM_NONSTDHERRNO
81 ISC_LIST(dig_lookup_t) lookup_list;
82 dig_serverlist_t server_list;
83 ISC_LIST(dig_searchlist_t) search_list;
86 have_ipv4 = ISC_FALSE,
87 have_ipv6 = ISC_FALSE,
88 specified_source = ISC_FALSE,
90 cancel_now = ISC_FALSE,
91 usesearch = ISC_FALSE,
93 is_dst_up = ISC_FALSE;
95 unsigned int timeout = 0;
96 isc_mem_t *mctx = 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;
108 int lookup_counter = 0;
112 * 0 Everything went well, including things like NXDOMAIN
114 * 7 Got too many RR's or Names
115 * 8 Couldn't open batch file
116 * 9 No reply from server
121 char keynametext[MXNAME];
122 char keyfile[MXNAME] = "";
123 char keysecret[MXNAME] = "";
124 isc_buffer_t *namebuf = NULL;
125 dns_tsigkey_t *key = NULL;
126 isc_boolean_t validated = ISC_TRUE;
127 isc_entropy_t *entp = NULL;
128 isc_mempool_t *commctx = NULL;
129 isc_boolean_t debugging = ISC_FALSE;
130 isc_boolean_t memdebugging = ISC_FALSE;
131 char *progname = NULL;
132 isc_mutex_t lookup_lock;
133 dig_lookup_t *current_lookup = NULL;
136 * Apply and clear locks at the event level in global task.
137 * Can I get rid of these using shutdown events? XXX
139 #define LOCK_LOOKUP {\
140 debug("lock_lookup %s:%d", __FILE__, __LINE__);\
141 check_result(isc_mutex_lock((&lookup_lock)), "isc_mutex_lock");\
144 #define UNLOCK_LOOKUP {\
145 debug("unlock_lookup %s:%d", __FILE__, __LINE__);\
146 check_result(isc_mutex_unlock((&lookup_lock)),\
147 "isc_mutex_unlock");\
151 cancel_lookup(dig_lookup_t *lookup);
154 recv_done(isc_task_t *task, isc_event_t *event);
157 connect_timeout(isc_task_t *task, isc_event_t *event);
160 launch_next_query(dig_query_t *query, isc_boolean_t include_question);
163 next_token(char **stringp, const char *delim) {
167 res = strsep(stringp, delim);
170 } while (*res == '\0');
175 count_dots(char *string) {
189 hex_dump(isc_buffer_t *b) {
193 isc_buffer_usedregion(b, &r);
195 printf("%d bytes\n", r.length);
196 for (len = 0; len < r.length; len++) {
197 printf("%02x ", r.base[len]);
206 * Append 'len' bytes of 'text' at '*p', failing with
207 * ISC_R_NOSPACE if that would advance p past 'end'.
210 append(const char *text, int len, char **p, char *end) {
212 return (ISC_R_NOSPACE);
213 memcpy(*p, text, len);
215 return (ISC_R_SUCCESS);
219 reverse_octets(const char *in, char **p, char *end) {
220 char *dot = strchr(in, '.');
224 result = reverse_octets(dot + 1, p, end);
225 if (result != ISC_R_SUCCESS)
227 result = append(".", 1, p, end);
228 if (result != ISC_R_SUCCESS)
234 return (append(in, len, p, end));
238 get_reverse(char *reverse, char *value, isc_boolean_t ip6_int,
239 isc_boolean_t strict)
245 addr.family = AF_INET6;
246 r = inet_pton(AF_INET6, value, &addr.type.in6);
248 /* This is a valid IPv6 address. */
249 dns_fixedname_t fname;
251 unsigned int options = DNS_BYADDROPT_IPV6NIBBLE;
254 options |= DNS_BYADDROPT_IPV6INT;
255 dns_fixedname_init(&fname);
256 name = dns_fixedname_name(&fname);
257 result = dns_byaddr_createptrname2(&addr, options, name);
258 if (result != ISC_R_SUCCESS)
260 dns_name_format(name, reverse, MXNAME);
261 return (ISC_R_SUCCESS);
264 * Not a valid IPv6 address. Assume IPv4.
265 * If 'strict' is not set, construct the
266 * in-addr.arpa name by blindly reversing
267 * octets whether or not they look like integers,
268 * so that this can be used for RFC2317 names
272 char *end = reverse + MXNAME;
273 if (strict && inet_pton(AF_INET, value, &addr.type.in) != 1)
274 return (DNS_R_BADDOTTEDQUAD);
275 result = reverse_octets(value, &p, end);
276 if (result != ISC_R_SUCCESS)
278 /* Append .in-addr.arpa. and a terminating NUL. */
279 result = append(".in-addr.arpa.", 15, &p, end);
280 if (result != ISC_R_SUCCESS)
282 return (ISC_R_SUCCESS);
287 fatal(const char *format, ...) {
290 fprintf(stderr, "%s: ", progname);
291 va_start(args, format);
292 vfprintf(stderr, format, args);
294 fprintf(stderr, "\n");
298 exitcode = fatalexit;
303 debug(const char *format, ...) {
307 va_start(args, format);
308 vfprintf(stderr, format, args);
310 fprintf(stderr, "\n");
315 check_result(isc_result_t result, const char *msg) {
316 if (result != ISC_R_SUCCESS) {
317 fatal("%s: %s", msg, isc_result_totext(result));
322 * Create a server structure, which is part of the lookup structure.
323 * This is little more than a linked list of servers to query in hopes
324 * of finding the answer the user is looking for
327 make_server(const char *servname) {
330 REQUIRE(servname != NULL);
332 debug("make_server(%s)", servname);
333 srv = isc_mem_allocate(mctx, sizeof(struct dig_server));
335 fatal("Memory allocation failure in %s:%d",
337 strncpy(srv->servername, servname, MXNAME);
338 srv->servername[MXNAME-1] = 0;
339 ISC_LINK_INIT(srv, link);
344 * Produce a cloned server list. The dest list must have already had
345 * ISC_LIST_INIT applied.
348 clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) {
349 dig_server_t *srv, *newsrv;
351 debug("clone_server_list()");
352 srv = ISC_LIST_HEAD(src);
353 while (srv != NULL) {
354 newsrv = make_server(srv->servername);
355 ISC_LINK_INIT(newsrv, link);
356 ISC_LIST_ENQUEUE(*dest, newsrv, link);
357 srv = ISC_LIST_NEXT(srv, link);
362 * Create an empty lookup structure, which holds all the information needed
363 * to get an answer to a user's question. This structure contains two
364 * linked lists: the server list (servers to query) and the query list
365 * (outstanding queries which have been made to the listed servers).
368 make_empty_lookup(void) {
369 dig_lookup_t *looknew;
371 debug("make_empty_lookup()");
375 looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup));
377 fatal("Memory allocation failure in %s:%d",
379 looknew->pending = ISC_TRUE;
380 looknew->textname[0] = 0;
381 looknew->cmdline[0] = 0;
382 looknew->rdtype = dns_rdatatype_a;
383 looknew->qrdtype = dns_rdatatype_a;
384 looknew->rdclass = dns_rdataclass_in;
385 looknew->rdtypeset = ISC_FALSE;
386 looknew->rdclassset = ISC_FALSE;
387 looknew->sendspace = NULL;
388 looknew->sendmsg = NULL;
389 looknew->name = NULL;
390 looknew->oname = NULL;
391 looknew->timer = NULL;
392 looknew->xfr_q = NULL;
393 looknew->current_query = NULL;
394 looknew->doing_xfr = ISC_FALSE;
395 looknew->ixfr_serial = ISC_FALSE;
396 looknew->trace = ISC_FALSE;
397 looknew->trace_root = ISC_FALSE;
398 looknew->identify = ISC_FALSE;
399 looknew->identify_previous_line = ISC_FALSE;
400 looknew->ignore = ISC_FALSE;
401 looknew->servfail_stops = ISC_TRUE;
402 looknew->besteffort = ISC_TRUE;
403 looknew->dnssec = ISC_FALSE;
404 looknew->udpsize = 0;
405 looknew->recurse = ISC_TRUE;
406 looknew->aaonly = ISC_FALSE;
407 looknew->adflag = ISC_FALSE;
408 looknew->cdflag = ISC_FALSE;
409 looknew->ns_search_only = ISC_FALSE;
410 looknew->origin = NULL;
411 looknew->tsigctx = NULL;
412 looknew->querysig = NULL;
413 looknew->retries = tries;
414 looknew->nsfound = 0;
415 looknew->tcp_mode = ISC_FALSE;
416 looknew->ip6_int = ISC_FALSE;
417 looknew->comments = ISC_TRUE;
418 looknew->stats = ISC_TRUE;
419 looknew->section_question = ISC_TRUE;
420 looknew->section_answer = ISC_TRUE;
421 looknew->section_authority = ISC_TRUE;
422 looknew->section_additional = ISC_TRUE;
423 looknew->new_search = ISC_FALSE;
424 ISC_LINK_INIT(looknew, link);
425 ISC_LIST_INIT(looknew->q);
426 ISC_LIST_INIT(looknew->my_server_list);
431 * Clone a lookup, perhaps copying the server list. This does not clone
432 * the query list, since it will be regenerated by the setup_lookup()
433 * function, nor does it queue up the new lookup for processing.
434 * Caution: If you don't clone the servers, you MUST clone the server
435 * list seperately from somewhere else, or construct it by hand.
438 clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
439 dig_lookup_t *looknew;
441 debug("clone_lookup()");
445 looknew = make_empty_lookup();
446 INSIST(looknew != NULL);
447 strncpy(looknew->textname, lookold->textname, MXNAME);
448 strncpy(looknew->cmdline, lookold->cmdline, MXNAME);
449 looknew->textname[MXNAME-1] = 0;
450 looknew->rdtype = lookold->rdtype;
451 looknew->qrdtype = lookold->qrdtype;
452 looknew->rdclass = lookold->rdclass;
453 looknew->rdtypeset = lookold->rdtypeset;
454 looknew->rdclassset = lookold->rdclassset;
455 looknew->doing_xfr = lookold->doing_xfr;
456 looknew->ixfr_serial = lookold->ixfr_serial;
457 looknew->trace = lookold->trace;
458 looknew->trace_root = lookold->trace_root;
459 looknew->identify = lookold->identify;
460 looknew->identify_previous_line = lookold->identify_previous_line;
461 looknew->ignore = lookold->ignore;
462 looknew->servfail_stops = lookold->servfail_stops;
463 looknew->besteffort = lookold->besteffort;
464 looknew->dnssec = lookold->dnssec;
465 looknew->udpsize = lookold->udpsize;
466 looknew->recurse = lookold->recurse;
467 looknew->aaonly = lookold->aaonly;
468 looknew->adflag = lookold->adflag;
469 looknew->cdflag = lookold->cdflag;
470 looknew->ns_search_only = lookold->ns_search_only;
471 looknew->tcp_mode = lookold->tcp_mode;
472 looknew->comments = lookold->comments;
473 looknew->stats = lookold->stats;
474 looknew->section_question = lookold->section_question;
475 looknew->section_answer = lookold->section_answer;
476 looknew->section_authority = lookold->section_authority;
477 looknew->section_additional = lookold->section_additional;
478 looknew->retries = lookold->retries;
479 looknew->tsigctx = NULL;
482 clone_server_list(lookold->my_server_list,
483 &looknew->my_server_list);
488 * Requeue a lookup for further processing, perhaps copying the server
489 * list. The new lookup structure is returned to the caller, and is
490 * queued for processing. If servers are not cloned in the requeue, they
491 * must be added before allowing the current event to complete, since the
492 * completion of the event may result in the next entry on the lookup
496 requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
497 dig_lookup_t *looknew;
499 debug("requeue_lookup()");
502 if (lookup_counter > LOOKUP_LIMIT)
503 fatal("Too many lookups");
505 looknew = clone_lookup(lookold, servers);
506 INSIST(looknew != NULL);
508 debug("before insertion, init@%p -> %p, new@%p -> %p",
509 lookold, lookold->link.next, looknew, looknew->link.next);
510 ISC_LIST_PREPEND(lookup_list, looknew, link);
511 debug("after insertion, init -> %p, new = %p, new -> %p",
512 lookold, looknew, looknew->link.next);
518 setup_text_key(void) {
521 isc_buffer_t secretbuf;
523 unsigned char *secretstore;
525 debug("setup_text_key()");
526 result = isc_buffer_allocate(mctx, &namebuf, MXNAME);
527 check_result(result, "isc_buffer_allocate");
528 dns_name_init(&keyname, NULL);
529 check_result(result, "dns_name_init");
530 isc_buffer_putstr(namebuf, keynametext);
531 secretsize = strlen(keysecret) * 3 / 4;
532 secretstore = isc_mem_allocate(mctx, secretsize);
533 if (secretstore == NULL)
534 fatal("Memory allocation failure in %s:%d",
536 isc_buffer_init(&secretbuf, secretstore, secretsize);
537 result = isc_base64_decodestring(keysecret, &secretbuf);
538 if (result != ISC_R_SUCCESS)
541 secretsize = isc_buffer_usedlength(&secretbuf);
543 result = dns_name_fromtext(&keyname, namebuf,
544 dns_rootname, ISC_FALSE,
546 if (result != ISC_R_SUCCESS)
549 result = dns_tsigkey_create(&keyname, dns_tsig_hmacmd5_name,
550 secretstore, secretsize,
551 ISC_FALSE, NULL, 0, 0, mctx,
554 if (result != ISC_R_SUCCESS)
555 printf(";; Couldn't create key %s: %s\n",
556 keynametext, isc_result_totext(result));
558 isc_mem_free(mctx, secretstore);
559 dns_name_invalidate(&keyname);
560 isc_buffer_free(&namebuf);
564 setup_file_key(void) {
566 dst_key_t *dstkey = NULL;
568 debug("setup_file_key()");
569 result = dst_key_fromnamedfile(keyfile, DST_TYPE_PRIVATE,
571 if (result != ISC_R_SUCCESS) {
572 fprintf(stderr, "Couldn't read key from %s: %s\n",
573 keyfile, isc_result_totext(result));
577 result = dns_tsigkey_createfromkey(dst_key_name(dstkey),
578 dns_tsig_hmacmd5_name,
579 dstkey, ISC_FALSE, NULL, 0, 0,
581 if (result != ISC_R_SUCCESS) {
582 printf(";; Couldn't create key %s: %s\n",
583 keynametext, isc_result_totext(result));
589 dst_key_free(&dstkey);
592 static dig_searchlist_t *
593 make_searchlist_entry(char *domain) {
594 dig_searchlist_t *search;
595 search = isc_mem_allocate(mctx, sizeof(*search));
597 fatal("Memory allocation failure in %s:%d",
599 strncpy(search->origin, domain, MXNAME);
600 search->origin[MXNAME-1] = 0;
601 ISC_LINK_INIT(search, link);
606 * Setup the system as a whole, reading key information and resolv.conf
611 char rcinput[MXNAME];
615 dig_searchlist_t *search, *domain = NULL;
616 isc_boolean_t get_servers;
619 debug("setup_system()");
621 free_now = ISC_FALSE;
622 get_servers = ISC_TF(server_list.head == NULL);
623 fp = fopen(RESOLV_CONF, "r");
624 /* XXX Use lwres resolv.conf reader */
628 while (fgets(rcinput, MXNAME, fp) != 0) {
630 ptr = next_token(&input, " \t\r\n");
633 strcasecmp(ptr, "nameserver") == 0) {
634 debug("got a nameserver line");
635 ptr = next_token(&input, " \t\r\n");
637 srv = make_server(ptr);
638 ISC_LIST_APPEND(server_list, srv, link);
640 } else if (strcasecmp(ptr, "options") == 0) {
641 ptr = next_token(&input, " \t\r\n");
643 if (strncasecmp(ptr, "ndots:", 6) == 0
646 ndots = atoi(&ptr[6]);
647 debug("ndots is %d.", ndots);
650 } else if (strcasecmp(ptr, "search") == 0){
651 while ((ptr = next_token(&input, " \t\r\n"))
653 debug("adding search %s", ptr);
654 search = make_searchlist_entry(ptr);
655 ISC_LIST_INITANDAPPEND(search_list,
658 } else if (strcasecmp(ptr, "domain") == 0) {
659 while ((ptr = next_token(&input, " \t\r\n"))
662 isc_mem_free(mctx, domain);
663 domain = make_searchlist_entry(ptr);
671 if (ISC_LIST_EMPTY(search_list) && domain != NULL) {
672 ISC_LIST_INITANDAPPEND(search_list, domain, link);
676 isc_mem_free(mctx, domain);
681 if (server_list.head == NULL) {
682 srv = make_server("127.0.0.1");
683 ISC_LIST_APPEND(server_list, srv, link);
688 else if (keysecret[0] != 0)
693 clear_searchlist(void) {
694 dig_searchlist_t *search;
695 while ((search = ISC_LIST_HEAD(search_list)) != NULL) {
696 ISC_LIST_UNLINK(search_list, search, link);
697 isc_mem_free(mctx, search);
702 * Override the search list derived from resolv.conf by 'domain'.
705 set_search_domain(char *domain) {
706 dig_searchlist_t *search;
709 search = make_searchlist_entry(domain);
710 ISC_LIST_APPEND(search_list, search, link);
714 * Setup the ISC and DNS libraries for use by the system.
720 debug("setup_libs()");
722 result = isc_net_probeipv4();
723 if (result == ISC_R_SUCCESS)
724 have_ipv4 = ISC_TRUE;
726 result = isc_net_probeipv6();
727 if (result == ISC_R_SUCCESS)
728 have_ipv6 = ISC_TRUE;
729 if (!have_ipv6 && !have_ipv4)
730 fatal("can't find either v4 or v6 networking");
732 result = isc_mem_create(0, 0, &mctx);
733 check_result(result, "isc_mem_create");
735 result = isc_taskmgr_create(mctx, 1, 0, &taskmgr);
736 check_result(result, "isc_taskmgr_create");
738 result = isc_task_create(taskmgr, 0, &global_task);
739 check_result(result, "isc_task_create");
741 result = isc_timermgr_create(mctx, &timermgr);
742 check_result(result, "isc_timermgr_create");
744 result = isc_socketmgr_create(mctx, &socketmgr);
745 check_result(result, "isc_socketmgr_create");
747 result = isc_entropy_create(mctx, &entp);
748 check_result(result, "isc_entropy_create");
750 result = dst_lib_init(mctx, entp, 0);
751 check_result(result, "dst_lib_init");
752 is_dst_up = ISC_TRUE;
754 result = isc_mempool_create(mctx, COMMSIZE, &commctx);
755 check_result(result, "isc_mempool_create");
756 isc_mempool_setname(commctx, "COMMPOOL");
758 * 6 and 2 set as reasonable parameters for 3 or 4 nameserver
761 isc_mempool_setfreemax(commctx, 6);
762 isc_mempool_setfillcount(commctx, 2);
764 result = isc_mutex_init(&lookup_lock);
765 check_result(result, "isc_mutex_init");
767 dns_result_register();
771 * Add EDNS0 option record to a message. Currently, the only supported
772 * options are UDP buffer size and the DO bit.
775 add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) {
776 dns_rdataset_t *rdataset = NULL;
777 dns_rdatalist_t *rdatalist = NULL;
778 dns_rdata_t *rdata = NULL;
782 result = dns_message_gettemprdataset(msg, &rdataset);
783 check_result(result, "dns_message_gettemprdataset");
784 dns_rdataset_init(rdataset);
785 result = dns_message_gettemprdatalist(msg, &rdatalist);
786 check_result(result, "dns_message_gettemprdatalist");
787 result = dns_message_gettemprdata(msg, &rdata);
788 check_result(result, "dns_message_gettemprdata");
790 debug("setting udp size of %d", udpsize);
791 rdatalist->type = dns_rdatatype_opt;
792 rdatalist->covers = 0;
793 rdatalist->rdclass = udpsize;
796 rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO;
799 ISC_LIST_INIT(rdatalist->rdata);
800 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
801 dns_rdatalist_tordataset(rdatalist, rdataset);
802 result = dns_message_setopt(msg, rdataset);
803 check_result(result, "dns_message_setopt");
807 * Add a question section to a message, asking for the specified name,
811 add_question(dns_message_t *message, dns_name_t *name,
812 dns_rdataclass_t rdclass, dns_rdatatype_t rdtype)
814 dns_rdataset_t *rdataset;
817 debug("add_question()");
819 result = dns_message_gettemprdataset(message, &rdataset);
820 check_result(result, "dns_message_gettemprdataset()");
821 dns_rdataset_init(rdataset);
822 dns_rdataset_makequestion(rdataset, rdclass, rdtype);
823 ISC_LIST_APPEND(name->list, rdataset, link);
827 * Check if we're done with all the queued lookups, which is true iff
828 * all sockets, sends, and recvs are accounted for (counters == 0),
829 * and the lookup list is empty.
830 * If we are done, pass control back out to dighost_shutdown() (which is
831 * part of dig.c, host.c, or nslookup.c) to either shutdown the system as
832 * a whole or reseed the lookup list.
835 check_if_done(void) {
836 debug("check_if_done()");
837 debug("list %s", ISC_LIST_EMPTY(lookup_list) ? "empty" : "full");
838 if (ISC_LIST_EMPTY(lookup_list) && current_lookup == NULL &&
840 INSIST(sockcount == 0);
841 INSIST(recvcount == 0);
842 debug("shutting down");
848 * Clear out a query when we're done with it. WARNING: This routine
849 * WILL invalidate the query pointer.
852 clear_query(dig_query_t *query) {
853 dig_lookup_t *lookup;
855 REQUIRE(query != NULL);
857 debug("clear_query(%p)", query);
859 lookup = query->lookup;
861 if (lookup->current_query == query)
862 lookup->current_query = NULL;
864 ISC_LIST_UNLINK(lookup->q, query, link);
865 if (ISC_LINK_LINKED(&query->recvbuf, link))
866 ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf,
868 if (ISC_LINK_LINKED(&query->lengthbuf, link))
869 ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf,
871 INSIST(query->recvspace != NULL);
872 if (query->sock != NULL) {
873 isc_socket_detach(&query->sock);
875 debug("sockcount=%d", sockcount);
877 isc_mempool_put(commctx, query->recvspace);
878 isc_buffer_invalidate(&query->recvbuf);
879 isc_buffer_invalidate(&query->lengthbuf);
880 isc_mem_free(mctx, query);
884 * Try and clear out a lookup if we're done with it. Return ISC_TRUE if
885 * the lookup was successfully cleared. If ISC_TRUE is returned, the
886 * lookup pointer has been invalidated.
889 try_clear_lookup(dig_lookup_t *lookup) {
894 REQUIRE(lookup != NULL);
896 debug("try_clear_lookup(%p)", lookup);
898 if (ISC_LIST_HEAD(lookup->q) != NULL) {
900 q = ISC_LIST_HEAD(lookup->q);
902 debug("query to %s still pending",
904 q = ISC_LIST_NEXT(q, link);
910 * At this point, we know there are no queries on the lookup,
911 * so can make it go away also.
914 s = ISC_LIST_HEAD(lookup->my_server_list);
916 debug("freeing server %p belonging to %p",
919 s = ISC_LIST_NEXT(s, link);
920 ISC_LIST_DEQUEUE(lookup->my_server_list,
921 (dig_server_t *)ptr, link);
922 isc_mem_free(mctx, ptr);
924 if (lookup->sendmsg != NULL)
925 dns_message_destroy(&lookup->sendmsg);
926 if (lookup->querysig != NULL) {
927 debug("freeing buffer %p", lookup->querysig);
928 isc_buffer_free(&lookup->querysig);
930 if (lookup->timer != NULL)
931 isc_timer_detach(&lookup->timer);
932 if (lookup->sendspace != NULL)
933 isc_mempool_put(commctx, lookup->sendspace);
935 if (lookup->tsigctx != NULL)
936 dst_context_destroy(&lookup->tsigctx);
938 isc_mem_free(mctx, lookup);
944 * If we can, start the next lookup in the queue running.
945 * This assumes that the lookup on the head of the queue hasn't been
946 * started yet. It also removes the lookup from the head of the queue,
947 * setting the current_lookup pointer pointing to it.
951 debug("start_lookup()");
956 * If there's a current lookup running, we really shouldn't get
959 INSIST(current_lookup == NULL);
961 current_lookup = ISC_LIST_HEAD(lookup_list);
963 * Put the current lookup somewhere so cancel_all can find it
965 if (current_lookup != NULL) {
966 ISC_LIST_DEQUEUE(lookup_list, current_lookup, link);
967 setup_lookup(current_lookup);
968 do_lookup(current_lookup);
975 * If we can, clear the current lookup and start the next one running.
976 * This calls try_clear_lookup, so may invalidate the lookup pointer.
979 check_next_lookup(dig_lookup_t *lookup) {
983 debug("check_next_lookup(%p)", lookup);
985 if (ISC_LIST_HEAD(lookup->q) != NULL) {
986 debug("still have a worker");
989 if (try_clear_lookup(lookup)) {
990 current_lookup = NULL;
996 * Create and queue a new lookup as a followup to the current lookup,
997 * based on the supplied message and section. This is used in trace and
998 * name server search modes to start a new lookup using servers from
999 * NS records in a reply. Returns the number of followup lookups made.
1002 followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section)
1004 dig_lookup_t *lookup = NULL;
1005 dig_server_t *srv = NULL;
1006 dns_rdataset_t *rdataset = NULL;
1007 dns_rdata_t rdata = DNS_RDATA_INIT;
1008 dns_name_t *name = NULL;
1009 isc_result_t result;
1010 isc_boolean_t success = ISC_FALSE;
1015 debug("following up %s", query->lookup->textname);
1017 for (result = dns_message_firstname(msg, section);
1018 result == ISC_R_SUCCESS;
1019 result = dns_message_nextname(msg, section))
1022 dns_message_currentname(msg, section, &name);
1025 result = dns_message_findtype(name, dns_rdatatype_ns, 0,
1027 if (result != ISC_R_SUCCESS)
1030 debug("found NS set");
1032 for (result = dns_rdataset_first(rdataset);
1033 result == ISC_R_SUCCESS;
1034 result = dns_rdataset_next(rdataset))
1036 char namestr[DNS_NAME_FORMATSIZE];
1039 if (query->lookup->trace_root &&
1040 query->lookup->nsfound >= MXSERV)
1043 dns_rdataset_current(rdataset, &rdata);
1045 query->lookup->nsfound++;
1046 (void)dns_rdata_tostruct(&rdata, &ns, NULL);
1047 dns_name_format(&ns.name, namestr, sizeof(namestr));
1048 dns_rdata_freestruct(&ns);
1050 /* Initialize lookup if we've not yet */
1051 debug("found NS %d %s", numLookups, namestr);
1056 lookup = requeue_lookup(query->lookup,
1058 cancel_lookup(query->lookup);
1059 lookup->doing_xfr = ISC_FALSE;
1060 if (!lookup->trace_root &&
1061 section == DNS_SECTION_ANSWER)
1062 lookup->trace = ISC_FALSE;
1064 lookup->trace = query->lookup->trace;
1065 lookup->ns_search_only =
1066 query->lookup->ns_search_only;
1067 lookup->trace_root = ISC_FALSE;
1069 srv = make_server(namestr);
1070 debug("adding server %s", srv->servername);
1071 ISC_LIST_APPEND(lookup->my_server_list, srv, link);
1072 dns_rdata_reset(&rdata);
1076 if (lookup == NULL &&
1077 section == DNS_SECTION_ANSWER &&
1078 (query->lookup->trace || query->lookup->ns_search_only))
1079 return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY));
1085 * Create and queue a new lookup using the next origin from the search
1086 * list, read in setup_system().
1088 * Return ISC_TRUE iff there was another searchlist entry.
1090 static isc_boolean_t
1091 next_origin(dns_message_t *msg, dig_query_t *query) {
1092 dig_lookup_t *lookup;
1098 debug("next_origin()");
1099 debug("following up %s", query->lookup->textname);
1103 * We're not using a search list, so don't even think
1104 * about finding the next entry.
1107 if (query->lookup->origin == NULL)
1109 * Then we just did rootorg; there's nothing left.
1112 lookup = requeue_lookup(query->lookup, ISC_TRUE);
1113 lookup->origin = ISC_LIST_NEXT(query->lookup->origin, link);
1114 cancel_lookup(query->lookup);
1119 * Insert an SOA record into the sendmessage in a lookup. Used for
1120 * creating IXFR queries.
1123 insert_soa(dig_lookup_t *lookup) {
1124 isc_result_t result;
1125 dns_rdata_soa_t soa;
1126 dns_rdata_t *rdata = NULL;
1127 dns_rdatalist_t *rdatalist = NULL;
1128 dns_rdataset_t *rdataset = NULL;
1129 dns_name_t *soaname = NULL;
1131 debug("insert_soa()");
1133 soa.serial = lookup->ixfr_serial;
1138 soa.common.rdclass = lookup->rdclass;
1139 soa.common.rdtype = dns_rdatatype_soa;
1141 dns_name_init(&soa.origin, NULL);
1142 dns_name_init(&soa.contact, NULL);
1144 dns_name_clone(dns_rootname, &soa.origin);
1145 dns_name_clone(dns_rootname, &soa.contact);
1147 isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore,
1148 sizeof(lookup->rdatastore));
1150 result = dns_message_gettemprdata(lookup->sendmsg, &rdata);
1151 check_result(result, "dns_message_gettemprdata");
1153 result = dns_rdata_fromstruct(rdata, lookup->rdclass,
1154 dns_rdatatype_soa, &soa,
1156 check_result(result, "isc_rdata_fromstruct");
1158 result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist);
1159 check_result(result, "dns_message_gettemprdatalist");
1161 result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset);
1162 check_result(result, "dns_message_gettemprdataset");
1164 dns_rdatalist_init(rdatalist);
1165 rdatalist->type = dns_rdatatype_soa;
1166 rdatalist->rdclass = lookup->rdclass;
1167 rdatalist->covers = 0;
1169 ISC_LIST_INIT(rdatalist->rdata);
1170 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1172 dns_rdataset_init(rdataset);
1173 dns_rdatalist_tordataset(rdatalist, rdataset);
1175 result = dns_message_gettempname(lookup->sendmsg, &soaname);
1176 check_result(result, "dns_message_gettempname");
1177 dns_name_init(soaname, NULL);
1178 dns_name_clone(lookup->name, soaname);
1179 ISC_LIST_INIT(soaname->list);
1180 ISC_LIST_APPEND(soaname->list, rdataset, link);
1181 dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY);
1185 * Setup the supplied lookup structure, making it ready to start sending
1186 * queries to servers. Create and initialize the message to be sent as
1187 * well as the query structures and buffer space for the replies. If the
1188 * server list is empty, clone it from the system default list.
1191 setup_lookup(dig_lookup_t *lookup) {
1192 isc_result_t result;
1198 dns_compress_t cctx;
1201 REQUIRE(lookup != NULL);
1204 debug("setup_lookup(%p)", lookup);
1206 result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
1208 check_result(result, "dns_message_create");
1210 if (lookup->new_search) {
1211 debug("resetting lookup counter.");
1215 if (ISC_LIST_EMPTY(lookup->my_server_list)) {
1216 debug("cloning server list");
1217 clone_server_list(server_list, &lookup->my_server_list);
1219 result = dns_message_gettempname(lookup->sendmsg, &lookup->name);
1220 check_result(result, "dns_message_gettempname");
1221 dns_name_init(lookup->name, NULL);
1223 isc_buffer_init(&lookup->namebuf, lookup->namespace,
1224 sizeof(lookup->namespace));
1225 isc_buffer_init(&lookup->onamebuf, lookup->onamespace,
1226 sizeof(lookup->onamespace));
1229 * If the name has too many dots, force the origin to be NULL
1230 * (which produces an absolute lookup). Otherwise, take the origin
1231 * we have if there's one in the struct already. If it's NULL,
1232 * take the first entry in the searchlist iff either usesearch
1233 * is TRUE or we got a domain line in the resolv.conf file.
1235 /* XXX New search here? */
1236 if ((count_dots(lookup->textname) >= ndots) || !usesearch)
1237 lookup->origin = NULL; /* Force abs lookup */
1238 else if (lookup->origin == NULL && lookup->new_search && usesearch) {
1239 lookup->origin = ISC_LIST_HEAD(search_list);
1241 if (lookup->origin != NULL) {
1242 debug("trying origin %s", lookup->origin->origin);
1243 result = dns_message_gettempname(lookup->sendmsg,
1245 check_result(result, "dns_message_gettempname");
1246 dns_name_init(lookup->oname, NULL);
1247 /* XXX Helper funct to conv char* to name? */
1248 len = strlen(lookup->origin->origin);
1249 isc_buffer_init(&b, lookup->origin->origin, len);
1250 isc_buffer_add(&b, len);
1251 result = dns_name_fromtext(lookup->oname, &b, dns_rootname,
1252 ISC_FALSE, &lookup->onamebuf);
1253 if (result != ISC_R_SUCCESS) {
1254 dns_message_puttempname(lookup->sendmsg,
1256 dns_message_puttempname(lookup->sendmsg,
1258 fatal("'%s' is not in legal name syntax (%s)",
1259 lookup->origin->origin,
1260 isc_result_totext(result));
1262 if (lookup->trace && lookup->trace_root) {
1263 dns_name_clone(dns_rootname, lookup->name);
1265 len = strlen(lookup->textname);
1266 isc_buffer_init(&b, lookup->textname, len);
1267 isc_buffer_add(&b, len);
1268 result = dns_name_fromtext(lookup->name, &b,
1269 lookup->oname, ISC_FALSE,
1272 if (result != ISC_R_SUCCESS) {
1273 dns_message_puttempname(lookup->sendmsg,
1275 dns_message_puttempname(lookup->sendmsg,
1277 fatal("'%s' is not in legal name syntax (%s)",
1278 lookup->textname, isc_result_totext(result));
1280 dns_message_puttempname(lookup->sendmsg, &lookup->oname);
1282 debug("using root origin");
1283 if (lookup->trace && lookup->trace_root)
1284 dns_name_clone(dns_rootname, lookup->name);
1286 len = strlen(lookup->textname);
1287 isc_buffer_init(&b, lookup->textname, len);
1288 isc_buffer_add(&b, len);
1289 result = dns_name_fromtext(lookup->name, &b,
1294 if (result != ISC_R_SUCCESS) {
1295 dns_message_puttempname(lookup->sendmsg,
1297 isc_buffer_init(&b, store, MXNAME);
1298 fatal("'%s' is not a legal name "
1299 "(%s)", lookup->textname,
1300 isc_result_totext(result));
1303 dns_name_format(lookup->name, store, sizeof(store));
1304 trying(store, lookup);
1305 INSIST(dns_name_isabsolute(lookup->name));
1307 isc_random_get(&id);
1308 lookup->sendmsg->id = (unsigned short)id & 0xFFFF;
1309 lookup->sendmsg->opcode = dns_opcode_query;
1310 lookup->msgcounter = 0;
1312 * If this is a trace request, completely disallow recursion, since
1313 * it's meaningless for traces.
1315 if (lookup->trace || (lookup->ns_search_only && !lookup->trace_root))
1316 lookup->recurse = ISC_FALSE;
1318 if (lookup->recurse &&
1319 lookup->rdtype != dns_rdatatype_axfr &&
1320 lookup->rdtype != dns_rdatatype_ixfr) {
1321 debug("recursive query");
1322 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_RD;
1326 if (lookup->aaonly) {
1328 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AA;
1331 if (lookup->adflag) {
1333 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AD;
1336 if (lookup->cdflag) {
1338 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_CD;
1341 dns_message_addname(lookup->sendmsg, lookup->name,
1342 DNS_SECTION_QUESTION);
1344 if (lookup->trace && lookup->trace_root) {
1345 lookup->qrdtype = lookup->rdtype;
1346 lookup->rdtype = dns_rdatatype_ns;
1349 if ((lookup->rdtype == dns_rdatatype_axfr) ||
1350 (lookup->rdtype == dns_rdatatype_ixfr)) {
1351 lookup->doing_xfr = ISC_TRUE;
1353 * Force TCP mode if we're doing an xfr.
1354 * XXX UDP ixfr's would be useful
1356 lookup->tcp_mode = ISC_TRUE;
1359 add_question(lookup->sendmsg, lookup->name, lookup->rdclass,
1363 if (lookup->rdtype == dns_rdatatype_ixfr)
1366 /* XXX Insist this? */
1367 lookup->tsigctx = NULL;
1368 lookup->querysig = NULL;
1370 debug("initializing keys");
1371 result = dns_message_settsigkey(lookup->sendmsg, key);
1372 check_result(result, "dns_message_settsigkey");
1375 lookup->sendspace = isc_mempool_get(commctx);
1376 if (lookup->sendspace == NULL)
1377 fatal("memory allocation failure");
1379 result = dns_compress_init(&cctx, -1, mctx);
1380 check_result(result, "dns_compress_init");
1382 debug("starting to render the message");
1383 isc_buffer_init(&lookup->sendbuf, lookup->sendspace, COMMSIZE);
1384 result = dns_message_renderbegin(lookup->sendmsg, &cctx,
1386 check_result(result, "dns_message_renderbegin");
1387 if (lookup->udpsize > 0 || lookup->dnssec) {
1388 if (lookup->udpsize == 0)
1389 lookup->udpsize = 2048;
1390 add_opt(lookup->sendmsg, lookup->udpsize, lookup->dnssec);
1393 result = dns_message_rendersection(lookup->sendmsg,
1394 DNS_SECTION_QUESTION, 0);
1395 check_result(result, "dns_message_rendersection");
1396 result = dns_message_rendersection(lookup->sendmsg,
1397 DNS_SECTION_AUTHORITY, 0);
1398 check_result(result, "dns_message_rendersection");
1399 result = dns_message_renderend(lookup->sendmsg);
1400 check_result(result, "dns_message_renderend");
1401 debug("done rendering");
1403 dns_compress_invalidate(&cctx);
1406 * Force TCP mode if the request is larger than 512 bytes.
1408 if (isc_buffer_usedlength(&lookup->sendbuf) > 512)
1409 lookup->tcp_mode = ISC_TRUE;
1411 lookup->pending = ISC_FALSE;
1413 for (serv = ISC_LIST_HEAD(lookup->my_server_list);
1415 serv = ISC_LIST_NEXT(serv, link)) {
1416 query = isc_mem_allocate(mctx, sizeof(dig_query_t));
1418 fatal("Memory allocation failure in %s:%d",
1419 __FILE__, __LINE__);
1420 debug("create query %p linked to lookup %p",
1422 query->lookup = lookup;
1423 query->waiting_connect = ISC_FALSE;
1424 query->recv_made = ISC_FALSE;
1425 query->first_pass = ISC_TRUE;
1426 query->first_soa_rcvd = ISC_FALSE;
1427 query->second_rr_rcvd = ISC_FALSE;
1428 query->first_repeat_rcvd = ISC_FALSE;
1429 query->warn_id = ISC_TRUE;
1430 query->first_rr_serial = 0;
1431 query->second_rr_serial = 0;
1432 query->servname = serv->servername;
1433 query->rr_count = 0;
1434 ISC_LINK_INIT(query, link);
1435 ISC_LIST_INIT(query->recvlist);
1436 ISC_LIST_INIT(query->lengthlist);
1438 query->recvspace = isc_mempool_get(commctx);
1439 if (query->recvspace == NULL)
1440 fatal("memory allocation failure");
1442 isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
1443 isc_buffer_init(&query->lengthbuf, query->lengthspace, 2);
1444 isc_buffer_init(&query->slbuf, query->slspace, 2);
1446 ISC_LINK_INIT(query, link);
1447 ISC_LIST_ENQUEUE(lookup->q, query, link);
1449 /* XXX qrflag, print_query, etc... */
1450 if (!ISC_LIST_EMPTY(lookup->q) && qr) {
1451 printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg,
1457 * Event handler for send completion. Track send counter, and clear out
1458 * the query if the send was canceled.
1461 send_done(isc_task_t *_task, isc_event_t *event) {
1462 REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1468 isc_event_free(&event);
1470 debug("send_done()");
1472 debug("sendcount=%d", sendcount);
1473 INSIST(sendcount >= 0);
1479 * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding
1480 * IO sockets. The cancel handlers should take care of cleaning up the
1481 * query and lookup structures
1484 cancel_lookup(dig_lookup_t *lookup) {
1485 dig_query_t *query, *next;
1487 debug("cancel_lookup()");
1488 query = ISC_LIST_HEAD(lookup->q);
1489 while (query != NULL) {
1490 next = ISC_LIST_NEXT(query, link);
1491 if (query->sock != NULL) {
1492 isc_socket_cancel(query->sock, global_task,
1493 ISC_SOCKCANCEL_ALL);
1500 if (lookup->timer != NULL)
1501 isc_timer_detach(&lookup->timer);
1502 lookup->pending = ISC_FALSE;
1503 lookup->retries = 0;
1507 bringup_timer(dig_query_t *query, unsigned int default_timeout) {
1509 unsigned int local_timeout;
1510 isc_result_t result;
1512 debug("bringup_timer()");
1514 * If the timer already exists, that means we're calling this
1515 * a second time (for a retry). Don't need to recreate it,
1519 if (ISC_LIST_NEXT(query, link) != NULL)
1520 local_timeout = SERVER_TIMEOUT;
1523 local_timeout = default_timeout;
1525 local_timeout = timeout;
1527 debug("have local timeout of %d", local_timeout);
1528 isc_interval_set(&l->interval, local_timeout, 0);
1529 if (l->timer != NULL)
1530 isc_timer_detach(&l->timer);
1531 result = isc_timer_create(timermgr,
1538 check_result(result, "isc_timer_create");
1542 connect_done(isc_task_t *task, isc_event_t *event);
1545 * Unlike send_udp, this can't be called multiple times with the same
1546 * query. When we retry TCP, we requeue the whole lookup, which should
1550 send_tcp_connect(dig_query_t *query) {
1551 isc_result_t result;
1555 debug("send_tcp_connect(%p)", query);
1558 query->waiting_connect = ISC_TRUE;
1559 query->lookup->current_query = query;
1560 get_address(query->servname, port, &query->sockaddr);
1562 if (specified_source &&
1563 (isc_sockaddr_pf(&query->sockaddr) !=
1564 isc_sockaddr_pf(&bind_address))) {
1565 printf(";; Skipping server %s, incompatible "
1566 "address family\n", query->servname);
1567 query->waiting_connect = ISC_FALSE;
1568 next = ISC_LIST_NEXT(query, link);
1572 printf(";; No acceptable nameservers\n");
1573 check_next_lookup(l);
1576 send_tcp_connect(next);
1579 INSIST(query->sock == NULL);
1580 result = isc_socket_create(socketmgr,
1581 isc_sockaddr_pf(&query->sockaddr),
1582 isc_sockettype_tcp, &query->sock) ;
1583 check_result(result, "isc_socket_create");
1585 debug("sockcount=%d", sockcount);
1586 if (specified_source)
1587 result = isc_socket_bind(query->sock, &bind_address);
1589 if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) &&
1591 isc_sockaddr_any(&bind_any);
1593 isc_sockaddr_any6(&bind_any);
1594 result = isc_socket_bind(query->sock, &bind_any);
1596 check_result(result, "isc_socket_bind");
1597 bringup_timer(query, TCP_TIMEOUT);
1598 result = isc_socket_connect(query->sock, &query->sockaddr,
1599 global_task, connect_done, query);
1600 check_result(result, "isc_socket_connect");
1602 * If we're at the endgame of a nameserver search, we need to
1603 * immediately bring up all the queries. Do it here.
1605 if (l->ns_search_only && !l->trace_root) {
1606 debug("sending next, since searching");
1607 next = ISC_LIST_NEXT(query, link);
1609 send_tcp_connect(next);
1614 * Send a UDP packet to the remote nameserver, possible starting the
1615 * recv action as well. Also make sure that the timer is running and
1616 * is properly reset.
1619 send_udp(dig_query_t *query) {
1620 dig_lookup_t *l = NULL;
1622 isc_result_t result;
1624 debug("send_udp(%p)", query);
1627 bringup_timer(query, UDP_TIMEOUT);
1628 l->current_query = query;
1629 debug("working on lookup %p, query %p",
1630 query->lookup, query);
1631 if (!query->recv_made) {
1632 /* XXX Check the sense of this, need assertion? */
1633 query->waiting_connect = ISC_FALSE;
1634 get_address(query->servname, port, &query->sockaddr);
1636 result = isc_socket_create(socketmgr,
1637 isc_sockaddr_pf(&query->sockaddr),
1638 isc_sockettype_udp, &query->sock);
1639 check_result(result, "isc_socket_create");
1641 debug("sockcount=%d", sockcount);
1642 if (specified_source) {
1643 result = isc_socket_bind(query->sock, &bind_address);
1645 isc_sockaddr_anyofpf(&bind_any,
1646 isc_sockaddr_pf(&query->sockaddr));
1647 result = isc_socket_bind(query->sock, &bind_any);
1649 check_result(result, "isc_socket_bind");
1651 query->recv_made = ISC_TRUE;
1652 ISC_LINK_INIT(&query->recvbuf, link);
1653 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf,
1655 debug("recving with lookup=%p, query=%p, sock=%p",
1656 query->lookup, query,
1658 result = isc_socket_recvv(query->sock,
1659 &query->recvlist, 1,
1660 global_task, recv_done,
1662 check_result(result, "isc_socket_recvv");
1664 debug("recvcount=%d", recvcount);
1666 ISC_LIST_INIT(query->sendlist);
1667 ISC_LINK_INIT(&l->sendbuf, link);
1668 ISC_LIST_ENQUEUE(query->sendlist, &l->sendbuf,
1670 debug("sending a request");
1671 result = isc_time_now(&query->time_sent);
1672 check_result(result, "isc_time_now");
1673 INSIST(query->sock != NULL);
1674 result = isc_socket_sendtov(query->sock, &query->sendlist,
1675 global_task, send_done, query,
1676 &query->sockaddr, NULL);
1677 check_result(result, "isc_socket_sendtov");
1680 * If we're at the endgame of a nameserver search, we need to
1681 * immediately bring up all the queries. Do it here.
1683 if (l->ns_search_only && !l->trace_root) {
1684 debug("sending next, since searching");
1685 next = ISC_LIST_NEXT(query, link);
1692 * IO timeout handler, used for both connect and recv timeouts. If
1693 * retries are still allowed, either resend the UDP packet or queue a
1694 * new TCP lookup. Otherwise, cancel the lookup.
1697 connect_timeout(isc_task_t *task, isc_event_t *event) {
1698 dig_lookup_t *l=NULL, *n;
1699 dig_query_t *query=NULL, *cq;
1702 REQUIRE(event->ev_type == ISC_TIMEREVENT_IDLE);
1704 debug("connect_timeout()");
1708 query = l->current_query;
1709 isc_event_free(&event);
1713 if ((query != NULL) && (query->lookup->current_query != NULL) &&
1714 (ISC_LIST_NEXT(query->lookup->current_query, link) != NULL)) {
1715 debug("trying next server...");
1716 cq = query->lookup->current_query;
1718 send_udp(ISC_LIST_NEXT(cq, link));
1720 send_tcp_connect(ISC_LIST_NEXT(cq, link));
1725 if (l->retries > 1) {
1728 debug("resending UDP request to first server");
1729 send_udp(ISC_LIST_HEAD(l->q));
1731 debug("making new TCP request, %d tries left",
1734 n = requeue_lookup(l, ISC_TRUE);
1736 check_next_lookup(l);
1739 fputs(l->cmdline, stdout);
1740 printf(";; connection timed out; no servers could be "
1743 check_next_lookup(l);
1751 * Event handler for the TCP recv which gets the length header of TCP
1752 * packets. Start the next recv of length bytes.
1755 tcp_length_done(isc_task_t *task, isc_event_t *event) {
1756 isc_socketevent_t *sevent;
1757 isc_buffer_t *b = NULL;
1758 isc_result_t result;
1759 dig_query_t *query = NULL;
1761 isc_uint16_t length;
1763 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
1768 debug("tcp_length_done()");
1771 sevent = (isc_socketevent_t *)event;
1772 query = event->ev_arg;
1775 INSIST(recvcount >= 0);
1777 if (sevent->result == ISC_R_CANCELED) {
1778 isc_event_free(&event);
1781 check_next_lookup(l);
1785 if (sevent->result != ISC_R_SUCCESS) {
1786 char sockstr[ISC_SOCKADDR_FORMATSIZE];
1787 isc_sockaddr_format(&query->sockaddr, sockstr,
1789 printf(";; communications error to %s: %s\n",
1790 sockstr, isc_result_totext(sevent->result));
1792 isc_socket_detach(&query->sock);
1794 debug("sockcount=%d", sockcount);
1795 INSIST(sockcount >= 0);
1796 isc_event_free(&event);
1798 check_next_lookup(l);
1802 b = ISC_LIST_HEAD(sevent->bufferlist);
1803 ISC_LIST_DEQUEUE(sevent->bufferlist, &query->lengthbuf, link);
1804 length = isc_buffer_getuint16(b);
1806 isc_event_free(&event);
1807 launch_next_query(query, ISC_FALSE);
1813 * Even though the buffer was already init'ed, we need
1814 * to redo it now, to force the length we want.
1816 isc_buffer_invalidate(&query->recvbuf);
1817 isc_buffer_init(&query->recvbuf, query->recvspace, length);
1818 ENSURE(ISC_LIST_EMPTY(query->recvlist));
1819 ISC_LINK_INIT(&query->recvbuf, link);
1820 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
1821 debug("recving with lookup=%p, query=%p",
1822 query->lookup, query);
1823 result = isc_socket_recvv(query->sock, &query->recvlist, length, task,
1825 check_result(result, "isc_socket_recvv");
1827 debug("resubmitted recv request with length %d, recvcount=%d",
1829 isc_event_free(&event);
1834 * For transfers that involve multiple recvs (XFR's in particular),
1835 * launch the next recv.
1838 launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
1839 isc_result_t result;
1844 debug("launch_next_query()");
1846 if (!query->lookup->pending) {
1847 debug("ignoring launch_next_query because !pending");
1848 isc_socket_detach(&query->sock);
1850 debug("sockcount=%d", sockcount);
1851 INSIST(sockcount >= 0);
1852 query->waiting_connect = ISC_FALSE;
1855 check_next_lookup(l);
1859 isc_buffer_clear(&query->slbuf);
1860 isc_buffer_clear(&query->lengthbuf);
1861 isc_buffer_putuint16(&query->slbuf, (isc_uint16_t) query->lookup->sendbuf.used);
1862 ISC_LIST_INIT(query->sendlist);
1863 ISC_LINK_INIT(&query->slbuf, link);
1864 ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link);
1865 if (include_question) {
1866 ISC_LINK_INIT(&query->lookup->sendbuf, link);
1867 ISC_LIST_ENQUEUE(query->sendlist, &query->lookup->sendbuf,
1870 ISC_LINK_INIT(&query->lengthbuf, link);
1871 ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link);
1873 result = isc_socket_recvv(query->sock, &query->lengthlist, 0,
1874 global_task, tcp_length_done, query);
1875 check_result(result, "isc_socket_recvv");
1877 debug("recvcount=%d",recvcount);
1878 if (!query->first_soa_rcvd) {
1879 debug("sending a request in launch_next_query");
1880 result = isc_time_now(&query->time_sent);
1881 check_result(result, "isc_time_now");
1882 result = isc_socket_sendv(query->sock, &query->sendlist,
1883 global_task, send_done, query);
1884 check_result(result, "isc_socket_sendv");
1886 debug("sendcount=%d", sendcount);
1888 query->waiting_connect = ISC_FALSE;
1890 check_next_lookup(query->lookup);
1896 * Event handler for TCP connect complete. Make sure the connection was
1897 * successful, then pass into launch_next_query to actually send the
1901 connect_done(isc_task_t *task, isc_event_t *event) {
1902 isc_socketevent_t *sevent = NULL;
1903 dig_query_t *query = NULL, *next;
1908 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
1911 debug("connect_done()");
1914 sevent = (isc_socketevent_t *)event;
1915 query = sevent->ev_arg;
1917 INSIST(query->waiting_connect);
1919 query->waiting_connect = ISC_FALSE;
1921 if (sevent->result == ISC_R_CANCELED) {
1922 debug("in cancel handler");
1923 isc_socket_detach(&query->sock);
1925 INSIST(sockcount >= 0);
1926 debug("sockcount=%d", sockcount);
1927 query->waiting_connect = ISC_FALSE;
1928 isc_event_free(&event);
1931 check_next_lookup(l);
1935 if (sevent->result != ISC_R_SUCCESS) {
1936 char sockstr[ISC_SOCKADDR_FORMATSIZE];
1938 debug("unsuccessful connection: %s",
1939 isc_result_totext(sevent->result));
1940 isc_sockaddr_format(&query->sockaddr, sockstr,
1942 if (sevent->result != ISC_R_CANCELED)
1943 printf(";; Connection to %s(%s) for %s failed: "
1945 query->servname, query->lookup->textname,
1946 isc_result_totext(sevent->result));
1947 isc_socket_detach(&query->sock);
1949 INSIST(sockcount >= 0);
1950 /* XXX Clean up exitcodes */
1953 debug("sockcount=%d", sockcount);
1954 query->waiting_connect = ISC_FALSE;
1955 isc_event_free(&event);
1957 if (l->current_query != NULL)
1958 next = ISC_LIST_NEXT(l->current_query, link);
1963 bringup_timer(next, TCP_TIMEOUT);
1964 send_tcp_connect(next);
1966 check_next_lookup(l);
1971 launch_next_query(query, ISC_TRUE);
1972 isc_event_free(&event);
1977 * Check if the ongoing XFR needs more data before it's complete, using
1978 * the semantics of IXFR and AXFR protocols. Much of the complexity of
1979 * this routine comes from determining when an IXFR is complete.
1980 * ISC_FALSE means more data is on the way, and the recv has been issued.
1982 static isc_boolean_t
1983 check_for_more_data(dig_query_t *query, dns_message_t *msg,
1984 isc_socketevent_t *sevent)
1986 dns_rdataset_t *rdataset = NULL;
1987 dns_rdata_t rdata = DNS_RDATA_INIT;
1988 dns_rdata_soa_t soa;
1989 isc_uint32_t serial;
1990 isc_result_t result;
1992 debug("check_for_more_data()");
1995 * By the time we're in this routine, we know we're doing
1996 * either an AXFR or IXFR. If there's no second_rr_type,
1997 * then we don't yet know which kind of answer we got back
1998 * from the server. Here, we're going to walk through the
1999 * rr's in the message, acting as necessary whenever we hit
2003 result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
2004 if (result != ISC_R_SUCCESS) {
2005 puts("; Transfer failed.");
2011 dns_message_currentname(msg, DNS_SECTION_ANSWER,
2013 for (rdataset = ISC_LIST_HEAD(name->list);
2015 rdataset = ISC_LIST_NEXT(rdataset, link)) {
2016 result = dns_rdataset_first(rdataset);
2017 if (result != ISC_R_SUCCESS)
2021 dns_rdata_reset(&rdata);
2022 dns_rdataset_current(rdataset, &rdata);
2024 * If this is the first rr, make sure
2027 if ((!query->first_soa_rcvd) &&
2028 (rdata.type != dns_rdatatype_soa)) {
2029 puts("; Transfer failed. "
2030 "Didn't start with "
2034 if ((!query->second_rr_rcvd) &&
2035 (rdata.type != dns_rdatatype_soa)) {
2036 query->second_rr_rcvd = ISC_TRUE;
2037 query->second_rr_serial = 0;
2038 debug("got the second rr as nonsoa");
2043 * If the record is anything except an SOA
2044 * now, just continue on...
2046 if (rdata.type != dns_rdatatype_soa)
2048 /* Now we have an SOA. Work with it. */
2049 debug("got an SOA");
2050 (void)dns_rdata_tostruct(&rdata, &soa, NULL);
2051 serial = soa.serial;
2052 dns_rdata_freestruct(&soa);
2053 if (!query->first_soa_rcvd) {
2054 query->first_soa_rcvd = ISC_TRUE;
2055 query->first_rr_serial = serial;
2056 debug("this is the first %d",
2057 query->lookup->ixfr_serial);
2058 if (query->lookup->ixfr_serial >=
2063 if (query->lookup->rdtype ==
2064 dns_rdatatype_axfr) {
2065 debug("doing axfr, got second SOA");
2068 if (!query->second_rr_rcvd) {
2069 if (query->first_rr_serial == serial) {
2070 debug("doing ixfr, got "
2074 debug("this is the second %d",
2075 query->lookup->ixfr_serial);
2076 query->second_rr_rcvd = ISC_TRUE;
2077 query->second_rr_serial = serial;
2080 if (query->second_rr_serial == 0) {
2082 * If the second RR was a non-SOA
2083 * record, and we're getting any
2084 * other SOA, then this is an
2085 * AXFR, and we're done.
2087 debug("done, since axfr");
2091 * If we get to this point, we're doing an
2092 * IXFR and have to start really looking
2093 * at serial numbers.
2095 if (query->first_rr_serial == serial) {
2096 debug("got a match for ixfr");
2097 if (!query->first_repeat_rcvd) {
2098 query->first_repeat_rcvd =
2102 debug("done with ixfr");
2105 debug("meaningless soa %d", serial);
2107 result = dns_rdataset_next(rdataset);
2108 } while (result == ISC_R_SUCCESS);
2110 result = dns_message_nextname(msg, DNS_SECTION_ANSWER);
2111 } while (result == ISC_R_SUCCESS);
2112 launch_next_query(query, ISC_FALSE);
2115 received(sevent->n, &sevent->address, query);
2120 * Event handler for recv complete. Perform whatever actions are necessary,
2121 * based on the specifics of the user's request.
2124 recv_done(isc_task_t *task, isc_event_t *event) {
2125 isc_socketevent_t *sevent = NULL;
2126 dig_query_t *query = NULL;
2127 isc_buffer_t *b = NULL;
2128 dns_message_t *msg = NULL;
2129 isc_result_t result;
2130 dig_lookup_t *n, *l;
2131 isc_boolean_t docancel = ISC_FALSE;
2132 isc_boolean_t match = ISC_TRUE;
2133 unsigned int parseflags;
2135 unsigned int msgflags;
2140 debug("recv_done()");
2144 debug("recvcount=%d", recvcount);
2145 INSIST(recvcount >= 0);
2147 query = event->ev_arg;
2148 debug("lookup=%p, query=%p", query->lookup, query);
2152 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
2153 sevent = (isc_socketevent_t *)event;
2155 if ((l->tcp_mode) && (l->timer != NULL))
2156 isc_timer_touch(l->timer);
2157 if ((!l->pending && !l->ns_search_only) || cancel_now) {
2158 debug("no longer pending. Got %s",
2159 isc_result_totext(sevent->result));
2160 query->waiting_connect = ISC_FALSE;
2162 isc_event_free(&event);
2164 check_next_lookup(l);
2169 if (sevent->result != ISC_R_SUCCESS) {
2170 if (sevent->result == ISC_R_CANCELED) {
2171 debug("in recv cancel handler");
2172 query->waiting_connect = ISC_FALSE;
2174 printf(";; communications error: %s\n",
2175 isc_result_totext(sevent->result));
2176 isc_socket_detach(&query->sock);
2178 debug("sockcount=%d", sockcount);
2179 INSIST(sockcount >= 0);
2181 isc_event_free(&event);
2183 check_next_lookup(l);
2188 b = ISC_LIST_HEAD(sevent->bufferlist);
2189 ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link);
2192 !isc_sockaddr_equal(&sevent->address, &query->sockaddr)) {
2193 char buf1[ISC_SOCKADDR_FORMATSIZE];
2194 char buf2[ISC_SOCKADDR_FORMATSIZE];
2197 if (isc_sockaddr_pf(&query->sockaddr) == AF_INET)
2198 isc_sockaddr_any(&any);
2200 isc_sockaddr_any6(&any);
2203 * We don't expect a match when the packet is
2204 * sent to 0.0.0.0, :: or to a multicast addresses.
2205 * XXXMPA broadcast needs to be handled here as well.
2207 if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) &&
2208 !isc_sockaddr_ismulticast(&query->sockaddr)) ||
2209 isc_sockaddr_getport(&query->sockaddr) !=
2210 isc_sockaddr_getport(&sevent->address)) {
2211 isc_sockaddr_format(&sevent->address, buf1,
2213 isc_sockaddr_format(&query->sockaddr, buf2,
2215 printf(";; reply from unexpected source: %s,"
2216 " expected %s\n", buf1, buf2);
2221 result = dns_message_peekheader(b, &id, &msgflags);
2222 if (result != ISC_R_SUCCESS || l->sendmsg->id != id) {
2225 isc_boolean_t fail = ISC_TRUE;
2226 if (result == ISC_R_SUCCESS) {
2227 if (!query->first_soa_rcvd ||
2229 printf(";; %s: ID mismatch: "
2230 "expected ID %u, got %u\n",
2231 query->first_soa_rcvd ?
2232 "WARNING" : "ERROR",
2233 l->sendmsg->id, id);
2234 if (query->first_soa_rcvd)
2236 query->warn_id = ISC_FALSE;
2238 printf(";; ERROR: short (< header size) message\n");
2240 isc_event_free(&event);
2242 check_next_lookup(l);
2247 } else if (result == ISC_R_SUCCESS)
2248 printf(";; Warning: ID mismatch: "
2249 "expected ID %u, got %u\n", l->sendmsg->id, id);
2251 printf(";; Warning: short (< header size) message received\n");
2255 isc_buffer_invalidate(&query->recvbuf);
2256 isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
2257 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
2258 result = isc_socket_recvv(query->sock, &query->recvlist, 1,
2259 global_task, recv_done, query);
2260 check_result(result, "isc_socket_recvv");
2262 isc_event_free(&event);
2267 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
2268 check_result(result, "dns_message_create");
2271 if (l->querysig == NULL) {
2272 debug("getting initial querysig");
2273 result = dns_message_getquerytsig(l->sendmsg, mctx,
2275 check_result(result, "dns_message_getquerytsig");
2277 result = dns_message_setquerytsig(msg, l->querysig);
2278 check_result(result, "dns_message_setquerytsig");
2279 result = dns_message_settsigkey(msg, key);
2280 check_result(result, "dns_message_settsigkey");
2281 msg->tsigctx = l->tsigctx;
2283 if (l->msgcounter != 0)
2284 msg->tcp_continuation = 1;
2288 debug("before parse starts");
2289 parseflags = DNS_MESSAGEPARSE_PRESERVEORDER;
2290 if (l->besteffort) {
2291 parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
2292 parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION;
2294 result = dns_message_parse(msg, b, parseflags);
2295 if (result == DNS_R_RECOVERABLE) {
2296 printf(";; Warning: Message parser reports malformed "
2297 "message packet.\n");
2298 result = ISC_R_SUCCESS;
2300 if (result != ISC_R_SUCCESS) {
2301 printf(";; Got bad packet: %s\n", isc_result_totext(result));
2303 query->waiting_connect = ISC_FALSE;
2304 dns_message_destroy(&msg);
2305 isc_event_free(&event);
2308 check_next_lookup(l);
2312 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0
2313 && !l->ignore && !l->tcp_mode)
2315 printf(";; Truncated, retrying in TCP mode.\n");
2316 n = requeue_lookup(l, ISC_TRUE);
2317 n->tcp_mode = ISC_TRUE;
2318 n->origin = query->lookup->origin;
2319 dns_message_destroy(&msg);
2320 isc_event_free(&event);
2323 check_next_lookup(l);
2327 if (msg->rcode == dns_rcode_servfail && !l->servfail_stops) {
2328 dig_query_t *next = ISC_LIST_NEXT(query, link);
2329 if (l->current_query == query)
2330 l->current_query = NULL;
2332 debug("sending query %p\n", next);
2334 send_tcp_connect(next);
2339 * If our query is at the head of the list and there
2340 * is no next, we're the only one left, so fall
2341 * through to print the message.
2343 if ((ISC_LIST_HEAD(l->q) != query) ||
2344 (ISC_LIST_NEXT(query, link) != NULL)) {
2345 printf(";; Got SERVFAIL reply from %s, "
2346 "trying next server\n",
2349 check_next_lookup(l);
2350 dns_message_destroy(&msg);
2351 isc_event_free(&event);
2358 result = dns_tsig_verify(&query->recvbuf, msg, NULL, NULL);
2359 if (result != ISC_R_SUCCESS) {
2360 printf(";; Couldn't verify signature: %s\n",
2361 isc_result_totext(result));
2362 validated = ISC_FALSE;
2364 l->tsigctx = msg->tsigctx;
2365 msg->tsigctx = NULL;
2366 if (l->querysig != NULL) {
2367 debug("freeing querysig buffer %p", l->querysig);
2368 isc_buffer_free(&l->querysig);
2370 result = dns_message_getquerytsig(msg, mctx, &l->querysig);
2371 check_result(result,"dns_message_getquerytsig");
2374 debug("after parse");
2375 if (l->doing_xfr && l->xfr_q == NULL) {
2378 * Once we are in the XFR message, increase
2379 * the timeout to much longer, so brief network
2380 * outages won't cause the XFR to abort
2382 if (timeout != INT_MAX && l->timer != NULL) {
2383 unsigned int local_timeout;
2387 local_timeout = TCP_TIMEOUT * 4;
2389 local_timeout = UDP_TIMEOUT * 4;
2391 if (timeout < (INT_MAX / 4))
2392 local_timeout = timeout * 4;
2394 local_timeout = INT_MAX;
2396 debug("have local timeout of %d", local_timeout);
2397 isc_interval_set(&l->interval, local_timeout, 0);
2398 result = isc_timer_reset(l->timer,
2403 check_result(result, "isc_timer_reset");
2407 if (!l->doing_xfr || l->xfr_q == query) {
2408 if (msg->rcode != dns_rcode_noerror && l->origin != NULL) {
2409 if (!next_origin(msg, query)) {
2410 printmessage(query, msg, ISC_TRUE);
2411 received(b->used, &sevent->address, query);
2413 } else if (!l->trace && !l->ns_search_only) {
2414 printmessage(query, msg, ISC_TRUE);
2415 } else if (l->trace) {
2417 int count = msg->counts[DNS_SECTION_ANSWER];
2419 debug("in TRACE code");
2420 if (!l->ns_search_only)
2421 printmessage(query, msg, ISC_TRUE);
2423 l->rdtype = l->qrdtype;
2424 if (l->trace_root || (l->ns_search_only && count > 0))
2427 l->rdtype = dns_rdatatype_soa;
2428 n = followup_lookup(msg, query,
2429 DNS_SECTION_ANSWER);
2430 l->trace_root = ISC_FALSE;
2431 } else if (count == 0)
2432 n = followup_lookup(msg, query,
2433 DNS_SECTION_AUTHORITY);
2435 docancel = ISC_TRUE;
2437 debug("in NSSEARCH code");
2439 if (l->trace_root) {
2441 * This is the initial NS query.
2445 l->rdtype = dns_rdatatype_soa;
2446 n = followup_lookup(msg, query,
2447 DNS_SECTION_ANSWER);
2449 docancel = ISC_TRUE;
2450 l->trace_root = ISC_FALSE;
2452 printmessage(query, msg, ISC_TRUE);
2457 debug("still pending.");
2459 if (query != l->xfr_q) {
2460 dns_message_destroy(&msg);
2461 isc_event_free(&event);
2462 query->waiting_connect = ISC_FALSE;
2467 docancel = check_for_more_data(query, msg, sevent);
2469 dns_message_destroy(&msg);
2472 check_next_lookup(l);
2475 if (msg->rcode == dns_rcode_noerror || l->origin == NULL)
2476 received(b->used, &sevent->address, query);
2477 if (!query->lookup->ns_search_only)
2478 query->lookup->pending = ISC_FALSE;
2479 if (!query->lookup->ns_search_only ||
2480 query->lookup->trace_root || docancel)
2482 dns_message_destroy(&msg);
2486 check_next_lookup(l);
2489 dns_message_destroy(&msg);
2490 isc_event_free(&event);
2495 * Turn a name into an address, using system-supplied routines. This is
2496 * used in looking up server names, etc... and needs to use system-supplied
2497 * routines, since they may be using a non-DNS system for these lookups.
2500 get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) {
2502 struct in6_addr in6;
2503 #ifdef USE_GETADDRINFO
2504 struct addrinfo *res = NULL, hints;
2510 debug("get_address()");
2512 if (inet_pton(AF_INET6, host, &in6) == 1) {
2514 fatal("Protocol family INET6 not supported '%s'", host);
2515 isc_sockaddr_fromin6(sockaddr, &in6, port);
2516 } else if (inet_pton(AF_INET, host, &in4) == 1) {
2518 isc_sockaddr_fromin(sockaddr, &in4, port);
2520 isc_sockaddr_v6fromin(sockaddr, &in4, port);
2522 #ifdef USE_GETADDRINFO
2523 memset(&hints, 0, sizeof(hints));
2524 if (specified_source)
2525 hints.ai_family = isc_sockaddr_pf(&bind_address);
2526 else if (!have_ipv6)
2527 hints.ai_family = PF_INET;
2528 else if (!have_ipv4)
2529 hints.ai_family = PF_INET6;
2531 hints.ai_family = PF_UNSPEC;
2532 #ifdef AI_ADDRCONFIG
2533 hints.ai_flags = AI_ADDRCONFIG;
2536 debug ("before getaddrinfo()");
2538 #ifdef AI_ADDRCONFIG
2541 result = getaddrinfo(host, NULL, &hints, &res);
2542 #ifdef AI_ADDRCONFIG
2543 if (result == EAI_BADFLAGS &&
2544 (hints.ai_flags & AI_ADDRCONFIG) != 0) {
2545 hints.ai_flags &= ~AI_ADDRCONFIG;
2551 fatal("Couldn't find server '%s': %s",
2552 host, gai_strerror(result));
2554 memcpy(&sockaddr->type.sa, res->ai_addr, res->ai_addrlen);
2555 sockaddr->length = res->ai_addrlen;
2556 isc_sockaddr_setport(sockaddr, port);
2559 debug ("before gethostbyname()");
2561 he = gethostbyname(host);
2564 fatal("Couldn't find server '%s' (h_errno=%d)",
2566 INSIST(he->h_addrtype == AF_INET);
2567 isc_sockaddr_fromin(sockaddr,
2568 (struct in_addr *)(he->h_addr_list[0]),
2575 * Initiate either a TCP or UDP lookup
2578 do_lookup(dig_lookup_t *lookup) {
2580 REQUIRE(lookup != NULL);
2582 debug("do_lookup()");
2583 lookup->pending = ISC_TRUE;
2584 if (lookup->tcp_mode)
2585 send_tcp_connect(ISC_LIST_HEAD(lookup->q));
2587 send_udp(ISC_LIST_HEAD(lookup->q));
2591 * Start everything in action upon task startup.
2594 onrun_callback(isc_task_t *task, isc_event_t *event) {
2597 isc_event_free(&event);
2604 * Make everything on the lookup queue go away. Mainly used by the
2609 dig_lookup_t *l, *n;
2610 dig_query_t *q, *nq;
2612 debug("cancel_all()");
2619 cancel_now = ISC_TRUE;
2620 if (current_lookup != NULL) {
2621 if (current_lookup->timer != NULL)
2622 isc_timer_detach(¤t_lookup->timer);
2623 q = ISC_LIST_HEAD(current_lookup->q);
2625 debug("cancelling query %p, belonging to %p",
2627 nq = ISC_LIST_NEXT(q, link);
2628 if (q->sock != NULL) {
2629 isc_socket_cancel(q->sock, NULL,
2630 ISC_SOCKCANCEL_ALL);
2637 l = ISC_LIST_HEAD(lookup_list);
2639 n = ISC_LIST_NEXT(l, link);
2640 ISC_LIST_DEQUEUE(lookup_list, l, link);
2641 try_clear_lookup(l);
2648 * Destroy all of the libs we are using, and get everything ready for a
2652 destroy_libs(void) {
2656 debug("destroy_libs()");
2657 if (global_task != NULL) {
2658 debug("freeing task");
2659 isc_task_detach(&global_task);
2662 * The taskmgr_destroy() call blocks until all events are cleared
2665 if (taskmgr != NULL) {
2666 debug("freeing taskmgr");
2667 isc_taskmgr_destroy(&taskmgr);
2670 REQUIRE(sockcount == 0);
2671 REQUIRE(recvcount == 0);
2672 REQUIRE(sendcount == 0);
2674 INSIST(ISC_LIST_HEAD(lookup_list) == NULL);
2675 INSIST(current_lookup == NULL);
2678 free_now = ISC_TRUE;
2680 s = ISC_LIST_HEAD(server_list);
2682 debug("freeing global server %p", s);
2684 s = ISC_LIST_NEXT(s, link);
2685 isc_mem_free(mctx, ptr);
2688 if (commctx != NULL) {
2689 debug("freeing commctx");
2690 isc_mempool_destroy(&commctx);
2692 if (socketmgr != NULL) {
2693 debug("freeing socketmgr");
2694 isc_socketmgr_destroy(&socketmgr);
2696 if (timermgr != NULL) {
2697 debug("freeing timermgr");
2698 isc_timermgr_destroy(&timermgr);
2701 debug("freeing key %p", key);
2702 dns_tsigkey_detach(&key);
2704 if (namebuf != NULL)
2705 isc_buffer_free(&namebuf);
2708 debug("destroy DST lib");
2710 is_dst_up = ISC_FALSE;
2713 debug("detach from entropy");
2714 isc_entropy_detach(&entp);
2718 DESTROYLOCK(&lookup_lock);
2719 if (memdebugging != 0)
2720 isc_mem_stats(mctx, stderr);
2722 isc_mem_destroy(&mctx);