mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-23 08:10:30 -05:00
Stub on same host works
git-svn-id: file:///svn/unbound/trunk@1276 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
5e1193f19d
commit
3385bcc255
7 changed files with 55 additions and 16 deletions
|
|
@ -3,6 +3,9 @@
|
||||||
- tests for sha256 support and downgrade resistance.
|
- tests for sha256 support and downgrade resistance.
|
||||||
- RSASHA256 and RSASHA512 support (using the draft in dnsext),
|
- RSASHA256 and RSASHA512 support (using the draft in dnsext),
|
||||||
using the drafted protocol numbers.
|
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
|
29 September 2008: Wouter
|
||||||
- EDNS lameness detection, if EDNS packets are dropped this is
|
- EDNS lameness detection, if EDNS packets are dropped this is
|
||||||
|
|
|
||||||
8
doc/plan
8
doc/plan
|
|
@ -62,11 +62,11 @@ not stats on SIGUSR1. perhaps also see which slow auth servers cause >1sec value
|
||||||
data for a name.
|
data for a name.
|
||||||
|
|
||||||
*** Improvements
|
*** Improvements
|
||||||
* fallback to noEDNS if all queries are dropped.
|
+ fallback to noEDNS if all queries are dropped.
|
||||||
* dnssec lameness fixen. Check to make sure.
|
+ dnssec lameness fixen. Check to make sure.
|
||||||
* negative caching to avoid DS queries, NSEC, NSEC3 (w params).
|
* negative caching to avoid DS queries, NSEC, NSEC3 (w params).
|
||||||
* SHA256 supported fully.
|
+ SHA256 supported fully.
|
||||||
* Make stub to localhost on different port work.
|
+ Make stub to localhost on different port work.
|
||||||
* IPv6 reverse, IP4 reverse local-data shorthand for PTR records (?).
|
* IPv6 reverse, IP4 reverse local-data shorthand for PTR records (?).
|
||||||
cumbersome to reverse notate by hand for the operator. For local-data.
|
cumbersome to reverse notate by hand for the operator. For local-data.
|
||||||
local-reverse-data: "1.2.3.4 mypc.example.com"
|
local-reverse-data: "1.2.3.4 mypc.example.com"
|
||||||
|
|
|
||||||
|
|
@ -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
|
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
|
private zone, and can even set the AD bit ('authentic'), but the AA
|
||||||
('authoritative') bit is not set on these replies.
|
('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
|
.TP
|
||||||
.B name: \fI<domain name>
|
.B name: \fI<domain name>
|
||||||
Name of the stub zone.
|
Name of the stub zone.
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,8 @@ compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
|
||||||
|
|
||||||
/** insert new hint info into hint structure */
|
/** insert new hint info into hint structure */
|
||||||
static int
|
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,
|
struct iter_hints_stub* node = regional_alloc(hints->region,
|
||||||
sizeof(struct iter_hints_stub));
|
sizeof(struct iter_hints_stub));
|
||||||
|
|
@ -151,6 +152,7 @@ hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp)
|
||||||
if(!nm)
|
if(!nm)
|
||||||
return 0;
|
return 0;
|
||||||
node->dp = dp;
|
node->dp = dp;
|
||||||
|
node->noprime = (uint8_t)noprime;
|
||||||
if(!name_tree_insert(&hints->tree, &node->node, nm, dp->namelen,
|
if(!name_tree_insert(&hints->tree, &node->node, nm, dp->namelen,
|
||||||
dp->namelabs, c)) {
|
dp->namelabs, c)) {
|
||||||
log_err("second hints ignored.");
|
log_err("second hints ignored.");
|
||||||
|
|
@ -210,13 +212,15 @@ read_stubs_host(struct iter_hints* hints, struct config_stub* s,
|
||||||
/** set stub server addresses */
|
/** set stub server addresses */
|
||||||
static int
|
static int
|
||||||
read_stubs_addr(struct iter_hints* hints, struct config_stub* s,
|
read_stubs_addr(struct iter_hints* hints, struct config_stub* s,
|
||||||
struct delegpt* dp)
|
struct delegpt* dp, int* noprime)
|
||||||
{
|
{
|
||||||
struct config_strlist* p;
|
struct config_strlist* p;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
for(p = s->addrs; p; p = p->next) {
|
for(p = s->addrs; p; p = p->next) {
|
||||||
log_assert(p->str);
|
log_assert(p->str);
|
||||||
|
if(strchr(p->str, '@'))
|
||||||
|
*noprime = 1;
|
||||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||||
log_err("cannot parse stub %s ip address: '%s'",
|
log_err("cannot parse stub %s ip address: '%s'",
|
||||||
s->name, p->str);
|
s->name, p->str);
|
||||||
|
|
@ -235,17 +239,19 @@ static int
|
||||||
read_stubs(struct iter_hints* hints, struct config_file* cfg)
|
read_stubs(struct iter_hints* hints, struct config_file* cfg)
|
||||||
{
|
{
|
||||||
struct config_stub* s;
|
struct config_stub* s;
|
||||||
|
int noprime;
|
||||||
for(s = cfg->stubs; s; s = s->next) {
|
for(s = cfg->stubs; s; s = s->next) {
|
||||||
struct delegpt* dp = delegpt_create(hints->region);
|
struct delegpt* dp = delegpt_create(hints->region);
|
||||||
if(!dp) {
|
if(!dp) {
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
noprime = 0;
|
||||||
if(!read_stubs_name(hints, s, dp) ||
|
if(!read_stubs_name(hints, s, dp) ||
|
||||||
!read_stubs_host(hints, s, dp) ||
|
!read_stubs_host(hints, s, dp) ||
|
||||||
!read_stubs_addr(hints, s, dp))
|
!read_stubs_addr(hints, s, dp, &noprime))
|
||||||
return 0;
|
return 0;
|
||||||
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
|
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, noprime))
|
||||||
return 0;
|
return 0;
|
||||||
delegpt_log(VERB_QUERY, dp);
|
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);
|
log_warn("root hints %s: no NS content", fname);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(!hints_insert(hints, c, dp)) {
|
if(!hints_insert(hints, c, dp, 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
delegpt_log(VERB_QUERY, dp);
|
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.");
|
verbose(VERB_ALGO, "no config, using builtin root hints.");
|
||||||
if(!dp)
|
if(!dp)
|
||||||
return 0;
|
return 0;
|
||||||
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
|
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, 0))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -426,7 +432,7 @@ hints_lookup_root(struct iter_hints* hints, uint16_t qclass)
|
||||||
return stub->dp;
|
return stub->dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct delegpt*
|
struct iter_hints_stub*
|
||||||
hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
|
hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
|
||||||
uint16_t qclass, struct delegpt* cache_dp)
|
uint16_t qclass, struct delegpt* cache_dp)
|
||||||
{
|
{
|
||||||
|
|
@ -440,12 +446,19 @@ hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
|
||||||
len, labs, qclass);
|
len, labs, qclass);
|
||||||
if(!r) return NULL;
|
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 our cached delegation point is above the hint, we need to prime.
|
||||||
*/
|
*/
|
||||||
if(dname_strict_subdomain(r->dp->name, r->dp->namelabs,
|
if(dname_strict_subdomain(r->dp->name, r->dp->namelabs,
|
||||||
cache_dp->name, cache_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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,8 @@ struct iter_hints_stub {
|
||||||
struct name_tree_node node;
|
struct name_tree_node node;
|
||||||
/** delegation point with hint information for this stub. */
|
/** delegation point with hint information for this stub. */
|
||||||
struct delegpt* dp;
|
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
|
* @return: A priming delegation point if there is a stub hint that must
|
||||||
* be primed, otherwise null.
|
* 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);
|
uint8_t* qname, uint16_t qclass, struct delegpt* dp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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
|
/* Lookup the stub hint. This will return null if the stub doesn't
|
||||||
* need to be re-primed. */
|
* need to be re-primed. */
|
||||||
struct delegpt* stub_dp = hints_lookup_stub(ie->hints, qname, qclass,
|
struct iter_hints_stub* stub = hints_lookup_stub(ie->hints,
|
||||||
iq->dp);
|
qname, qclass, iq->dp);
|
||||||
|
struct delegpt* stub_dp;
|
||||||
struct module_qstate* subq;
|
struct module_qstate* subq;
|
||||||
/* The stub (if there is one) does not need priming. */
|
/* The stub (if there is one) does not need priming. */
|
||||||
if(!stub_dp)
|
if(!stub)
|
||||||
return 0;
|
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. */
|
/* Otherwise, we need to (re)prime the stub. */
|
||||||
log_nametypeclass(VERB_DETAIL, "priming stub", stub_dp->name,
|
log_nametypeclass(VERB_DETAIL, "priming stub", stub_dp->name,
|
||||||
|
|
|
||||||
BIN
testdata/stub_udp.tpkg
vendored
Normal file
BIN
testdata/stub_udp.tpkg
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue