From: Wouter Wijngaards Date: Tue, 30 Sep 2008 13:40:44 +0000 (+0000) Subject: Stub on same host works X-Git-Tag: release-1.1.0~75 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3385bcc255982c97a948f356f993b9d7105e1829;p=thirdparty%2Funbound.git Stub on same host works git-svn-id: file:///svn/unbound/trunk@1276 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index fe13d2734..3d27a8ed2 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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 diff --git a/doc/plan b/doc/plan index 2bffae5ac..faeaa934a 100644 --- 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" diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 810309dc6..c62db50ee 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -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 Name of the stub zone. diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 9f614b902..45ebfcffc 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -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; } diff --git a/iterator/iter_hints.h b/iterator/iter_hints.h index d93d6e648..343db0af7 100644 --- a/iterator/iter_hints.h +++ b/iterator/iter_hints.h @@ -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); /** diff --git a/iterator/iterator.c b/iterator/iterator.c index e2f4901f3..0decd27be 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -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 index 000000000..f5d42c07b Binary files /dev/null and b/testdata/stub_udp.tpkg differ