diff options
Diffstat (limited to 'contrib/bind9/bin/dig/dighost.c')
-rw-r--r-- | contrib/bind9/bin/dig/dighost.c | 657 |
1 files changed, 478 insertions, 179 deletions
diff --git a/contrib/bind9/bin/dig/dighost.c b/contrib/bind9/bin/dig/dighost.c index 398711d..2e950a4 100644 --- a/contrib/bind9/bin/dig/dighost.c +++ b/contrib/bind9/bin/dig/dighost.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.221.2.19.2.36 2006/12/07 01:26:33 marka Exp $ */ +/* $Id: dighost.c,v 1.259.18.39 2007/02/14 23:45:43 marka Exp $ */ -/* +/*! \file + * \note * Notice to programmers: Do not use this code as an example of how to * use the ISC library to perform DNS lookups. Dig and Host both operate * on the request level, since they allow fine-tuning of output and are @@ -32,6 +33,17 @@ #include <string.h> #include <limits.h> +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif + +#ifdef WITH_IDN +#include <idn/result.h> +#include <idn/log.h> +#include <idn/resconf.h> +#include <idn/api.h> +#endif + #include <dns/byaddr.h> #ifdef DIG_SIGCHASE #include <dns/dnssec.h> @@ -95,16 +107,19 @@ dig_serverlist_t server_list; dig_searchlistlist_t search_list; isc_boolean_t + check_ra = ISC_FALSE, have_ipv4 = ISC_FALSE, have_ipv6 = ISC_FALSE, specified_source = ISC_FALSE, free_now = ISC_FALSE, cancel_now = ISC_FALSE, usesearch = ISC_FALSE, + showsearch = ISC_FALSE, qr = ISC_FALSE, is_dst_up = ISC_FALSE; in_port_t port = 53; unsigned int timeout = 0; +unsigned int extrabytes; isc_mem_t *mctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_task_t *global_task = NULL; @@ -119,20 +134,35 @@ int ndots = -1; int tries = 3; int lookup_counter = 0; -/* +#ifdef WITH_IDN +static void initialize_idn(void); +static isc_result_t output_filter(isc_buffer_t *buffer, + unsigned int used_org, + isc_boolean_t absolute); +static idn_result_t append_textname(char *name, const char *origin, + size_t namesize); +static void idn_check_result(idn_result_t r, const char *msg); + +#define MAXDLEN 256 +#endif + +/*% * Exit Codes: - * 0 Everything went well, including things like NXDOMAIN - * 1 Usage error - * 7 Got too many RR's or Names - * 8 Couldn't open batch file - * 9 No reply from server - * 10 Internal error + * + *\li 0 Everything went well, including things like NXDOMAIN + *\li 1 Usage error + *\li 7 Got too many RR's or Names + *\li 8 Couldn't open batch file + *\li 9 No reply from server + *\li 10 Internal error */ int exitcode = 0; int fatalexit = 0; char keynametext[MXNAME]; char keyfile[MXNAME] = ""; char keysecret[MXNAME] = ""; +dns_name_t *hmacname = NULL; +unsigned int digestbits = 0; isc_buffer_t *namebuf = NULL; dns_tsigkey_t *key = NULL; isc_boolean_t validated = ISC_TRUE; @@ -246,7 +276,7 @@ dns_name_t chase_name; /* the query name */ /* * the current name is the parent name when we follow delegation */ -dns_name_t chase_current_name; +dns_name_t chase_current_name; /* * the child name is used for delegation (NS DS responses in AUTHORITY section) */ @@ -293,7 +323,7 @@ struct_tk_list tk_list = { {NULL, NULL, NULL, NULL, NULL}, 0}; #define DIG_MAX_ADDRESSES 20 -/* +/*% * Apply and clear locks at the event level in global task. * Can I get rid of these using shutdown events? XXX */ @@ -377,7 +407,7 @@ hex_dump(isc_buffer_t *b) { printf("\n"); } -/* +/*% * Append 'len' bytes of 'text' at '*p', failing with * ISC_R_NOSPACE if that would advance p past 'end'. */ @@ -493,7 +523,7 @@ check_result(isc_result_t result, const char *msg) { } } -/* +/*% * Create a server structure, which is part of the lookup structure. * This is little more than a linked list of servers to query in hopes * of finding the answer the user is looking for @@ -535,7 +565,7 @@ addr2af(int lwresaddrtype) return (af); } -/* +/*% * Create a copy of the server list from the lwres configuration structure. * The dest list must have already had ISC_LIST_INIT applied. */ @@ -585,7 +615,7 @@ set_nameserver(char *opt) { return; result = bind9_getaddresses(opt, 0, sockaddrs, - DIG_MAX_ADDRESSES, &count); + DIG_MAX_ADDRESSES, &count); if (result != ISC_R_SUCCESS) fatal("couldn't get address for '%s': %s", opt, isc_result_totext(result)); @@ -630,7 +660,7 @@ add_nameserver(lwres_conf_t *confdata, const char *addr, int af) { return (ISC_R_FAILURE); } -/* +/*% * Produce a cloned server list. The dest list must have already had * ISC_LIST_INIT applied. */ @@ -648,7 +678,7 @@ clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) { } } -/* +/*% * Create an empty lookup structure, which holds all the information needed * to get an answer to a user's question. This structure contains two * linked lists: the server list (servers to query) and the query list @@ -704,6 +734,7 @@ make_empty_lookup(void) { #endif #endif looknew->udpsize = 0; + looknew->edns = -1; looknew->recurse = ISC_TRUE; looknew->aaonly = ISC_FALSE; looknew->adflag = ISC_FALSE; @@ -723,13 +754,15 @@ make_empty_lookup(void) { looknew->section_authority = ISC_TRUE; looknew->section_additional = ISC_TRUE; looknew->new_search = ISC_FALSE; + looknew->done_as_is = ISC_FALSE; + looknew->need_search = ISC_FALSE; ISC_LINK_INIT(looknew, link); ISC_LIST_INIT(looknew->q); ISC_LIST_INIT(looknew->my_server_list); return (looknew); } -/* +/*% * Clone a lookup, perhaps copying the server list. This does not clone * the query list, since it will be regenerated by the setup_lookup() * function, nor does it queue up the new lookup for processing. @@ -780,6 +813,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { #endif #endif looknew->udpsize = lookold->udpsize; + looknew->edns = lookold->edns; looknew->recurse = lookold->recurse; looknew->aaonly = lookold->aaonly; looknew->adflag = lookold->adflag; @@ -794,6 +828,8 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { looknew->section_additional = lookold->section_additional; looknew->retries = lookold->retries; looknew->tsigctx = NULL; + looknew->need_search = lookold->need_search; + looknew->done_as_is = lookold->done_as_is; if (servers) clone_server_list(lookold->my_server_list, @@ -801,7 +837,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { return (looknew); } -/* +/*% * Requeue a lookup for further processing, perhaps copying the server * list. The new lookup structure is returned to the caller, and is * queued for processing. If servers are not cloned in the requeue, they @@ -863,14 +899,15 @@ setup_text_key(void) { if (result != ISC_R_SUCCESS) goto failure; - result = dns_tsigkey_create(&keyname, dns_tsig_hmacmd5_name, - secretstore, secretsize, - ISC_FALSE, NULL, 0, 0, mctx, + result = dns_tsigkey_create(&keyname, hmacname, secretstore, + secretsize, ISC_FALSE, NULL, 0, 0, mctx, NULL, &key); failure: if (result != ISC_R_SUCCESS) printf(";; Couldn't create key %s: %s\n", keynametext, isc_result_totext(result)); + else + dst_key_setbits(key->key, digestbits); isc_mem_free(mctx, secretstore); dns_name_invalidate(&keyname); @@ -891,8 +928,31 @@ setup_file_key(void) { goto failure; } - result = dns_tsigkey_createfromkey(dst_key_name(dstkey), - dns_tsig_hmacmd5_name, + switch (dst_key_alg(dstkey)) { + case DST_ALG_HMACMD5: + hmacname = DNS_TSIG_HMACMD5_NAME; + break; + case DST_ALG_HMACSHA1: + hmacname = DNS_TSIG_HMACSHA1_NAME; + break; + case DST_ALG_HMACSHA224: + hmacname = DNS_TSIG_HMACSHA224_NAME; + break; + case DST_ALG_HMACSHA256: + hmacname = DNS_TSIG_HMACSHA256_NAME; + break; + case DST_ALG_HMACSHA384: + hmacname = DNS_TSIG_HMACSHA384_NAME; + break; + case DST_ALG_HMACSHA512: + hmacname = DNS_TSIG_HMACSHA512_NAME; + break; + default: + printf(";; Couldn't create key %s: bad algorithm\n", + keynametext); + goto failure; + } + result = dns_tsigkey_createfromkey(dst_key_name(dstkey), hmacname, dstkey, ISC_FALSE, NULL, 0, 0, mctx, NULL, &key); if (result != ISC_R_SUCCESS) { @@ -933,7 +993,7 @@ create_search_list(lwres_conf_t *confdata) { } } -/* +/*% * Setup the system as a whole, reading key information and resolv.conf * settings. */ @@ -987,6 +1047,10 @@ setup_system(void) { if (ISC_LIST_EMPTY(server_list)) copy_server_list(lwconf, &server_list); +#ifdef WITH_IDN + initialize_idn(); +#endif + if (keyfile[0] != 0) setup_file_key(); else if (keysecret[0] != 0) @@ -1017,7 +1081,7 @@ clear_searchlist(void) { } } -/* +/*% * Override the search list derived from resolv.conf by 'domain'. */ void @@ -1029,7 +1093,7 @@ set_search_domain(char *domain) { ISC_LIST_APPEND(search_list, search, link); } -/* +/*% * Setup the ISC and DNS libraries for use by the system. */ void @@ -1086,12 +1150,14 @@ setup_libs(void) { dns_result_register(); } -/* +/*% * Add EDNS0 option record to a message. Currently, the only supported * options are UDP buffer size and the DO bit. */ static void -add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) { +add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns, + isc_boolean_t dnssec) +{ dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdata_t *rdata = NULL; @@ -1110,9 +1176,9 @@ add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) { rdatalist->type = dns_rdatatype_opt; rdatalist->covers = 0; rdatalist->rdclass = udpsize; - rdatalist->ttl = 0; + rdatalist->ttl = edns << 16; if (dnssec) - rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO; + rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO; rdata->data = NULL; rdata->length = 0; ISC_LIST_INIT(rdatalist->rdata); @@ -1122,7 +1188,7 @@ add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) { check_result(result, "dns_message_setopt"); } -/* +/*% * Add a question section to a message, asking for the specified name, * type, and class. */ @@ -1142,7 +1208,7 @@ add_question(dns_message_t *message, dns_name_t *name, ISC_LIST_APPEND(name->list, rdataset, link); } -/* +/*% * Check if we're done with all the queued lookups, which is true iff * all sockets, sends, and recvs are accounted for (counters == 0), * and the lookup list is empty. @@ -1163,7 +1229,7 @@ check_if_done(void) { } } -/* +/*% * Clear out a query when we're done with it. WARNING: This routine * WILL invalidate the query pointer. */ @@ -1202,7 +1268,7 @@ clear_query(dig_query_t *query) { isc_mem_free(mctx, query); } -/* +/*% * Try and clear out a lookup if we're done with it. Return ISC_TRUE if * the lookup was successfully cleared. If ISC_TRUE is returned, the * lookup pointer has been invalidated. @@ -1260,7 +1326,7 @@ try_clear_lookup(dig_lookup_t *lookup) { return (ISC_TRUE); } -/* +/*% * If we can, start the next lookup in the queue running. * This assumes that the lookup on the head of the queue hasn't been * started yet. It also removes the lookup from the head of the queue, @@ -1336,7 +1402,7 @@ start_lookup(void) { current_lookup->qrdtype_sigchase = current_lookup->qrdtype; current_lookup->qrdtype = dns_rdatatype_ns; - + current_lookup->rdclass_sigchase = current_lookup->rdclass; current_lookup->rdclass_sigchaseset @@ -1373,7 +1439,7 @@ start_lookup(void) { } } -/* +/*% * If we can, clear the current lookup and start the next one running. * This calls try_clear_lookup, so may invalidate the lookup pointer. */ @@ -1394,7 +1460,7 @@ check_next_lookup(dig_lookup_t *lookup) { } } -/* +/*% * Create and queue a new lookup as a followup to the current lookup, * based on the supplied message and section. This is used in trace and * name server search modes to start a new lookup using servers from @@ -1411,6 +1477,8 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) isc_result_t result; isc_boolean_t success = ISC_FALSE; int numLookups = 0; + dns_name_t *domain; + isc_boolean_t horizontal = ISC_FALSE, bad = ISC_FALSE; INSIST(!free_now); @@ -1437,6 +1505,26 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) debug("found NS set"); + if (query->lookup->trace && !query->lookup->trace_root) { + dns_namereln_t namereln; + unsigned int nlabels; + int order; + + domain = dns_fixedname_name(&query->lookup->fdomain); + namereln = dns_name_fullcompare(name, domain, + &order, &nlabels); + if (namereln == dns_namereln_equal) { + if (!horizontal) + printf(";; BAD (HORIZONTAL) REFERRAL\n"); + horizontal = ISC_TRUE; + } else if (namereln != dns_namereln_subdomain) { + if (!bad) + printf(";; BAD REFERRAL\n"); + bad = ISC_TRUE; + continue; + } + } + for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { @@ -1474,6 +1562,9 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) lookup->trace_root = ISC_FALSE; if (lookup->ns_search_only) lookup->recurse = ISC_FALSE; + dns_fixedname_init(&lookup->fdomain); + domain = dns_fixedname_name(&lookup->fdomain); + dns_name_copy(name, domain, NULL); } srv = make_server(namestr, namestr); debug("adding server %s", srv->servername); @@ -1487,10 +1578,32 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) (query->lookup->trace || query->lookup->ns_search_only)) return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY)); - return numLookups; + /* + * Randomize the order the nameserver will be tried. + */ + if (numLookups > 1) { + isc_uint32_t i, j; + dig_serverlist_t my_server_list; + + ISC_LIST_INIT(my_server_list); + + for (i = numLookups; i > 0; i--) { + isc_random_get(&j); + j %= i; + srv = ISC_LIST_HEAD(lookup->my_server_list); + while (j-- > 0) + srv = ISC_LIST_NEXT(srv, link); + ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link); + ISC_LIST_APPEND(my_server_list, srv, link); + } + ISC_LIST_APPENDLIST(lookup->my_server_list, + my_server_list, link); + } + + return (numLookups); } -/* +/*% * Create and queue a new lookup using the next origin from the search * list, read in setup_system(). * @@ -1499,6 +1612,7 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) static isc_boolean_t next_origin(dns_message_t *msg, dig_query_t *query) { dig_lookup_t *lookup; + dig_searchlist_t *search; UNUSED(msg); @@ -1513,18 +1627,27 @@ next_origin(dns_message_t *msg, dig_query_t *query) { * about finding the next entry. */ return (ISC_FALSE); - if (query->lookup->origin == NULL) + if (query->lookup->origin == NULL && !query->lookup->need_search) /* * Then we just did rootorg; there's nothing left. */ return (ISC_FALSE); - lookup = requeue_lookup(query->lookup, ISC_TRUE); - lookup->origin = ISC_LIST_NEXT(query->lookup->origin, link); + if (query->lookup->origin == NULL && query->lookup->need_search) { + lookup = requeue_lookup(query->lookup, ISC_TRUE); + lookup->origin = ISC_LIST_HEAD(search_list); + lookup->need_search = ISC_FALSE; + } else { + search = ISC_LIST_NEXT(query->lookup->origin, link); + if (search == NULL && query->lookup->done_as_is) + return (ISC_FALSE); + lookup = requeue_lookup(query->lookup, ISC_TRUE); + lookup->origin = search; + } cancel_lookup(query->lookup); return (ISC_TRUE); } -/* +/*% * Insert an SOA record into the sendmessage in a lookup. Used for * creating IXFR queries. */ @@ -1590,7 +1713,7 @@ insert_soa(dig_lookup_t *lookup) { dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY); } -/* +/*% * Setup the supplied lookup structure, making it ready to start sending * queries to servers. Create and initialize the message to be sent as * well as the query structures and buffer space for the replies. If the @@ -1606,6 +1729,15 @@ setup_lookup(dig_lookup_t *lookup) { isc_buffer_t b; dns_compress_t cctx; char store[MXNAME]; +#ifdef WITH_IDN + idn_result_t mr; + char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME]; +#endif + +#ifdef WITH_IDN + result = dns_name_settotextfilter(output_filter); + check_result(result, "dns_name_settotextfilter"); +#endif REQUIRE(lookup != NULL); INSIST(!free_now); @@ -1634,6 +1766,17 @@ setup_lookup(dig_lookup_t *lookup) { isc_buffer_init(&lookup->onamebuf, lookup->onamespace, sizeof(lookup->onamespace)); +#ifdef WITH_IDN + /* + * We cannot convert `textname' and `origin' separately. + * `textname' doesn't contain TLD, but local mapping needs + * TLD. + */ + mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname, + utf8_textname, sizeof(utf8_textname)); + idn_check_result(mr, "convert textname to UTF-8"); +#endif + /* * If the name has too many dots, force the origin to be NULL * (which produces an absolute lookup). Otherwise, take the origin @@ -1641,12 +1784,43 @@ setup_lookup(dig_lookup_t *lookup) { * take the first entry in the searchlist iff either usesearch * is TRUE or we got a domain line in the resolv.conf file. */ - /* XXX New search here? */ - if ((count_dots(lookup->textname) >= ndots) || !usesearch) - lookup->origin = NULL; /* Force abs lookup */ - else if (lookup->origin == NULL && lookup->new_search && usesearch) - lookup->origin = ISC_LIST_HEAD(search_list); + if (lookup->new_search) { +#ifdef WITH_IDN + if ((count_dots(utf8_textname) >= ndots) || !usesearch) { + lookup->origin = NULL; /* Force abs lookup */ + lookup->done_as_is = ISC_TRUE; + lookup->need_search = usesearch; + } else if (lookup->origin == NULL && usesearch) { + lookup->origin = ISC_LIST_HEAD(search_list); + lookup->need_search = ISC_FALSE; + } +#else + if ((count_dots(lookup->textname) >= ndots) || !usesearch) { + lookup->origin = NULL; /* Force abs lookup */ + lookup->done_as_is = ISC_TRUE; + lookup->need_search = usesearch; + } else if (lookup->origin == NULL && usesearch) { + lookup->origin = ISC_LIST_HEAD(search_list); + lookup->need_search = ISC_FALSE; + } +#endif + } +#ifdef WITH_IDN + if (lookup->origin != NULL) { + mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, + lookup->origin->origin, utf8_origin, + sizeof(utf8_origin)); + idn_check_result(mr, "convert origin to UTF-8"); + mr = append_textname(utf8_textname, utf8_origin, + sizeof(utf8_textname)); + idn_check_result(mr, "append origin to textname"); + } + mr = idn_encodename(IDN_LOCALMAP | IDN_NAMEPREP | IDN_ASCCHECK | + IDN_IDNCONV | IDN_LENCHECK, utf8_textname, + idn_textname, sizeof(idn_textname)); + idn_check_result(mr, "convert UTF-8 textname to IDN encoding"); +#else if (lookup->origin != NULL) { debug("trying origin %s", lookup->origin->origin); result = dns_message_gettempname(lookup->sendmsg, @@ -1687,11 +1861,22 @@ setup_lookup(dig_lookup_t *lookup) { lookup->textname, isc_result_totext(result)); } dns_message_puttempname(lookup->sendmsg, &lookup->oname); - } else { + } else +#endif + { debug("using root origin"); if (lookup->trace && lookup->trace_root) dns_name_clone(dns_rootname, lookup->name); else { +#ifdef WITH_IDN + len = strlen(idn_textname); + isc_buffer_init(&b, idn_textname, len); + isc_buffer_add(&b, len); + result = dns_name_fromtext(lookup->name, &b, + dns_rootname, + ISC_FALSE, + &lookup->namebuf); +#else len = strlen(lookup->textname); isc_buffer_init(&b, lookup->textname, len); isc_buffer_add(&b, len); @@ -1699,6 +1884,7 @@ setup_lookup(dig_lookup_t *lookup) { dns_rootname, ISC_FALSE, &lookup->namebuf); +#endif } if (result != ISC_R_SUCCESS) { dns_message_puttempname(lookup->sendmsg, @@ -1793,10 +1979,13 @@ setup_lookup(dig_lookup_t *lookup) { result = dns_message_renderbegin(lookup->sendmsg, &cctx, &lookup->renderbuf); check_result(result, "dns_message_renderbegin"); - if (lookup->udpsize > 0 || lookup->dnssec) { + if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1) { if (lookup->udpsize == 0) - lookup->udpsize = 2048; - add_opt(lookup->sendmsg, lookup->udpsize, lookup->dnssec); + lookup->udpsize = 4096; + if (lookup->edns < 0) + lookup->edns = 0; + add_opt(lookup->sendmsg, lookup->udpsize, + lookup->edns, lookup->dnssec); } result = dns_message_rendersection(lookup->sendmsg, @@ -1844,6 +2033,7 @@ setup_lookup(dig_lookup_t *lookup) { query->userarg = serv->userarg; query->rr_count = 0; query->msg_count = 0; + query->byte_count = 0; ISC_LINK_INIT(query, link); ISC_LIST_INIT(query->recvlist); ISC_LIST_INIT(query->lengthlist); @@ -1862,12 +2052,13 @@ setup_lookup(dig_lookup_t *lookup) { } /* XXX qrflag, print_query, etc... */ if (!ISC_LIST_EMPTY(lookup->q) && qr) { + extrabytes = 0; printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg, ISC_TRUE); } } -/* +/*% * Event handler for send completion. Track send counter, and clear out * the query if the send was canceled. */ @@ -1914,7 +2105,7 @@ send_done(isc_task_t *_task, isc_event_t *event) { UNLOCK_LOOKUP; } -/* +/*% * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding * IO sockets. The cancel handlers should take care of cleaning up the * query and lookup structures @@ -1976,7 +2167,7 @@ bringup_timer(dig_query_t *query, unsigned int default_timeout) { static void connect_done(isc_task_t *task, isc_event_t *event); -/* +/*% * Unlike send_udp, this can't be called multiple times with the same * query. When we retry TCP, we requeue the whole lookup, which should * start anew. @@ -2045,7 +2236,7 @@ send_tcp_connect(dig_query_t *query) { } } -/* +/*% * Send a UDP packet to the remote nameserver, possible starting the * recv action as well. Also make sure that the timer is running and * is properly reset. @@ -2106,7 +2297,7 @@ send_udp(dig_query_t *query) { sendcount++; } -/* +/*% * IO timeout handler, used for both connect and recv timeouts. If * retries are still allowed, either resend the UDP packet or queue a * new TCP lookup. Otherwise, cancel the lookup. @@ -2165,7 +2356,7 @@ connect_timeout(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; } -/* +/*% * Event handler for the TCP recv which gets the length header of TCP * packets. Start the next recv of length bytes. */ @@ -2249,7 +2440,7 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; } -/* +/*% * For transfers that involve multiple recvs (XFR's in particular), * launch the next recv. */ @@ -2308,7 +2499,7 @@ launch_next_query(dig_query_t *query, isc_boolean_t include_question) { return; } -/* +/*% * Event handler for TCP connect complete. Make sure the connection was * successful, then pass into launch_next_query to actually send the * question. @@ -2388,7 +2579,7 @@ connect_done(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; } -/* +/*% * Check if the ongoing XFR needs more data before it's complete, using * the semantics of IXFR and AXFR protocols. Much of the complexity of * this routine comes from determining when an IXFR is complete. @@ -2416,6 +2607,7 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, */ query->msg_count++; + query->byte_count += sevent->n; result = dns_message_firstname(msg, DNS_SECTION_ANSWER); if (result != ISC_R_SUCCESS) { puts("; Transfer failed."); @@ -2531,7 +2723,7 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, return (ISC_TRUE); } -/* +/*% * Event handler for recv complete. Perform whatever actions are necessary, * based on the specifics of the user's request. */ @@ -2616,36 +2808,25 @@ recv_done(isc_task_t *task, isc_event_t *event) { } if (!l->tcp_mode && - !isc_sockaddr_equal(&sevent->address, &query->sockaddr)) { + !isc_sockaddr_compare(&sevent->address, &query->sockaddr, + ISC_SOCKADDR_CMPADDR| + ISC_SOCKADDR_CMPPORT| + ISC_SOCKADDR_CMPSCOPE| + ISC_SOCKADDR_CMPSCOPEZERO)) { char buf1[ISC_SOCKADDR_FORMATSIZE]; char buf2[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t any; - if (isc_sockaddr_pf(&query->sockaddr) == AF_INET) + if (isc_sockaddr_pf(&query->sockaddr) == AF_INET) isc_sockaddr_any(&any); else isc_sockaddr_any6(&any); -#ifdef ISC_PLATFORM_HAVESCOPEID /* - * Accept answers from any scope if we havn't specified the - * scope as long as the address and port match. - */ - if (isc_sockaddr_pf(&query->sockaddr) == AF_INET6 && - query->sockaddr.type.sin6.sin6_scope_id == 0 && - memcmp(&sevent->address.type.sin6.sin6_addr, - &query->sockaddr.type.sin6.sin6_addr, - sizeof(query->sockaddr.type.sin6.sin6_addr)) == 0 && - isc_sockaddr_getport(&sevent->address) == - isc_sockaddr_getport(&query->sockaddr)) - /* empty */; - else -#endif - /* - * We don't expect a match above when the packet is - * sent to 0.0.0.0, :: or to a multicast addresses. - * XXXMPA broadcast needs to be handled here as well. - */ + * We don't expect a match when the packet is + * sent to 0.0.0.0, :: or to a multicast addresses. + * XXXMPA broadcast needs to be handled here as well. + */ if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) && !isc_sockaddr_ismulticast(&query->sockaddr)) || isc_sockaddr_getport(&query->sockaddr) != @@ -2695,6 +2876,9 @@ recv_done(isc_task_t *task, isc_event_t *event) { "(< header size) message received\n"); } + if (result == ISC_R_SUCCESS && (msgflags & DNS_MESSAGEFLAG_QR) == 0) + printf(";; Warning: query response not set\n"); + if (!match) { isc_buffer_invalidate(&query->recvbuf); isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); @@ -2761,8 +2945,8 @@ recv_done(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; return; } - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 - && !l->ignore && !l->tcp_mode) { + if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 && + !l->ignore && !l->tcp_mode) { printf(";; Truncated, retrying in TCP mode.\n"); n = requeue_lookup(l, ISC_TRUE); n->tcp_mode = ISC_TRUE; @@ -2775,7 +2959,9 @@ recv_done(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; return; } - if (msg->rcode == dns_rcode_servfail && !l->servfail_stops) { + if ((msg->rcode == dns_rcode_servfail && !l->servfail_stops) || + (check_ra && (msg->flags & DNS_MESSAGEFLAG_RA) == 0 && l->recurse)) + { dig_query_t *next = ISC_LIST_NEXT(query, link); if (l->current_query == query) l->current_query = NULL; @@ -2793,9 +2979,13 @@ recv_done(isc_task_t *task, isc_event_t *event) { */ if ((ISC_LIST_HEAD(l->q) != query) || (ISC_LIST_NEXT(query, link) != NULL)) { - printf(";; Got SERVFAIL reply from %s, " - "trying next server\n", - query->servname); + if( l->comments == ISC_TRUE ) + printf(";; Got %s from %s, " + "trying next server\n", + msg->rcode == dns_rcode_servfail ? + "SERVFAIL reply" : + "recursion not available", + query->servname); clear_query(query); check_next_lookup(l); dns_message_destroy(&msg); @@ -2822,6 +3012,8 @@ recv_done(isc_task_t *task, isc_event_t *event) { check_result(result,"dns_message_getquerytsig"); } + extrabytes = isc_buffer_remaininglength(b); + debug("after parse"); if (l->doing_xfr && l->xfr_q == NULL) { l->xfr_q = query; @@ -2856,8 +3048,9 @@ recv_done(isc_task_t *task, isc_event_t *event) { } if (!l->doing_xfr || l->xfr_q == query) { - if (msg->rcode != dns_rcode_noerror && l->origin != NULL) { - if (!next_origin(msg, query)) { + if (msg->rcode != dns_rcode_noerror && + (l->origin != NULL || l->need_search)) { + if (!next_origin(msg, query) || showsearch) { printmessage(query, msg, ISC_TRUE); received(b->used, &sevent->address, query); } @@ -2891,7 +3084,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { if (l->trace_root) { /* - * This is the initial NS query. + * This is the initial NS query. */ int n; @@ -2906,7 +3099,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { if (!do_sigchase) #endif printmessage(query, msg, ISC_TRUE); - } + } #ifdef DIG_SIGCHASE if (do_sigchase) { chase_msg = isc_mem_allocate(mctx, @@ -2925,13 +3118,13 @@ recv_done(isc_task_t *task, isc_event_t *event) { isc_buffer_usedregion(b, &r); result = isc_buffer_allocate(mctx, &buf, r.length); - + check_result(result, "isc_buffer_allocate"); result = isc_buffer_copyregion(buf, &r); check_result(result, "isc_buffer_copyregion"); - + result = dns_message_parse(msg_temp, buf, 0); - + isc_buffer_free(&buf); chase_msg->msg = msg_temp; @@ -2946,11 +3139,10 @@ recv_done(isc_task_t *task, isc_event_t *event) { chase_msg2->msg = msg; } #endif - } - + #ifdef DIG_SIGCHASE - if (l->sigchase && ISC_LIST_EMPTY(lookup_list)) { + if (l->sigchase && ISC_LIST_EMPTY(lookup_list)) { sigchase(msg_temp); } #endif @@ -3009,7 +3201,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; } -/* +/*% * Turn a name into an address, using system-supplied routines. This is * used in looking up server names, etc... and needs to use system-supplied * routines, since they may be using a non-DNS system for these lookups. @@ -3028,7 +3220,7 @@ get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) { INSIST(count == 1); } -/* +/*% * Initiate either a TCP or UDP lookup */ void @@ -3044,7 +3236,7 @@ do_lookup(dig_lookup_t *lookup) { send_udp(ISC_LIST_HEAD(lookup->q)); } -/* +/*% * Start everything in action upon task startup. */ void @@ -3057,7 +3249,7 @@ onrun_callback(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; } -/* +/*% * Make everything on the lookup queue go away. Mainly used by the * SIGINT handler. */ @@ -3101,16 +3293,19 @@ cancel_all(void) { UNLOCK_LOOKUP; } -/* +/*% * Destroy all of the libs we are using, and get everything ready for a * clean shutdown. */ void destroy_libs(void) { -#ifdef DIG_SIGCHASE +#ifdef DIG_SIGCHASE void * ptr; dig_message_t *chase_msg; #endif +#ifdef WITH_IDN + isc_result_t result; +#endif debug("destroy_libs()"); if (global_task != NULL) { @@ -3142,6 +3337,13 @@ destroy_libs(void) { flush_server_list(); clear_searchlist(); + +#ifdef WITH_IDN + result = dns_name_settotextfilter(NULL); + check_result(result, "dns_name_settotextfilter"); +#endif + dns_name_destroy(); + if (commctx != NULL) { debug("freeing commctx"); isc_mempool_destroy(&commctx); @@ -3218,8 +3420,104 @@ destroy_libs(void) { isc_mem_destroy(&mctx); } +#ifdef WITH_IDN +static void +initialize_idn(void) { + idn_result_t r; + isc_result_t result; + +#ifdef HAVE_SETLOCALE + /* Set locale */ + (void)setlocale(LC_ALL, ""); +#endif + /* Create configuration context. */ + r = idn_nameinit(1); + if (r != idn_success) + fatal("idn api initialization failed: %s", + idn_result_tostring(r)); + + /* Set domain name -> text post-conversion filter. */ + result = dns_name_settotextfilter(output_filter); + check_result(result, "dns_name_settotextfilter"); +} + +static isc_result_t +output_filter(isc_buffer_t *buffer, unsigned int used_org, + isc_boolean_t absolute) +{ + char tmp1[MAXDLEN], tmp2[MAXDLEN]; + size_t fromlen, tolen; + isc_boolean_t end_with_dot; + + /* + * Copy contents of 'buffer' to 'tmp1', supply trailing dot + * if 'absolute' is true, and terminate with NUL. + */ + fromlen = isc_buffer_usedlength(buffer) - used_org; + if (fromlen >= MAXDLEN) + return (ISC_R_SUCCESS); + memcpy(tmp1, (char *)isc_buffer_base(buffer) + used_org, fromlen); + end_with_dot = (tmp1[fromlen - 1] == '.') ? ISC_TRUE : ISC_FALSE; + if (absolute && !end_with_dot) { + fromlen++; + if (fromlen >= MAXDLEN) + return (ISC_R_SUCCESS); + tmp1[fromlen - 1] = '.'; + } + tmp1[fromlen] = '\0'; + + /* + * Convert contents of 'tmp1' to local encoding. + */ + if (idn_decodename(IDN_DECODE_APP, tmp1, tmp2, MAXDLEN) != idn_success) + return (ISC_R_SUCCESS); + strcpy(tmp1, tmp2); + + /* + * Copy the converted contents in 'tmp1' back to 'buffer'. + * If we have appended trailing dot, remove it. + */ + tolen = strlen(tmp1); + if (absolute && !end_with_dot && tmp1[tolen - 1] == '.') + tolen--; + + if (isc_buffer_length(buffer) < used_org + tolen) + return (ISC_R_NOSPACE); + + isc_buffer_subtract(buffer, isc_buffer_usedlength(buffer) - used_org); + memcpy(isc_buffer_used(buffer), tmp1, tolen); + isc_buffer_add(buffer, tolen); + + return (ISC_R_SUCCESS); +} + +static idn_result_t +append_textname(char *name, const char *origin, size_t namesize) { + size_t namelen = strlen(name); + size_t originlen = strlen(origin); + + /* Already absolute? */ + if (namelen > 0 && name[namelen - 1] == '.') + return idn_success; + /* Append dot and origin */ + if (namelen + 1 + originlen >= namesize) + return idn_buffer_overflow; + + name[namelen++] = '.'; + (void)strcpy(name + namelen, origin); + return idn_success; +} + +static void +idn_check_result(idn_result_t r, const char *msg) { + if (r != idn_success) { + exitcode = 1; + fatal("%s: %s", msg, idn_result_tostring(r)); + } +} +#endif /* WITH_IDN */ #ifdef DIG_SIGCHASE void @@ -3247,12 +3545,12 @@ void dump_database_section(dns_message_t *msg, int section) { dns_name_t *msg_name=NULL; - + dns_rdataset_t *rdataset; do { dns_message_currentname(msg, section, &msg_name); - + for (rdataset = ISC_LIST_HEAD(msg_name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { dns_name_print(msg_name, stdout); @@ -3271,15 +3569,15 @@ dump_database(void) { for (msg = ISC_LIST_HEAD(chase_message_list); msg != NULL; msg = ISC_LIST_NEXT(msg, link)) { if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER) - == ISC_R_SUCCESS) + == ISC_R_SUCCESS) dump_database_section(msg->msg, DNS_SECTION_ANSWER); - + if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY) - == ISC_R_SUCCESS) + == ISC_R_SUCCESS) dump_database_section(msg->msg, DNS_SECTION_AUTHORITY); if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL) - == ISC_R_SUCCESS) + == ISC_R_SUCCESS) dump_database_section(msg->msg, DNS_SECTION_ADDITIONAL); } } @@ -3347,7 +3645,7 @@ chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers) { dns_rdataset_t *rdataset = NULL; dig_message_t * msg; - + for (msg = ISC_LIST_HEAD(chase_message_list2); msg != NULL; msg = ISC_LIST_NEXT(msg, link)) { if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER) @@ -3440,7 +3738,7 @@ insert_trustedkey(dst_key_t * key) return; tk_list.key[tk_list.nb_tk++] = key; - return; + return; } void @@ -3463,7 +3761,7 @@ char alphnum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; isc_result_t -removetmpkey(isc_mem_t *mctx, const char *file) +removetmpkey(isc_mem_t *mctx, const char *file) { char *tempnamekey = NULL; int tempnamekeylen; @@ -3476,7 +3774,7 @@ removetmpkey(isc_mem_t *mctx, const char *file) return (ISC_R_NOMEMORY); memset(tempnamekey, 0, tempnamekeylen); - + strcat(tempnamekey, file); strcat(tempnamekey,".key"); isc_file_remove(tempnamekey); @@ -3516,14 +3814,14 @@ opentmpkey(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { isc_mem_free(mctx, tempname); return (ISC_R_FAILURE); } - + x = cp--; while (cp >= tempname && *cp == 'X') { isc_random_get(&which); *cp = alphnum[which % (sizeof(alphnum) - 1)]; x = cp--; } - + tempnamekeylen = tempnamelen+5; tempnamekey = isc_mem_allocate(mctx, tempnamekeylen); if (tempnamekey == NULL) @@ -3533,7 +3831,7 @@ opentmpkey(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { strncpy(tempnamekey, tempname, tempnamelen); strcat(tempnamekey ,".key"); - + if (isc_file_exists(tempnamekey)) { isc_mem_free(mctx, tempnamekey); isc_mem_free(mctx, tempname); @@ -3568,7 +3866,7 @@ get_trusted_key(isc_mem_t *mctx) char buf[1500]; FILE *fp, *fptemp; dst_key_t *key = NULL; - + result = isc_file_exists(trustedkey); if (result != ISC_TRUE) { result = isc_file_exists("/etc/trusted-key.key"); @@ -3646,11 +3944,11 @@ nameFromString(const char *str, dns_name_t *p_ret) { result = dns_name_dup(dns_fixedname_name(&fixedname), mctx, p_ret); check_result(result, "nameFromString"); -} +} #if DIG_SIGCHASE_TD -isc_result_t +isc_result_t prepare_lookup(dns_name_t *name) { isc_result_t result; @@ -3668,7 +3966,7 @@ prepare_lookup(dns_name_t *name) lookup->rdtype = lookup->rdtype_sigchase; lookup->rdtypeset = ISC_TRUE; lookup->qrdtype = lookup->qrdtype_sigchase; - + s = ISC_LIST_HEAD(lookup->my_server_list); while (s != NULL) { debug("freeing server %p belonging to %p", @@ -3702,11 +4000,11 @@ prepare_lookup(dns_name_t *name) dns_rdataset_current(chase_nsrdataset, &rdata); (void)dns_rdata_tostruct(&rdata, &ns, NULL); - - - + + + #ifdef __FOLLOW_GLUE__ - + result = advanced_rrsearch(&rdataset, &ns.name, dns_rdatatype_aaaa, dns_rdatatype_any, &true); @@ -3730,12 +4028,12 @@ prepare_lookup(dns_name_t *name) srv = make_server(namestr, namestr); - + ISC_LIST_APPEND(lookup->my_server_list, srv, link); } } - + rdataset = NULL; result = advanced_rrsearch(&rdataset, &ns.name, dns_rdatatype_a, dns_rdatatype_any, &true); @@ -3757,28 +4055,28 @@ prepare_lookup(dns_name_t *name) isc_buffer_free(&b); dns_rdata_reset(&a); printf("ns name: %s\n", namestr); - + srv = make_server(namestr, namestr); - + ISC_LIST_APPEND(lookup->my_server_list, srv, link); } } #else - + dns_name_format(&ns.name, namestr, sizeof(namestr)); printf("ns name: "); dns_name_print(&ns.name, stdout); printf("\n"); srv = make_server(namestr, namestr); - + ISC_LIST_APPEND(lookup->my_server_list, srv, link); -#endif +#endif dns_rdata_freestruct(&ns); dns_rdata_reset(&rdata); - + } ISC_LIST_APPEND(lookup_list, lookup, link); @@ -3832,10 +4130,10 @@ grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t *sigrdataset) do { dns_rdataset_current(sigrdataset, &sigrdata); - + result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); check_result(result, "sigrdata tostruct siginfo"); - + if (dns_name_compare(&siginfo.signer, zone_name) == 0) { dns_rdata_freestruct(&siginfo); dns_rdata_reset(&sigrdata); @@ -3843,7 +4141,7 @@ grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t *sigrdataset) } dns_rdata_freestruct(&siginfo); - + } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS); dns_rdata_reset(&sigrdata); @@ -3873,7 +4171,7 @@ initialization(dns_name_t *name) return (ISC_R_SUCCESS); } -#endif +#endif void print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset, isc_mem_t *mctx) @@ -3897,10 +4195,10 @@ print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset, isc_mem_t *mctx) } -void +void dup_name(dns_name_t *source, dns_name_t *target, isc_mem_t *mctx) { - isc_result_t result; - + isc_result_t result; + if (dns_name_dynamic(target)) free_name(target, mctx); result = dns_name_dup(source, mctx, target); @@ -3944,12 +4242,12 @@ contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset, do { dns_rdataset_current(rdataset, &rdata); INSIST(rdata.type == dns_rdatatype_dnskey); - + result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dnsseckey); check_result(result, "dns_dnssec_keyfromrdata"); - + for (i = 0; i < tk_list.nb_tk; i++) { if (dst_key_compare(tk_list.key[i], dnsseckey) == ISC_TRUE) { @@ -3969,7 +4267,7 @@ contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset, } } } - + dns_rdata_reset(&rdata); if (dnsseckey != NULL) dst_key_free(&dnsseckey); @@ -3999,7 +4297,7 @@ sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset, do { dns_rdataset_current(keyrdataset, &keyrdata); INSIST(keyrdata.type == dns_rdatatype_dnskey); - + result = dns_dnssec_keyfromrdata(name, &keyrdata, mctx, &dnsseckey); check_result(result, "dns_dnssec_keyfromrdata"); @@ -4031,22 +4329,22 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset, result = dns_rdataset_first(sigrdataset); check_result(result, "empty RRSIG dataset"); dns_rdata_init(&sigrdata); - + do { dns_rdataset_current(sigrdataset, &sigrdata); result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); check_result(result, "sigrdata tostruct siginfo"); - + /* * Test if the id of the DNSKEY is * the id of the DNSKEY signer's */ if (siginfo.keyid == dst_key_id(dnsseckey)) { - + result = dns_rdataset_first(rdataset); check_result(result, "empty DS dataset"); - + result = dns_dnssec_verify(name, rdataset, dnsseckey, ISC_FALSE, mctx, &sigrdata); @@ -4063,7 +4361,7 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset, } } dns_rdata_freestruct(&siginfo); - + } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS); dns_rdata_reset(&sigrdata); @@ -4089,18 +4387,18 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, dns_rdata_init(&dsrdata); do { dns_rdataset_current(dsrdataset, &dsrdata); - + result = dns_rdata_tostruct(&dsrdata, &dsinfo, NULL); check_result(result, "dns_rdata_tostruct for DS"); - + result = dns_rdataset_first(keyrdataset); check_result(result, "empty KEY dataset"); - dns_rdata_init(&keyrdata); + dns_rdata_init(&keyrdata); do { dns_rdataset_current(keyrdataset, &keyrdata); INSIST(keyrdata.type == dns_rdatatype_dnskey); - + result = dns_dnssec_keyfromrdata(name, &keyrdata, mctx, &dnsseckey); check_result(result, "dns_dnssec_keyfromrdata"); @@ -4115,14 +4413,14 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, result = dns_ds_buildrdata(name, &keyrdata, dsinfo.digest_type, dsbuf, &newdsrdata); - dns_rdata_freestruct(&dsinfo); + dns_rdata_freestruct(&dsinfo); if (result != ISC_R_SUCCESS) { dns_rdata_reset(&keyrdata); dns_rdata_reset(&newdsrdata); dns_rdata_reset(&dsrdata); dst_key_free(&dnsseckey); - dns_rdata_freestruct(&dsinfo); + dns_rdata_freestruct(&dsinfo); printf("Oops: impossible to build" " new DS rdata\n"); return (result); @@ -4136,7 +4434,7 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, printf(";; Now verify that this" " DNSKEY validates the " "DNSKEY RRset\n"); - + result = sigchase_verify_sig_key(name, keyrdataset, dnsseckey, @@ -4147,7 +4445,7 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, dns_rdata_reset(&newdsrdata); dns_rdata_reset(&dsrdata); dst_key_free(&dnsseckey); - + return (result); } } else { @@ -4161,12 +4459,12 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, dnsseckey = NULL; } while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS); dns_rdata_reset(&keyrdata); - + } while (dns_rdataset_next(chase_dsrdataset) == ISC_R_SUCCESS); #if 0 dns_rdata_reset(&dsrdata); WARNING #endif - + return (ISC_R_NOTFOUND); } @@ -4179,13 +4477,13 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, * ISC_R_SUCCESS: if we found the rrset * ISC_R_NOTFOUND: we do not found the rrset in cache * and we do a query on the net - * ISC_R_FAILURE: rrset not found + * ISC_R_FAILURE: rrset not found */ isc_result_t advanced_rrsearch(dns_rdataset_t **rdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, isc_boolean_t *lookedup) -{ +{ isc_boolean_t tmplookedup; INSIST(rdataset != NULL); @@ -4260,7 +4558,7 @@ sigchase_td(dns_message_t *msg) } } - + if (have_answer) { chase_rdataset = chase_scanname_section(msg, &chase_name, @@ -4320,7 +4618,7 @@ sigchase_td(dns_message_t *msg) chase_dsrdataset, mctx); } - + if (result != ISC_R_SUCCESS) { printf("\n;; chain of trust can't be validated:" " FAILED\n\n"); @@ -4372,7 +4670,7 @@ sigchase_td(dns_message_t *msg) chase_sigrdataset = NULL; have_response = ISC_FALSE; have_delegation_ns = ISC_FALSE; - + dns_name_init(&tmp_name, NULL); result = child_of_zone(&chase_name, &chase_current_name, &tmp_name); @@ -4451,8 +4749,8 @@ sigchase_td(dns_message_t *msg) } chase_keyrdataset = NULL; chase_sigkeyrdataset = NULL; - - + + prepare_lookup(&chase_authority_name); have_response = ISC_FALSE; @@ -4548,7 +4846,7 @@ sigchase_td(dns_message_t *msg) } } -#endif +#endif #if DIG_SIGCHASE_BU @@ -4565,7 +4863,7 @@ getneededrr(dns_message_t *msg) if ((result = dns_message_firstname(msg, DNS_SECTION_ANSWER)) != ISC_R_SUCCESS) { printf(";; NO ANSWERS: %s\n", isc_result_totext(result)); - + if (chase_name.ndata == NULL) return (ISC_R_ADDRNOTAVAIL); } else { @@ -4608,7 +4906,7 @@ getneededrr(dns_message_t *msg) } INSIST(chase_sigrdataset != NULL); - + /* first find the DNSKEY name */ result = dns_rdataset_first(chase_sigrdataset); check_result(result, "empty RRSIG dataset"); @@ -4619,7 +4917,7 @@ getneededrr(dns_message_t *msg) dup_name(&siginfo.signer, &chase_signame, mctx); dns_rdata_freestruct(&siginfo); dns_rdata_reset(&sigrdata); - + /* Do we have a key? */ if (chase_keyrdataset == NULL) { result = advanced_rrsearch(&chase_keyrdataset, @@ -4688,7 +4986,7 @@ getneededrr(dns_message_t *msg) print_rdataset(&chase_signame, chase_dsrdataset, mctx); } } - + if (chase_dsrdataset != NULL) { /* * if there is no RRSIG of DS, @@ -4747,7 +5045,7 @@ sigchase_bu(dns_message_t *msg) dns_name_init(&query_name, NULL); dns_name_init(&rdata_name, NULL); nameFromString(current_lookup->textname, &query_name); - + result = prove_nx(msg, &query_name, current_lookup->rdclass, current_lookup->rdtype, &rdata_name, &rdataset, &sigrdataset); @@ -4850,7 +5148,7 @@ sigchase_bu(dns_message_t *msg) chase_sigdsrdataset = NULL; chase_siglookedup = chase_keylookedup = ISC_FALSE; chase_dslookedup = chase_sigdslookedup = ISC_FALSE; - + printf(";; Now, we want to validate the DS : recursive call\n"); sigchase(msg); return; @@ -4943,7 +5241,7 @@ prove_nx_domain(dns_message_t *msg, " validate the non-existence : FAILED\n"); return (ISC_R_FAILURE); } - + do { nsecname = NULL; dns_message_currentname(msg, DNS_SECTION_AUTHORITY, &nsecname); @@ -5089,5 +5387,6 @@ prove_nx(dns_message_t *msg, dns_name_t *name, dns_rdataclass_t class, rdataset, sigrdataset); return (ret); } + /* Never get here */ } #endif |