From 4b772ed57133a37139efe62a120e3fef3c5de819 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 25 Feb 2022 10:27:56 +0100 Subject: [PATCH] - Fix to detect that no IPv6 support means that IPv6 addresses are useless for delegation point lookups. --- daemon/cachedump.c | 4 +- doc/Changelog | 4 + iterator/iter_utils.c | 24 +++-- iterator/iter_utils.h | 6 +- iterator/iterator.c | 2 +- testdata/iter_dp_ip6useless.rpl | 168 ++++++++++++++++++++++++++++++++ 6 files changed, 199 insertions(+), 9 deletions(-) create mode 100644 testdata/iter_dp_ip6useless.rpl diff --git a/daemon/cachedump.c b/daemon/cachedump.c index b1ce53b59..8a8694c42 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -51,6 +51,7 @@ #include "util/regional.h" #include "util/net_help.h" #include "util/data/dname.h" +#include "util/config_file.h" #include "iterator/iterator.h" #include "iterator/iter_delegpt.h" #include "iterator/iter_utils.h" @@ -854,7 +855,8 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, "cache; goes to configured roots\n"); } /* go up? */ - if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) { + if(iter_dp_is_useless(&qinfo, BIT_RD, dp, + worker->env.cfg->do_ip4, worker->env.cfg->do_ip6)) { print_dp_main(ssl, dp, msg); print_dp_details(ssl, worker, dp); if(!ssl_printf(ssl, "cache delegation was " diff --git a/doc/Changelog b/doc/Changelog index e0793c16d..b968383aa 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +25 February 2022: Wouter + - Fix to detect that no IPv6 support means that IPv6 addresses are + useless for delegation point lookups. + 18 February 2022: Wouter - Fix that address not available is squelched from the logs for udp connect failures. It is visible on verbosity 4 and more. diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 2482a1f40..f3bea46d6 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -743,9 +743,10 @@ iter_mark_pside_cycle_targets(struct module_qstate* qstate, struct delegpt* dp) int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, - struct delegpt* dp) + struct delegpt* dp, int supports_ipv4, int supports_ipv6) { struct delegpt_ns* ns; + struct delegpt_addr* a; /* check: * o RD qflag is on. * o no addresses are provided. @@ -758,13 +759,24 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, */ if(!(qflags&BIT_RD)) return 0; - /* either available or unused targets */ - if(dp->usable_list || dp->result_list) - return 0; + /* either available or unused targets, + * if they exist, the dp is not useless. */ + for(a = dp->usable_list; a; a = a->next_usable) { + if(!addr_is_ip6(&a->addr, a->addrlen) && supports_ipv4) + return 0; + else if(addr_is_ip6(&a->addr, a->addrlen) && supports_ipv6) + return 0; + } + for(a = dp->result_list; a; a = a->next_result) { + if(!addr_is_ip6(&a->addr, a->addrlen) && supports_ipv4) + return 0; + else if(addr_is_ip6(&a->addr, a->addrlen) && supports_ipv6) + return 0; + } /* see if query is for one of the nameservers, which is glue */ - if( (qinfo->qtype == LDNS_RR_TYPE_A || - qinfo->qtype == LDNS_RR_TYPE_AAAA) && + if( ((qinfo->qtype == LDNS_RR_TYPE_A && supports_ipv4) || + (qinfo->qtype == LDNS_RR_TYPE_AAAA && supports_ipv6)) && dname_subdomain_c(qinfo->qname, dp->name) && delegpt_find_ns(dp, qinfo->qname, qinfo->qname_len)) return 1; diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index 0a40916c0..c0e518157 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -175,10 +175,14 @@ void iter_mark_pside_cycle_targets(struct module_qstate* qstate, * @param qinfo: query name and type * @param qflags: query flags with RD flag * @param dp: delegpt to check. + * @param supports_ipv4: if we support ipv4 for lookups to the target. + * if not, then the IPv4 addresses are useless. + * @param supports_ipv6: if we support ipv6 for lookups to the target. + * if not, then the IPv6 addresses are useless. * @return true if dp is useless. */ int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, - struct delegpt* dp); + struct delegpt* dp, int supports_ipv4, int supports_ipv6); /** * See if qname has DNSSEC needs. This is true if there is a trust anchor above diff --git a/iterator/iterator.c b/iterator/iterator.c index 320d2e8fc..cf4f1beac 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1547,7 +1547,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, * same server reply) if useless-checked. */ if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags, - iq->dp)) { + iq->dp, ie->supports_ipv4, ie->supports_ipv6)) { struct delegpt* retdp = NULL; if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) { if(retdp) { diff --git a/testdata/iter_dp_ip6useless.rpl b/testdata/iter_dp_ip6useless.rpl new file mode 100644 index 000000000..9a7746e11 --- /dev/null +++ b/testdata/iter_dp_ip6useless.rpl @@ -0,0 +1,168 @@ +; config options +server: + do-ip6: no + target-fetch-policy: "0 0 0 0 0" + qname-minimisation: no +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test iterator when doip6 is no and dp is useless with only ip6 + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS K.ROOT-SERVERS.NET. +SECTION ADDITIONAL +K.ROOT-SERVERS.NET. IN A 193.0.14.129 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION AUTHORITY +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END +RANGE_END + +; a.gtld-servers.net. +RANGE_BEGIN 0 100 + ADDRESS 192.5.6.30 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION ANSWER +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION AUTHORITY +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +; short TTL here, so it can expire +ns.example.com. 1 IN A 1.2.3.4 +ns.example.com. 100 IN AAAA ::53 +ENTRY_END +RANGE_END + +; ns.example.com. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.4 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION ANSWER +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +; short TTL here, so it can expire +ns.example.com. 1 IN A 1.2.3.4 +ns.example.com. 100 IN AAAA ::53 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +ns.example.com. IN A +SECTION ANSWER +; short TTL +ns.example.com. 1 IN A 1.2.3.4 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +ns.example.com. IN AAAA +SECTION ANSWER +ns.example.com. IN AAAA ::53 +ENTRY_END + + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +mail.example.com. IN A +SECTION ANSWER +mail.example.com. IN A 10.20.30.50 +ENTRY_END +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END + +STEP 20 TIME_PASSES ELAPSE 5.0 + +STEP 30 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +mail.example.com. IN A +ENTRY_END + +STEP 40 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +mail.example.com. IN A +SECTION ANSWER +mail.example.com. IN A 10.20.30.50 +ENTRY_END + +SCENARIO_END