From: Wouter Wijngaards Date: Fri, 12 Jun 2009 09:01:42 +0000 (+0000) Subject: Fixup stub below a forward, the stub is still honored and not trumped by the X-Git-Tag: release-1.3.1~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07411c16a94ef36fa990a8cfd81eccc015143aff;p=thirdparty%2Funbound.git Fixup stub below a forward, the stub is still honored and not trumped by the forward zone. git-svn-id: file:///svn/unbound/trunk@1653 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 6e5b8dd77..6db6a89d1 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -2,6 +2,7 @@ - Fixup potential wrong NSEC picked out of the cache. - If unfulfilled callbacks are deleted they are called with an error. - fptr wlist checks for mesh callbacks. + - fwd above stub in configuration works. 11 June 2009: Wouter - Fix queries for type DS when forward or stub zones are there. diff --git a/doc/TODO b/doc/TODO index aba9d87d4..eef334781 100644 --- a/doc/TODO +++ b/doc/TODO @@ -98,7 +98,6 @@ o infra and lame cache: easier size config (in Mb), show usage in graphs. then perform DNSKEY query) if that DNSKEY query fails servfail, perform the x8 lameness retry fallback. - winevent - poll if too many fds -- fwd above stub, make hole in fwds. config non-forwarded-domain names. - fix indent # ifs later diff --git a/iterator/iter_fwd.c b/iterator/iter_fwd.c index 94ca78f82..61e69d633 100644 --- a/iterator/iter_fwd.c +++ b/iterator/iter_fwd.c @@ -88,9 +88,10 @@ forwards_delete(struct iter_forwards* fwd) free(fwd); } -/** insert new info into forward structure */ +/** insert info into forward structure */ static int -forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp) +forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm, + size_t nmlen, int nmlabs, struct delegpt* dp) { struct iter_forward_zone* node = regional_alloc(fwd->region, sizeof(struct iter_forward_zone)); @@ -98,11 +99,11 @@ forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp) return 0; node->node.key = node; node->dclass = c; - node->name = regional_alloc_init(fwd->region, dp->name, dp->namelen); + node->name = regional_alloc_init(fwd->region, nm, nmlen); if(!node->name) return 0; - node->namelen = dp->namelen; - node->namelabs = dp->namelabs; + node->namelen = nmlen; + node->namelabs = nmlabs; node->dp = dp; if(!rbtree_insert(fwd->tree, &node->node)) { log_err("duplicate forward zone ignored."); @@ -110,6 +111,14 @@ forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp) return 1; } +/** insert new info into forward structure given dp */ +static int +forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp) +{ + return forwards_insert_data(fwd, c, dp->name, dp->namelen, + dp->namelabs, dp); +} + /** initialise parent pointers in the tree */ static void fwd_init_parents(struct iter_forwards* fwd) @@ -234,6 +243,56 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg) return 1; } +/** see if zone needs to have a hole inserted */ +static int +need_hole_insert(rbtree_t* tree, struct iter_forward_zone* zone) +{ + struct iter_forward_zone k; + if(rbtree_search(tree, zone)) + return 0; /* exact match exists */ + k = *zone; + k.node.key = &k; + /* search up the tree */ + do { + dname_remove_label(&k.name, &k.namelen); + k.namelabs --; + if(rbtree_search(tree, &k)) + return 1; /* found an upper forward zone, need hole */ + } while(k.namelabs > 1); + return 0; /* no forwards above, no holes needed */ +} + +/** make NULL entries for stubs */ +static int +make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg) +{ + struct config_stub* s; + struct iter_forward_zone key; + key.node.key = &key; + key.dclass = LDNS_RR_CLASS_IN; + for(s = cfg->stubs; s; s = s->next) { + ldns_rdf* rdf = ldns_dname_new_frm_str(s->name); + if(!rdf) { + log_err("cannot parse stub name '%s'", s->name); + return 0; + } + key.name = ldns_rdf_data(rdf); + key.namelabs = dname_count_size_labels(key.name, &key.namelen); + if(!need_hole_insert(fwd->tree, &key)) { + ldns_rdf_deep_free(rdf); + continue; + } + if(!forwards_insert_data(fwd, key.dclass, key.name, + key.namelen, key.namelabs, NULL)) { + ldns_rdf_deep_free(rdf); + log_err("out of memory"); + return 0; + } + ldns_rdf_deep_free(rdf); + } + return 1; +} + int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg) { @@ -246,6 +305,8 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg) /* read forward zones */ if(!read_forwards(fwd, cfg)) return 0; + if(!make_stub_holes(fwd, cfg)) + return 0; fwd_init_parents(fwd); return 1; } diff --git a/iterator/iter_fwd.h b/iterator/iter_fwd.h index 6ea2d1230..39b6ec18c 100644 --- a/iterator/iter_fwd.h +++ b/iterator/iter_fwd.h @@ -75,7 +75,9 @@ struct iter_forward_zone { size_t namelen; /** number of labels in name */ int namelabs; - /** delegation point with forward server information for this zone. */ + /** delegation point with forward server information for this zone. + * If NULL then this forward entry is used to indicate that a + * stub-zone with the same name exists, and should be used. */ struct delegpt* dp; /** pointer to parent in tree (or NULL if none) */ struct iter_forward_zone* parent; diff --git a/testdata/iter_fwdstub.rpl b/testdata/iter_fwdstub.rpl new file mode 100644 index 000000000..06a8789b7 --- /dev/null +++ b/testdata/iter_fwdstub.rpl @@ -0,0 +1,218 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +forward-zone: + name: "example.com" + forward-addr: 10.0.0.1 +stub-zone: + name: "sub.example.com" + stub-addr: 10.0.0.2 +CONFIG_END + +SCENARIO_BEGIN Test iterative resolve with a stub under a forward zone + +; 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 qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.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 qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.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 +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 + +; forwarder for example.com. +RANGE_BEGIN 0 100 + ADDRESS 10.0.0.1 +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 +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.0.0.4 +SECTION AUTHORITY +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ENTRY_END + +; fail all other queries +ENTRY_BEGIN +MATCH opcode +ADJUST copy_id copy_query +REPLY QR SERVFAIL +SECTION QUESTION +example.com. IN A +ENTRY_END +RANGE_END + +; stub for sub.example.com. +RANGE_BEGIN 0 100 + ADDRESS 10.0.0.2 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +sub.example.com. IN NS +SECTION ANSWER +sub.example.com. IN NS ns.sub.example.com. +SECTION ADDITIONAL +ns.sub.example.com. IN A 1.2.3.44 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.sub.example.com. IN A +SECTION ANSWER +www.sub.example.com. IN A 10.0.0.5 +SECTION AUTHORITY +sub.example.com. IN NS ns.sub.example.com. +SECTION ADDITIONAL +ns.sub.example.com. IN A 1.2.3.44 +ENTRY_END +RANGE_END + + +; check if forwarder is honored +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +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.0.0.4 +SECTION AUTHORITY +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ENTRY_END + +; try to resolve from stub zone +STEP 20 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.sub.example.com. IN A +ENTRY_END + +STEP 30 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.sub.example.com. IN A +SECTION ANSWER +www.sub.example.com. IN A 10.0.0.5 +SECTION AUTHORITY +sub.example.com. IN NS ns.sub.example.com. +SECTION ADDITIONAL +ns.sub.example.com. IN A 1.2.3.44 +ENTRY_END + +SCENARIO_END