]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Fixup stub below a forward, the stub is still honored and not trumped by the
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 12 Jun 2009 09:01:42 +0000 (09:01 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 12 Jun 2009 09:01:42 +0000 (09:01 +0000)
forward zone.

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

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

index 6e5b8dd779a2876d226177224419efd5752d2cdd..6db6a89d1da6dd6f49eacfbc6477281a8f834e07 100644 (file)
@@ -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.
index aba9d87d492ef381151ddd2b42673d39e0b69d15..eef3347812a4e58bd611bbd0974b2be671ff91e8 100644 (file)
--- 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
index 94ca78f824dc040583ba23efdc5cba6323450b30..61e69d633b4d3f2241d7d64a2915682771f119da 100644 (file)
@@ -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;
 }
index 6ea2d12304ca197f9b2998c5f70ca11590c9b27c..39b6ec18c9aee9406f4768e2aa98b10e47b0660f 100644 (file)
@@ -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 (file)
index 0000000..06a8789
--- /dev/null
@@ -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