]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Stub on same host works
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 30 Sep 2008 13:40:44 +0000 (13:40 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 30 Sep 2008 13:40:44 +0000 (13:40 +0000)
git-svn-id: file:///svn/unbound/trunk@1276 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
doc/plan
doc/unbound.conf.5.in
iterator/iter_hints.c
iterator/iter_hints.h
iterator/iterator.c
testdata/stub_udp.tpkg [new file with mode: 0644]

index fe13d27345a4b8e8fcd7d893a4fdce0fe9185068..3d27a8ed28e0b3b8642d7f57ed8badb4df44fa20 100644 (file)
@@ -3,6 +3,9 @@
        - tests for sha256 support and downgrade resistance.
        - RSASHA256 and RSASHA512 support (using the draft in dnsext),
          using the drafted protocol numbers.
+       - when using stub on localhost (127.0.0.1@10053) unbound works.
+         Like when running NSD to host a local zone, on the same machine.
+         The noprime feature. manpages more explanation. Added a test for it.
 
 29 September 2008: Wouter
        - EDNS lameness detection, if EDNS packets are dropped this is
index 2bffae5accb325fd6b973755f9fc88768738297e..faeaa934a00b9194ab9b68fb546cb3ae619adc80 100644 (file)
--- a/doc/plan
+++ b/doc/plan
@@ -62,11 +62,11 @@ not stats on SIGUSR1. perhaps also see which slow auth servers cause >1sec value
   data for a name.
 
 *** Improvements
-* fallback to noEDNS if all queries are dropped.
-* dnssec lameness fixen. Check to make sure.
++ fallback to noEDNS if all queries are dropped.
++ dnssec lameness fixen. Check to make sure.
 * negative caching to avoid DS queries, NSEC, NSEC3 (w params).
-* SHA256 supported fully.
-* Make stub to localhost on different port work.
++ SHA256 supported fully.
++ Make stub to localhost on different port work.
 * IPv6 reverse, IP4 reverse local-data shorthand for PTR records (?).
   cumbersome to reverse notate by hand for the operator. For local-data.
   local-reverse-data: "1.2.3.4 mypc.example.com"
index 810309dc6f052203d97e469df8fe72f5ff3e5366..c62db50eef4ea84bde1306190153b32e0d62486f 100644 (file)
@@ -744,6 +744,12 @@ bit on replies for the private zone (authoritative servers do not set the
 AD bit).  This setup makes unbound capable of answering queries for the 
 private zone, and can even set the AD bit ('authentic'), but the AA 
 ('authoritative') bit is not set on these replies. 
+.P
+To make a stub setup work, the stub server must serve an NS record set with 
+an up to date list of servers that serve the zone.
+If the NS record set does not list any useful servers for the zone,
+then resolution fails.  When running the authority server on a specific
+port number (using the '@' notation) the NS record set does not matter.
 .TP
 .B name: \fI<domain name>
 Name of the stub zone.
index 9f614b902e90f50006d3d256c43f5d90c6e449dc..45ebfcffcb28db07757ee1ac68edbe1b69f6e2c6 100644 (file)
@@ -140,7 +140,8 @@ compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
 
 /** insert new hint info into hint structure */
 static int
-hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp)
+hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp,
+       int noprime)
 {
        struct iter_hints_stub* node = regional_alloc(hints->region,
                sizeof(struct iter_hints_stub));
@@ -151,6 +152,7 @@ hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp)
        if(!nm)
                return 0;
        node->dp = dp;
+       node->noprime = (uint8_t)noprime;
        if(!name_tree_insert(&hints->tree, &node->node, nm, dp->namelen,
                dp->namelabs, c)) {
                log_err("second hints ignored.");
@@ -210,13 +212,15 @@ read_stubs_host(struct iter_hints* hints, struct config_stub* s,
 /** set stub server addresses */
 static int 
 read_stubs_addr(struct iter_hints* hints, struct config_stub* s, 
-       struct delegpt* dp)
+       struct delegpt* dp, int* noprime)
 {
        struct config_strlist* p;
        struct sockaddr_storage addr;
        socklen_t addrlen;
        for(p = s->addrs; p; p = p->next) {
                log_assert(p->str);
+               if(strchr(p->str, '@'))
+                       *noprime = 1;
                if(!extstrtoaddr(p->str, &addr, &addrlen)) {
                        log_err("cannot parse stub %s ip address: '%s'", 
                                s->name, p->str);
@@ -235,17 +239,19 @@ static int
 read_stubs(struct iter_hints* hints, struct config_file* cfg)
 {
        struct config_stub* s;
+       int noprime;
        for(s = cfg->stubs; s; s = s->next) {
                struct delegpt* dp = delegpt_create(hints->region);
                if(!dp) {
                        log_err("out of memory");
                        return 0;
                }
+               noprime = 0;
                if(!read_stubs_name(hints, s, dp) ||
                        !read_stubs_host(hints, s, dp) ||
-                       !read_stubs_addr(hints, s, dp))
+                       !read_stubs_addr(hints, s, dp, &noprime))
                        return 0;
-               if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
+               if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, noprime))
                        return 0;
                delegpt_log(VERB_QUERY, dp);
        }
@@ -350,7 +356,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
                log_warn("root hints %s: no NS content", fname);
                return 1;
        }
-       if(!hints_insert(hints, c, dp)) {
+       if(!hints_insert(hints, c, dp, 0)) {
                return 0;
        }
        delegpt_log(VERB_QUERY, dp);
@@ -406,7 +412,7 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
                verbose(VERB_ALGO, "no config, using builtin root hints.");
                if(!dp) 
                        return 0;
-               if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
+               if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, 0))
                        return 0;
        }
 
