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"
/** 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));
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.");
/** 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);
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);
}
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);
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;
}
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)
{
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;
}
{
/* 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,