]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix queries leaking up for stubs and forwards, if the configured
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 11 Apr 2013 10:08:34 +0000 (10:08 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 11 Apr 2013 10:08:34 +0000 (10:08 +0000)
  nameservers all fail to answer.

git-svn-id: file:///svn/unbound/trunk@2882 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_fwd.c
iterator/iter_fwd.h
iterator/iterator.c
testdata/iter_stublastresort.rpl [new file with mode: 0644]

index 6c639d5e2ceb95331e96606e1a84810158499daf..922d040ad58bddace00bae43c49b669674682587 100644 (file)
@@ -1,3 +1,7 @@
+11 April 2013: Wouter
+       - Fix queries leaking up for stubs and forwards, if the configured
+         nameservers all fail to answer.
+
 10 April 2013: Wouter
        - code improve for minimal responses, small speed increase.
 
index 0b3b6525c26b6e3575cc0086abbd96b0c209bf56..b84e5eff60d0944a09690e5ef43fcf01f14ec6c9 100644 (file)
@@ -324,6 +324,20 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
        return 1;
 }
 
+struct delegpt* 
+forwards_find(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
+{
+       rbnode_t* res = NULL;
+       struct iter_forward_zone key;
+       key.node.key = &key;
+       key.dclass = qclass;
+       key.name = qname;
+       key.namelabs = dname_count_size_labels(qname, &key.namelen);
+       res = rbtree_search(fwd->tree, &key);
+       if(res) return ((struct iter_forward_zone*)res)->dp;
+       return NULL;
+}
+
 struct delegpt* 
 forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
 {
index dbb84f226126f64732126360312989cacfd9556d..62408ad52e2bb52fba085ea0e38d12b5f95e036c 100644 (file)
@@ -104,6 +104,16 @@ void forwards_delete(struct iter_forwards* fwd);
  */
 int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
 
+/**
+ * Find forward zone exactly by name
+ * @param fwd: forward storage.
+ * @param qname: The qname of the query.
+ * @param qclass: The qclass of the query.
+ * @return: A delegation point or null.
+ */
+struct delegpt* forwards_find(struct iter_forwards* fwd, uint8_t* qname,
+       uint16_t qclass);
+
 /**
  * Find forward zone information
  * For this qname/qclass find forward zone information, returns delegation
index e3f058fe51229d8cfe672a910df1007a5f1d0a5d..f8a1f8e2916138fd9838372be8b28e5b3f632c32 100644 (file)
@@ -1409,6 +1409,34 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
        return 1;
 }
 
+/** see if last resort is possible - does config allow queries to parent */
+static int
+can_have_last_resort(struct module_env* env, struct delegpt* dp,
+       struct iter_qstate* iq)
+{
+       struct delegpt* fwddp;
+       struct iter_hints_stub* stub;
+       /* do not process a last resort (the parent side) if a stub
+        * or forward is configured, because we do not want to go 'above'
+        * the configured servers */
+       if((stub = (struct iter_hints_stub*)name_tree_find(&env->hints->tree,
+               dp->name, dp->namelen, dp->namelabs, iq->qchase.qclass)) &&
+               /* has_parent side is turned off for stub_first, where we
+                * are allowed to go to the parent */
+               stub->dp->has_parent_side_NS) {
+               verbose(VERB_QUERY, "configured stub servers failed -- returning SERVFAIL");
+               return 0;
+       }
+       if((fwddp = forwards_find(env->fwds, dp->name, iq->qchase.qclass)) &&
+               /* has_parent_side is turned off for forward_first, where
+                * we are allowed to go to the parent */
+               fwddp->has_parent_side_NS) {
+               verbose(VERB_QUERY, "configured forward servers failed -- returning SERVFAIL");
+               return 0;
+       }
+       return 1;
+}
+
 /**
  * Called by processQueryTargets when it would like extra targets to query
  * but it seems to be out of options.  At last resort some less appealing
@@ -1430,6 +1458,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
        verbose(VERB_ALGO, "No more query targets, attempting last resort");
        log_assert(iq->dp);
 
+       if(!can_have_last_resort(qstate->env, iq->dp, iq)) {
+               /* fail -- no more targets, no more hope of targets, no hope 
+                * of a response. */
+               return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
+       }
        if(!iq->dp->has_parent_side_NS && dname_is_root(iq->dp->name)) {
                struct delegpt* p = hints_lookup_root(qstate->env->hints,
                        iq->qchase.qclass);
diff --git a/testdata/iter_stublastresort.rpl b/testdata/iter_stublastresort.rpl
new file mode 100644 (file)
index 0000000..b607789
--- /dev/null
@@ -0,0 +1,259 @@
+; config options
+server:
+       target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+
+stub-zone:
+       name: "example.com"
+       stub-addr: 1.2.3.6
+       stub-prime: yes
+
+CONFIG_END
+
+SCENARIO_BEGIN Test stub with stub-prime and last resort fallback
+; the last resort fallback should not activate, as the
+; configured stub must be used for this data, or its primed data.
+
+; 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 A
+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 A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+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
+ns.example.com.                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 A
+SECTION ANSWER
+ns.example.com.                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
+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
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+RANGE_END
+
+; the stub-prime server.
+; local authority (that fails a lot)
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.7
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+;ns.example.com.               IN      A       1.2.3.7
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.70
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; the primed server
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.7
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com.                IN      A       1.2.3.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.80
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; crap server that the primed server refers to.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.8
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+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 SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.50
+SECTION AUTHORITY
+;example.com.  IN NS   ns.example.com.
+SECTION ADDITIONAL
+;ns.example.com.               IN      A       1.2.3.4
+ENTRY_END
+
+SCENARIO_END