Skip to content

Commit

Permalink
Merge pull request #1221 from NLnetLabs/bugfix/consider-auth-zones-wh…
Browse files Browse the repository at this point in the history
…en-forwarding

Consider auth zones when checking for forwarders
  • Loading branch information
gthess authored Jan 17, 2025
2 parents 3945888 + b2fec3b commit 9882a39
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 4 deletions.
34 changes: 34 additions & 0 deletions iterator/iter_fwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down
10 changes: 6 additions & 4 deletions iterator/iter_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
155 changes: 155 additions & 0 deletions testdata/iter_fwdstubauth.rpl
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 9882a39

Please sign in to comment.