2 * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or 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.328.22.4 2010/08/10 08:43:40 marka Exp $ */
22 * Notice to programmers: Do not use this code as an example of how to
23 * use the ISC library to perform DNS lookups. Dig and Host both operate
24 * on the request level, since they allow fine-tuning of output and are
25 * intended as debugging tools. As a result, they perform many of the
26 * functions which could be better handled using the dns_resolver
27 * functions in most applications.
41 #include <idn/result.h>
43 #include <idn/resconf.h>
47 #include <dns/byaddr.h>
49 #include <dns/dnssec.h>
52 #include <isc/random.h>
55 #include <dns/fixedname.h>
57 #include <dns/message.h>
59 #include <dns/rdata.h>
60 #include <dns/rdataclass.h>
61 #include <dns/rdatalist.h>
62 #include <dns/rdataset.h>
63 #include <dns/rdatastruct.h>
64 #include <dns/rdatatype.h>
65 #include <dns/result.h>
71 #include <isc/base64.h>
72 #include <isc/entropy.h>
76 #include <isc/netaddr.h>
78 #include <isc/netdb.h>
80 #include <isc/parseint.h>
81 #include <isc/print.h>
82 #include <isc/random.h>
83 #include <isc/result.h>
84 #include <isc/string.h>
86 #include <isc/timer.h>
87 #include <isc/types.h>
90 #include <isccfg/namedconf.h>
92 #include <lwres/lwres.h>
93 #include <lwres/net.h>
95 #include <bind9/getaddresses.h>
99 #if ! defined(NS_INADDRSZ)
100 #define NS_INADDRSZ 4
103 #if ! defined(NS_IN6ADDRSZ)
104 #define NS_IN6ADDRSZ 16
107 static lwres_context_t *lwctx = NULL;
108 static lwres_conf_t *lwconf;
110 dig_lookuplist_t lookup_list;
111 dig_serverlist_t server_list;
112 dig_searchlistlist_t search_list;
115 check_ra = ISC_FALSE,
116 have_ipv4 = ISC_FALSE,
117 have_ipv6 = ISC_FALSE,
118 specified_source = ISC_FALSE,
119 free_now = ISC_FALSE,
120 cancel_now = ISC_FALSE,
121 usesearch = ISC_FALSE,
122 showsearch = ISC_FALSE,
124 is_dst_up = ISC_FALSE;
126 unsigned int timeout = 0;
127 unsigned int extrabytes;
128 isc_mem_t *mctx = NULL;
129 isc_log_t *lctx = NULL;
130 isc_taskmgr_t *taskmgr = NULL;
131 isc_task_t *global_task = NULL;
132 isc_timermgr_t *timermgr = NULL;
133 isc_socketmgr_t *socketmgr = NULL;
134 isc_sockaddr_t bind_address;
135 isc_sockaddr_t bind_any;
141 int lookup_counter = 0;
144 static void initialize_idn(void);
145 static isc_result_t output_filter(isc_buffer_t *buffer,
146 unsigned int used_org,
147 isc_boolean_t absolute);
148 static idn_result_t append_textname(char *name, const char *origin,
150 static void idn_check_result(idn_result_t r, const char *msg);
159 *\li 0 Everything went well, including things like NXDOMAIN
161 *\li 7 Got too many RR's or Names
162 *\li 8 Couldn't open batch file
163 *\li 9 No reply from server
164 *\li 10 Internal error
168 char keynametext[MXNAME];
169 char keyfile[MXNAME] = "";
170 char keysecret[MXNAME] = "";
171 dns_name_t *hmacname = NULL;
172 unsigned int digestbits = 0;
173 isc_buffer_t *namebuf = NULL;
174 dns_tsigkey_t *key = NULL;
175 isc_boolean_t validated = ISC_TRUE;
176 isc_entropy_t *entp = NULL;
177 isc_mempool_t *commctx = NULL;
178 isc_boolean_t debugging = ISC_FALSE;
179 isc_boolean_t memdebugging = ISC_FALSE;
180 char *progname = NULL;
181 isc_mutex_t lookup_lock;
182 dig_lookup_t *current_lookup = NULL;
186 isc_result_t get_trusted_key(isc_mem_t *mctx);
187 dns_rdataset_t * sigchase_scanname(dns_rdatatype_t type,
188 dns_rdatatype_t covers,
189 isc_boolean_t *lookedup,
190 dns_name_t *rdata_name);
191 dns_rdataset_t * chase_scanname_section(dns_message_t *msg,
193 dns_rdatatype_t type,
194 dns_rdatatype_t covers,
196 isc_result_t advanced_rrsearch(dns_rdataset_t **rdataset,
198 dns_rdatatype_t type,
199 dns_rdatatype_t covers,
200 isc_boolean_t *lookedup);
201 isc_result_t sigchase_verify_sig_key(dns_name_t *name,
202 dns_rdataset_t *rdataset,
203 dst_key_t* dnsseckey,
204 dns_rdataset_t *sigrdataset,
206 isc_result_t sigchase_verify_sig(dns_name_t *name,
207 dns_rdataset_t *rdataset,
208 dns_rdataset_t *keyrdataset,
209 dns_rdataset_t *sigrdataset,
211 isc_result_t sigchase_verify_ds(dns_name_t *name,
212 dns_rdataset_t *keyrdataset,
213 dns_rdataset_t *dsrdataset,
215 void sigchase(dns_message_t *msg);
216 void print_rdata(dns_rdata_t *rdata, isc_mem_t *mctx);
217 void print_rdataset(dns_name_t *name,
218 dns_rdataset_t *rdataset, isc_mem_t *mctx);
219 void dup_name(dns_name_t *source, dns_name_t* target,
221 void free_name(dns_name_t *name, isc_mem_t *mctx);
222 void dump_database(void);
223 void dump_database_section(dns_message_t *msg, int section);
224 dns_rdataset_t * search_type(dns_name_t *name, dns_rdatatype_t type,
225 dns_rdatatype_t covers);
226 isc_result_t contains_trusted_key(dns_name_t *name,
227 dns_rdataset_t *rdataset,
228 dns_rdataset_t *sigrdataset,
230 void print_type(dns_rdatatype_t type);
231 isc_result_t prove_nx_domain(dns_message_t * msg,
233 dns_name_t * rdata_name,
234 dns_rdataset_t ** rdataset,
235 dns_rdataset_t ** sigrdataset);
236 isc_result_t prove_nx_type(dns_message_t * msg, dns_name_t *name,
237 dns_rdataset_t *nsec,
238 dns_rdataclass_t class,
239 dns_rdatatype_t type,
240 dns_name_t * rdata_name,
241 dns_rdataset_t ** rdataset,
242 dns_rdataset_t ** sigrdataset);
243 isc_result_t prove_nx(dns_message_t * msg, dns_name_t * name,
244 dns_rdataclass_t class,
245 dns_rdatatype_t type,
246 dns_name_t * rdata_name,
247 dns_rdataset_t ** rdataset,
248 dns_rdataset_t ** sigrdataset);
249 static void nameFromString(const char *str, dns_name_t *p_ret);
250 int inf_name(dns_name_t * name1, dns_name_t * name2);
251 isc_result_t opentmpkey(isc_mem_t *mctx, const char *file,
252 char **tempp, FILE **fp);
253 isc_result_t removetmpkey(isc_mem_t *mctx, const char *file);
254 void clean_trustedkey(void);
255 void insert_trustedkey(dst_key_t * key);
257 isc_result_t getneededrr(dns_message_t *msg);
258 void sigchase_bottom_up(dns_message_t *msg);
259 void sigchase_bu(dns_message_t *msg);
262 isc_result_t initialization(dns_name_t *name);
263 isc_result_t prepare_lookup(dns_name_t *name);
264 isc_result_t grandfather_pb_test(dns_name_t * zone_name,
265 dns_rdataset_t *sigrdataset);
266 isc_result_t child_of_zone(dns_name_t *name,
267 dns_name_t *zone_name,
268 dns_name_t *child_name);
269 void sigchase_td(dns_message_t *msg);
271 char trustedkey[MXNAME] = "";
273 dns_rdataset_t *chase_rdataset = NULL;
274 dns_rdataset_t *chase_sigrdataset = NULL;
275 dns_rdataset_t *chase_dsrdataset = NULL;
276 dns_rdataset_t *chase_sigdsrdataset = NULL;
277 dns_rdataset_t *chase_keyrdataset = NULL;
278 dns_rdataset_t *chase_sigkeyrdataset = NULL;
279 dns_rdataset_t *chase_nsrdataset = NULL;
281 dns_name_t chase_name; /* the query name */
284 * the current name is the parent name when we follow delegation
286 dns_name_t chase_current_name;
288 * the child name is used for delegation (NS DS responses in AUTHORITY section)
290 dns_name_t chase_authority_name;
293 dns_name_t chase_signame;
297 isc_boolean_t chase_siglookedup = ISC_FALSE;
298 isc_boolean_t chase_keylookedup = ISC_FALSE;
299 isc_boolean_t chase_sigkeylookedup = ISC_FALSE;
300 isc_boolean_t chase_dslookedup = ISC_FALSE;
301 isc_boolean_t chase_sigdslookedup = ISC_FALSE;
303 isc_boolean_t chase_nslookedup = ISC_FALSE;
304 isc_boolean_t chase_lookedup = ISC_FALSE;
307 isc_boolean_t delegation_follow = ISC_FALSE;
308 isc_boolean_t grandfather_pb = ISC_FALSE;
309 isc_boolean_t have_response = ISC_FALSE;
310 isc_boolean_t have_delegation_ns = ISC_FALSE;
311 dns_message_t * error_message = NULL;
314 isc_boolean_t dsvalidating = ISC_FALSE;
315 isc_boolean_t chase_name_dup = ISC_FALSE;
317 ISC_LIST(dig_message_t) chase_message_list;
318 ISC_LIST(dig_message_t) chase_message_list2;
321 #define MAX_TRUSTED_KEY 5
322 typedef struct struct_trusted_key_list {
323 dst_key_t * key[MAX_TRUSTED_KEY];
327 struct_tk_list tk_list = { {NULL, NULL, NULL, NULL, NULL}, 0};
331 #define DIG_MAX_ADDRESSES 20
334 * Apply and clear locks at the event level in global task.
335 * Can I get rid of these using shutdown events? XXX
337 #define LOCK_LOOKUP {\
338 debug("lock_lookup %s:%d", __FILE__, __LINE__);\
339 check_result(isc_mutex_lock((&lookup_lock)), "isc_mutex_lock");\
342 #define UNLOCK_LOOKUP {\
343 debug("unlock_lookup %s:%d", __FILE__, __LINE__);\
344 check_result(isc_mutex_unlock((&lookup_lock)),\
345 "isc_mutex_unlock");\
349 cancel_lookup(dig_lookup_t *lookup);
352 recv_done(isc_task_t *task, isc_event_t *event);
355 send_udp(dig_query_t *query);
358 connect_timeout(isc_task_t *task, isc_event_t *event);
361 launch_next_query(dig_query_t *query, isc_boolean_t include_question);
365 mem_alloc(void *arg, size_t size) {
366 return (isc_mem_get(arg, size));
370 mem_free(void *arg, void *mem, size_t size) {
371 isc_mem_put(arg, mem, size);
375 next_token(char **stringp, const char *delim) {
379 res = strsep(stringp, delim);
382 } while (*res == '\0');
387 count_dots(char *string) {
401 hex_dump(isc_buffer_t *b) {
405 isc_buffer_usedregion(b, &r);
407 printf("%d bytes\n", r.length);
408 for (len = 0; len < r.length; len++) {
409 printf("%02x ", r.base[len]);
410 if (len % 16 == 15) {
412 for (i = len - 15; i <= len; i++) {
413 if (r.base[i] >= '!' && r.base[i] <= '}')
422 for (i = len; (i % 16) != 0; i++)
425 for (i = ((len>>4)<<4); i < len; i++) {
426 if (r.base[i] >= '!' && r.base[i] <= '}')
436 * Append 'len' bytes of 'text' at '*p', failing with
437 * ISC_R_NOSPACE if that would advance p past 'end'.
440 append(const char *text, int len, char **p, char *end) {
442 return (ISC_R_NOSPACE);
443 memcpy(*p, text, len);
445 return (ISC_R_SUCCESS);
449 reverse_octets(const char *in, char **p, char *end) {
450 char *dot = strchr(in, '.');
454 result = reverse_octets(dot + 1, p, end);
455 if (result != ISC_R_SUCCESS)
457 result = append(".", 1, p, end);
458 if (result != ISC_R_SUCCESS)
464 return (append(in, len, p, end));
468 get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int,
469 isc_boolean_t strict)
475 addr.family = AF_INET6;
476 r = inet_pton(AF_INET6, value, &addr.type.in6);
478 /* This is a valid IPv6 address. */
479 dns_fixedname_t fname;
481 unsigned int options = 0;
484 options |= DNS_BYADDROPT_IPV6INT;
485 dns_fixedname_init(&fname);
486 name = dns_fixedname_name(&fname);
487 result = dns_byaddr_createptrname2(&addr, options, name);
488 if (result != ISC_R_SUCCESS)
490 dns_name_format(name, reverse, len);
491 return (ISC_R_SUCCESS);
494 * Not a valid IPv6 address. Assume IPv4.
495 * If 'strict' is not set, construct the
496 * in-addr.arpa name by blindly reversing
497 * octets whether or not they look like integers,
498 * so that this can be used for RFC2317 names
502 char *end = reverse + len;
503 if (strict && inet_pton(AF_INET, value, &addr.type.in) != 1)
504 return (DNS_R_BADDOTTEDQUAD);
505 result = reverse_octets(value, &p, end);
506 if (result != ISC_R_SUCCESS)
508 /* Append .in-addr.arpa. and a terminating NUL. */
509 result = append(".in-addr.arpa.", 15, &p, end);
510 if (result != ISC_R_SUCCESS)
512 return (ISC_R_SUCCESS);
517 fatal(const char *format, ...) {
521 fprintf(stderr, "%s: ", progname);
522 va_start(args, format);
523 vfprintf(stderr, format, args);
525 fprintf(stderr, "\n");
529 exitcode = fatalexit;
534 debug(const char *format, ...) {
539 va_start(args, format);
540 vfprintf(stderr, format, args);
542 fprintf(stderr, "\n");
547 check_result(isc_result_t result, const char *msg) {
548 if (result != ISC_R_SUCCESS) {
549 fatal("%s: %s", msg, isc_result_totext(result));
554 * Create a server structure, which is part of the lookup structure.
555 * This is little more than a linked list of servers to query in hopes
556 * of finding the answer the user is looking for
559 make_server(const char *servname, const char *userarg) {
562 REQUIRE(servname != NULL);
564 debug("make_server(%s)", servname);
565 srv = isc_mem_allocate(mctx, sizeof(struct dig_server));
567 fatal("memory allocation failure in %s:%d",
569 strncpy(srv->servername, servname, MXNAME);
570 strncpy(srv->userarg, userarg, MXNAME);
571 srv->servername[MXNAME-1] = 0;
572 srv->userarg[MXNAME-1] = 0;
573 ISC_LINK_INIT(srv, link);
578 addr2af(int lwresaddrtype)
582 switch (lwresaddrtype) {
583 case LWRES_ADDRTYPE_V4:
587 case LWRES_ADDRTYPE_V6:
596 * Create a copy of the server list from the lwres configuration structure.
597 * The dest list must have already had ISC_LIST_INIT applied.
600 copy_server_list(lwres_conf_t *confdata, dig_serverlist_t *dest) {
601 dig_server_t *newsrv;
602 char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
606 debug("copy_server_list()");
607 for (i = 0; i < confdata->nsnext; i++) {
608 af = addr2af(confdata->nameservers[i].family);
610 if (af == AF_INET && !have_ipv4)
612 if (af == AF_INET6 && !have_ipv6)
615 lwres_net_ntop(af, confdata->nameservers[i].address,
617 newsrv = make_server(tmp, tmp);
618 ISC_LINK_INIT(newsrv, link);
619 ISC_LIST_ENQUEUE(*dest, newsrv, link);
624 flush_server_list(void) {
625 dig_server_t *s, *ps;
627 debug("flush_server_list()");
628 s = ISC_LIST_HEAD(server_list);
631 s = ISC_LIST_NEXT(s, link);
632 ISC_LIST_DEQUEUE(server_list, ps, link);
633 isc_mem_free(mctx, ps);
638 set_nameserver(char *opt) {
640 isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES];
641 isc_netaddr_t netaddr;
644 char tmp[ISC_NETADDR_FORMATSIZE];
649 result = bind9_getaddresses(opt, 0, sockaddrs,
650 DIG_MAX_ADDRESSES, &count);
651 if (result != ISC_R_SUCCESS)
652 fatal("couldn't get address for '%s': %s",
653 opt, isc_result_totext(result));
657 for (i = 0; i < count; i++) {
658 isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]);
659 isc_netaddr_format(&netaddr, tmp, sizeof(tmp));
660 srv = make_server(tmp, opt);
662 fatal("memory allocation failure");
663 ISC_LIST_APPEND(server_list, srv, link);
668 add_nameserver(lwres_conf_t *confdata, const char *addr, int af) {
670 int i = confdata->nsnext;
672 if (confdata->nsnext >= LWRES_CONFMAXNAMESERVERS)
673 return (ISC_R_FAILURE);
677 confdata->nameservers[i].family = LWRES_ADDRTYPE_V4;
678 confdata->nameservers[i].length = NS_INADDRSZ;
681 confdata->nameservers[i].family = LWRES_ADDRTYPE_V6;
682 confdata->nameservers[i].length = NS_IN6ADDRSZ;
685 return (ISC_R_FAILURE);
688 if (lwres_net_pton(af, addr, &confdata->nameservers[i].address) == 1) {
690 return (ISC_R_SUCCESS);
692 return (ISC_R_FAILURE);
696 * Produce a cloned server list. The dest list must have already had
697 * ISC_LIST_INIT applied.
700 clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) {
701 dig_server_t *srv, *newsrv;
703 debug("clone_server_list()");
704 srv = ISC_LIST_HEAD(src);
705 while (srv != NULL) {
706 newsrv = make_server(srv->servername, srv->userarg);
707 ISC_LINK_INIT(newsrv, link);
708 ISC_LIST_ENQUEUE(*dest, newsrv, link);
709 srv = ISC_LIST_NEXT(srv, link);
714 * Create an empty lookup structure, which holds all the information needed
715 * to get an answer to a user's question. This structure contains two
716 * linked lists: the server list (servers to query) and the query list
717 * (outstanding queries which have been made to the listed servers).
720 make_empty_lookup(void) {
721 dig_lookup_t *looknew;
723 debug("make_empty_lookup()");
727 looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup));
729 fatal("memory allocation failure in %s:%d",
731 looknew->pending = ISC_TRUE;
732 looknew->textname[0] = 0;
733 looknew->cmdline[0] = 0;
734 looknew->rdtype = dns_rdatatype_a;
735 looknew->qrdtype = dns_rdatatype_a;
736 looknew->rdclass = dns_rdataclass_in;
737 looknew->rdtypeset = ISC_FALSE;
738 looknew->rdclassset = ISC_FALSE;
739 looknew->sendspace = NULL;
740 looknew->sendmsg = NULL;
741 looknew->name = NULL;
742 looknew->oname = NULL;
743 looknew->timer = NULL;
744 looknew->xfr_q = NULL;
745 looknew->current_query = NULL;
746 looknew->doing_xfr = ISC_FALSE;
747 looknew->ixfr_serial = ISC_FALSE;
748 looknew->trace = ISC_FALSE;
749 looknew->trace_root = ISC_FALSE;
750 looknew->identify = ISC_FALSE;
751 looknew->identify_previous_line = ISC_FALSE;
752 looknew->ignore = ISC_FALSE;
753 looknew->servfail_stops = ISC_TRUE;
754 looknew->besteffort = ISC_TRUE;
755 looknew->dnssec = ISC_FALSE;
756 looknew->nsid = ISC_FALSE;
758 looknew->sigchase = ISC_FALSE;
760 looknew->do_topdown = ISC_FALSE;
761 looknew->trace_root_sigchase = ISC_FALSE;
762 looknew->rdtype_sigchaseset = ISC_FALSE;
763 looknew->rdtype_sigchase = dns_rdatatype_any;
764 looknew->qrdtype_sigchase = dns_rdatatype_any;
765 looknew->rdclass_sigchase = dns_rdataclass_in;
766 looknew->rdclass_sigchaseset = ISC_FALSE;
769 looknew->udpsize = 0;
771 looknew->recurse = ISC_TRUE;
772 looknew->aaonly = ISC_FALSE;
773 looknew->adflag = ISC_FALSE;
774 looknew->cdflag = ISC_FALSE;
775 looknew->ns_search_only = ISC_FALSE;
776 looknew->origin = NULL;
777 looknew->tsigctx = NULL;
778 looknew->querysig = NULL;
779 looknew->retries = tries;
780 looknew->nsfound = 0;
781 looknew->tcp_mode = ISC_FALSE;
782 looknew->ip6_int = ISC_FALSE;
783 looknew->comments = ISC_TRUE;
784 looknew->stats = ISC_TRUE;
785 looknew->section_question = ISC_TRUE;
786 looknew->section_answer = ISC_TRUE;
787 looknew->section_authority = ISC_TRUE;
788 looknew->section_additional = ISC_TRUE;
789 looknew->new_search = ISC_FALSE;
790 looknew->done_as_is = ISC_FALSE;
791 looknew->need_search = ISC_FALSE;
792 ISC_LINK_INIT(looknew, link);
793 ISC_LIST_INIT(looknew->q);
794 ISC_LIST_INIT(looknew->my_server_list);
799 * Clone a lookup, perhaps copying the server list. This does not clone
800 * the query list, since it will be regenerated by the setup_lookup()
801 * function, nor does it queue up the new lookup for processing.
802 * Caution: If you don't clone the servers, you MUST clone the server
803 * list separately from somewhere else, or construct it by hand.
806 clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
807 dig_lookup_t *looknew;
809 debug("clone_lookup()");
813 looknew = make_empty_lookup();
814 INSIST(looknew != NULL);
815 strncpy(looknew->textname, lookold->textname, MXNAME);
817 strncpy(looknew->textnamesigchase, lookold->textnamesigchase, MXNAME);
819 strncpy(looknew->cmdline, lookold->cmdline, MXNAME);
820 looknew->textname[MXNAME-1] = 0;
821 looknew->rdtype = lookold->rdtype;
822 looknew->qrdtype = lookold->qrdtype;
823 looknew->rdclass = lookold->rdclass;
824 looknew->rdtypeset = lookold->rdtypeset;
825 looknew->rdclassset = lookold->rdclassset;
826 looknew->doing_xfr = lookold->doing_xfr;
827 looknew->ixfr_serial = lookold->ixfr_serial;
828 looknew->trace = lookold->trace;
829 looknew->trace_root = lookold->trace_root;
830 looknew->identify = lookold->identify;
831 looknew->identify_previous_line = lookold->identify_previous_line;
832 looknew->ignore = lookold->ignore;
833 looknew->servfail_stops = lookold->servfail_stops;
834 looknew->besteffort = lookold->besteffort;
835 looknew->dnssec = lookold->dnssec;
836 looknew->nsid = lookold->nsid;
838 looknew->sigchase = lookold->sigchase;
840 looknew->do_topdown = lookold->do_topdown;
841 looknew->trace_root_sigchase = lookold->trace_root_sigchase;
842 looknew->rdtype_sigchaseset = lookold->rdtype_sigchaseset;
843 looknew->rdtype_sigchase = lookold->rdtype_sigchase;
844 looknew->qrdtype_sigchase = lookold->qrdtype_sigchase;
845 looknew->rdclass_sigchase = lookold->rdclass_sigchase;
846 looknew->rdclass_sigchaseset = lookold->rdclass_sigchaseset;
849 looknew->udpsize = lookold->udpsize;
850 looknew->edns = lookold->edns;
851 looknew->recurse = lookold->recurse;
852 looknew->aaonly = lookold->aaonly;
853 looknew->adflag = lookold->adflag;
854 looknew->cdflag = lookold->cdflag;
855 looknew->ns_search_only = lookold->ns_search_only;
856 looknew->tcp_mode = lookold->tcp_mode;
857 looknew->comments = lookold->comments;
858 looknew->stats = lookold->stats;
859 looknew->section_question = lookold->section_question;
860 looknew->section_answer = lookold->section_answer;
861 looknew->section_authority = lookold->section_authority;
862 looknew->section_additional = lookold->section_additional;
863 looknew->retries = lookold->retries;
864 looknew->tsigctx = NULL;
865 looknew->need_search = lookold->need_search;
866 looknew->done_as_is = lookold->done_as_is;
869 clone_server_list(lookold->my_server_list,
870 &looknew->my_server_list);
875 * Requeue a lookup for further processing, perhaps copying the server
876 * list. The new lookup structure is returned to the caller, and is
877 * queued for processing. If servers are not cloned in the requeue, they
878 * must be added before allowing the current event to complete, since the
879 * completion of the event may result in the next entry on the lookup
883 requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
884 dig_lookup_t *looknew;
886 debug("requeue_lookup()");
889 if (lookup_counter > LOOKUP_LIMIT)
890 fatal("too many lookups");
892 looknew = clone_lookup(lookold, servers);
893 INSIST(looknew != NULL);
895 debug("before insertion, init@%p -> %p, new@%p -> %p",
896 lookold, lookold->link.next, looknew, looknew->link.next);
897 ISC_LIST_PREPEND(lookup_list, looknew, link);
898 debug("after insertion, init -> %p, new = %p, new -> %p",
899 lookold, looknew, looknew->link.next);
905 setup_text_key(void) {
908 isc_buffer_t secretbuf;
910 unsigned char *secretstore;
912 debug("setup_text_key()");
913 result = isc_buffer_allocate(mctx, &namebuf, MXNAME);
914 check_result(result, "isc_buffer_allocate");
915 dns_name_init(&keyname, NULL);
916 check_result(result, "dns_name_init");
917 isc_buffer_putstr(namebuf, keynametext);
918 secretsize = strlen(keysecret) * 3 / 4;
919 secretstore = isc_mem_allocate(mctx, secretsize);
920 if (secretstore == NULL)
921 fatal("memory allocation failure in %s:%d",
923 isc_buffer_init(&secretbuf, secretstore, secretsize);
924 result = isc_base64_decodestring(keysecret, &secretbuf);
925 if (result != ISC_R_SUCCESS)
928 secretsize = isc_buffer_usedlength(&secretbuf);
930 result = dns_name_fromtext(&keyname, namebuf, dns_rootname, 0, namebuf);
931 if (result != ISC_R_SUCCESS)
934 result = dns_tsigkey_create(&keyname, hmacname, secretstore,
935 secretsize, ISC_FALSE, NULL, 0, 0, mctx,
938 if (result != ISC_R_SUCCESS)
939 printf(";; Couldn't create key %s: %s\n",
940 keynametext, isc_result_totext(result));
942 dst_key_setbits(key->key, digestbits);
944 isc_mem_free(mctx, secretstore);
945 dns_name_invalidate(&keyname);
946 isc_buffer_free(&namebuf);
950 parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
953 isc_result_t result = isc_parse_uint32(&n, value, 10);
954 if (result == ISC_R_SUCCESS && n > max)
955 result = ISC_R_RANGE;
956 if (result != ISC_R_SUCCESS) {
957 printf("invalid %s '%s': %s\n", desc,
958 value, isc_result_totext(result));
962 return (ISC_R_SUCCESS);
966 parse_bits(char *arg, const char *desc, isc_uint32_t max) {
970 result = parse_uint(&tmp, arg, max, desc);
971 if (result != ISC_R_SUCCESS)
972 fatal("couldn't parse digest bits");
973 tmp = (tmp + 7) & ~0x7U;
979 * Parse HMAC algorithm specification
982 parse_hmac(const char *hmac) {
986 REQUIRE(hmac != NULL);
989 if (len >= (int) sizeof(buf))
990 fatal("unknown key type '%.*s'", len, hmac);
991 strncpy(buf, hmac, sizeof(buf));
995 if (strcasecmp(buf, "hmac-md5") == 0) {
996 hmacname = DNS_TSIG_HMACMD5_NAME;
997 } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) {
998 hmacname = DNS_TSIG_HMACMD5_NAME;
999 digestbits = parse_bits(&buf[9], "digest-bits [0..128]", 128);
1000 } else if (strcasecmp(buf, "hmac-sha1") == 0) {
1001 hmacname = DNS_TSIG_HMACSHA1_NAME;
1003 } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) {
1004 hmacname = DNS_TSIG_HMACSHA1_NAME;
1005 digestbits = parse_bits(&buf[10], "digest-bits [0..160]", 160);
1006 } else if (strcasecmp(buf, "hmac-sha224") == 0) {
1007 hmacname = DNS_TSIG_HMACSHA224_NAME;
1008 } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) {
1009 hmacname = DNS_TSIG_HMACSHA224_NAME;
1010 digestbits = parse_bits(&buf[12], "digest-bits [0..224]", 224);
1011 } else if (strcasecmp(buf, "hmac-sha256") == 0) {
1012 hmacname = DNS_TSIG_HMACSHA256_NAME;
1013 } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) {
1014 hmacname = DNS_TSIG_HMACSHA256_NAME;
1015 digestbits = parse_bits(&buf[12], "digest-bits [0..256]", 256);
1016 } else if (strcasecmp(buf, "hmac-sha384") == 0) {
1017 hmacname = DNS_TSIG_HMACSHA384_NAME;
1018 } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) {
1019 hmacname = DNS_TSIG_HMACSHA384_NAME;
1020 digestbits = parse_bits(&buf[12], "digest-bits [0..384]", 384);
1021 } else if (strcasecmp(buf, "hmac-sha512") == 0) {
1022 hmacname = DNS_TSIG_HMACSHA512_NAME;
1023 } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) {
1024 hmacname = DNS_TSIG_HMACSHA512_NAME;
1025 digestbits = parse_bits(&buf[12], "digest-bits [0..512]", 512);
1027 fprintf(stderr, ";; Warning, ignoring "
1028 "invalid TSIG algorithm %s\n", buf);
1033 * Get a key from a named.conf format keyfile
1036 read_confkey(void) {
1037 isc_log_t *lctx = NULL;
1038 cfg_parser_t *pctx = NULL;
1039 cfg_obj_t *file = NULL;
1040 const cfg_obj_t *key = NULL;
1041 const cfg_obj_t *secretobj = NULL;
1042 const cfg_obj_t *algorithmobj = NULL;
1043 const char *keyname;
1044 const char *secretstr;
1045 const char *algorithm;
1046 isc_result_t result;
1048 if (! isc_file_exists(keyfile))
1049 return (ISC_R_FILENOTFOUND);
1051 result = cfg_parser_create(mctx, lctx, &pctx);
1052 if (result != ISC_R_SUCCESS)
1055 result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
1057 if (result != ISC_R_SUCCESS)
1060 result = cfg_map_get(file, "key", &key);
1061 if (result != ISC_R_SUCCESS)
1064 (void) cfg_map_get(key, "secret", &secretobj);
1065 (void) cfg_map_get(key, "algorithm", &algorithmobj);
1066 if (secretobj == NULL || algorithmobj == NULL)
1067 fatal("key must have algorithm and secret");
1069 keyname = cfg_obj_asstring(cfg_map_getname(key));
1070 secretstr = cfg_obj_asstring(secretobj);
1071 algorithm = cfg_obj_asstring(algorithmobj);
1073 strncpy(keynametext, keyname, sizeof(keynametext));
1074 strncpy(keysecret, secretstr, sizeof(keysecret));
1075 parse_hmac(algorithm);
1081 cfg_obj_destroy(pctx, &file);
1082 cfg_parser_destroy(&pctx);
1089 setup_file_key(void) {
1090 isc_result_t result;
1091 dst_key_t *dstkey = NULL;
1093 debug("setup_file_key()");
1095 /* Try reading the key from a K* pair */
1096 result = dst_key_fromnamedfile(keyfile, NULL,
1097 DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
1100 /* If that didn't work, try reading it as a session.key keyfile */
1101 if (result != ISC_R_SUCCESS) {
1102 result = read_confkey();
1103 if (result == ISC_R_SUCCESS)
1107 if (result != ISC_R_SUCCESS) {
1108 fprintf(stderr, "Couldn't read key from %s: %s\n",
1109 keyfile, isc_result_totext(result));
1113 switch (dst_key_alg(dstkey)) {
1114 case DST_ALG_HMACMD5:
1115 hmacname = DNS_TSIG_HMACMD5_NAME;
1117 case DST_ALG_HMACSHA1:
1118 hmacname = DNS_TSIG_HMACSHA1_NAME;
1120 case DST_ALG_HMACSHA224:
1121 hmacname = DNS_TSIG_HMACSHA224_NAME;
1123 case DST_ALG_HMACSHA256:
1124 hmacname = DNS_TSIG_HMACSHA256_NAME;
1126 case DST_ALG_HMACSHA384:
1127 hmacname = DNS_TSIG_HMACSHA384_NAME;
1129 case DST_ALG_HMACSHA512:
1130 hmacname = DNS_TSIG_HMACSHA512_NAME;
1133 printf(";; Couldn't create key %s: bad algorithm\n",
1137 result = dns_tsigkey_createfromkey(dst_key_name(dstkey), hmacname,
1138 dstkey, ISC_FALSE, NULL, 0, 0,
1140 if (result != ISC_R_SUCCESS) {
1141 printf(";; Couldn't create key %s: %s\n",
1142 keynametext, isc_result_totext(result));
1148 dst_key_free(&dstkey);
1151 static dig_searchlist_t *
1152 make_searchlist_entry(char *domain) {
1153 dig_searchlist_t *search;
1154 search = isc_mem_allocate(mctx, sizeof(*search));
1156 fatal("memory allocation failure in %s:%d",
1157 __FILE__, __LINE__);
1158 strncpy(search->origin, domain, MXNAME);
1159 search->origin[MXNAME-1] = 0;
1160 ISC_LINK_INIT(search, link);
1165 clear_searchlist(void) {
1166 dig_searchlist_t *search;
1167 while ((search = ISC_LIST_HEAD(search_list)) != NULL) {
1168 ISC_LIST_UNLINK(search_list, search, link);
1169 isc_mem_free(mctx, search);
1174 create_search_list(lwres_conf_t *confdata) {
1176 dig_searchlist_t *search;
1178 debug("create_search_list()");
1181 for (i = 0; i < confdata->searchnxt; i++) {
1182 search = make_searchlist_entry(confdata->search[i]);
1183 ISC_LIST_APPEND(search_list, search, link);
1188 * Setup the system as a whole, reading key information and resolv.conf
1192 setup_system(void) {
1193 dig_searchlist_t *domain = NULL;
1194 lwres_result_t lwresult;
1195 unsigned int lwresflags;
1197 debug("setup_system()");
1199 lwresflags = LWRES_CONTEXT_SERVERMODE;
1201 lwresflags |= LWRES_CONTEXT_USEIPV4;
1203 lwresflags |= LWRES_CONTEXT_USEIPV6;
1205 lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free,
1207 if (lwresult != LWRES_R_SUCCESS)
1208 fatal("lwres_context_create failed");
1210 lwresult = lwres_conf_parse(lwctx, RESOLV_CONF);
1211 if (lwresult != LWRES_R_SUCCESS && lwresult != LWRES_R_NOTFOUND)
1212 fatal("parse of %s failed", RESOLV_CONF);
1214 lwconf = lwres_conf_get(lwctx);
1216 /* Make the search list */
1217 if (lwconf->searchnxt > 0)
1218 create_search_list(lwconf);
1219 else { /* No search list. Use the domain name if any */
1220 if (lwconf->domainname != NULL) {
1221 domain = make_searchlist_entry(lwconf->domainname);
1222 ISC_LIST_APPEND(search_list, domain, link);
1228 ndots = lwconf->ndots;
1229 debug("ndots is %d.", ndots);
1232 /* If user doesn't specify server use nameservers from resolv.conf. */
1233 if (ISC_LIST_EMPTY(server_list))
1234 copy_server_list(lwconf, &server_list);
1236 /* If we don't find a nameserver fall back to localhost */
1237 if (ISC_LIST_EMPTY(server_list)) {
1239 lwresult = add_nameserver(lwconf, "127.0.0.1", AF_INET);
1240 if (lwresult != ISC_R_SUCCESS)
1241 fatal("add_nameserver failed");
1244 lwresult = add_nameserver(lwconf, "::1", AF_INET6);
1245 if (lwresult != ISC_R_SUCCESS)
1246 fatal("add_nameserver failed");
1249 copy_server_list(lwconf, &server_list);
1256 if (keyfile[0] != 0)
1258 else if (keysecret[0] != 0)
1261 /* Setup the list of messages for +sigchase */
1262 ISC_LIST_INIT(chase_message_list);
1263 ISC_LIST_INIT(chase_message_list2);
1264 dns_name_init(&chase_name, NULL);
1266 dns_name_init(&chase_current_name, NULL);
1267 dns_name_init(&chase_authority_name, NULL);
1270 dns_name_init(&chase_signame, NULL);
1278 * Override the search list derived from resolv.conf by 'domain'.
1281 set_search_domain(char *domain) {
1282 dig_searchlist_t *search;
1285 search = make_searchlist_entry(domain);
1286 ISC_LIST_APPEND(search_list, search, link);
1290 * Setup the ISC and DNS libraries for use by the system.
1294 isc_result_t result;
1295 isc_logconfig_t *logconfig = NULL;
1297 debug("setup_libs()");
1299 result = isc_net_probeipv4();
1300 if (result == ISC_R_SUCCESS)
1301 have_ipv4 = ISC_TRUE;
1303 result = isc_net_probeipv6();
1304 if (result == ISC_R_SUCCESS)
1305 have_ipv6 = ISC_TRUE;
1306 if (!have_ipv6 && !have_ipv4)
1307 fatal("can't find either v4 or v6 networking");
1309 result = isc_mem_create(0, 0, &mctx);
1310 check_result(result, "isc_mem_create");
1312 result = isc_log_create(mctx, &lctx, &logconfig);
1313 check_result(result, "isc_log_create");
1315 isc_log_setcontext(lctx);
1317 dns_log_setcontext(lctx);
1319 result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL);
1320 check_result(result, "isc_log_usechannel");
1322 isc_log_setdebuglevel(lctx, 0);
1324 result = isc_taskmgr_create(mctx, 1, 0, &taskmgr);
1325 check_result(result, "isc_taskmgr_create");
1327 result = isc_task_create(taskmgr, 0, &global_task);
1328 check_result(result, "isc_task_create");
1330 result = isc_timermgr_create(mctx, &timermgr);
1331 check_result(result, "isc_timermgr_create");
1333 result = isc_socketmgr_create(mctx, &socketmgr);
1334 check_result(result, "isc_socketmgr_create");
1336 result = isc_entropy_create(mctx, &entp);
1337 check_result(result, "isc_entropy_create");
1339 result = dst_lib_init(mctx, entp, 0);
1340 check_result(result, "dst_lib_init");
1341 is_dst_up = ISC_TRUE;
1343 result = isc_mempool_create(mctx, COMMSIZE, &commctx);
1344 check_result(result, "isc_mempool_create");
1345 isc_mempool_setname(commctx, "COMMPOOL");
1347 * 6 and 2 set as reasonable parameters for 3 or 4 nameserver
1350 isc_mempool_setfreemax(commctx, 6);
1351 isc_mempool_setfillcount(commctx, 2);
1353 result = isc_mutex_init(&lookup_lock);
1354 check_result(result, "isc_mutex_init");
1356 dns_result_register();
1360 * Add EDNS0 option record to a message. Currently, the only supported
1361 * options are UDP buffer size, the DO bit, and NSID request.
1364 add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns,
1365 isc_boolean_t dnssec, isc_boolean_t nsid)
1367 dns_rdataset_t *rdataset = NULL;
1368 dns_rdatalist_t *rdatalist = NULL;
1369 dns_rdata_t *rdata = NULL;
1370 isc_result_t result;
1373 result = dns_message_gettemprdataset(msg, &rdataset);
1374 check_result(result, "dns_message_gettemprdataset");
1375 dns_rdataset_init(rdataset);
1376 result = dns_message_gettemprdatalist(msg, &rdatalist);
1377 check_result(result, "dns_message_gettemprdatalist");
1378 result = dns_message_gettemprdata(msg, &rdata);
1379 check_result(result, "dns_message_gettemprdata");
1381 debug("setting udp size of %d", udpsize);
1382 rdatalist->type = dns_rdatatype_opt;
1383 rdatalist->covers = 0;
1384 rdatalist->rdclass = udpsize;
1385 rdatalist->ttl = edns << 16;
1387 rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
1389 isc_buffer_t *b = NULL;
1391 result = isc_buffer_allocate(mctx, &b, 4);
1392 check_result(result, "isc_buffer_allocate");
1393 isc_buffer_putuint16(b, DNS_OPT_NSID);
1394 isc_buffer_putuint16(b, 0);
1395 rdata->data = isc_buffer_base(b);
1396 rdata->length = isc_buffer_usedlength(b);
1397 dns_message_takebuffer(msg, &b);
1402 ISC_LIST_INIT(rdatalist->rdata);
1403 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1404 dns_rdatalist_tordataset(rdatalist, rdataset);
1405 result = dns_message_setopt(msg, rdataset);
1406 check_result(result, "dns_message_setopt");
1410 * Add a question section to a message, asking for the specified name,
1414 add_question(dns_message_t *message, dns_name_t *name,
1415 dns_rdataclass_t rdclass, dns_rdatatype_t rdtype)
1417 dns_rdataset_t *rdataset;
1418 isc_result_t result;
1420 debug("add_question()");
1422 result = dns_message_gettemprdataset(message, &rdataset);
1423 check_result(result, "dns_message_gettemprdataset()");
1424 dns_rdataset_init(rdataset);
1425 dns_rdataset_makequestion(rdataset, rdclass, rdtype);
1426 ISC_LIST_APPEND(name->list, rdataset, link);
1430 * Check if we're done with all the queued lookups, which is true iff
1431 * all sockets, sends, and recvs are accounted for (counters == 0),
1432 * and the lookup list is empty.
1433 * If we are done, pass control back out to dighost_shutdown() (which is
1434 * part of dig.c, host.c, or nslookup.c) to either shutdown the system as
1435 * a whole or reseed the lookup list.
1438 check_if_done(void) {
1439 debug("check_if_done()");
1440 debug("list %s", ISC_LIST_EMPTY(lookup_list) ? "empty" : "full");
1441 if (ISC_LIST_EMPTY(lookup_list) && current_lookup == NULL &&
1443 INSIST(sockcount == 0);
1444 INSIST(recvcount == 0);
1445 debug("shutting down");
1451 * Clear out a query when we're done with it. WARNING: This routine
1452 * WILL invalidate the query pointer.
1455 clear_query(dig_query_t *query) {
1456 dig_lookup_t *lookup;
1458 REQUIRE(query != NULL);
1460 debug("clear_query(%p)", query);
1462 lookup = query->lookup;
1464 if (lookup->current_query == query)
1465 lookup->current_query = NULL;
1467 ISC_LIST_UNLINK(lookup->q, query, link);
1468 if (ISC_LINK_LINKED(&query->recvbuf, link))
1469 ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf,
1471 if (ISC_LINK_LINKED(&query->lengthbuf, link))
1472 ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf,
1474 INSIST(query->recvspace != NULL);
1475 if (query->sock != NULL) {
1476 isc_socket_detach(&query->sock);
1478 debug("sockcount=%d", sockcount);
1480 isc_mempool_put(commctx, query->recvspace);
1481 isc_buffer_invalidate(&query->recvbuf);
1482 isc_buffer_invalidate(&query->lengthbuf);
1483 if (query->waiting_senddone)
1484 query->pending_free = ISC_TRUE;
1486 isc_mem_free(mctx, query);
1490 * Try and clear out a lookup if we're done with it. Return ISC_TRUE if
1491 * the lookup was successfully cleared. If ISC_TRUE is returned, the
1492 * lookup pointer has been invalidated.
1494 static isc_boolean_t
1495 try_clear_lookup(dig_lookup_t *lookup) {
1498 REQUIRE(lookup != NULL);
1500 debug("try_clear_lookup(%p)", lookup);
1502 if (ISC_LIST_HEAD(lookup->q) != NULL) {
1504 q = ISC_LIST_HEAD(lookup->q);
1506 debug("query to %s still pending", q->servname);
1507 q = ISC_LIST_NEXT(q, link);
1514 * At this point, we know there are no queries on the lookup,
1515 * so can make it go away also.
1517 destroy_lookup(lookup);
1522 destroy_lookup(dig_lookup_t *lookup) {
1527 s = ISC_LIST_HEAD(lookup->my_server_list);
1529 debug("freeing server %p belonging to %p", s, lookup);
1531 s = ISC_LIST_NEXT(s, link);
1532 ISC_LIST_DEQUEUE(lookup->my_server_list,
1533 (dig_server_t *)ptr, link);
1534 isc_mem_free(mctx, ptr);
1536 if (lookup->sendmsg != NULL)
1537 dns_message_destroy(&lookup->sendmsg);
1538 if (lookup->querysig != NULL) {
1539 debug("freeing buffer %p", lookup->querysig);
1540 isc_buffer_free(&lookup->querysig);
1542 if (lookup->timer != NULL)
1543 isc_timer_detach(&lookup->timer);
1544 if (lookup->sendspace != NULL)
1545 isc_mempool_put(commctx, lookup->sendspace);
1547 if (lookup->tsigctx != NULL)
1548 dst_context_destroy(&lookup->tsigctx);
1550 isc_mem_free(mctx, lookup);
1554 * If we can, start the next lookup in the queue running.
1555 * This assumes that the lookup on the head of the queue hasn't been
1556 * started yet. It also removes the lookup from the head of the queue,
1557 * setting the current_lookup pointer pointing to it.
1560 start_lookup(void) {
1561 debug("start_lookup()");
1566 * If there's a current lookup running, we really shouldn't get
1569 INSIST(current_lookup == NULL);
1571 current_lookup = ISC_LIST_HEAD(lookup_list);
1573 * Put the current lookup somewhere so cancel_all can find it
1575 if (current_lookup != NULL) {
1576 ISC_LIST_DEQUEUE(lookup_list, current_lookup, link);
1578 if (current_lookup->do_topdown &&
1579 !current_lookup->rdtype_sigchaseset) {
1580 dst_key_t *trustedkey = NULL;
1581 isc_buffer_t *b = NULL;
1583 isc_result_t result;
1584 dns_name_t query_name;
1585 dns_name_t *key_name;
1588 result = get_trusted_key(mctx);
1589 if (result != ISC_R_SUCCESS) {
1590 printf("\n;; No trusted key, "
1591 "+sigchase option is disabled\n");
1592 current_lookup->sigchase = ISC_FALSE;
1595 dns_name_init(&query_name, NULL);
1596 nameFromString(current_lookup->textname, &query_name);
1598 for (i = 0; i < tk_list.nb_tk; i++) {
1599 key_name = dst_key_name(tk_list.key[i]);
1601 if (dns_name_issubdomain(&query_name,
1602 key_name) == ISC_TRUE)
1603 trustedkey = tk_list.key[i];
1605 * Verify temp is really the lowest
1609 if (trustedkey == NULL) {
1610 printf("\n;; The queried zone: ");
1611 dns_name_print(&query_name, stdout);
1612 printf(" isn't a subdomain of any Trusted Keys"
1613 ": +sigchase option is disable\n");
1614 current_lookup->sigchase = ISC_FALSE;
1615 free_name(&query_name, mctx);
1618 free_name(&query_name, mctx);
1620 current_lookup->rdtype_sigchase
1621 = current_lookup->rdtype;
1622 current_lookup->rdtype_sigchaseset
1623 = current_lookup->rdtypeset;
1624 current_lookup->rdtype = dns_rdatatype_ns;
1626 current_lookup->qrdtype_sigchase
1627 = current_lookup->qrdtype;
1628 current_lookup->qrdtype = dns_rdatatype_ns;
1630 current_lookup->rdclass_sigchase
1631 = current_lookup->rdclass;
1632 current_lookup->rdclass_sigchaseset
1633 = current_lookup->rdclassset;
1634 current_lookup->rdclass = dns_rdataclass_in;
1636 strncpy(current_lookup->textnamesigchase,
1637 current_lookup->textname, MXNAME);
1639 current_lookup->trace_root_sigchase = ISC_TRUE;
1641 result = isc_buffer_allocate(mctx, &b, BUFSIZE);
1642 check_result(result, "isc_buffer_allocate");
1643 result = dns_name_totext(dst_key_name(trustedkey),
1645 check_result(result, "dns_name_totext");
1646 isc_buffer_usedregion(b, &r);
1647 r.base[r.length] = '\0';
1648 strncpy(current_lookup->textname, (char*)r.base,
1650 isc_buffer_free(&b);
1652 nameFromString(current_lookup->textnamesigchase,
1655 dns_name_init(&chase_authority_name, NULL);
1659 setup_lookup(current_lookup);
1660 do_lookup(current_lookup);
1667 * If we can, clear the current lookup and start the next one running.
1668 * This calls try_clear_lookup, so may invalidate the lookup pointer.
1671 check_next_lookup(dig_lookup_t *lookup) {
1675 debug("check_next_lookup(%p)", lookup);
1677 if (ISC_LIST_HEAD(lookup->q) != NULL) {
1678 debug("still have a worker");
1681 if (try_clear_lookup(lookup)) {
1682 current_lookup = NULL;
1688 * Create and queue a new lookup as a followup to the current lookup,
1689 * based on the supplied message and section. This is used in trace and
1690 * name server search modes to start a new lookup using servers from
1691 * NS records in a reply. Returns the number of followup lookups made.
1694 followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section)
1696 dig_lookup_t *lookup = NULL;
1697 dig_server_t *srv = NULL;
1698 dns_rdataset_t *rdataset = NULL;
1699 dns_rdata_t rdata = DNS_RDATA_INIT;
1700 dns_name_t *name = NULL;
1701 isc_result_t result;
1702 isc_boolean_t success = ISC_FALSE;
1705 isc_boolean_t horizontal = ISC_FALSE, bad = ISC_FALSE;
1709 debug("following up %s", query->lookup->textname);
1711 for (result = dns_message_firstname(msg, section);
1712 result == ISC_R_SUCCESS;
1713 result = dns_message_nextname(msg, section)) {
1715 dns_message_currentname(msg, section, &name);
1717 if (section == DNS_SECTION_AUTHORITY) {
1719 result = dns_message_findtype(name, dns_rdatatype_soa,
1721 if (result == ISC_R_SUCCESS)
1725 result = dns_message_findtype(name, dns_rdatatype_ns, 0,
1727 if (result != ISC_R_SUCCESS)
1730 debug("found NS set");
1732 if (query->lookup->trace && !query->lookup->trace_root) {
1733 dns_namereln_t namereln;
1734 unsigned int nlabels;
1737 domain = dns_fixedname_name(&query->lookup->fdomain);
1738 namereln = dns_name_fullcompare(name, domain,
1740 if (namereln == dns_namereln_equal) {
1742 printf(";; BAD (HORIZONTAL) REFERRAL\n");
1743 horizontal = ISC_TRUE;
1744 } else if (namereln != dns_namereln_subdomain) {
1746 printf(";; BAD REFERRAL\n");
1752 for (result = dns_rdataset_first(rdataset);
1753 result == ISC_R_SUCCESS;
1754 result = dns_rdataset_next(rdataset)) {
1755 char namestr[DNS_NAME_FORMATSIZE];
1758 if (query->lookup->trace_root &&
1759 query->lookup->nsfound >= MXSERV)
1762 dns_rdataset_current(rdataset, &rdata);
1764 query->lookup->nsfound++;
1765 result = dns_rdata_tostruct(&rdata, &ns, NULL);
1766 check_result(result, "dns_rdata_tostruct");
1767 dns_name_format(&ns.name, namestr, sizeof(namestr));
1768 dns_rdata_freestruct(&ns);
1770 /* Initialize lookup if we've not yet */
1771 debug("found NS %d %s", numLookups, namestr);
1776 lookup = requeue_lookup(query->lookup,
1778 cancel_lookup(query->lookup);
1779 lookup->doing_xfr = ISC_FALSE;
1780 if (!lookup->trace_root &&
1781 section == DNS_SECTION_ANSWER)
1782 lookup->trace = ISC_FALSE;
1784 lookup->trace = query->lookup->trace;
1785 lookup->ns_search_only =
1786 query->lookup->ns_search_only;
1787 lookup->trace_root = ISC_FALSE;
1788 if (lookup->ns_search_only)
1789 lookup->recurse = ISC_FALSE;
1790 dns_fixedname_init(&lookup->fdomain);
1791 domain = dns_fixedname_name(&lookup->fdomain);
1792 dns_name_copy(name, domain, NULL);
1794 srv = make_server(namestr, namestr);
1795 debug("adding server %s", srv->servername);
1796 ISC_LIST_APPEND(lookup->my_server_list, srv, link);
1797 dns_rdata_reset(&rdata);
1801 if (lookup == NULL &&
1802 section == DNS_SECTION_ANSWER &&
1803 (query->lookup->trace || query->lookup->ns_search_only))
1804 return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY));
1807 * Randomize the order the nameserver will be tried.
1809 if (numLookups > 1) {
1811 dig_serverlist_t my_server_list;
1813 ISC_LIST_INIT(my_server_list);
1815 for (i = numLookups; i > 0; i--) {
1818 srv = ISC_LIST_HEAD(lookup->my_server_list);
1820 srv = ISC_LIST_NEXT(srv, link);
1821 ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link);
1822 ISC_LIST_APPEND(my_server_list, srv, link);
1824 ISC_LIST_APPENDLIST(lookup->my_server_list,
1825 my_server_list, link);
1828 return (numLookups);
1832 * Create and queue a new lookup using the next origin from the search
1833 * list, read in setup_system().
1835 * Return ISC_TRUE iff there was another searchlist entry.
1837 static isc_boolean_t
1838 next_origin(dns_message_t *msg, dig_query_t *query) {
1839 dig_lookup_t *lookup;
1840 dig_searchlist_t *search;
1846 debug("next_origin()");
1847 debug("following up %s", query->lookup->textname);
1851 * We're not using a search list, so don't even think
1852 * about finding the next entry.
1855 if (query->lookup->origin == NULL && !query->lookup->need_search)
1857 * Then we just did rootorg; there's nothing left.
1860 if (query->lookup->origin == NULL && query->lookup->need_search) {
1861 lookup = requeue_lookup(query->lookup, ISC_TRUE);
1862 lookup->origin = ISC_LIST_HEAD(search_list);
1863 lookup->need_search = ISC_FALSE;
1865 search = ISC_LIST_NEXT(query->lookup->origin, link);
1866 if (search == NULL && query->lookup->done_as_is)
1868 lookup = requeue_lookup(query->lookup, ISC_TRUE);
1869 lookup->origin = search;
1871 cancel_lookup(query->lookup);
1876 * Insert an SOA record into the sendmessage in a lookup. Used for
1877 * creating IXFR queries.
1880 insert_soa(dig_lookup_t *lookup) {
1881 isc_result_t result;
1882 dns_rdata_soa_t soa;
1883 dns_rdata_t *rdata = NULL;
1884 dns_rdatalist_t *rdatalist = NULL;
1885 dns_rdataset_t *rdataset = NULL;
1886 dns_name_t *soaname = NULL;
1888 debug("insert_soa()");
1890 soa.serial = lookup->ixfr_serial;
1895 soa.common.rdclass = lookup->rdclass;
1896 soa.common.rdtype = dns_rdatatype_soa;
1898 dns_name_init(&soa.origin, NULL);
1899 dns_name_init(&soa.contact, NULL);
1901 dns_name_clone(dns_rootname, &soa.origin);
1902 dns_name_clone(dns_rootname, &soa.contact);
1904 isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore,
1905 sizeof(lookup->rdatastore));
1907 result = dns_message_gettemprdata(lookup->sendmsg, &rdata);
1908 check_result(result, "dns_message_gettemprdata");
1910 result = dns_rdata_fromstruct(rdata, lookup->rdclass,
1911 dns_rdatatype_soa, &soa,
1913 check_result(result, "isc_rdata_fromstruct");
1915 result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist);
1916 check_result(result, "dns_message_gettemprdatalist");
1918 result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset);
1919 check_result(result, "dns_message_gettemprdataset");
1921 dns_rdatalist_init(rdatalist);
1922 rdatalist->type = dns_rdatatype_soa;
1923 rdatalist->rdclass = lookup->rdclass;
1924 rdatalist->covers = 0;
1926 ISC_LIST_INIT(rdatalist->rdata);
1927 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1929 dns_rdataset_init(rdataset);
1930 dns_rdatalist_tordataset(rdatalist, rdataset);
1932 result = dns_message_gettempname(lookup->sendmsg, &soaname);
1933 check_result(result, "dns_message_gettempname");
1934 dns_name_init(soaname, NULL);
1935 dns_name_clone(lookup->name, soaname);
1936 ISC_LIST_INIT(soaname->list);
1937 ISC_LIST_APPEND(soaname->list, rdataset, link);
1938 dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY);
1942 * Setup the supplied lookup structure, making it ready to start sending
1943 * queries to servers. Create and initialize the message to be sent as
1944 * well as the query structures and buffer space for the replies. If the
1945 * server list is empty, clone it from the system default list.
1948 setup_lookup(dig_lookup_t *lookup) {
1949 isc_result_t result;
1955 dns_compress_t cctx;
1959 char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME];
1963 result = dns_name_settotextfilter(output_filter);
1964 check_result(result, "dns_name_settotextfilter");
1967 REQUIRE(lookup != NULL);
1970 debug("setup_lookup(%p)", lookup);
1972 result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
1974 check_result(result, "dns_message_create");
1976 if (lookup->new_search) {
1977 debug("resetting lookup counter.");
1981 if (ISC_LIST_EMPTY(lookup->my_server_list)) {
1982 debug("cloning server list");
1983 clone_server_list(server_list, &lookup->my_server_list);
1985 result = dns_message_gettempname(lookup->sendmsg, &lookup->name);
1986 check_result(result, "dns_message_gettempname");
1987 dns_name_init(lookup->name, NULL);
1989 isc_buffer_init(&lookup->namebuf, lookup->namespace,
1990 sizeof(lookup->namespace));
1991 isc_buffer_init(&lookup->onamebuf, lookup->onamespace,
1992 sizeof(lookup->onamespace));
1996 * We cannot convert `textname' and `origin' separately.
1997 * `textname' doesn't contain TLD, but local mapping needs
2000 mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname,
2001 utf8_textname, sizeof(utf8_textname));
2002 idn_check_result(mr, "convert textname to UTF-8");
2006 * If the name has too many dots, force the origin to be NULL
2007 * (which produces an absolute lookup). Otherwise, take the origin
2008 * we have if there's one in the struct already. If it's NULL,
2009 * take the first entry in the searchlist iff either usesearch
2010 * is TRUE or we got a domain line in the resolv.conf file.
2012 if (lookup->new_search) {
2014 if ((count_dots(utf8_textname) >= ndots) || !usesearch) {
2015 lookup->origin = NULL; /* Force abs lookup */
2016 lookup->done_as_is = ISC_TRUE;
2017 lookup->need_search = usesearch;
2018 } else if (lookup->origin == NULL && usesearch) {
2019 lookup->origin = ISC_LIST_HEAD(search_list);
2020 lookup->need_search = ISC_FALSE;
2023 if ((count_dots(lookup->textname) >= ndots) || !usesearch) {
2024 lookup->origin = NULL; /* Force abs lookup */
2025 lookup->done_as_is = ISC_TRUE;
2026 lookup->need_search = usesearch;
2027 } else if (lookup->origin == NULL && usesearch) {
2028 lookup->origin = ISC_LIST_HEAD(search_list);
2029 lookup->need_search = ISC_FALSE;
2035 if (lookup->origin != NULL) {
2036 mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP,
2037 lookup->origin->origin, utf8_origin,
2038 sizeof(utf8_origin));
2039 idn_check_result(mr, "convert origin to UTF-8");
2040 mr = append_textname(utf8_textname, utf8_origin,
2041 sizeof(utf8_textname));
2042 idn_check_result(mr, "append origin to textname");
2044 mr = idn_encodename(idnoptions | IDN_LOCALMAP | IDN_NAMEPREP |
2045 IDN_IDNCONV | IDN_LENCHECK, utf8_textname,
2046 idn_textname, sizeof(idn_textname));
2047 idn_check_result(mr, "convert UTF-8 textname to IDN encoding");
2049 if (lookup->origin != NULL) {
2050 debug("trying origin %s", lookup->origin->origin);
2051 result = dns_message_gettempname(lookup->sendmsg,
2053 check_result(result, "dns_message_gettempname");
2054 dns_name_init(lookup->oname, NULL);
2055 /* XXX Helper funct to conv char* to name? */
2056 len = strlen(lookup->origin->origin);
2057 isc_buffer_init(&b, lookup->origin->origin, len);
2058 isc_buffer_add(&b, len);
2059 result = dns_name_fromtext(lookup->oname, &b, dns_rootname,
2060 0, &lookup->onamebuf);
2061 if (result != ISC_R_SUCCESS) {
2062 dns_message_puttempname(lookup->sendmsg,
2064 dns_message_puttempname(lookup->sendmsg,
2066 fatal("'%s' is not in legal name syntax (%s)",
2067 lookup->origin->origin,
2068 isc_result_totext(result));
2070 if (lookup->trace && lookup->trace_root) {
2071 dns_name_clone(dns_rootname, lookup->name);
2073 len = strlen(lookup->textname);
2074 isc_buffer_init(&b, lookup->textname, len);
2075 isc_buffer_add(&b, len);
2076 result = dns_name_fromtext(lookup->name, &b,
2080 if (result != ISC_R_SUCCESS) {
2081 dns_message_puttempname(lookup->sendmsg,
2083 dns_message_puttempname(lookup->sendmsg,
2085 fatal("'%s' is not in legal name syntax (%s)",
2086 lookup->textname, isc_result_totext(result));
2088 dns_message_puttempname(lookup->sendmsg, &lookup->oname);
2092 debug("using root origin");
2093 if (lookup->trace && lookup->trace_root)
2094 dns_name_clone(dns_rootname, lookup->name);
2097 len = strlen(idn_textname);
2098 isc_buffer_init(&b, idn_textname, len);
2099 isc_buffer_add(&b, len);
2100 result = dns_name_fromtext(lookup->name, &b,
2104 len = strlen(lookup->textname);
2105 isc_buffer_init(&b, lookup->textname, len);
2106 isc_buffer_add(&b, len);
2107 result = dns_name_fromtext(lookup->name, &b,
2112 if (result != ISC_R_SUCCESS) {
2113 dns_message_puttempname(lookup->sendmsg,
2115 isc_buffer_init(&b, store, MXNAME);
2116 fatal("'%s' is not a legal name "
2117 "(%s)", lookup->textname,
2118 isc_result_totext(result));
2121 dns_name_format(lookup->name, store, sizeof(store));
2122 trying(store, lookup);
2123 INSIST(dns_name_isabsolute(lookup->name));
2125 isc_random_get(&id);
2126 lookup->sendmsg->id = (unsigned short)id & 0xFFFF;
2127 lookup->sendmsg->opcode = dns_opcode_query;
2128 lookup->msgcounter = 0;
2130 * If this is a trace request, completely disallow recursion, since
2131 * it's meaningless for traces.
2133 if (lookup->trace || (lookup->ns_search_only && !lookup->trace_root))
2134 lookup->recurse = ISC_FALSE;
2136 if (lookup->recurse &&
2137 lookup->rdtype != dns_rdatatype_axfr &&
2138 lookup->rdtype != dns_rdatatype_ixfr) {
2139 debug("recursive query");
2140 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_RD;
2144 if (lookup->aaonly) {
2146 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AA;
2149 if (lookup->adflag) {
2151 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AD;
2154 if (lookup->cdflag) {
2156 lookup->sendmsg->flags |= DNS_MESSAGEFLAG_CD;
2159 dns_message_addname(lookup->sendmsg, lookup->name,
2160 DNS_SECTION_QUESTION);
2162 if (lookup->trace && lookup->trace_root) {
2163 lookup->qrdtype = lookup->rdtype;
2164 lookup->rdtype = dns_rdatatype_ns;
2167 if ((lookup->rdtype == dns_rdatatype_axfr) ||
2168 (lookup->rdtype == dns_rdatatype_ixfr)) {
2170 * Force TCP mode if we're doing an axfr.
2172 if (lookup->rdtype == dns_rdatatype_axfr) {
2173 lookup->doing_xfr = ISC_TRUE;
2174 lookup->tcp_mode = ISC_TRUE;
2175 } else if (lookup->tcp_mode) {
2176 lookup->doing_xfr = ISC_TRUE;
2180 add_question(lookup->sendmsg, lookup->name, lookup->rdclass,
2184 if (lookup->rdtype == dns_rdatatype_ixfr)
2187 /* XXX Insist this? */
2188 lookup->tsigctx = NULL;
2189 lookup->querysig = NULL;
2191 debug("initializing keys");
2192 result = dns_message_settsigkey(lookup->sendmsg, key);
2193 check_result(result, "dns_message_settsigkey");
2196 lookup->sendspace = isc_mempool_get(commctx);
2197 if (lookup->sendspace == NULL)
2198 fatal("memory allocation failure");
2200 result = dns_compress_init(&cctx, -1, mctx);
2201 check_result(result, "dns_compress_init");
2203 debug("starting to render the message");
2204 isc_buffer_init(&lookup->renderbuf, lookup->sendspace, COMMSIZE);
2205 result = dns_message_renderbegin(lookup->sendmsg, &cctx,
2206 &lookup->renderbuf);
2207 check_result(result, "dns_message_renderbegin");
2208 if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1) {
2209 if (lookup->udpsize == 0)
2210 lookup->udpsize = 4096;
2211 if (lookup->edns < 0)
2213 add_opt(lookup->sendmsg, lookup->udpsize,
2214 lookup->edns, lookup->dnssec, lookup->nsid);
2217 result = dns_message_rendersection(lookup->sendmsg,
2218 DNS_SECTION_QUESTION, 0);
2219 check_result(result, "dns_message_rendersection");
2220 result = dns_message_rendersection(lookup->sendmsg,
2221 DNS_SECTION_AUTHORITY, 0);
2222 check_result(result, "dns_message_rendersection");
2223 result = dns_message_renderend(lookup->sendmsg);
2224 check_result(result, "dns_message_renderend");
2225 debug("done rendering");
2227 dns_compress_invalidate(&cctx);
2230 * Force TCP mode if the request is larger than 512 bytes.
2232 if (isc_buffer_usedlength(&lookup->renderbuf) > 512)
2233 lookup->tcp_mode = ISC_TRUE;
2235 lookup->pending = ISC_FALSE;
2237 for (serv = ISC_LIST_HEAD(lookup->my_server_list);
2239 serv = ISC_LIST_NEXT(serv, link)) {
2240 query = isc_mem_allocate(mctx, sizeof(dig_query_t));
2242 fatal("memory allocation failure in %s:%d",
2243 __FILE__, __LINE__);
2244 debug("create query %p linked to lookup %p",
2246 query->lookup = lookup;
2247 query->waiting_connect = ISC_FALSE;
2248 query->waiting_senddone = ISC_FALSE;
2249 query->pending_free = ISC_FALSE;
2250 query->recv_made = ISC_FALSE;
2251 query->first_pass = ISC_TRUE;
2252 query->first_soa_rcvd = ISC_FALSE;
2253 query->second_rr_rcvd = ISC_FALSE;
2254 query->first_repeat_rcvd = ISC_FALSE;
2255 query->warn_id = ISC_TRUE;
2256 query->first_rr_serial = 0;
2257 query->second_rr_serial = 0;
2258 query->servname = serv->servername;
2259 query->userarg = serv->userarg;
2260 query->rr_count = 0;
2261 query->msg_count = 0;
2262 query->byte_count = 0;
2263 ISC_LINK_INIT(query, link);
2264 ISC_LIST_INIT(query->recvlist);
2265 ISC_LIST_INIT(query->lengthlist);
2267 query->recvspace = isc_mempool_get(commctx);
2268 if (query->recvspace == NULL)
2269 fatal("memory allocation failure");
2271 isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
2272 isc_buffer_init(&query->lengthbuf, query->lengthspace, 2);
2273 isc_buffer_init(&query->slbuf, query->slspace, 2);
2274 query->sendbuf = lookup->renderbuf;
2276 ISC_LINK_INIT(query, link);
2277 ISC_LIST_ENQUEUE(lookup->q, query, link);
2279 /* XXX qrflag, print_query, etc... */
2280 if (!ISC_LIST_EMPTY(lookup->q) && qr) {
2282 printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg,
2288 * Event handler for send completion. Track send counter, and clear out
2289 * the query if the send was canceled.
2292 send_done(isc_task_t *_task, isc_event_t *event) {
2293 isc_socketevent_t *sevent = (isc_socketevent_t *)event;
2294 isc_buffer_t *b = NULL;
2295 dig_query_t *query, *next;
2298 REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
2304 debug("send_done()");
2306 debug("sendcount=%d", sendcount);
2307 INSIST(sendcount >= 0);
2309 for (b = ISC_LIST_HEAD(sevent->bufferlist);
2311 b = ISC_LIST_HEAD(sevent->bufferlist))
2312 ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
2314 query = event->ev_arg;
2315 query->waiting_senddone = ISC_FALSE;
2318 if (l->ns_search_only && !l->trace_root) {
2319 debug("sending next, since searching");
2320 next = ISC_LIST_NEXT(query, link);
2325 isc_event_free(&event);
2327 if (query->pending_free)
2328 isc_mem_free(mctx, query);
2335 * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding
2336 * IO sockets. The cancel handlers should take care of cleaning up the
2337 * query and lookup structures
2340 cancel_lookup(dig_lookup_t *lookup) {
2341 dig_query_t *query, *next;
2343 debug("cancel_lookup()");
2344 query = ISC_LIST_HEAD(lookup->q);
2345 while (query != NULL) {
2346 next = ISC_LIST_NEXT(query, link);
2347 if (query->sock != NULL) {
2348 isc_socket_cancel(query->sock, global_task,
2349 ISC_SOCKCANCEL_ALL);
2356 if (lookup->timer != NULL)
2357 isc_timer_detach(&lookup->timer);
2358 lookup->pending = ISC_FALSE;
2359 lookup->retries = 0;
2363 bringup_timer(dig_query_t *query, unsigned int default_timeout) {
2365 unsigned int local_timeout;
2366 isc_result_t result;
2368 debug("bringup_timer()");
2370 * If the timer already exists, that means we're calling this
2371 * a second time (for a retry). Don't need to recreate it,
2375 if (ISC_LIST_NEXT(query, link) != NULL)
2376 local_timeout = SERVER_TIMEOUT;
2379 local_timeout = default_timeout;
2381 local_timeout = timeout;
2383 debug("have local timeout of %d", local_timeout);
2384 isc_interval_set(&l->interval, local_timeout, 0);
2385 if (l->timer != NULL)
2386 isc_timer_detach(&l->timer);
2387 result = isc_timer_create(timermgr, isc_timertype_once, NULL,
2388 &l->interval, global_task, connect_timeout,
2390 check_result(result, "isc_timer_create");
2394 force_timeout(dig_lookup_t *l, dig_query_t *query) {
2397 event = isc_event_allocate(mctx, query, ISC_TIMEREVENT_IDLE,
2399 sizeof(isc_event_t));
2400 if (event == NULL) {
2401 fatal("isc_event_allocate: %s",
2402 isc_result_totext(ISC_R_NOMEMORY));
2404 isc_task_send(global_task, &event);
2407 * The timer may have expired if, for example, get_address() takes
2408 * long time and the timer was running on a different thread.
2409 * We need to cancel the possible timeout event not to confuse
2410 * ourselves due to the duplicate events.
2412 if (l->timer != NULL)
2413 isc_timer_detach(&l->timer);
2418 connect_done(isc_task_t *task, isc_event_t *event);
2421 * Unlike send_udp, this can't be called multiple times with the same
2422 * query. When we retry TCP, we requeue the whole lookup, which should
2426 send_tcp_connect(dig_query_t *query) {
2427 isc_result_t result;
2431 debug("send_tcp_connect(%p)", query);
2434 query->waiting_connect = ISC_TRUE;
2435 query->lookup->current_query = query;
2436 result = get_address(query->servname, port, &query->sockaddr);
2437 if (result != ISC_R_SUCCESS) {
2439 * This servname doesn't have an address. Try the next server
2440 * by triggering an immediate 'timeout' (we lie, but the effect
2443 force_timeout(l, query);
2447 if (specified_source &&
2448 (isc_sockaddr_pf(&query->sockaddr) !=
2449 isc_sockaddr_pf(&bind_address))) {
2450 printf(";; Skipping server %s, incompatible "
2451 "address family\n", query->servname);
2452 query->waiting_connect = ISC_FALSE;
2453 next = ISC_LIST_NEXT(query, link);
2457 printf(";; No acceptable nameservers\n");
2458 check_next_lookup(l);
2461 send_tcp_connect(next);
2464 INSIST(query->sock == NULL);
2465 result = isc_socket_create(socketmgr,
2466 isc_sockaddr_pf(&query->sockaddr),
2467 isc_sockettype_tcp, &query->sock);
2468 check_result(result, "isc_socket_create");
2470 debug("sockcount=%d", sockcount);
2471 if (specified_source)
2472 result = isc_socket_bind(query->sock, &bind_address,
2473 ISC_SOCKET_REUSEADDRESS);
2475 if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) &&
2477 isc_sockaddr_any(&bind_any);
2479 isc_sockaddr_any6(&bind_any);
2480 result = isc_socket_bind(query->sock, &bind_any, 0);
2482 check_result(result, "isc_socket_bind");
2483 bringup_timer(query, TCP_TIMEOUT);
2484 result = isc_socket_connect(query->sock, &query->sockaddr,
2485 global_task, connect_done, query);
2486 check_result(result, "isc_socket_connect");
2488 * If we're at the endgame of a nameserver search, we need to
2489 * immediately bring up all the queries. Do it here.
2491 if (l->ns_search_only && !l->trace_root) {
2492 debug("sending next, since searching");
2493 next = ISC_LIST_NEXT(query, link);
2495 send_tcp_connect(next);
2500 * Send a UDP packet to the remote nameserver, possible starting the
2501 * recv action as well. Also make sure that the timer is running and
2502 * is properly reset.
2505 send_udp(dig_query_t *query) {
2506 dig_lookup_t *l = NULL;
2507 isc_result_t result;
2509 debug("send_udp(%p)", query);
2512 bringup_timer(query, UDP_TIMEOUT);
2513 l->current_query = query;
2514 debug("working on lookup %p, query %p", query->lookup, query);
2515 if (!query->recv_made) {
2516 /* XXX Check the sense of this, need assertion? */
2517 query->waiting_connect = ISC_FALSE;
2518 result = get_address(query->servname, port, &query->sockaddr);
2519 if (result != ISC_R_SUCCESS) {
2520 /* This servname doesn't have an address. */
2521 force_timeout(l, query);
2525 result = isc_socket_create(socketmgr,
2526 isc_sockaddr_pf(&query->sockaddr),
2527 isc_sockettype_udp, &query->sock);
2528 check_result(result, "isc_socket_create");
2530 debug("sockcount=%d", sockcount);
2531 if (specified_source) {
2532 result = isc_socket_bind(query->sock, &bind_address,
2533 ISC_SOCKET_REUSEADDRESS);
2535 isc_sockaddr_anyofpf(&bind_any,
2536 isc_sockaddr_pf(&query->sockaddr));
2537 result = isc_socket_bind(query->sock, &bind_any, 0);
2539 check_result(result, "isc_socket_bind");
2541 query->recv_made = ISC_TRUE;
2542 ISC_LINK_INIT(&query->recvbuf, link);
2543 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf,
2545 debug("recving with lookup=%p, query=%p, sock=%p",
2546 query->lookup, query, query->sock);
2547 result = isc_socket_recvv(query->sock, &query->recvlist, 1,
2548 global_task, recv_done, query);
2549 check_result(result, "isc_socket_recvv");
2551 debug("recvcount=%d", recvcount);
2553 ISC_LIST_INIT(query->sendlist);
2554 ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link);
2555 debug("sending a request");
2556 TIME_NOW(&query->time_sent);
2557 INSIST(query->sock != NULL);
2558 query->waiting_senddone = ISC_TRUE;
2559 result = isc_socket_sendtov(query->sock, &query->sendlist,
2560 global_task, send_done, query,
2561 &query->sockaddr, NULL);
2562 check_result(result, "isc_socket_sendtov");
2567 * IO timeout handler, used for both connect and recv timeouts. If
2568 * retries are still allowed, either resend the UDP packet or queue a
2569 * new TCP lookup. Otherwise, cancel the lookup.
2572 connect_timeout(isc_task_t *task, isc_event_t *event) {
2573 dig_lookup_t *l = NULL;
2574 dig_query_t *query = NULL, *cq;
2577 REQUIRE(event->ev_type == ISC_TIMEREVENT_IDLE);
2579 debug("connect_timeout()");
2583 query = l->current_query;
2584 isc_event_free(&event);
2588 if ((query != NULL) && (query->lookup->current_query != NULL) &&
2589 (ISC_LIST_NEXT(query->lookup->current_query, link) != NULL)) {
2590 debug("trying next server...");
2591 cq = query->lookup->current_query;
2593 send_udp(ISC_LIST_NEXT(cq, link));
2595 if (query->sock != NULL)
2596 isc_socket_cancel(query->sock, NULL,
2597 ISC_SOCKCANCEL_ALL);
2598 send_tcp_connect(ISC_LIST_NEXT(cq, link));
2604 if (l->retries > 1) {
2607 debug("resending UDP request to first server");
2608 send_udp(ISC_LIST_HEAD(l->q));
2610 debug("making new TCP request, %d tries left",
2613 requeue_lookup(l, ISC_TRUE);
2615 check_next_lookup(l);
2618 fputs(l->cmdline, stdout);
2619 printf(";; connection timed out; no servers could be "
2622 check_next_lookup(l);
2630 * Event handler for the TCP recv which gets the length header of TCP
2631 * packets. Start the next recv of length bytes.
2634 tcp_length_done(isc_task_t *task, isc_event_t *event) {
2635 isc_socketevent_t *sevent;
2636 isc_buffer_t *b = NULL;
2637 isc_result_t result;
2638 dig_query_t *query = NULL;
2640 isc_uint16_t length;
2642 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
2647 debug("tcp_length_done()");
2650 sevent = (isc_socketevent_t *)event;
2651 query = event->ev_arg;
2654 INSIST(recvcount >= 0);
2656 b = ISC_LIST_HEAD(sevent->bufferlist);
2657 INSIST(b == &query->lengthbuf);
2658 ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
2660 if (sevent->result == ISC_R_CANCELED) {
2661 isc_event_free(&event);
2664 check_next_lookup(l);
2668 if (sevent->result != ISC_R_SUCCESS) {
2669 char sockstr[ISC_SOCKADDR_FORMATSIZE];
2670 isc_sockaddr_format(&query->sockaddr, sockstr,
2672 printf(";; communications error to %s: %s\n",
2673 sockstr, isc_result_totext(sevent->result));
2675 isc_socket_detach(&query->sock);
2677 debug("sockcount=%d", sockcount);
2678 INSIST(sockcount >= 0);
2679 isc_event_free(&event);
2681 check_next_lookup(l);
2685 length = isc_buffer_getuint16(b);
2687 isc_event_free(&event);
2688 launch_next_query(query, ISC_FALSE);
2694 * Even though the buffer was already init'ed, we need
2695 * to redo it now, to force the length we want.
2697 isc_buffer_invalidate(&query->recvbuf);
2698 isc_buffer_init(&query->recvbuf, query->recvspace, length);
2699 ENSURE(ISC_LIST_EMPTY(query->recvlist));
2700 ISC_LINK_INIT(&query->recvbuf, link);
2701 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
2702 debug("recving with lookup=%p, query=%p", query->lookup, query);
2703 result = isc_socket_recvv(query->sock, &query->recvlist, length, task,
2705 check_result(result, "isc_socket_recvv");
2707 debug("resubmitted recv request with length %d, recvcount=%d",
2709 isc_event_free(&event);
2714 * For transfers that involve multiple recvs (XFR's in particular),
2715 * launch the next recv.
2718 launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
2719 isc_result_t result;
2724 debug("launch_next_query()");
2726 if (!query->lookup->pending) {
2727 debug("ignoring launch_next_query because !pending");
2728 isc_socket_detach(&query->sock);
2730 debug("sockcount=%d", sockcount);
2731 INSIST(sockcount >= 0);
2732 query->waiting_connect = ISC_FALSE;
2735 check_next_lookup(l);
2739 isc_buffer_clear(&query->slbuf);
2740 isc_buffer_clear(&query->lengthbuf);
2741 isc_buffer_putuint16(&query->slbuf, (isc_uint16_t) query->sendbuf.used);
2742 ISC_LIST_INIT(query->sendlist);
2743 ISC_LINK_INIT(&query->slbuf, link);
2744 ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link);
2745 if (include_question)
2746 ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link);
2747 ISC_LINK_INIT(&query->lengthbuf, link);
2748 ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link);
2750 result = isc_socket_recvv(query->sock, &query->lengthlist, 0,
2751 global_task, tcp_length_done, query);
2752 check_result(result, "isc_socket_recvv");
2754 debug("recvcount=%d", recvcount);
2755 if (!query->first_soa_rcvd) {
2756 debug("sending a request in launch_next_query");
2757 TIME_NOW(&query->time_sent);
2758 query->waiting_senddone = ISC_TRUE;
2759 result = isc_socket_sendv(query->sock, &query->sendlist,
2760 global_task, send_done, query);
2761 check_result(result, "isc_socket_sendv");
2763 debug("sendcount=%d", sendcount);
2765 query->waiting_connect = ISC_FALSE;
2767 check_next_lookup(query->lookup);
2773 * Event handler for TCP connect complete. Make sure the connection was
2774 * successful, then pass into launch_next_query to actually send the
2778 connect_done(isc_task_t *task, isc_event_t *event) {
2779 isc_socketevent_t *sevent = NULL;
2780 dig_query_t *query = NULL, *next;
2785 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
2788 debug("connect_done()");
2791 sevent = (isc_socketevent_t *)event;
2792 query = sevent->ev_arg;
2794 INSIST(query->waiting_connect);
2796 query->waiting_connect = ISC_FALSE;
2798 if (sevent->result == ISC_R_CANCELED) {
2799 debug("in cancel handler");
2800 isc_socket_detach(&query->sock);
2801 INSIST(sockcount > 0);
2803 debug("sockcount=%d", sockcount);
2804 query->waiting_connect = ISC_FALSE;
2805 isc_event_free(&event);
2808 check_next_lookup(l);
2812 if (sevent->result != ISC_R_SUCCESS) {
2813 char sockstr[ISC_SOCKADDR_FORMATSIZE];
2815 debug("unsuccessful connection: %s",
2816 isc_result_totext(sevent->result));
2817 isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr));
2818 if (sevent->result != ISC_R_CANCELED)
2819 printf(";; Connection to %s(%s) for %s failed: "
2821 query->servname, query->lookup->textname,
2822 isc_result_totext(sevent->result));
2823 isc_socket_detach(&query->sock);
2825 INSIST(sockcount >= 0);
2826 /* XXX Clean up exitcodes */
2829 debug("sockcount=%d", sockcount);
2830 query->waiting_connect = ISC_FALSE;
2831 isc_event_free(&event);
2833 if (l->current_query != NULL)
2834 next = ISC_LIST_NEXT(l->current_query, link);
2839 bringup_timer(next, TCP_TIMEOUT);
2840 send_tcp_connect(next);
2842 check_next_lookup(l);
2847 launch_next_query(query, ISC_TRUE);
2848 isc_event_free(&event);
2853 * Check if the ongoing XFR needs more data before it's complete, using
2854 * the semantics of IXFR and AXFR protocols. Much of the complexity of
2855 * this routine comes from determining when an IXFR is complete.
2856 * ISC_FALSE means more data is on the way, and the recv has been issued.
2858 static isc_boolean_t
2859 check_for_more_data(dig_query_t *query, dns_message_t *msg,
2860 isc_socketevent_t *sevent)
2862 dns_rdataset_t *rdataset = NULL;
2863 dns_rdata_t rdata = DNS_RDATA_INIT;
2864 dns_rdata_soa_t soa;
2865 isc_uint32_t serial;
2866 isc_result_t result;
2868 debug("check_for_more_data()");
2871 * By the time we're in this routine, we know we're doing
2872 * either an AXFR or IXFR. If there's no second_rr_type,
2873 * then we don't yet know which kind of answer we got back
2874 * from the server. Here, we're going to walk through the
2875 * rr's in the message, acting as necessary whenever we hit
2880 query->byte_count += sevent->n;
2881 result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
2882 if (result != ISC_R_SUCCESS) {
2883 puts("; Transfer failed.");
2889 dns_message_currentname(msg, DNS_SECTION_ANSWER,
2891 for (rdataset = ISC_LIST_HEAD(name->list);
2893 rdataset = ISC_LIST_NEXT(rdataset, link)) {
2894 result = dns_rdataset_first(rdataset);
2895 if (result != ISC_R_SUCCESS)
2899 dns_rdata_reset(&rdata);
2900 dns_rdataset_current(rdataset, &rdata);
2902 * If this is the first rr, make sure
2905 if ((!query->first_soa_rcvd) &&
2906 (rdata.type != dns_rdatatype_soa)) {
2907 puts("; Transfer failed. "
2908 "Didn't start with SOA answer.");
2911 if ((!query->second_rr_rcvd) &&
2912 (rdata.type != dns_rdatatype_soa)) {
2913 query->second_rr_rcvd = ISC_TRUE;
2914 query->second_rr_serial = 0;
2915 debug("got the second rr as nonsoa");
2920 * If the record is anything except an SOA
2921 * now, just continue on...
2923 if (rdata.type != dns_rdatatype_soa)
2925 /* Now we have an SOA. Work with it. */
2926 debug("got an SOA");
2927 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2928 check_result(result, "dns_rdata_tostruct");
2929 serial = soa.serial;
2930 dns_rdata_freestruct(&soa);
2931 if (!query->first_soa_rcvd) {
2932 query->first_soa_rcvd = ISC_TRUE;
2933 query->first_rr_serial = serial;
2934 debug("this is the first %d",
2935 query->lookup->ixfr_serial);
2936 if (query->lookup->ixfr_serial >=
2941 if (query->lookup->rdtype ==
2942 dns_rdatatype_axfr) {
2943 debug("doing axfr, got second SOA");
2946 if (!query->second_rr_rcvd) {
2947 if (query->first_rr_serial == serial) {
2948 debug("doing ixfr, got "
2952 debug("this is the second %d",
2953 query->lookup->ixfr_serial);
2954 query->second_rr_rcvd = ISC_TRUE;
2955 query->second_rr_serial = serial;
2958 if (query->second_rr_serial == 0) {
2960 * If the second RR was a non-SOA
2961 * record, and we're getting any
2962 * other SOA, then this is an
2963 * AXFR, and we're done.
2965 debug("done, since axfr");
2969 * If we get to this point, we're doing an
2970 * IXFR and have to start really looking
2971 * at serial numbers.
2973 if (query->first_rr_serial == serial) {
2974 debug("got a match for ixfr");
2975 if (!query->first_repeat_rcvd) {
2976 query->first_repeat_rcvd =
2980 debug("done with ixfr");
2983 debug("meaningless soa %d", serial);
2985 result = dns_rdataset_next(rdataset);
2986 } while (result == ISC_R_SUCCESS);
2988 result = dns_message_nextname(msg, DNS_SECTION_ANSWER);
2989 } while (result == ISC_R_SUCCESS);
2990 launch_next_query(query, ISC_FALSE);
2993 received(sevent->n, &sevent->address, query);
2998 * Event handler for recv complete. Perform whatever actions are necessary,
2999 * based on the specifics of the user's request.
3002 recv_done(isc_task_t *task, isc_event_t *event) {
3003 isc_socketevent_t *sevent = NULL;
3004 dig_query_t *query = NULL;
3005 isc_buffer_t *b = NULL;
3006 dns_message_t *msg = NULL;
3008 dig_message_t *chase_msg = NULL;
3009 dig_message_t *chase_msg2 = NULL;
3011 isc_result_t result;
3012 dig_lookup_t *n, *l;
3013 isc_boolean_t docancel = ISC_FALSE;
3014 isc_boolean_t match = ISC_TRUE;
3015 unsigned int parseflags;
3017 unsigned int msgflags;
3019 isc_result_t do_sigchase = ISC_FALSE;
3021 dns_message_t *msg_temp = NULL;
3023 isc_buffer_t *buf = NULL;
3029 debug("recv_done()");
3033 debug("recvcount=%d", recvcount);
3034 INSIST(recvcount >= 0);
3036 query = event->ev_arg;
3037 debug("lookup=%p, query=%p", query->lookup, query);
3041 REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
3042 sevent = (isc_socketevent_t *)event;
3044 b = ISC_LIST_HEAD(sevent->bufferlist);
3045 INSIST(b == &query->recvbuf);
3046 ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link);
3048 if ((l->tcp_mode) && (l->timer != NULL))
3049 isc_timer_touch(l->timer);
3050 if ((!l->pending && !l->ns_search_only) || cancel_now) {
3051 debug("no longer pending. Got %s",
3052 isc_result_totext(sevent->result));
3053 query->waiting_connect = ISC_FALSE;
3055 isc_event_free(&event);
3057 check_next_lookup(l);
3062 if (sevent->result != ISC_R_SUCCESS) {
3063 if (sevent->result == ISC_R_CANCELED) {
3064 debug("in recv cancel handler");
3065 query->waiting_connect = ISC_FALSE;
3067 printf(";; communications error: %s\n",
3068 isc_result_totext(sevent->result));
3069 isc_socket_detach(&query->sock);
3071 debug("sockcount=%d", sockcount);
3072 INSIST(sockcount >= 0);
3074 isc_event_free(&event);
3076 check_next_lookup(l);
3082 !isc_sockaddr_compare(&sevent->address, &query->sockaddr,
3083 ISC_SOCKADDR_CMPADDR|
3084 ISC_SOCKADDR_CMPPORT|
3085 ISC_SOCKADDR_CMPSCOPE|
3086 ISC_SOCKADDR_CMPSCOPEZERO)) {
3087 char buf1[ISC_SOCKADDR_FORMATSIZE];
3088 char buf2[ISC_SOCKADDR_FORMATSIZE];
3091 if (isc_sockaddr_pf(&query->sockaddr) == AF_INET)
3092 isc_sockaddr_any(&any);
3094 isc_sockaddr_any6(&any);
3097 * We don't expect a match when the packet is
3098 * sent to 0.0.0.0, :: or to a multicast addresses.
3099 * XXXMPA broadcast needs to be handled here as well.
3101 if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) &&
3102 !isc_sockaddr_ismulticast(&query->sockaddr)) ||
3103 isc_sockaddr_getport(&query->sockaddr) !=
3104 isc_sockaddr_getport(&sevent->address)) {
3105 isc_sockaddr_format(&sevent->address, buf1,
3107 isc_sockaddr_format(&query->sockaddr, buf2,
3109 printf(";; reply from unexpected source: %s,"
3110 " expected %s\n", buf1, buf2);
3115 result = dns_message_peekheader(b, &id, &msgflags);
3116 if (result != ISC_R_SUCCESS || l->sendmsg->id != id) {
3119 isc_boolean_t fail = ISC_TRUE;
3120 if (result == ISC_R_SUCCESS) {
3121 if (!query->first_soa_rcvd ||
3123 printf(";; %s: ID mismatch: "
3124 "expected ID %u, got %u\n",
3125 query->first_soa_rcvd ?
3126 "WARNING" : "ERROR",
3127 l->sendmsg->id, id);
3128 if (query->first_soa_rcvd)
3130 query->warn_id = ISC_FALSE;
3132 printf(";; ERROR: short "
3133 "(< header size) message\n");
3135 isc_event_free(&event);
3137 check_next_lookup(l);
3142 } else if (result == ISC_R_SUCCESS)
3143 printf(";; Warning: ID mismatch: "
3144 "expected ID %u, got %u\n", l->sendmsg->id, id);
3146 printf(";; Warning: short "
3147 "(< header size) message received\n");
3150 if (result == ISC_R_SUCCESS && (msgflags & DNS_MESSAGEFLAG_QR) == 0)
3151 printf(";; Warning: query response not set\n");
3156 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
3157 check_result(result, "dns_message_create");
3160 if (l->querysig == NULL) {
3161 debug("getting initial querysig");
3162 result = dns_message_getquerytsig(l->sendmsg, mctx,
3164 check_result(result, "dns_message_getquerytsig");
3166 result = dns_message_setquerytsig(msg, l->querysig);
3167 check_result(result, "dns_message_setquerytsig");
3168 result = dns_message_settsigkey(msg, key);
3169 check_result(result, "dns_message_settsigkey");
3170 msg->tsigctx = l->tsigctx;
3172 if (l->msgcounter != 0)
3173 msg->tcp_continuation = 1;
3177 debug("before parse starts");
3178 parseflags = DNS_MESSAGEPARSE_PRESERVEORDER;
3181 do_sigchase = ISC_FALSE;
3184 do_sigchase = ISC_TRUE;
3187 if (l->besteffort) {
3188 parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
3189 parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION;
3191 result = dns_message_parse(msg, b, parseflags);
3192 if (result == DNS_R_RECOVERABLE) {
3193 printf(";; Warning: Message parser reports malformed "
3194 "message packet.\n");
3195 result = ISC_R_SUCCESS;
3197 if (result != ISC_R_SUCCESS) {
3198 printf(";; Got bad packet: %s\n", isc_result_totext(result));
3200 query->waiting_connect = ISC_FALSE;
3201 dns_message_destroy(&msg);
3202 isc_event_free(&event);
3205 check_next_lookup(l);
3209 if (msg->counts[DNS_SECTION_QUESTION] != 0) {
3211 for (result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
3212 result == ISC_R_SUCCESS && match;
3213 result = dns_message_nextname(msg, DNS_SECTION_QUESTION)) {
3214 dns_name_t *name = NULL;
3215 dns_rdataset_t *rdataset;
3217 dns_message_currentname(msg, DNS_SECTION_QUESTION,
3219 for (rdataset = ISC_LIST_HEAD(name->list);
3221 rdataset = ISC_LIST_NEXT(rdataset, link)) {
3222 if (l->rdtype != rdataset->type ||
3223 l->rdclass != rdataset->rdclass ||
3224 !dns_name_equal(l->name, name)) {
3225 char namestr[DNS_NAME_FORMATSIZE];
3226 char typebuf[DNS_RDATATYPE_FORMATSIZE];
3227 char classbuf[DNS_RDATACLASS_FORMATSIZE];
3228 dns_name_format(name, namestr,
3230 dns_rdatatype_format(rdataset->type,
3233 dns_rdataclass_format(rdataset->rdclass,
3236 printf(";; Question section mismatch: "
3238 namestr, typebuf, classbuf);
3244 dns_message_destroy(&msg);
3246 isc_event_free(&event);
3248 check_next_lookup(l);
3255 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 &&
3256 !l->ignore && !l->tcp_mode) {
3257 printf(";; Truncated, retrying in TCP mode.\n");
3258 n = requeue_lookup(l, ISC_TRUE);
3259 n->tcp_mode = ISC_TRUE;
3260 n->origin = query->lookup->origin;
3261 dns_message_destroy(&msg);
3262 isc_event_free(&event);
3265 check_next_lookup(l);
3269 if ((msg->rcode == dns_rcode_servfail && !l->servfail_stops) ||
3270 (check_ra && (msg->flags & DNS_MESSAGEFLAG_RA) == 0 && l->recurse))
3272 dig_query_t *next = ISC_LIST_NEXT(query, link);
3273 if (l->current_query == query)
3274 l->current_query = NULL;
3276 debug("sending query %p\n", next);
3278 send_tcp_connect(next);
3283 * If our query is at the head of the list and there
3284 * is no next, we're the only one left, so fall
3285 * through to print the message.
3287 if ((ISC_LIST_HEAD(l->q) != query) ||
3288 (ISC_LIST_NEXT(query, link) != NULL)) {
3289 if( l->comments == ISC_TRUE )
3290 printf(";; Got %s from %s, "
3291 "trying next server\n",
3292 msg->rcode == dns_rcode_servfail ?
3294 "recursion not available",
3297 check_next_lookup(l);
3298 dns_message_destroy(&msg);
3299 isc_event_free(&event);
3306 result = dns_tsig_verify(&query->recvbuf, msg, NULL, NULL);
3307 if (result != ISC_R_SUCCESS) {
3308 printf(";; Couldn't verify signature: %s\n",
3309 isc_result_totext(result));
3310 validated = ISC_FALSE;
3312 l->tsigctx = msg->tsigctx;
3313 msg->tsigctx = NULL;
3314 if (l->querysig != NULL) {
3315 debug("freeing querysig buffer %p", l->querysig);
3316 isc_buffer_free(&l->querysig);
3318 result = dns_message_getquerytsig(msg, mctx, &l->querysig);
3319 check_result(result,"dns_message_getquerytsig");
3322 extrabytes = isc_buffer_remaininglength(b);
3324 debug("after parse");
3325 if (l->doing_xfr && l->xfr_q == NULL) {
3328 * Once we are in the XFR message, increase
3329 * the timeout to much longer, so brief network
3330 * outages won't cause the XFR to abort
3332 if (timeout != INT_MAX && l->timer != NULL) {
3333 unsigned int local_timeout;
3337 local_timeout = TCP_TIMEOUT * 4;
3339 local_timeout = UDP_TIMEOUT * 4;
3341 if (timeout < (INT_MAX / 4))
3342 local_timeout = timeout * 4;
3344 local_timeout = INT_MAX;
3346 debug("have local timeout of %d", local_timeout);
3347 isc_interval_set(&l->interval, local_timeout, 0);
3348 result = isc_timer_reset(l->timer,
3353 check_result(result, "isc_timer_reset");
3357 if (!l->doing_xfr || l->xfr_q == query) {
3358 if (msg->rcode != dns_rcode_noerror &&
3359 (l->origin != NULL || l->need_search)) {
3360 if (!next_origin(msg, query) || showsearch) {
3361 printmessage(query, msg, ISC_TRUE);
3362 received(b->used, &sevent->address, query);
3364 } else if (!l->trace && !l->ns_search_only) {
3368 printmessage(query, msg, ISC_TRUE);
3369 } else if (l->trace) {
3371 int count = msg->counts[DNS_SECTION_ANSWER];
3373 debug("in TRACE code");
3374 if (!l->ns_search_only)
3375 printmessage(query, msg, ISC_TRUE);
3377 l->rdtype = l->qrdtype;
3378 if (l->trace_root || (l->ns_search_only && count > 0)) {
3380 l->rdtype = dns_rdatatype_soa;
3381 n = followup_lookup(msg, query,
3382 DNS_SECTION_ANSWER);
3383 l->trace_root = ISC_FALSE;
3384 } else if (count == 0)
3385 n = followup_lookup(msg, query,
3386 DNS_SECTION_AUTHORITY);
3388 docancel = ISC_TRUE;
3390 debug("in NSSEARCH code");
3392 if (l->trace_root) {
3394 * This is the initial NS query.
3398 l->rdtype = dns_rdatatype_soa;
3399 n = followup_lookup(msg, query,
3400 DNS_SECTION_ANSWER);
3402 docancel = ISC_TRUE;
3403 l->trace_root = ISC_FALSE;
3408 printmessage(query, msg, ISC_TRUE);
3412 chase_msg = isc_mem_allocate(mctx,
3413 sizeof(dig_message_t));
3414 if (chase_msg == NULL) {
3415 fatal("Memory allocation failure in %s:%d",
3416 __FILE__, __LINE__);
3418 ISC_LIST_INITANDAPPEND(chase_message_list, chase_msg,
3420 if (dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
3421 &msg_temp) != ISC_R_SUCCESS) {
3422 fatal("dns_message_create in %s:%d",
3423 __FILE__, __LINE__);
3426 isc_buffer_usedregion(b, &r);
3427 result = isc_buffer_allocate(mctx, &buf, r.length);
3429 check_result(result, "isc_buffer_allocate");
3430 result = isc_buffer_copyregion(buf, &r);
3431 check_result(result, "isc_buffer_copyregion");
3433 result = dns_message_parse(msg_temp, buf, 0);
3435 isc_buffer_free(&buf);
3436 chase_msg->msg = msg_temp;
3438 chase_msg2 = isc_mem_allocate(mctx,
3439 sizeof(dig_message_t));
3440 if (chase_msg2 == NULL) {
3441 fatal("Memory allocation failure in %s:%d",
3442 __FILE__, __LINE__);
3444 ISC_LIST_INITANDAPPEND(chase_message_list2, chase_msg2,
3446 chase_msg2->msg = msg;
3452 if (l->sigchase && ISC_LIST_EMPTY(lookup_list)) {
3458 debug("still pending.");
3460 if (query != l->xfr_q) {
3461 dns_message_destroy(&msg);
3462 isc_event_free(&event);
3463 query->waiting_connect = ISC_FALSE;
3468 docancel = check_for_more_data(query, msg, sevent);
3470 dns_message_destroy(&msg);
3473 check_next_lookup(l);
3477 if (msg->rcode == dns_rcode_noerror || l->origin == NULL) {
3482 received(b->used, &sevent->address, query);
3485 if (!query->lookup->ns_search_only)
3486 query->lookup->pending = ISC_FALSE;
3487 if (!query->lookup->ns_search_only ||
3488 query->lookup->trace_root || docancel) {
3492 dns_message_destroy(&msg);
3497 check_next_lookup(l);
3505 dns_message_destroy(&msg);
3507 isc_event_free(&event);
3512 isc_buffer_invalidate(&query->recvbuf);
3513 isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
3514 ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
3515 result = isc_socket_recvv(query->sock, &query->recvlist, 1,
3516 global_task, recv_done, query);
3517 check_result(result, "isc_socket_recvv");
3519 isc_event_free(&event);
3525 * Turn a name into an address, using system-supplied routines. This is
3526 * used in looking up server names, etc... and needs to use system-supplied
3527 * routines, since they may be using a non-DNS system for these lookups.
3530 get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) {
3532 isc_result_t result;
3535 result = bind9_getaddresses(host, port, sockaddr, 1, &count);
3537 if (result != ISC_R_SUCCESS)
3542 return (ISC_R_SUCCESS);
3546 * Initiate either a TCP or UDP lookup
3549 do_lookup(dig_lookup_t *lookup) {
3551 REQUIRE(lookup != NULL);
3553 debug("do_lookup()");
3554 lookup->pending = ISC_TRUE;
3555 if (lookup->tcp_mode)
3556 send_tcp_connect(ISC_LIST_HEAD(lookup->q));
3558 send_udp(ISC_LIST_HEAD(lookup->q));
3562 * Start everything in action upon task startup.
3565 onrun_callback(isc_task_t *task, isc_event_t *event) {
3568 isc_event_free(&event);
3575 * Make everything on the lookup queue go away. Mainly used by the
3580 dig_lookup_t *l, *n;
3581 dig_query_t *q, *nq;
3583 debug("cancel_all()");
3590 cancel_now = ISC_TRUE;
3591 if (current_lookup != NULL) {
3592 if (current_lookup->timer != NULL)
3593 isc_timer_detach(¤t_lookup->timer);
3594 q = ISC_LIST_HEAD(current_lookup->q);
3596 debug("canceling query %p, belonging to %p",
3598 nq = ISC_LIST_NEXT(q, link);
3599 if (q->sock != NULL) {
3600 isc_socket_cancel(q->sock, NULL,
3601 ISC_SOCKCANCEL_ALL);
3608 l = ISC_LIST_HEAD(lookup_list);
3610 n = ISC_LIST_NEXT(l, link);
3611 ISC_LIST_DEQUEUE(lookup_list, l, link);
3612 try_clear_lookup(l);
3619 * Destroy all of the libs we are using, and get everything ready for a
3623 destroy_libs(void) {
3626 dig_message_t *chase_msg;
3629 isc_result_t result;
3632 debug("destroy_libs()");
3633 if (global_task != NULL) {
3634 debug("freeing task");
3635 isc_task_detach(&global_task);
3638 * The taskmgr_destroy() call blocks until all events are cleared
3641 if (taskmgr != NULL) {
3642 debug("freeing taskmgr");
3643 isc_taskmgr_destroy(&taskmgr);
3646 REQUIRE(sockcount == 0);
3647 REQUIRE(recvcount == 0);
3648 REQUIRE(sendcount == 0);
3650 INSIST(ISC_LIST_HEAD(lookup_list) == NULL);
3651 INSIST(current_lookup == NULL);
3654 free_now = ISC_TRUE;
3656 lwres_conf_clear(lwctx);
3657 lwres_context_destroy(&lwctx);
3659 flush_server_list();
3664 result = dns_name_settotextfilter(NULL);
3665 check_result(result, "dns_name_settotextfilter");
3669 if (commctx != NULL) {
3670 debug("freeing commctx");
3671 isc_mempool_destroy(&commctx);
3673 if (socketmgr != NULL) {
3674 debug("freeing socketmgr");
3675 isc_socketmgr_destroy(&socketmgr);
3677 if (timermgr != NULL) {
3678 debug("freeing timermgr");
3679 isc_timermgr_destroy(&timermgr);
3682 debug("freeing key %p", key);
3683 dns_tsigkey_detach(&key);
3685 if (namebuf != NULL)
3686 isc_buffer_free(&namebuf);
3689 debug("destroy DST lib");
3691 is_dst_up = ISC_FALSE;
3694 debug("detach from entropy");
3695 isc_entropy_detach(&entp);
3699 DESTROYLOCK(&lookup_lock);
3702 debug("Destroy the messages kept for sigchase");
3703 /* Destroy the messages kept for sigchase */
3704 chase_msg = ISC_LIST_HEAD(chase_message_list);
3706 while (chase_msg != NULL) {
3707 INSIST(chase_msg->msg != NULL);
3708 dns_message_destroy(&(chase_msg->msg));
3710 chase_msg = ISC_LIST_NEXT(chase_msg, link);
3711 isc_mem_free(mctx, ptr);
3714 chase_msg = ISC_LIST_HEAD(chase_message_list2);
3716 while (chase_msg != NULL) {
3717 INSIST(chase_msg->msg != NULL);
3718 dns_message_destroy(&(chase_msg->msg));
3720 chase_msg = ISC_LIST_NEXT(chase_msg, link);
3721 isc_mem_free(mctx, ptr);
3723 if (dns_name_dynamic(&chase_name))
3724 free_name(&chase_name, mctx);
3726 if (dns_name_dynamic(&chase_current_name))
3727 free_name(&chase_current_name, mctx);
3728 if (dns_name_dynamic(&chase_authority_name))
3729 free_name(&chase_authority_name, mctx);
3732 if (dns_name_dynamic(&chase_signame))
3733 free_name(&chase_signame, mctx);
3737 debug("Removing log context");
3738 isc_log_destroy(&lctx);
3740 debug("Destroy memory");
3741 if (memdebugging != 0)
3742 isc_mem_stats(mctx, stderr);
3744 isc_mem_destroy(&mctx);
3749 initialize_idn(void) {
3751 isc_result_t result;
3753 #ifdef HAVE_SETLOCALE
3755 (void)setlocale(LC_ALL, "");
3757 /* Create configuration context. */
3758 r = idn_nameinit(1);
3759 if (r != idn_success)
3760 fatal("idn api initialization failed: %s",
3761 idn_result_tostring(r));
3763 /* Set domain name -> text post-conversion filter. */
3764 result = dns_name_settotextfilter(output_filter);
3765 check_result(result, "dns_name_settotextfilter");
3769 output_filter(isc_buffer_t *buffer, unsigned int used_org,
3770 isc_boolean_t absolute)
3772 char tmp1[MAXDLEN], tmp2[MAXDLEN];
3773 size_t fromlen, tolen;
3774 isc_boolean_t end_with_dot;
3777 * Copy contents of 'buffer' to 'tmp1', supply trailing dot
3778 * if 'absolute' is true, and terminate with NUL.
3780 fromlen = isc_buffer_usedlength(buffer) - used_org;
3781 if (fromlen >= MAXDLEN)
3782 return (ISC_R_SUCCESS);
3783 memcpy(tmp1, (char *)isc_buffer_base(buffer) + used_org, fromlen);
3784 end_with_dot = (tmp1[fromlen - 1] == '.') ? ISC_TRUE : ISC_FALSE;
3785 if (absolute && !end_with_dot) {
3787 if (fromlen >= MAXDLEN)
3788 return (ISC_R_SUCCESS);
3789 tmp1[fromlen - 1] = '.';
3791 tmp1[fromlen] = '\0';
3794 * Convert contents of 'tmp1' to local encoding.
3796 if (idn_decodename(IDN_DECODE_APP, tmp1, tmp2, MAXDLEN) != idn_success)
3797 return (ISC_R_SUCCESS);
3801 * Copy the converted contents in 'tmp1' back to 'buffer'.
3802 * If we have appended trailing dot, remove it.
3804 tolen = strlen(tmp1);
3805 if (absolute && !end_with_dot && tmp1[tolen - 1] == '.')
3808 if (isc_buffer_length(buffer) < used_org + tolen)
3809 return (ISC_R_NOSPACE);
3811 isc_buffer_subtract(buffer, isc_buffer_usedlength(buffer) - used_org);
3812 memcpy(isc_buffer_used(buffer), tmp1, tolen);
3813 isc_buffer_add(buffer, tolen);
3815 return (ISC_R_SUCCESS);
3819 append_textname(char *name, const char *origin, size_t namesize) {
3820 size_t namelen = strlen(name);
3821 size_t originlen = strlen(origin);
3823 /* Already absolute? */
3824 if (namelen > 0 && name[namelen - 1] == '.')
3827 /* Append dot and origin */
3829 if (namelen + 1 + originlen >= namesize)
3830 return idn_buffer_overflow;
3832 name[namelen++] = '.';
3833 (void)strcpy(name + namelen, origin);
3838 idn_check_result(idn_result_t r, const char *msg) {
3839 if (r != idn_success) {
3841 fatal("%s: %s", msg, idn_result_tostring(r));
3844 #endif /* WITH_IDN */
3848 print_type(dns_rdatatype_t type)
3850 isc_buffer_t * b = NULL;
3851 isc_result_t result;
3854 result = isc_buffer_allocate(mctx, &b, 4000);
3855 check_result(result, "isc_buffer_allocate");
3857 result = dns_rdatatype_totext(type, b);
3858 check_result(result, "print_type");
3860 isc_buffer_usedregion(b, &r);
3861 r.base[r.length] = '\0';
3863 printf("%s", r.base);
3865 isc_buffer_free(&b);
3869 dump_database_section(dns_message_t *msg, int section)
3871 dns_name_t *msg_name=NULL;
3873 dns_rdataset_t *rdataset;
3876 dns_message_currentname(msg, section, &msg_name);
3878 for (rdataset = ISC_LIST_HEAD(msg_name->list); rdataset != NULL;
3879 rdataset = ISC_LIST_NEXT(rdataset, link)) {
3880 dns_name_print(msg_name, stdout);
3882 print_rdataset(msg_name, rdataset, mctx);
3886 } while (dns_message_nextname(msg, section) == ISC_R_SUCCESS);
3890 dump_database(void) {
3891 dig_message_t * msg;
3893 for (msg = ISC_LIST_HEAD(chase_message_list); msg != NULL;
3894 msg = ISC_LIST_NEXT(msg, link)) {
3895 if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER)
3897 dump_database_section(msg->msg, DNS_SECTION_ANSWER);
3899 if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY)
3901 dump_database_section(msg->msg, DNS_SECTION_AUTHORITY);
3903 if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL)
3905 dump_database_section(msg->msg, DNS_SECTION_ADDITIONAL);
3911 search_type(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers) {
3912 dns_rdataset_t *rdataset;
3913 dns_rdata_sig_t siginfo;
3914 dns_rdata_t sigrdata = DNS_RDATA_INIT;
3915 isc_result_t result;
3917 for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
3918 rdataset = ISC_LIST_NEXT(rdataset, link)) {
3919 if (type == dns_rdatatype_any) {
3920 if (rdataset->type != dns_rdatatype_rrsig)
3922 } else if ((type == dns_rdatatype_rrsig) &&
3923 (rdataset->type == dns_rdatatype_rrsig)) {
3924 result = dns_rdataset_first(rdataset);
3925 check_result(result, "empty rdataset");
3926 dns_rdataset_current(rdataset, &sigrdata);
3927 result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
3928 check_result(result, "sigrdata tostruct siginfo");
3930 if ((siginfo.covered == covers) ||
3931 (covers == dns_rdatatype_any)) {
3932 dns_rdata_reset(&sigrdata);
3933 dns_rdata_freestruct(&siginfo);
3936 dns_rdata_reset(&sigrdata);
3937 dns_rdata_freestruct(&siginfo);
3938 } else if (rdataset->type == type)
3945 chase_scanname_section(dns_message_t *msg, dns_name_t *name,
3946 dns_rdatatype_t type, dns_rdatatype_t covers,
3949 dns_rdataset_t *rdataset;
3950 dns_name_t *msg_name = NULL;
3953 dns_message_currentname(msg, section, &msg_name);
3954 if (dns_name_compare(msg_name, name) == 0) {
3955 rdataset = search_type(msg_name, type, covers);
3956 if (rdataset != NULL)
3960 } while (dns_message_nextname(msg, section) == ISC_R_SUCCESS);
3967 chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers)
3969 dns_rdataset_t *rdataset = NULL;
3970 dig_message_t * msg;
3972 for (msg = ISC_LIST_HEAD(chase_message_list2); msg != NULL;
3973 msg = ISC_LIST_NEXT(msg, link)) {
3974 if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER)
3976 rdataset = chase_scanname_section(msg->msg, name,
3978 DNS_SECTION_ANSWER);
3979 if (rdataset != NULL)
3981 if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY)
3984 chase_scanname_section(msg->msg, name,
3986 DNS_SECTION_AUTHORITY);
3987 if (rdataset != NULL)
3989 if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL)
3992 chase_scanname_section(msg->msg, name, type,
3994 DNS_SECTION_ADDITIONAL);
3995 if (rdataset != NULL)
4003 sigchase_scanname(dns_rdatatype_t type, dns_rdatatype_t covers,
4004 isc_boolean_t * lookedup, dns_name_t *rdata_name)
4006 dig_lookup_t *lookup;
4007 isc_buffer_t *b = NULL;
4009 isc_result_t result;
4010 dns_rdataset_t * temp;
4011 dns_rdatatype_t querytype;
4013 temp = chase_scanname(rdata_name, type, covers);
4017 if (*lookedup == ISC_TRUE)
4020 lookup = clone_lookup(current_lookup, ISC_TRUE);
4021 lookup->trace_root = ISC_FALSE;
4022 lookup->new_search = ISC_TRUE;
4024 result = isc_buffer_allocate(mctx, &b, BUFSIZE);
4025 check_result(result, "isc_buffer_allocate");
4026 result = dns_name_totext(rdata_name, ISC_FALSE, b);
4027 check_result(result, "dns_name_totext");
4028 isc_buffer_usedregion(b, &r);
4029 r.base[r.length] = '\0';
4030 strcpy(lookup->textname, (char*)r.base);
4031 isc_buffer_free(&b);
4033 if (type == dns_rdatatype_rrsig)
4038 if (querytype == 0 || querytype == 255) {
4039 printf("Error in the queried type: %d\n", querytype);
4043 lookup->rdtype = querytype;
4044 lookup->rdtypeset = ISC_TRUE;
4045 lookup->qrdtype = querytype;
4046 *lookedup = ISC_TRUE;
4048 ISC_LIST_APPEND(lookup_list, lookup, link);
4049 printf("\n\nLaunch a query to find a RRset of type ");
4051 printf(" for zone: %s\n", lookup->textname);
4056 insert_trustedkey(dst_key_t * key)
4060 if (tk_list.nb_tk >= MAX_TRUSTED_KEY)
4063 tk_list.key[tk_list.nb_tk++] = key;
4072 for (i= 0; i < MAX_TRUSTED_KEY; i++) {
4073 if (tk_list.key[i] != NULL) {
4074 dst_key_free(&tk_list.key[i]);
4075 tk_list.key[i] = NULL;
4084 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
4087 removetmpkey(isc_mem_t *mctx, const char *file)
4089 char *tempnamekey = NULL;
4091 isc_result_t result;
4093 tempnamekeylen = strlen(file)+10;
4095 tempnamekey = isc_mem_allocate(mctx, tempnamekeylen);
4096 if (tempnamekey == NULL)
4097 return (ISC_R_NOMEMORY);
4099 memset(tempnamekey, 0, tempnamekeylen);
4101 strcat(tempnamekey, file);
4102 strcat(tempnamekey,".key");
4103 isc_file_remove(tempnamekey);
4105 result = isc_file_remove(tempnamekey);
4106 isc_mem_free(mctx, tempnamekey);
4111 opentmpkey(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) {
4113 isc_result_t result;
4114 char *tempname = NULL;
4115 char *tempnamekey = NULL;
4123 tempnamelen = strlen(file) + 20;
4124 tempname = isc_mem_allocate(mctx, tempnamelen);
4125 if (tempname == NULL)
4126 return (ISC_R_NOMEMORY);
4127 memset(tempname, 0, tempnamelen);
4129 result = isc_file_mktemplate(file, tempname, tempnamelen);
4130 if (result != ISC_R_SUCCESS)
4136 if (cp == tempname) {
4137 isc_mem_free(mctx, tempname);
4138 return (ISC_R_FAILURE);
4142 while (cp >= tempname && *cp == 'X') {
4143 isc_random_get(&which);
4144 *cp = alphnum[which % (sizeof(alphnum) - 1)];
4148 tempnamekeylen = tempnamelen+5;
4149 tempnamekey = isc_mem_allocate(mctx, tempnamekeylen);
4150 if (tempnamekey == NULL)
4151 return (ISC_R_NOMEMORY);
4153 memset(tempnamekey, 0, tempnamekeylen);
4154 strncpy(tempnamekey, tempname, tempnamelen);
4155 strcat(tempnamekey ,".key");
4158 if (isc_file_exists(tempnamekey)) {
4159 isc_mem_free(mctx, tempnamekey);
4160 isc_mem_free(mctx, tempname);
4164 if ((f = fopen(tempnamekey, "w")) == NULL) {
4165 printf("get_trusted_key(): trusted key not found %s\n",
4167 return (ISC_R_FAILURE);
4171 isc_mem_free(mctx, tempnamekey);
4174 return (ISC_R_SUCCESS);
4177 isc_mem_free(mctx, tempname);
4184 get_trusted_key(isc_mem_t *mctx)
4186 isc_result_t result;
4187 const char *filename = NULL;
4188 char *filetemp = NULL;
4191 dst_key_t *key = NULL;
4193 result = isc_file_exists(trustedkey);
4194 if (result != ISC_TRUE) {
4195 result = isc_file_exists("/etc/trusted-key.key");
4196 if (result != ISC_TRUE) {
4197 result = isc_file_exists("./trusted-key.key");
4198 if (result != ISC_TRUE)
4199 return (ISC_R_FAILURE);
4201 filename = "./trusted-key.key";
4203 filename = "/etc/trusted-key.key";
4205 filename = trustedkey;
4207 if (filename == NULL) {
4208 printf("No trusted key\n");
4209 return (ISC_R_FAILURE);
4212 if ((fp = fopen(filename, "r")) == NULL) {
4213 printf("get_trusted_key(): trusted key not found %s\n",
4215 return (ISC_R_FAILURE);
4217 while (fgets(buf, sizeof(buf), fp) != NULL) {
4218 result = opentmpkey(mctx,"tmp_file", &filetemp, &fptemp);
4219 if (result != ISC_R_SUCCESS) {
4221 return (ISC_R_FAILURE);
4223 if (fputs(buf, fptemp) < 0) {
4226 return (ISC_R_FAILURE);
4229 result = dst_key_fromnamedfile(filetemp, NULL, DST_TYPE_PUBLIC,
4231 removetmpkey(mctx, filetemp);
4232 isc_mem_free(mctx, filetemp);
4233 if (result != ISC_R_SUCCESS) {
4235 return (ISC_R_FAILURE);
4237 insert_trustedkey(key);
4239 dst_key_tofile(key, DST_TYPE_PUBLIC,"/tmp");
4243 return (ISC_R_SUCCESS);
4248 nameFromString(const char *str, dns_name_t *p_ret) {
4249 size_t len = strlen(str);
4250 isc_result_t result;
4251 isc_buffer_t buffer;
4252 dns_fixedname_t fixedname;
4254 REQUIRE(p_ret != NULL);
4255 REQUIRE(str != NULL);
4257 isc_buffer_init(&buffer, str, len);
4258 isc_buffer_add(&buffer, len);
4260 dns_fixedname_init(&fixedname);
4261 result = dns_name_fromtext(dns_fixedname_name(&fixedname), &buffer,
4262 dns_rootname, DNS_NAME_DOWNCASE, NULL);
4263 check_result(result, "nameFromString");
4265 if (dns_name_dynamic(p_ret))
4266 free_name(p_ret, mctx);
4268 result = dns_name_dup(dns_fixedname_name(&fixedname), mctx, p_ret);
4269 check_result(result, "nameFromString");
4275 prepare_lookup(dns_name_t *name)
4277 isc_result_t result;
4278 dig_lookup_t *lookup = NULL;
4282 lookup = clone_lookup(current_lookup, ISC_TRUE);
4283 lookup->trace_root = ISC_FALSE;
4284 lookup->new_search = ISC_TRUE;
4285 lookup->trace_root_sigchase = ISC_FALSE;
4287 strncpy(lookup->textname, lookup->textnamesigchase, MXNAME);
4289 lookup->rdtype = lookup->rdtype_sigchase;
4290 lookup->rdtypeset = ISC_TRUE;
4291 lookup->qrdtype = lookup->qrdtype_sigchase;
4293 s = ISC_LIST_HEAD(lookup->my_server_list);
4295 debug("freeing server %p belonging to %p",
4298 s = ISC_LIST_NEXT(s, link);
4299 ISC_LIST_DEQUEUE(lookup->my_server_list,
4300 (dig_server_t *)ptr, link);
4301 isc_mem_free(mctx, ptr);
4305 for (result = dns_rdataset_first(chase_nsrdataset);
4306 result == ISC_R_SUCCESS;
4307 result = dns_rdataset_next(chase_nsrdataset)) {
4308 char namestr[DNS_NAME_FORMATSIZE];
4310 dns_rdata_t rdata = DNS_RDATA_INIT;
4311 dig_server_t * srv = NULL;
4312 #define __FOLLOW_GLUE__
4313 #ifdef __FOLLOW_GLUE__
4314 isc_buffer_t *b = NULL;
4315 isc_result_t result;
4317 dns_rdataset_t *rdataset = NULL;
4318 isc_boolean_t true = ISC_TRUE;
4321 memset(namestr, 0, DNS_NAME_FORMATSIZE);
4323 dns_rdataset_current(chase_nsrdataset, &rdata);
4325 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4326 check_result(result, "dns_rdata_tostruct");
4328 #ifdef __FOLLOW_GLUE__
4330 result = advanced_rrsearch(&rdataset, &ns.name,
4332 dns_rdatatype_any, &true);
4333 if (result == ISC_R_SUCCESS) {
4334 for (result = dns_rdataset_first(rdataset);
4335 result == ISC_R_SUCCESS;
4336 result = dns_rdataset_next(rdataset)) {
4337 dns_rdata_t aaaa = DNS_RDATA_INIT;
4338 dns_rdataset_current(rdataset, &aaaa);
4340 result = isc_buffer_allocate(mctx, &b, 80);
4341 check_result(result, "isc_buffer_allocate");
4343 dns_rdata_totext(&aaaa, &ns.name, b);
4344 isc_buffer_usedregion(b, &r);
4345 r.base[r.length] = '\0';
4346 strncpy(namestr, (char*)r.base,
4347 DNS_NAME_FORMATSIZE);
4348 isc_buffer_free(&b);
4349 dns_rdata_reset(&aaaa);
4352 srv = make_server(namestr, namestr);
4354 ISC_LIST_APPEND(lookup->my_server_list,
4360 result = advanced_rrsearch(&rdataset, &ns.name, dns_rdatatype_a,
4361 dns_rdatatype_any, &true);
4362 if (result == ISC_R_SUCCESS) {
4363 for (result = dns_rdataset_first(rdataset);
4364 result == ISC_R_SUCCESS;
4365 result = dns_rdataset_next(rdataset)) {
4366 dns_rdata_t a = DNS_RDATA_INIT;
4367 dns_rdataset_current(rdataset, &a);
4369 result = isc_buffer_allocate(mctx, &b, 80);
4370 check_result(result, "isc_buffer_allocate");
4372 dns_rdata_totext(&a, &ns.name, b);
4373 isc_buffer_usedregion(b, &r);
4374 r.base[r.length] = '\0';
4375 strncpy(namestr, (char*)r.base,
4376 DNS_NAME_FORMATSIZE);
4377 isc_buffer_free(&b);
4378 dns_rdata_reset(&a);
4379 printf("ns name: %s\n", namestr);
4382 srv = make_server(namestr, namestr);
4384 ISC_LIST_APPEND(lookup->my_server_list,
4390 dns_name_format(&ns.name, namestr, sizeof(namestr));
4391 printf("ns name: ");
4392 dns_name_print(&ns.name, stdout);
4394 srv = make_server(namestr, namestr);
4396 ISC_LIST_APPEND(lookup->my_server_list, srv, link);
4399 dns_rdata_freestruct(&ns);
4400 dns_rdata_reset(&rdata);
4404 ISC_LIST_APPEND(lookup_list, lookup, link);
4405 printf("\nLaunch a query to find a RRset of type ");
4406 print_type(lookup->rdtype);
4407 printf(" for zone: %s", lookup->textname);
4408 printf(" with nameservers:");
4410 print_rdataset(name, chase_nsrdataset, mctx);
4411 return (ISC_R_SUCCESS);
4416 child_of_zone(dns_name_t * name, dns_name_t * zone_name,
4417 dns_name_t * child_name)
4419 dns_namereln_t name_reln;
4421 unsigned int nlabelsp;
4423 name_reln = dns_name_fullcompare(name, zone_name, &orderp, &nlabelsp);
4424 if (name_reln != dns_namereln_subdomain ||
4425 dns_name_countlabels(name) <= dns_name_countlabels(zone_name) + 1) {
4426 printf("\n;; ERROR : ");
4427 dns_name_print(name, stdout);
4428 printf(" is not a subdomain of: ");
4429 dns_name_print(zone_name, stdout);
4430 printf(" FAILED\n\n");
4431 return (ISC_R_FAILURE);
4434 dns_name_getlabelsequence(name,
4435 dns_name_countlabels(name) -
4436 dns_name_countlabels(zone_name) -1,
4437 dns_name_countlabels(zone_name) +1,
4439 return (ISC_R_SUCCESS);
4443 grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t *sigrdataset)
4445 isc_result_t result;
4446 dns_rdata_t sigrdata = DNS_RDATA_INIT;
4447 dns_rdata_sig_t siginfo;
4449 result = dns_rdataset_first(sigrdataset);
4450 check_result(result, "empty RRSIG dataset");
4451 dns_rdata_init(&sigrdata);
4454 dns_rdataset_current(sigrdataset, &sigrdata);
4456 result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
4457 check_result(result, "sigrdata tostruct siginfo");
4459 if (dns_name_compare(&siginfo.signer, zone_name) == 0) {
4460 dns_rdata_freestruct(&siginfo);
4461 dns_rdata_reset(&sigrdata);
4462 return (ISC_R_SUCCESS);
4465 dns_rdata_freestruct(&siginfo);
4466 dns_rdata_reset(&sigrdata);
4468 } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS);
4470 dns_rdata_reset(&sigrdata);
4472 return (ISC_R_FAILURE);
4477 initialization(dns_name_t *name)
4479 isc_result_t result;
4480 isc_boolean_t true = ISC_TRUE;
4482 chase_nsrdataset = NULL;
4483 result = advanced_rrsearch(&chase_nsrdataset, name, dns_rdatatype_ns,
4484 dns_rdatatype_any, &true);
4485 if (result != ISC_R_SUCCESS) {
4486 printf("\n;; NS RRset is missing to continue validation:"
4488 return (ISC_R_FAILURE);
4490 INSIST(chase_nsrdataset != NULL);
4491 prepare_lookup(name);
4493 dup_name(name, &chase_current_name, mctx);
4495 return (ISC_R_SUCCESS);
4500 print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset, isc_mem_t *mctx)
4502 isc_buffer_t *b = NULL;
4503 isc_result_t result;
4506 result = isc_buffer_allocate(mctx, &b, 9000);
4507 check_result(result, "isc_buffer_allocate");
4509 printrdataset(name, rdataset, b);
4511 isc_buffer_usedregion(b, &r);
4512 r.base[r.length] = '\0';
4515 printf("%s\n", r.base);
4517 isc_buffer_free(&b);
4522 dup_name(dns_name_t *source, dns_name_t *target, isc_mem_t *mctx) {
4523 isc_result_t result;
4525 if (dns_name_dynamic(target))
4526 free_name(target, mctx);
4527 result = dns_name_dup(source, mctx, target);
4528 check_result(result, "dns_name_dup");
4532 free_name(dns_name_t *name, isc_mem_t *mctx) {
4533 dns_name_free(name, mctx);
4534 dns_name_init(name, NULL);
4539 * take a DNSKEY RRset and the RRSIG RRset corresponding in parameter
4540 * return ISC_R_SUCCESS if the DNSKEY RRset contains a trusted_key
4541 * and the RRset is valid
4542 * return ISC_R_NOTFOUND if not contains trusted key
4543 or if the RRset isn't valid
4544 * return ISC_R_FAILURE if problem
4548 contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset,
4549 dns_rdataset_t *sigrdataset,
4552 isc_result_t result;
4553 dns_rdata_t rdata = DNS_RDATA_INIT;
4554 dst_key_t *trustedKey = NULL;
4555 dst_key_t *dnsseckey = NULL;
4558 if (name == NULL || rdataset == NULL)
4559 return (ISC_R_FAILURE);
4561 result = dns_rdataset_first(rdataset);
4562 check_result(result, "empty rdataset");
4565 dns_rdataset_current(rdataset, &rdata);
4566 INSIST(rdata.type == dns_rdatatype_dnskey);
4568 result = dns_dnssec_keyfromrdata(name, &rdata,
4570 check_result(result, "dns_dnssec_keyfromrdata");
4573 for (i = 0; i < tk_list.nb_tk; i++) {
4574 if (dst_key_compare(tk_list.key[i], dnsseckey)
4576 dns_rdata_reset(&rdata);
4578 printf(";; Ok, find a Trusted Key in the "
4579 "DNSKEY RRset: %d\n",
4580 dst_key_id(dnsseckey));
4581 if (sigchase_verify_sig_key(name, rdataset,
4586 dst_key_free(&dnsseckey);
4588 return (ISC_R_SUCCESS);
4593 dns_rdata_reset(&rdata);
4594 if (dnsseckey != NULL)
4595 dst_key_free(&dnsseckey);
4596 } while (dns_rdataset_next(rdataset) == ISC_R_SUCCESS);
4598 if (trustedKey != NULL)
4599 dst_key_free(&trustedKey);
4602 return (ISC_R_NOTFOUND);
4606 sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset,
4607 dns_rdataset_t *keyrdataset,
4608 dns_rdataset_t *sigrdataset,
4611 isc_result_t result;
4612 dns_rdata_t keyrdata = DNS_RDATA_INIT;
4613 dst_key_t *dnsseckey = NULL;
4615 result = dns_rdataset_first(keyrdataset);
4616 check_result(result, "empty DNSKEY dataset");
4617 dns_rdata_init(&keyrdata);
4620 dns_rdataset_current(keyrdataset, &keyrdata);
4621 INSIST(keyrdata.type == dns_rdatatype_dnskey);
4623 result = dns_dnssec_keyfromrdata(name, &keyrdata,
4625 check_result(result, "dns_dnssec_keyfromrdata");
4627 result = sigchase_verify_sig_key(name, rdataset, dnsseckey,
4629 if (result == ISC_R_SUCCESS) {
4630 dns_rdata_reset(&keyrdata);
4631 dst_key_free(&dnsseckey);
4632 return (ISC_R_SUCCESS);
4634 dst_key_free(&dnsseckey);
4635 dns_rdata_reset(&keyrdata);
4636 } while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS);
4638 dns_rdata_reset(&keyrdata);
4640 return (ISC_R_NOTFOUND);
4644 sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset,
4645 dst_key_t *dnsseckey, dns_rdataset_t *sigrdataset,
4648 isc_result_t result;
4649 dns_rdata_t sigrdata = DNS_RDATA_INIT;
4650 dns_rdata_sig_t siginfo;
4652 result = dns_rdataset_first(sigrdataset);
4653 check_result(result, "empty RRSIG dataset");
4654 dns_rdata_init(&sigrdata);
4657 dns_rdataset_current(sigrdataset, &sigrdata);
4659 result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
4660 check_result(result, "sigrdata tostruct siginfo");
4663 * Test if the id of the DNSKEY is
4664 * the id of the DNSKEY signer's
4666 if (siginfo.keyid == dst_key_id(dnsseckey)) {
4668 result = dns_rdataset_first(rdataset);
4669 check_result(result, "empty DS dataset");
4671 result = dns_dnssec_verify(name, rdataset, dnsseckey,
4672 ISC_FALSE, mctx, &sigrdata);
4674 printf(";; VERIFYING ");
4675 print_type(rdataset->type);
4676 printf(" RRset for ");
4677 dns_name_print(name, stdout);
4678 printf(" with DNSKEY:%d: %s\n", dst_key_id(dnsseckey),
4679 isc_result_totext(result));
4681 if (result == ISC_R_SUCCESS) {
4682 dns_rdata_reset(&sigrdata);
4686 dns_rdata_freestruct(&siginfo);
4687 dns_rdata_reset(&sigrdata);
4689 } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS);
4691 dns_rdata_reset(&sigrdata);
4693 return (ISC_R_NOTFOUND);
4698 sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
4699 dns_rdataset_t *dsrdataset, isc_mem_t *mctx)
4701 isc_result_t result;
4702 dns_rdata_t keyrdata = DNS_RDATA_INIT;
4703 dns_rdata_t newdsrdata = DNS_RDATA_INIT;
4704 dns_rdata_t dsrdata = DNS_RDATA_INIT;
4705 dns_rdata_ds_t dsinfo;
4706 dst_key_t *dnsseckey = NULL;
4707 unsigned char dsbuf[DNS_DS_BUFFERSIZE];
4709 result = dns_rdataset_first(dsrdataset);
4710 check_result(result, "empty DSset dataset");
4712 dns_rdataset_current(dsrdataset, &dsrdata);
4714 result = dns_rdata_tostruct(&dsrdata, &dsinfo, NULL);
4715 check_result(result, "dns_rdata_tostruct for DS");
4717 result = dns_rdataset_first(keyrdataset);
4718 check_result(result, "empty KEY dataset");
4721 dns_rdataset_current(keyrdataset, &keyrdata);
4722 INSIST(keyrdata.type == dns_rdatatype_dnskey);
4724 result = dns_dnssec_keyfromrdata(name, &keyrdata,
4726 check_result(result, "dns_dnssec_keyfromrdata");
4729 * Test if the id of the DNSKEY is the
4730 * id of DNSKEY referenced by the DS
4732 if (dsinfo.key_tag == dst_key_id(dnsseckey)) {
4734 result = dns_ds_buildrdata(name, &keyrdata,
4736 dsbuf, &newdsrdata);
4737 dns_rdata_freestruct(&dsinfo);
4739 if (result != ISC_R_SUCCESS) {
4740 dns_rdata_reset(&keyrdata);
4741 dns_rdata_reset(&newdsrdata);
4742 dns_rdata_reset(&dsrdata);
4743 dst_key_free(&dnsseckey);
4744 dns_rdata_freestruct(&dsinfo);
4745 printf("Oops: impossible to build"
4751 if (dns_rdata_compare(&dsrdata,
4752 &newdsrdata) == 0) {
4753 printf(";; OK a DS valids a DNSKEY"
4755 printf(";; Now verify that this"
4756 " DNSKEY validates the "
4759 result = sigchase_verify_sig_key(name,
4762 chase_sigkeyrdataset,
4764 if (result == ISC_R_SUCCESS) {
4765 dns_rdata_reset(&keyrdata);
4766 dns_rdata_reset(&newdsrdata);
4767 dns_rdata_reset(&dsrdata);
4768 dst_key_free(&dnsseckey);
4773 printf(";; This DS is NOT the DS for"
4774 " the chasing KEY: FAILED\n");
4777 dns_rdata_reset(&newdsrdata);
4779 dst_key_free(&dnsseckey);
4780 dns_rdata_reset(&keyrdata);
4782 } while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS);
4783 dns_rdata_reset(&dsrdata);
4785 } while (dns_rdataset_next(chase_dsrdataset) == ISC_R_SUCCESS);
4787 dns_rdata_reset(&keyrdata);
4788 dns_rdata_reset(&newdsrdata);
4789 dns_rdata_reset(&dsrdata);
4791 return (ISC_R_NOTFOUND);
4796 * take a pointer on a rdataset in parameter and try to resolv it.
4797 * the searched rrset is a rrset on 'name' with type 'type'
4798 * (and if the type is a rrsig the signature cover 'covers').
4799 * the lookedup is to known if you have already done the query on the net.
4800 * ISC_R_SUCCESS: if we found the rrset
4801 * ISC_R_NOTFOUND: we do not found the rrset in cache
4802 * and we do a query on the net
4803 * ISC_R_FAILURE: rrset not found
4806 advanced_rrsearch(dns_rdataset_t **rdataset, dns_name_t *name,
4807 dns_rdatatype_t type, dns_rdatatype_t covers,
4808 isc_boolean_t *lookedup)
4810 isc_boolean_t tmplookedup;
4812 INSIST(rdataset != NULL);
4814 if (*rdataset != NULL)
4815 return (ISC_R_SUCCESS);
4817 tmplookedup = *lookedup;
4818 if ((*rdataset = sigchase_scanname(type, covers,
4819 lookedup, name)) == NULL) {
4821 return (ISC_R_FAILURE);
4822 return (ISC_R_NOTFOUND);
4824 *lookedup = ISC_FALSE;
4825 return (ISC_R_SUCCESS);
4832 sigchase_td(dns_message_t *msg)
4834 isc_result_t result;
4835 dns_name_t *name = NULL;
4836 isc_boolean_t have_answer = ISC_FALSE;
4837 isc_boolean_t true = ISC_TRUE;
4839 if ((result = dns_message_firstname(msg, DNS_SECTION_ANSWER))
4841 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
4842 if (current_lookup->trace_root_sigchase) {
4843 initialization(name);
4848 if (!current_lookup->trace_root_sigchase) {
4849 result = dns_message_firstname(msg,
4850 DNS_SECTION_AUTHORITY);
4851 if (result == ISC_R_SUCCESS)
4852 dns_message_currentname(msg,
4853 DNS_SECTION_AUTHORITY,
4856 = chase_scanname_section(msg, name,
4859 DNS_SECTION_AUTHORITY);
4860 dup_name(name, &chase_authority_name, mctx);
4861 if (chase_nsrdataset != NULL) {
4862 have_delegation_ns = ISC_TRUE;
4863 printf("no response but there is a delegation"
4864 " in authority section:");
4865 dns_name_print(name, stdout);
4868 printf("no response and no delegation in "
4869 "authority section but a reference"
4871 dns_name_print(name, stdout);
4873 error_message = msg;
4876 printf(";; NO ANSWERS: %s\n",
4877 isc_result_totext(result));
4878 free_name(&chase_name, mctx);
4887 = chase_scanname_section(msg, &chase_name,
4891 DNS_SECTION_ANSWER);
4892 if (chase_rdataset != NULL)
4893 have_response = ISC_TRUE;
4896 result = advanced_rrsearch(&chase_keyrdataset,
4897 &chase_current_name,
4898 dns_rdatatype_dnskey,
4900 &chase_keylookedup);
4901 if (result == ISC_R_FAILURE) {
4902 printf("\n;; DNSKEY is missing to continue validation:"
4906 if (result == ISC_R_NOTFOUND)
4908 INSIST(chase_keyrdataset != NULL);
4909 printf("\n;; DNSKEYset:\n");
4910 print_rdataset(&chase_current_name , chase_keyrdataset, mctx);
4913 result = advanced_rrsearch(&chase_sigkeyrdataset,
4914 &chase_current_name,
4915 dns_rdatatype_rrsig,
4916 dns_rdatatype_dnskey,
4917 &chase_sigkeylookedup);
4918 if (result == ISC_R_FAILURE) {
4919 printf("\n;; RRSIG of DNSKEY is missing to continue validation:"
4923 if (result == ISC_R_NOTFOUND)
4925 INSIST(chase_sigkeyrdataset != NULL);
4926 printf("\n;; RRSIG of the DNSKEYset:\n");
4927 print_rdataset(&chase_current_name , chase_sigkeyrdataset, mctx);
4930 if (!chase_dslookedup && !chase_nslookedup) {
4931 if (!delegation_follow) {
4932 result = contains_trusted_key(&chase_current_name,
4934 chase_sigkeyrdataset,
4937 INSIST(chase_dsrdataset != NULL);
4938 INSIST(chase_sigdsrdataset != NULL);
4939 result = sigchase_verify_ds(&chase_current_name,
4945 if (result != ISC_R_SUCCESS) {
4946 printf("\n;; chain of trust can't be validated:"
4950 chase_dsrdataset = NULL;
4951 chase_sigdsrdataset = NULL;
4955 if (have_response || (!have_delegation_ns && !have_response)) {
4956 /* test if it's a grand father case */
4958 if (have_response) {
4959 result = advanced_rrsearch(&chase_sigrdataset,
4961 dns_rdatatype_rrsig,
4965 if (result == ISC_R_FAILURE) {
4966 printf("\n;; RRset is missing to continue"
4967 " validation SHOULD NOT APPEND:"
4973 result = advanced_rrsearch(&chase_sigrdataset,
4974 &chase_authority_name,
4975 dns_rdatatype_rrsig,
4978 if (result == ISC_R_FAILURE) {
4979 printf("\n;; RRSIG is missing to continue"
4980 " validation SHOULD NOT APPEND:"
4985 result = grandfather_pb_test(&chase_current_name,
4987 if (result != ISC_R_SUCCESS) {
4988 dns_name_t tmp_name;
4990 printf("\n;; We are in a Grand Father Problem:"
4991 " See 2.2.1 in RFC 3568\n");
4992 chase_rdataset = NULL;
4993 chase_sigrdataset = NULL;
4994 have_response = ISC_FALSE;
4995 have_delegation_ns = ISC_FALSE;
4997 dns_name_init(&tmp_name, NULL);
4998 result = child_of_zone(&chase_name, &chase_current_name,
5000 if (dns_name_dynamic(&chase_authority_name))
5001 free_name(&chase_authority_name, mctx);
5002 dup_name(&tmp_name, &chase_authority_name, mctx);
5003 printf(";; and we try to continue chain of trust"
5004 " validation of the zone: ");
5005 dns_name_print(&chase_authority_name, stdout);
5007 have_delegation_ns = ISC_TRUE;
5012 chase_sigrdataset = NULL;
5016 if (have_delegation_ns) {
5017 chase_nsrdataset = NULL;
5018 result = advanced_rrsearch(&chase_nsrdataset,
5019 &chase_authority_name,
5023 if (result == ISC_R_FAILURE) {
5024 printf("\n;;NSset is missing to continue validation:"
5028 if (result == ISC_R_NOTFOUND) {
5031 INSIST(chase_nsrdataset != NULL);
5033 result = advanced_rrsearch(&chase_dsrdataset,
5034 &chase_authority_name,
5038 if (result == ISC_R_FAILURE) {
5039 printf("\n;; DSset is missing to continue validation:"
5043 if (result == ISC_R_NOTFOUND)
5045 INSIST(chase_dsrdataset != NULL);
5046 printf("\n;; DSset:\n");
5047 print_rdataset(&chase_authority_name , chase_dsrdataset, mctx);
5049 result = advanced_rrsearch(&chase_sigdsrdataset,
5050 &chase_authority_name,
5051 dns_rdatatype_rrsig,
5054 if (result != ISC_R_SUCCESS) {
5055 printf("\n;; DSset is missing to continue validation:"
5059 printf("\n;; RRSIGset of DSset\n");
5060 print_rdataset(&chase_authority_name,
5061 chase_sigdsrdataset, mctx);
5062 INSIST(chase_sigdsrdataset != NULL);
5064 result = sigchase_verify_sig(&chase_authority_name,
5067 chase_sigdsrdataset, mctx);
5068 if (result != ISC_R_SUCCESS) {
5069 printf("\n;; Impossible to verify the DSset:"
5073 chase_keyrdataset = NULL;
5074 chase_sigkeyrdataset = NULL;
5077 prepare_lookup(&chase_authority_name);
5079 have_response = ISC_FALSE;
5080 have_delegation_ns = ISC_FALSE;
5081 delegation_follow = ISC_TRUE;
5082 error_message = NULL;
5083 dup_name(&chase_authority_name, &chase_current_name, mctx);
5084 free_name(&chase_authority_name, mctx);
5089 if (error_message != NULL) {
5090 dns_rdataset_t *rdataset;
5091 dns_rdataset_t *sigrdataset;
5092 dns_name_t rdata_name;
5093 isc_result_t ret = ISC_R_FAILURE;
5095 dns_name_init(&rdata_name, NULL);
5096 result = prove_nx(error_message, &chase_name,
5097 current_lookup->rdclass_sigchase,
5098 current_lookup->rdtype_sigchase, &rdata_name,
5099 &rdataset, &sigrdataset);
5100 if (rdataset == NULL || sigrdataset == NULL ||
5101 dns_name_countlabels(&rdata_name) == 0) {
5102 printf("\n;; Impossible to verify the non-existence,"
5103 " the NSEC RRset can't be validated:"
5107 ret = sigchase_verify_sig(&rdata_name, rdataset,
5110 if (ret != ISC_R_SUCCESS) {
5111 free_name(&rdata_name, mctx);
5112 printf("\n;; Impossible to verify the NSEC RR to prove"
5113 " the non-existence : FAILED\n\n");
5116 free_name(&rdata_name, mctx);
5117 if (result != ISC_R_SUCCESS) {
5118 printf("\n;; Impossible to verify the non-existence:"
5122 printf("\n;; OK the query doesn't have response but"
5123 " we have validate this fact : SUCCESS\n\n");
5129 printf(";; cleanandgo \n");
5130 if (dns_name_dynamic(&chase_current_name))
5131 free_name(&chase_current_name, mctx);
5132 if (dns_name_dynamic(&chase_authority_name))
5133 free_name(&chase_authority_name, mctx);
5138 result = advanced_rrsearch(&chase_rdataset, &chase_name,
5139 current_lookup->rdtype_sigchase,
5142 if (result == ISC_R_FAILURE) {
5143 printf("\n;; RRsig of RRset is missing to continue validation"
5144 " SHOULD NOT APPEND: FAILED\n\n");
5147 result = sigchase_verify_sig(&chase_name, chase_rdataset,
5149 chase_sigrdataset, mctx);
5150 if (result != ISC_R_SUCCESS) {
5151 printf("\n;; Impossible to verify the RRset : FAILED\n\n");
5154 print_rdataset(&chase_name , chase_rdataset, mctx);
5155 printf("DNSKEYset:\n");
5156 print_rdataset(&chase_name , chase_keyrdataset, mctx);
5157 printf("RRSIG of RRset:\n");
5158 print_rdataset(&chase_name , chase_sigrdataset, mctx);
5163 printf("\n;; The Answer:\n");
5164 print_rdataset(&chase_name , chase_rdataset, mctx);
5166 printf("\n;; FINISH : we have validate the DNSSEC chain"
5167 " of trust: SUCCESS\n\n");
5178 getneededrr(dns_message_t *msg)
5180 isc_result_t result;
5181 dns_name_t *name = NULL;
5182 dns_rdata_t sigrdata = DNS_RDATA_INIT;
5183 dns_rdata_sig_t siginfo;
5184 isc_boolean_t true = ISC_TRUE;
5186 if ((result = dns_message_firstname(msg, DNS_SECTION_ANSWER))
5188 printf(";; NO ANSWERS: %s\n", isc_result_totext(result));
5190 if (chase_name.ndata == NULL)
5191 return (ISC_R_ADDRNOTAVAIL);
5193 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
5196 /* What do we chase? */
5197 if (chase_rdataset == NULL) {
5198 result = advanced_rrsearch(&chase_rdataset, name,
5200 dns_rdatatype_any, &true);
5201 if (result != ISC_R_SUCCESS) {
5202 printf("\n;; No Answers: Validation FAILED\n\n");
5203 return (ISC_R_NOTFOUND);
5205 dup_name(name, &chase_name, mctx);
5206 printf(";; RRset to chase:\n");
5207 print_rdataset(&chase_name, chase_rdataset, mctx);
5209 INSIST(chase_rdataset != NULL);
5212 if (chase_sigrdataset == NULL) {
5213 result = advanced_rrsearch(&chase_sigrdataset, name,
5214 dns_rdatatype_rrsig,
5215 chase_rdataset->type,
5216 &chase_siglookedup);
5217 if (result == ISC_R_FAILURE) {
5218 printf("\n;; RRSIG is missing for continue validation:"
5220 if (dns_name_dynamic(&chase_name))
5221 free_name(&chase_name, mctx);
5222 return (ISC_R_NOTFOUND);
5224 if (result == ISC_R_NOTFOUND) {
5225 return (ISC_R_NOTFOUND);
5227 printf("\n;; RRSIG of the RRset to chase:\n");
5228 print_rdataset(&chase_name, chase_sigrdataset, mctx);
5230 INSIST(chase_sigrdataset != NULL);
5233 /* first find the DNSKEY name */
5234 result = dns_rdataset_first(chase_sigrdataset);
5235 check_result(result, "empty RRSIG dataset");
5236 dns_rdataset_current(chase_sigrdataset, &sigrdata);
5237 result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
5238 check_result(result, "sigrdata tostruct siginfo");
5239 dup_name(&siginfo.signer, &chase_signame, mctx);
5240 dns_rdata_freestruct(&siginfo);
5241 dns_rdata_reset(&sigrdata);
5243 /* Do we have a key? */
5244 if (chase_keyrdataset == NULL) {
5245 result = advanced_rrsearch(&chase_keyrdataset,
5247 dns_rdatatype_dnskey,
5249 &chase_keylookedup);
5250 if (result == ISC_R_FAILURE) {
5251 printf("\n;; DNSKEY is missing to continue validation:"
5253 free_name(&chase_signame, mctx);
5254 if (dns_name_dynamic(&chase_name))
5255 free_name(&chase_name, mctx);
5256 return (ISC_R_NOTFOUND);
5258 if (result == ISC_R_NOTFOUND) {
5259 free_name(&chase_signame, mctx);
5260 return (ISC_R_NOTFOUND);
5262 printf("\n;; DNSKEYset that signs the RRset to chase:\n");
5263 print_rdataset(&chase_signame, chase_keyrdataset, mctx);
5265 INSIST(chase_keyrdataset != NULL);
5267 if (chase_sigkeyrdataset == NULL) {
5268 result = advanced_rrsearch(&chase_sigkeyrdataset,
5270 dns_rdatatype_rrsig,
5271 dns_rdatatype_dnskey,
5272 &chase_sigkeylookedup);
5273 if (result == ISC_R_FAILURE) {
5274 printf("\n;; RRSIG for DNSKEY is missing to continue"
5275 " validation : FAILED\n\n");
5276 free_name(&chase_signame, mctx);
5277 if (dns_name_dynamic(&chase_name))
5278 free_name(&chase_name, mctx);
5279 return (ISC_R_NOTFOUND);
5281 if (result == ISC_R_NOTFOUND) {
5282 free_name(&chase_signame, mctx);
5283 return (ISC_R_NOTFOUND);
5285 printf("\n;; RRSIG of the DNSKEYset that signs the "
5286 "RRset to chase:\n");
5287 print_rdataset(&chase_signame, chase_sigkeyrdataset, mctx);
5289 INSIST(chase_sigkeyrdataset != NULL);
5292 if (chase_dsrdataset == NULL) {
5293 result = advanced_rrsearch(&chase_dsrdataset, &chase_signame,
5297 if (result == ISC_R_FAILURE) {
5298 printf("\n;; WARNING There is no DS for the zone: ");
5299 dns_name_print(&chase_signame, stdout);
5302 if (result == ISC_R_NOTFOUND) {
5303 free_name(&chase_signame, mctx);
5304 return (ISC_R_NOTFOUND);
5306 if (chase_dsrdataset != NULL) {
5307 printf("\n;; DSset of the DNSKEYset\n");
5308 print_rdataset(&chase_signame, chase_dsrdataset, mctx);
5312 if (chase_dsrdataset != NULL) {
5314 * if there is no RRSIG of DS,
5315 * we don't want to search on the network
5317 result = advanced_rrsearch(&chase_sigdsrdataset,
5319 dns_rdatatype_rrsig,
5320 dns_rdatatype_ds, &true);
5321 if (result == ISC_R_FAILURE) {
5322 printf(";; WARNING : NO RRSIG DS : RRSIG DS"
5323 " should come with DS\n");
5325 * We continue even the DS couldn't be validated,
5326 * because the DNSKEY could be a Trusted Key.
5328 chase_dsrdataset = NULL;
5330 printf("\n;; RRSIG of the DSset of the DNSKEYset\n");
5331 print_rdataset(&chase_signame, chase_sigdsrdataset,
5341 sigchase_bu(dns_message_t *msg)
5343 isc_result_t result;
5346 if (tk_list.nb_tk == 0) {
5347 result = get_trusted_key(mctx);
5348 if (result != ISC_R_SUCCESS) {
5349 printf("No trusted keys present\n");
5355 ret = getneededrr(msg);
5356 if (ret == ISC_R_NOTFOUND)
5359 if (ret == ISC_R_ADDRNOTAVAIL) {
5360 /* We have no response */
5361 dns_rdataset_t *rdataset;
5362 dns_rdataset_t *sigrdataset;
5363 dns_name_t rdata_name;
5364 dns_name_t query_name;
5367 dns_name_init(&query_name, NULL);
5368 dns_name_init(&rdata_name, NULL);
5369 nameFromString(current_lookup->textname, &query_name);
5371 result = prove_nx(msg, &query_name, current_lookup->rdclass,
5372 current_lookup->rdtype, &rdata_name,
5373 &rdataset, &sigrdataset);
5374 free_name(&query_name, mctx);
5375 if (rdataset == NULL || sigrdataset == NULL ||
5376 dns_name_countlabels(&rdata_name) == 0) {
5377 printf("\n;; Impossible to verify the Non-existence,"
5378 " the NSEC RRset can't be validated: "
5384 if (result != ISC_R_SUCCESS) {
5385 printf("\n No Answers and impossible to prove the"
5386 " unsecurity : Validation FAILED\n\n");
5390 printf(";; An NSEC prove the non-existence of a answers,"
5391 " Now we want validate this NSEC\n");
5393 dup_name(&rdata_name, &chase_name, mctx);
5394 free_name(&rdata_name, mctx);
5395 chase_rdataset = rdataset;
5396 chase_sigrdataset = sigrdataset;
5397 chase_keyrdataset = NULL;
5398 chase_sigkeyrdataset = NULL;
5399 chase_dsrdataset = NULL;
5400 chase_sigdsrdataset = NULL;
5401 chase_siglookedup = ISC_FALSE;
5402 chase_keylookedup = ISC_FALSE;
5403 chase_dslookedup = ISC_FALSE;
5404 chase_sigdslookedup = ISC_FALSE;
5411 printf("\n\n\n;; WE HAVE MATERIAL, WE NOW DO VALIDATION\n");
5413 result = sigchase_verify_sig(&chase_name, chase_rdataset,
5415 chase_sigrdataset, mctx);
5416 if (result != ISC_R_SUCCESS) {
5417 free_name(&chase_name, mctx);
5418 free_name(&chase_signame, mctx);
5419 printf(";; No DNSKEY is valid to check the RRSIG"
5420 " of the RRset: FAILED\n");
5424 printf(";; OK We found DNSKEY (or more) to validate the RRset\n");
5426 result = contains_trusted_key(&chase_signame, chase_keyrdataset,
5427 chase_sigkeyrdataset, mctx);
5428 if (result == ISC_R_SUCCESS) {
5429 free_name(&chase_name, mctx);
5430 free_name(&chase_signame, mctx);
5431 printf("\n;; Ok this DNSKEY is a Trusted Key,"
5432 " DNSSEC validation is ok: SUCCESS\n\n");
5437 printf(";; Now, we are going to validate this DNSKEY by the DS\n");
5439 if (chase_dsrdataset == NULL) {
5440 free_name(&chase_name, mctx);
5441 free_name(&chase_signame, mctx);
5442 printf(";; the DNSKEY isn't trusted-key and there isn't"
5443 " DS to validate the DNSKEY: FAILED\n");
5448 result = sigchase_verify_ds(&chase_signame, chase_keyrdataset,
5449 chase_dsrdataset, mctx);
5450 if (result != ISC_R_SUCCESS) {
5451 free_name(&chase_signame, mctx);
5452 free_name(&chase_name, mctx);
5453 printf(";; ERROR no DS validates a DNSKEY in the"
5454 " DNSKEY RRset: FAILED\n");
5458 printf(";; OK this DNSKEY (validated by the DS) validates"
5459 " the RRset of the DNSKEYs, thus the DNSKEY validates"
5461 INSIST(chase_sigdsrdataset != NULL);
5463 dup_name(&chase_signame, &chase_name, mctx);
5464 free_name(&chase_signame, mctx);
5465 chase_rdataset = chase_dsrdataset;
5466 chase_sigrdataset = chase_sigdsrdataset;
5467 chase_keyrdataset = NULL;
5468 chase_sigkeyrdataset = NULL;
5469 chase_dsrdataset = NULL;
5470 chase_sigdsrdataset = NULL;
5471 chase_siglookedup = chase_keylookedup = ISC_FALSE;
5472 chase_dslookedup = chase_sigdslookedup = ISC_FALSE;
5474 printf(";; Now, we want to validate the DS : recursive call\n");
5481 sigchase(dns_message_t *msg) {
5483 if (current_lookup->do_topdown) {
5496 * return 1 if name1 < name2
5497 * 0 if name1 == name2
5498 * -1 if name1 > name2
5502 inf_name(dns_name_t *name1, dns_name_t *name2)
5506 unsigned int nblabel1;
5507 unsigned int nblabel2;
5512 nblabel1 = dns_name_countlabels(name1);
5513 nblabel2 = dns_name_countlabels(name2);
5515 if (nblabel1 >= nblabel2)
5516 min_lum_label = nblabel2;
5518 min_lum_label = nblabel1;
5521 for (i=1 ; i < min_lum_label; i++) {
5522 dns_name_getlabel(name1, nblabel1 -1 - i, &label1);
5523 dns_name_getlabel(name2, nblabel2 -1 - i, &label2);
5524 if ((ret = isc_region_compare(&label1, &label2)) != 0) {
5531 if (nblabel1 == nblabel2)
5534 if (nblabel1 < nblabel2)
5546 prove_nx_domain(dns_message_t *msg,
5548 dns_name_t *rdata_name,
5549 dns_rdataset_t **rdataset,
5550 dns_rdataset_t **sigrdataset)
5552 isc_result_t ret = ISC_R_FAILURE;
5553 isc_result_t result = ISC_R_NOTFOUND;
5554 dns_rdataset_t *nsecset = NULL;
5555 dns_rdataset_t *signsecset = NULL ;
5556 dns_rdata_t nsec = DNS_RDATA_INIT;
5557 dns_name_t *nsecname;
5558 dns_rdata_nsec_t nsecstruct;
5560 if ((result = dns_message_firstname(msg, DNS_SECTION_AUTHORITY))
5562 printf(";; nothing in authority section : impossible to"
5563 " validate the non-existence : FAILED\n");
5564 return (ISC_R_FAILURE);
5569 dns_message_currentname(msg, DNS_SECTION_AUTHORITY, &nsecname);
5570 nsecset = search_type(nsecname, dns_rdatatype_nsec,
5572 if (nsecset == NULL)
5575 printf("There is a NSEC for this zone in the"
5576 " AUTHORITY section:\n");
5577 print_rdataset(nsecname, nsecset, mctx);
5579 for (result = dns_rdataset_first(nsecset);
5580 result == ISC_R_SUCCESS;
5581 result = dns_rdataset_next(nsecset)) {
5582 dns_rdataset_current(nsecset, &nsec);
5586 = chase_scanname_section(msg, nsecname,
5587 dns_rdatatype_rrsig,
5589 DNS_SECTION_AUTHORITY);
5590 if (signsecset == NULL) {
5591 printf(";; no RRSIG NSEC in authority section:"
5592 " impossible to validate the "
5593 "non-existence: FAILED\n");
5594 return (ISC_R_FAILURE);
5597 ret = dns_rdata_tostruct(&nsec, &nsecstruct, NULL);
5598 check_result(ret,"dns_rdata_tostruct");
5600 if ((inf_name(nsecname, &nsecstruct.next) == 1 &&
5601 inf_name(name, &nsecstruct.next) == 1) ||
5602 (inf_name(name, nsecname) == 1 &&
5603 inf_name(&nsecstruct.next, name) == 1)) {
5604 dns_rdata_freestruct(&nsecstruct);
5605 *rdataset = nsecset;
5606 *sigrdataset = signsecset;
5607 dup_name(nsecname, rdata_name, mctx);
5609 return (ISC_R_SUCCESS);
5612 dns_rdata_freestruct(&nsecstruct);
5613 dns_rdata_reset(&nsec);
5615 } while (dns_message_nextname(msg, DNS_SECTION_AUTHORITY)
5619 *sigrdataset = NULL;
5621 return (ISC_R_FAILURE);
5632 prove_nx_type(dns_message_t *msg, dns_name_t *name, dns_rdataset_t *nsecset,
5633 dns_rdataclass_t class, dns_rdatatype_t type,
5634 dns_name_t *rdata_name, dns_rdataset_t **rdataset,
5635 dns_rdataset_t **sigrdataset)
5638 dns_rdataset_t *signsecset;
5639 dns_rdata_t nsec = DNS_RDATA_INIT;
5643 ret = dns_rdataset_first(nsecset);
5644 check_result(ret,"dns_rdataset_first");
5646 dns_rdataset_current(nsecset, &nsec);
5648 ret = dns_nsec_typepresent(&nsec, type);
5649 if (ret == ISC_R_SUCCESS)
5650 printf("OK the NSEC said that the type doesn't exist \n");
5652 signsecset = chase_scanname_section(msg, name,
5653 dns_rdatatype_rrsig,
5655 DNS_SECTION_AUTHORITY);
5656 if (signsecset == NULL) {
5657 printf("There isn't RRSIG NSEC for the zone \n");
5658 return (ISC_R_FAILURE);
5660 dup_name(name, rdata_name, mctx);
5661 *rdataset = nsecset;
5662 *sigrdataset = signsecset;
5674 prove_nx(dns_message_t *msg, dns_name_t *name, dns_rdataclass_t class,
5675 dns_rdatatype_t type, dns_name_t *rdata_name,
5676 dns_rdataset_t **rdataset, dns_rdataset_t **sigrdataset)
5679 dns_rdataset_t *nsecset = NULL;
5681 printf("We want to prove the non-existence of a type of rdata %d"
5682 " or of the zone: \n", type);
5684 if ((ret = dns_message_firstname(msg, DNS_SECTION_AUTHORITY))
5686 printf(";; nothing in authority section : impossible to"
5687 " validate the non-existence : FAILED\n");
5688 return (ISC_R_FAILURE);
5691 nsecset = chase_scanname_section(msg, name, dns_rdatatype_nsec,
5693 DNS_SECTION_AUTHORITY);
5694 if (nsecset != NULL) {
5695 printf("We have a NSEC for this zone :OK\n");
5696 ret = prove_nx_type(msg, name, nsecset, class,
5697 type, rdata_name, rdataset,
5699 if (ret != ISC_R_SUCCESS) {
5700 printf("prove_nx: ERROR type exist\n");
5703 printf("prove_nx: OK type does not exist\n");
5704 return (ISC_R_SUCCESS);
5707 printf("there is no NSEC for this zone: validating "
5708 "that the zone doesn't exist\n");
5709 ret = prove_nx_domain(msg, name, rdata_name,
5710 rdataset, sigrdataset);
5713 /* Never get here */