@@ -426,7 +432,7 @@ hints_lookup_root(struct iter_hints* hints, uint16_t qclass)
        return stub->dp;
 }
 
-struct delegpt
+struct iter_hints_stub
 hints_lookup_stub(struct iter_hints* hints, uint8_t* qname, 
        uint16_t qclass, struct delegpt* cache_dp)
 {
@@ -439,13 +445,20 @@ hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
        r = (struct iter_hints_stub*)name_tree_lookup(&hints->tree, qname,
                len, labs, qclass);
        if(!r) return NULL;
+
+       /*
+        * If the stub is same as the delegation we got
+        * And has noprime set, we need to 'prime' to use this stub instead.
+        */
+       if(r->noprime && query_dname_compare(cache_dp->name, r->dp->name)==0)
+               return r; /* use this stub instead of cached dp */
        
        /* 
         * If our cached delegation point is above the hint, we need to prime.
         */
        if(dname_strict_subdomain(r->dp->name, r->dp->namelabs,
                cache_dp->name, cache_dp->namelabs))
-               return r->dp; /* need to prime this stub */
+               return r; /* need to prime this stub */
        return NULL;
 }
 
index d93d6e648fa1028ac4488dc51ad2be9cba4d783e..343db0af7ff81558a0af5fdbd7c5db3bb944bf8c 100644 (file)
@@ -73,6 +73,8 @@ struct iter_hints_stub {
        struct name_tree_node node;
        /** delegation point with hint information for this stub. */
        struct delegpt* dp;
+       /** does the stub need to forego priming (like on other ports) */
+       uint8_t noprime;
 };
 
 /**
@@ -115,7 +117,7 @@ struct delegpt* hints_lookup_root(struct iter_hints* hints, uint16_t qclass);
  * @return: A priming delegation point if there is a stub hint that must
  *         be primed, otherwise null.
  */
-struct delegpt* hints_lookup_stub(struct iter_hints* hints, 
+struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints, 
        uint8_t* qname, uint16_t qclass, struct delegpt* dp);
 
 /**
index e2f4901f30e66eb309dcca24999b5ae238f08578..0decd27bea91a149e65e5b0ac473e482158e1199 100644 (file)
@@ -565,12 +565,27 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
 {
        /* Lookup the stub hint. This will return null if the stub doesn't 
         * need to be re-primed. */
-       struct delegpt* stub_dp = hints_lookup_stub(ie->hints, qname, qclass, 
-               iq->dp);
+       struct iter_hints_stub* stub = hints_lookup_stub(ie->hints, 
+               qname, qclass, iq->dp);
+       struct delegpt* stub_dp;
        struct module_qstate* subq;
        /* The stub (if there is one) does not need priming. */
-       if(!stub_dp)
+       if(!stub)
                return 0;
+       stub_dp = stub->dp;
+
+       /* is it a noprime stub (always use) */
+       if(stub->noprime) {
+               iq->dp = delegpt_copy(stub_dp, qstate->region);
+               if(!iq->dp) {
+                       log_err("out of memory priming stub");
+                       (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+                       return 1; /* return 1 to make module stop, with error */
+               }
+               log_nametypeclass(VERB_DETAIL, "use stub", stub_dp->name, 
+                       LDNS_RR_TYPE_NS, qclass);
+               return 0;
+       }
 
        /* Otherwise, we need to (re)prime the stub. */
        log_nametypeclass(VERB_DETAIL, "priming stub", stub_dp->name, 
diff --git a/testdata/stub_udp.tpkg b/testdata/stub_udp.tpkg
new file mode 100644 (file)
index 0000000..f5d42c0
Binary files /dev/null and b/testdata/stub_udp.tpkg differ