useless for delegation point lookups.
#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"
"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 "
+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.
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.
*/
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;
* @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
* 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) {
--- /dev/null
+; 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