]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Take configured auth zones into consideration when checking if a 1221/head
authorYorgos Thessalonikefs <yorgos@nlnetlabs.nl>
Tue, 14 Jan 2025 15:38:53 +0000 (16:38 +0100)
committerYorgos Thessalonikefs <yorgos@nlnetlabs.nl>
Tue, 14 Jan 2025 15:38:53 +0000 (16:38 +0100)
  request needs to be forwarded.

iterator/iter_fwd.c
iterator/iter_utils.c
testdata/iter_fwdstubauth.rpl [new file with mode: 0644]

index 7099116560e6dcab54863c14da92775ab29b2421..048d674019d5110b22ae8849dcf9561ab9983619 100644 (file)
@@ -331,6 +331,30 @@ make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
        return 1;
 }
 
+/** make NULL entries for auths */
+static int
+make_auth_holes(struct iter_forwards* fwd, struct config_file* cfg)
+{
+       struct config_auth* a;
+       uint8_t* dname;
+       size_t dname_len;
+       for(a = cfg->auths; a; a = a->next) {
+               if(!a->name) continue;
+               dname = sldns_str2wire_dname(a->name, &dname_len);
+               if(!dname) {
+                       log_err("cannot parse auth name '%s'", a->name);
+                       return 0;
+               }
+               if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) {
+                       free(dname);
+                       log_err("out of memory");
+                       return 0;
+               }
+               free(dname);
+       }
+       return 1;
+}
+
 int 
 forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
 {
@@ -353,6 +377,16 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
                lock_rw_unlock(&fwd->lock);
                return 0;
        }
+       /* TODO: Now we punch holes for auth zones as well so that in
+        *       iterator:forward_request() we see the configured
+        *       delegation point, but code flow/naming is hard to follow.
+        *       Consider having a single tree with configured
+        *       delegation points for all categories
+        *       (stubs, forwards, auths). */
+       if(!make_auth_holes(fwd, cfg)) {
+               lock_rw_unlock(&fwd->lock);
+               return 0;
+       }
        fwd_init_parents(fwd);
        lock_rw_unlock(&fwd->lock);
        return 1;
index e5cf13eca7bdabc0d3f99fb1935c48e9e9d305c3..5acd7a1566c05d1b2a2a120cab5f6adab896ca33 100644 (file)
@@ -1489,14 +1489,15 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
 
        /* check stub */
        if (stub != NULL && stub->dp != NULL) {
+               enum verbosity_value level = VERB_ALGO;
                int stub_no_cache = stub->dp->no_cache;
                lock_rw_unlock(&qstate->env->fwds->lock);
-               if(stub_no_cache) {
+               if(verbosity >= level && stub_no_cache) {
                        char qname[LDNS_MAX_DOMAINLEN];
                        char dpname[LDNS_MAX_DOMAINLEN];
                        dname_str(qinf->qname, qname);
                        dname_str(stub->dp->name, dpname);
-                       verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
+                       verbose(level, "stub for %s %s has no_cache", qname, dpname);
                }
                if(retdpname) {
                        if(stub->dp->namelen > dpname_storage_len) {
@@ -1517,14 +1518,15 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
 
        /* Check for forward. */
        if (dp) {
+               enum verbosity_value level = VERB_ALGO;
                int dp_no_cache = dp->no_cache;
                lock_rw_unlock(&qstate->env->hints->lock);
-               if(dp_no_cache) {
+               if(verbosity >= level && dp_no_cache) {
                        char qname[LDNS_MAX_DOMAINLEN];
                        char dpname[LDNS_MAX_DOMAINLEN];
                        dname_str(qinf->qname, qname);
                        dname_str(dp->name, dpname);
-                       verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
+                       verbose(level, "forward for %s %s has no_cache", qname, dpname);
                }
                if(retdpname) {
                        if(dp->namelen > dpname_storage_len) {
diff --git a/testdata/iter_fwdstubauth.rpl b/testdata/iter_fwdstubauth.rpl
new file mode 100644 (file)
index 0000000..fefb636
--- /dev/null
@@ -0,0 +1,155 @@
+; config options
+server:
+       target-fetch-policy: "0 0 0 0 0"
+
+auth-zone:
+       name: "example.tld."
+       for-upstream: yes
+       for-downstream: no
+       fallback-enabled: no
+       ## this line generates zonefile: "/tmp/xxx.example.tld"
+       zonefile:
+TEMPFILE_NAME example.tld
+       ## this is the inline file /tmp/xxx.example.tld
+       ## the tempfiles are deleted when the testrun is over.
+TEMPFILE_CONTENTS example.tld
+$ORIGIN tld.
+example        3600    IN      SOA     a b 1 2 3 4 5
+       3600    IN      NS      ns.example.tld.
+$ORIGIN example.tld.
+ns     3600    IN      A       1.2.3.4
+www    3600    IN      A       3.3.3.3
+more   3600    IN      NS      ns.more.tld.
+TEMPFILE_END
+
+forward-zone:
+       name: "."
+       forward-addr: 9.9.9.9
+
+stub-zone:
+       name: "tld"
+       stub-addr: 2.3.4.5
+stub-zone:
+       name: "more.example.tld"
+       stub-addr: 2.3.4.7
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator's ability to route the request to the correct, configured delegation point
+; Preference should be auth-zone > stub-zone > forward-zone
+; But configuration-wise, since everything is an entry on the forwards tree
+; (or a hole in the case of stub/auth), forwards cannot be replaced by
+; stubs/auth.
+; Also stub/auth zones end the part of the tree that gets forwarded, e.g.,
+; delegations from an auth/stub cannot be caught by a higher forwarder, it will
+; be recursively resolved instead.
+
+; '.' forwarder
+RANGE_BEGIN 0 100
+       ADDRESS 9.9.9.9
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.deleg.tld. IN A
+SECTION ANSWER
+www.deleg.tld. IN A 3.3.3.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.more.example.tld. IN A
+SECTION ANSWER
+www.more.example.tld. IN A 3.3.3.3
+ENTRY_END
+RANGE_END
+
+; 'tld.' stub server
+RANGE_BEGIN 0 100
+       ADDRESS 2.3.4.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.tld. IN A
+SECTION ANSWER
+www.tld. IN A 3.3.3.3
+ENTRY_END
+RANGE_END
+
+; 'more.example.tld.' stub server
+RANGE_BEGIN 0 100
+       ADDRESS 2.3.4.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.more.example.tld. IN A
+SECTION ANSWER
+www.more.example.tld. IN A 3.3.3.3
+ENTRY_END
+RANGE_END
+
+; query www.tld ...
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.tld. IN A
+ENTRY_END
+
+; ... answer should come from 'tld.' stub zone
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.tld. IN A
+SECTION ANSWER
+www.tld. IN A 3.3.3.3
+ENTRY_END
+
+; query www.example.tld ...
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.tld. IN A
+ENTRY_END
+
+; ... answer should come from 'example.tld.' auth zone
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.tld. IN A
+SECTION ANSWER
+www.example.tld. IN A 3.3.3.3
+ENTRY_END
+
+; query www.more.example.tld ...
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.more.example.tld. IN A
+ENTRY_END
+
+; ... answer should come from 'more.example.tld.' stub zone
+STEP 6 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.more.example.tld. IN A
+SECTION ANSWER
+www.more.example.tld. IN A 3.3.3.3
+ENTRY_END
+
+SCENARIO_END