mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
parent-child misconfigured data lookup.
git-svn-id: file:///svn/unbound/trunk@2119 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
233fb4466e
commit
6d77834955
23 changed files with 667 additions and 217 deletions
|
|
@ -1,5 +1,16 @@
|
||||||
28 May 2010: Wouter
|
28 May 2010: Wouter
|
||||||
- iana portlist updated.
|
- iana portlist updated.
|
||||||
|
- parent-child disagreement approach altered. Older fixes are
|
||||||
|
removed in place of a more exhaustive search for misconfigured data
|
||||||
|
available via the parent of a delegation.
|
||||||
|
This is designed to be throttled by cache entries, with TTL from the
|
||||||
|
parent if possible. Additionally the loop-counter is used.
|
||||||
|
It also tests for NS RRset differences between parent and child.
|
||||||
|
The fetch of misconfigured data should be more reliable and thorough.
|
||||||
|
It should work reliably even with no or only partial data in cache.
|
||||||
|
Data received from the child (as always) is deemed more
|
||||||
|
authoritative than information received from the delegation parent.
|
||||||
|
The search for misconfigured data is not performed normally.
|
||||||
|
|
||||||
26 May 2010: Wouter
|
26 May 2010: Wouter
|
||||||
- Contribution from Migiel de Vos (Surfnet): nagios patch for
|
- Contribution from Migiel de Vos (Surfnet): nagios patch for
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,15 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
||||||
if(!delegpt_set_name(copy, region, dp->name))
|
if(!delegpt_set_name(copy, region, dp->name))
|
||||||
return NULL;
|
return NULL;
|
||||||
copy->bogus = dp->bogus;
|
copy->bogus = dp->bogus;
|
||||||
|
copy->has_parent_side_NS = dp->has_parent_side_NS;
|
||||||
for(ns = dp->nslist; ns; ns = ns->next) {
|
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||||
if(!delegpt_add_ns(copy, region, ns->name))
|
if(!delegpt_add_ns(copy, region, ns->name, (int)ns->lame))
|
||||||
return NULL;
|
return NULL;
|
||||||
copy->nslist->resolved = ns->resolved;
|
copy->nslist->resolved = ns->resolved;
|
||||||
copy->nslist->got4 = ns->got4;
|
copy->nslist->got4 = ns->got4;
|
||||||
copy->nslist->got6 = ns->got6;
|
copy->nslist->got6 = ns->got6;
|
||||||
|
copy->nslist->done_pside4 = ns->done_pside4;
|
||||||
|
copy->nslist->done_pside6 = ns->done_pside6;
|
||||||
}
|
}
|
||||||
for(a = dp->target_list; a; a = a->next_target) {
|
for(a = dp->target_list; a; a = a->next_target) {
|
||||||
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
|
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
|
||||||
|
|
@ -93,7 +96,8 @@ delegpt_set_name(struct delegpt* dp, struct regional* region, uint8_t* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name)
|
delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name,
|
||||||
|
int lame)
|
||||||
{
|
{
|
||||||
struct delegpt_ns* ns;
|
struct delegpt_ns* ns;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
@ -113,6 +117,9 @@ delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name)
|
||||||
ns->resolved = 0;
|
ns->resolved = 0;
|
||||||
ns->got4 = 0;
|
ns->got4 = 0;
|
||||||
ns->got6 = 0;
|
ns->got6 = 0;
|
||||||
|
ns->lame = (uint8_t)lame;
|
||||||
|
ns->done_pside4 = 0;
|
||||||
|
ns->done_pside6 = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,15 +252,19 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp)
|
||||||
delegpt_count_ns(dp, &numns, &missing);
|
delegpt_count_ns(dp, &numns, &missing);
|
||||||
delegpt_count_addr(dp, &numaddr, &numres, &numavail);
|
delegpt_count_addr(dp, &numaddr, &numres, &numavail);
|
||||||
log_info("DelegationPoint<%s>: %u names (%u missing), "
|
log_info("DelegationPoint<%s>: %u names (%u missing), "
|
||||||
"%u addrs (%u result, %u avail)",
|
"%u addrs (%u result, %u avail)%s",
|
||||||
buf, (unsigned)numns, (unsigned)missing,
|
buf, (unsigned)numns, (unsigned)missing,
|
||||||
(unsigned)numaddr, (unsigned)numres, (unsigned)numavail);
|
(unsigned)numaddr, (unsigned)numres, (unsigned)numavail,
|
||||||
|
(dp->has_parent_side_NS?" parentNS":" cacheNS"));
|
||||||
if(verbosity >= VERB_ALGO) {
|
if(verbosity >= VERB_ALGO) {
|
||||||
for(ns = dp->nslist; ns; ns = ns->next) {
|
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||||
dname_str(ns->name, buf);
|
dname_str(ns->name, buf);
|
||||||
log_info(" %s %s%s%s%s", buf, (ns->resolved?"*":""),
|
log_info(" %s %s%s%s%s%s%s%s", buf,
|
||||||
|
(ns->resolved?"*":""),
|
||||||
(ns->got4?" A":""), (ns->got6?" AAAA":""),
|
(ns->got4?" A":""), (ns->got6?" AAAA":""),
|
||||||
(dp->bogus?" BOGUS":"") );
|
(dp->bogus?" BOGUS":""), (ns->lame?" PARENTSIDE":""),
|
||||||
|
(ns->done_pside4?" PSIDE_A":""),
|
||||||
|
(ns->done_pside6?" PSIDE_AAAA":""));
|
||||||
}
|
}
|
||||||
for(a = dp->target_list; a; a = a->next_target) {
|
for(a = dp->target_list; a; a = a->next_target) {
|
||||||
const char* str = " ";
|
const char* str = " ";
|
||||||
|
|
@ -277,6 +288,16 @@ delegpt_add_unused_targets(struct delegpt* dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
delegpt_count_targets(struct delegpt* dp)
|
||||||
|
{
|
||||||
|
struct delegpt_addr* a;
|
||||||
|
size_t n = 0;
|
||||||
|
for(a = dp->target_list; a; a = a->next_target)
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
delegpt_count_missing_targets(struct delegpt* dp)
|
delegpt_count_missing_targets(struct delegpt* dp)
|
||||||
{
|
{
|
||||||
|
|
@ -325,9 +346,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)
|
||||||
dp = delegpt_create(region);
|
dp = delegpt_create(region);
|
||||||
if(!dp)
|
if(!dp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
dp->has_parent_side_NS = 1; /* created from message */
|
||||||
if(!delegpt_set_name(dp, region, ns_rrset->rk.dname))
|
if(!delegpt_set_name(dp, region, ns_rrset->rk.dname))
|
||||||
return NULL;
|
return NULL;
|
||||||
if(!delegpt_rrset_add_ns(dp, region, ns_rrset))
|
if(!delegpt_rrset_add_ns(dp, region, ns_rrset, 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* add glue, A and AAAA in answer and additional section */
|
/* add glue, A and AAAA in answer and additional section */
|
||||||
|
|
@ -351,7 +373,7 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)
|
||||||
|
|
||||||
int
|
int
|
||||||
delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
|
delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
|
||||||
struct ub_packed_rrset_key* ns_rrset)
|
struct ub_packed_rrset_key* ns_rrset, int lame)
|
||||||
{
|
{
|
||||||
struct packed_rrset_data* nsdata = (struct packed_rrset_data*)
|
struct packed_rrset_data* nsdata = (struct packed_rrset_data*)
|
||||||
ns_rrset->entry.data;
|
ns_rrset->entry.data;
|
||||||
|
|
@ -364,7 +386,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
|
||||||
(size_t)ldns_read_uint16(nsdata->rr_data[i]))
|
(size_t)ldns_read_uint16(nsdata->rr_data[i]))
|
||||||
continue; /* bad format */
|
continue; /* bad format */
|
||||||
/* add rdata of NS (= wirefmt dname), skip rdatalen bytes */
|
/* add rdata of NS (= wirefmt dname), skip rdatalen bytes */
|
||||||
if(!delegpt_add_ns(dp, region, nsdata->rr_data[i]+2))
|
if(!delegpt_add_ns(dp, region, nsdata->rr_data[i]+2, lame))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -418,16 +440,16 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
||||||
|
|
||||||
int
|
int
|
||||||
delegpt_add_rrset(struct delegpt* dp, struct regional* region,
|
delegpt_add_rrset(struct delegpt* dp, struct regional* region,
|
||||||
struct ub_packed_rrset_key* rrset)
|
struct ub_packed_rrset_key* rrset, int lame)
|
||||||
{
|
{
|
||||||
if(!rrset)
|
if(!rrset)
|
||||||
return 1;
|
return 1;
|
||||||
if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)
|
if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)
|
||||||
return delegpt_rrset_add_ns(dp, region, rrset);
|
return delegpt_rrset_add_ns(dp, region, rrset, lame);
|
||||||
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)
|
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)
|
||||||
return delegpt_add_rrset_A(dp, region, rrset, 0, 1);
|
return delegpt_add_rrset_A(dp, region, rrset, lame, 1);
|
||||||
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)
|
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)
|
||||||
return delegpt_add_rrset_AAAA(dp, region, rrset, 0, 1);
|
return delegpt_add_rrset_AAAA(dp, region, rrset, lame, 1);
|
||||||
log_warn("Unknown rrset type added to delegpt");
|
log_warn("Unknown rrset type added to delegpt");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,11 @@ struct delegpt {
|
||||||
|
|
||||||
/** if true, the NS RRset was bogus. All info is bad. */
|
/** if true, the NS RRset was bogus. All info is bad. */
|
||||||
int bogus;
|
int bogus;
|
||||||
|
/** if true, the parent-side NS record has been applied:
|
||||||
|
* its names have been added and their addresses can follow later.
|
||||||
|
* Also true if the delegationpoint was created from a delegation
|
||||||
|
* message and thus contains the parent-side-info already. */
|
||||||
|
uint8_t has_parent_side_NS;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -90,13 +95,26 @@ struct delegpt_ns {
|
||||||
* If the name has been resolved. false if not queried for yet.
|
* If the name has been resolved. false if not queried for yet.
|
||||||
* true if the A, AAAA queries have been generated.
|
* true if the A, AAAA queries have been generated.
|
||||||
* marked true if those queries fail.
|
* marked true if those queries fail.
|
||||||
* and marked true is got4 and got6 are both true.
|
* and marked true if got4 and got6 are both true.
|
||||||
*/
|
*/
|
||||||
int resolved;
|
int resolved;
|
||||||
/** if the ipv4 address is in the delegpt */
|
/** if the ipv4 address is in the delegpt */
|
||||||
uint8_t got4;
|
uint8_t got4;
|
||||||
/** if the ipv6 address is in the delegpt */
|
/** if the ipv6 address is in the delegpt */
|
||||||
uint8_t got6;
|
uint8_t got6;
|
||||||
|
/**
|
||||||
|
* If the name is parent-side only and thus dispreferred.
|
||||||
|
* Its addresses become dispreferred as well
|
||||||
|
*/
|
||||||
|
uint8_t lame;
|
||||||
|
/** if the parent-side ipv4 address has been looked up (last resort).
|
||||||
|
* Also enabled if a parent-side cache entry exists, or a parent-side
|
||||||
|
* negative-cache entry exists. */
|
||||||
|
uint8_t done_pside4;
|
||||||
|
/** if the parent-side ipv6 address has been looked up (last resort).
|
||||||
|
* Also enabled if a parent-side cache entry exists, or a parent-side
|
||||||
|
* negative-cache entry exists. */
|
||||||
|
uint8_t done_pside6;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -155,20 +173,22 @@ int delegpt_set_name(struct delegpt* dp, struct regional* regional,
|
||||||
* @param dp: delegation point.
|
* @param dp: delegation point.
|
||||||
* @param regional: where to allocate the info.
|
* @param regional: where to allocate the info.
|
||||||
* @param name: domain name in wire format.
|
* @param name: domain name in wire format.
|
||||||
|
* @param lame: name is lame, disprefer it.
|
||||||
* @return false on error.
|
* @return false on error.
|
||||||
*/
|
*/
|
||||||
int delegpt_add_ns(struct delegpt* dp, struct regional* regional,
|
int delegpt_add_ns(struct delegpt* dp, struct regional* regional,
|
||||||
uint8_t* name);
|
uint8_t* name, int lame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add NS rrset; calls add_ns repeatedly.
|
* Add NS rrset; calls add_ns repeatedly.
|
||||||
* @param dp: delegation point.
|
* @param dp: delegation point.
|
||||||
* @param regional: where to allocate the info.
|
* @param regional: where to allocate the info.
|
||||||
* @param ns_rrset: NS rrset.
|
* @param ns_rrset: NS rrset.
|
||||||
|
* @param lame: rrset is lame, disprefer it.
|
||||||
* return 0 on alloc error.
|
* return 0 on alloc error.
|
||||||
*/
|
*/
|
||||||
int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
|
int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
|
||||||
struct ub_packed_rrset_key* ns_rrset);
|
struct ub_packed_rrset_key* ns_rrset, int lame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add target address to the delegation point.
|
* Add target address to the delegation point.
|
||||||
|
|
@ -219,10 +239,11 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
|
||||||
* @param dp: delegation point.
|
* @param dp: delegation point.
|
||||||
* @param regional: where to allocate the info.
|
* @param regional: where to allocate the info.
|
||||||
* @param rrset: RRset to add, NS, A, AAAA.
|
* @param rrset: RRset to add, NS, A, AAAA.
|
||||||
|
* @param lame: rrset is lame, disprefer it.
|
||||||
* @return 0 on alloc error.
|
* @return 0 on alloc error.
|
||||||
*/
|
*/
|
||||||
int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
||||||
struct ub_packed_rrset_key* rrset);
|
struct ub_packed_rrset_key* rrset, int lame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add address to the delegation point. No servername is associated or checked.
|
* Add address to the delegation point. No servername is associated or checked.
|
||||||
|
|
@ -286,6 +307,9 @@ void delegpt_add_unused_targets(struct delegpt* dp);
|
||||||
*/
|
*/
|
||||||
size_t delegpt_count_missing_targets(struct delegpt* dp);
|
size_t delegpt_count_missing_targets(struct delegpt* dp);
|
||||||
|
|
||||||
|
/** count total number of targets in dp */
|
||||||
|
size_t delegpt_count_targets(struct delegpt* dp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new delegation point from a dns message
|
* Create new delegation point from a dns message
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ read_fwds_host(struct iter_forwards* fwd, struct config_stub* s,
|
||||||
s->name, p->str);
|
s->name, p->str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!delegpt_add_ns(dp, fwd->region, ldns_rdf_data(rdf))) {
|
if(!delegpt_add_ns(dp, fwd->region, ldns_rdf_data(rdf), 0)) {
|
||||||
ldns_rdf_deep_free(rdf);
|
ldns_rdf_deep_free(rdf);
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -235,6 +235,9 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* set flag that parent side NS information is included.
|
||||||
|
* Asking an (higher up) server on the internet is not useful*/
|
||||||
|
dp->has_parent_side_NS = 1;
|
||||||
if(!read_fwds_name(fwd, s, dp) ||
|
if(!read_fwds_name(fwd, s, dp) ||
|
||||||
!read_fwds_host(fwd, s, dp) ||
|
!read_fwds_host(fwd, s, dp) ||
|
||||||
!read_fwds_addr(fwd, s, dp))
|
!read_fwds_addr(fwd, s, dp))
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ ah(struct delegpt* dp, struct regional* r, const char* sv, const char* ip)
|
||||||
log_err("could not parse %s", sv);
|
log_err("could not parse %s", sv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf)) ||
|
if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf), 0) ||
|
||||||
!extstrtoaddr(ip, &addr, &addrlen) ||
|
!extstrtoaddr(ip, &addr, &addrlen) ||
|
||||||
!delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
|
!delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
|
||||||
&addr, addrlen, 0, 0, 1)) {
|
&addr, addrlen, 0, 0, 1)) {
|
||||||
|
|
@ -112,6 +112,7 @@ compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
|
||||||
struct delegpt* dp = delegpt_create(r);
|
struct delegpt* dp = delegpt_create(r);
|
||||||
if(!dp)
|
if(!dp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
dp->has_parent_side_NS = 1;
|
||||||
if(!delegpt_set_name(dp, r, (uint8_t*)"\000"))
|
if(!delegpt_set_name(dp, r, (uint8_t*)"\000"))
|
||||||
return NULL;
|
return NULL;
|
||||||
if(do_ip4) {
|
if(do_ip4) {
|
||||||
|
|
@ -202,7 +203,7 @@ read_stubs_host(struct iter_hints* hints, struct config_stub* s,
|
||||||
s->name, p->str);
|
s->name, p->str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!delegpt_add_ns(dp, hints->region, ldns_rdf_data(rdf))) {
|
if(!delegpt_add_ns(dp, hints->region, ldns_rdf_data(rdf), 0)) {
|
||||||
ldns_rdf_deep_free(rdf);
|
ldns_rdf_deep_free(rdf);
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -247,6 +248,7 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
dp->has_parent_side_NS = 1;
|
||||||
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))
|
||||||
|
|
@ -283,6 +285,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
verbose(VERB_QUERY, "Reading root hints from %s", fname);
|
verbose(VERB_QUERY, "Reading root hints from %s", fname);
|
||||||
|
dp->has_parent_side_NS = 1;
|
||||||
while(!feof(f)) {
|
while(!feof(f)) {
|
||||||
status = ldns_rr_new_frm_fp_l(&rr, f,
|
status = ldns_rr_new_frm_fp_l(&rr, f,
|
||||||
&default_ttl, &origin, &prev_rr, &lineno);
|
&default_ttl, &origin, &prev_rr, &lineno);
|
||||||
|
|
@ -297,7 +300,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||||
}
|
}
|
||||||
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
|
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
|
||||||
if(!delegpt_add_ns(dp, hints->region,
|
if(!delegpt_add_ns(dp, hints->region,
|
||||||
ldns_rdf_data(ldns_rr_rdf(rr, 0)))) {
|
ldns_rdf_data(ldns_rr_rdf(rr, 0)), 0)) {
|
||||||
log_err("out of memory reading root hints");
|
log_err("out of memory reading root hints");
|
||||||
goto stop_read;
|
goto stop_read;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -430,54 +430,6 @@ iter_ns_probability(struct ub_randstate* rnd, int n, int m)
|
||||||
return (sel < n);
|
return (sel < n);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iter_suspect_exists(struct query_info* qinfo, struct delegpt* dp,
|
|
||||||
struct module_env* env)
|
|
||||||
{
|
|
||||||
struct ub_packed_rrset_key* r;
|
|
||||||
if(qinfo->qtype != LDNS_RR_TYPE_A && qinfo->qtype != LDNS_RR_TYPE_AAAA)
|
|
||||||
return 0; /* not glue type */
|
|
||||||
if(!dname_subdomain_c(qinfo->qname, dp->name))
|
|
||||||
return 0; /* not in-zone */
|
|
||||||
if(!delegpt_find_ns(dp, qinfo->qname, qinfo->qname_len))
|
|
||||||
return 0; /* not glue */
|
|
||||||
|
|
||||||
/* do we suspect that it exists? lookup with time=0 */
|
|
||||||
r = rrset_cache_lookup(env->rrset_cache, qinfo->qname,
|
|
||||||
qinfo->qname_len, qinfo->qtype, qinfo->qclass, 0, 0, 0);
|
|
||||||
if(r) {
|
|
||||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
|
||||||
r->entry.data;
|
|
||||||
/* if it is valid, no need for queries to parent zone */
|
|
||||||
if(*env->now <= d->ttl) {
|
|
||||||
lock_rw_unlock(&r->entry.lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* was it recently expired? */
|
|
||||||
if( (*env->now - d->ttl) <= SUSPICION_RECENT_EXPIRY) {
|
|
||||||
verbose(VERB_ALGO, "suspect glue at parent: "
|
|
||||||
"rrset recently expired");
|
|
||||||
lock_rw_unlock(&r->entry.lock);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lock_rw_unlock(&r->entry.lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* so, qinfo not there, does the other A/AAAA type exist in cache? */
|
|
||||||
r=rrset_cache_lookup(env->rrset_cache, qinfo->qname, qinfo->qname_len,
|
|
||||||
(qinfo->qtype==LDNS_RR_TYPE_A)?LDNS_RR_TYPE_AAAA:LDNS_RR_TYPE_A,
|
|
||||||
qinfo->qclass, 0, *env->now, 0);
|
|
||||||
if(r) {
|
|
||||||
/* it exists and explains why the glue is there */
|
|
||||||
lock_rw_unlock(&r->entry.lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* neither exist, so logically, one should exist for a nameserver */
|
|
||||||
verbose(VERB_ALGO, "suspect glue at parent: "
|
|
||||||
"neither A nor AAAA exist in cache");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** detect dependency cycle for query and target */
|
/** detect dependency cycle for query and target */
|
||||||
static int
|
static int
|
||||||
causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
|
causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
|
||||||
|
|
@ -516,6 +468,27 @@ iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
iter_mark_pside_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
|
||||||
|
{
|
||||||
|
struct delegpt_ns* ns;
|
||||||
|
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||||
|
if(ns->done_pside4 && ns->done_pside6)
|
||||||
|
continue;
|
||||||
|
/* see if this ns as target causes dependency cycle */
|
||||||
|
if(causes_cycle(qstate, ns->name, ns->namelen,
|
||||||
|
LDNS_RR_TYPE_AAAA, qstate->qinfo.qclass) ||
|
||||||
|
causes_cycle(qstate, ns->name, ns->namelen,
|
||||||
|
LDNS_RR_TYPE_A, qstate->qinfo.qclass)) {
|
||||||
|
log_nametypeclass(VERB_QUERY, "skipping target due "
|
||||||
|
"to dependency cycle", ns->name,
|
||||||
|
LDNS_RR_TYPE_A, qstate->qinfo.qclass);
|
||||||
|
ns->done_pside4 = 1;
|
||||||
|
ns->done_pside6 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||||
struct delegpt* dp)
|
struct delegpt* dp)
|
||||||
|
|
@ -735,56 +708,162 @@ reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iter_store_inzone_glue(struct module_env* env, struct query_info* qinfo,
|
iter_store_parentside_rrset(struct module_env* env,
|
||||||
struct reply_info* rep)
|
struct ub_packed_rrset_key* rrset)
|
||||||
{
|
{
|
||||||
struct rrset_ref ref;
|
struct rrset_ref ref;
|
||||||
struct ub_packed_rrset_key* rrset;
|
|
||||||
if(qinfo->qtype != LDNS_RR_TYPE_A && qinfo->qtype != LDNS_RR_TYPE_AAAA)
|
|
||||||
return;
|
|
||||||
rrset = reply_find_rrset(rep, qinfo->qname, qinfo->qname_len,
|
|
||||||
qinfo->qtype, qinfo->qclass);
|
|
||||||
if(!rrset)
|
|
||||||
return;
|
|
||||||
/* got A or AAAA glue rrset. store it in case its handy */
|
|
||||||
rrset = packed_rrset_copy_alloc(rrset, env->alloc, *env->now);
|
rrset = packed_rrset_copy_alloc(rrset, env->alloc, *env->now);
|
||||||
if(!rrset) {
|
if(!rrset) {
|
||||||
log_err("malloc failure in store_inzone_glue");
|
log_err("malloc failure in store_parentside_rrset");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rrset->rk.flags |= PACKED_RRSET_PARENT_SIDE;
|
rrset->rk.flags |= PACKED_RRSET_PARENT_SIDE;
|
||||||
rrset->entry.hash = rrset_key_hash(&rrset->rk);
|
rrset->entry.hash = rrset_key_hash(&rrset->rk);
|
||||||
ref.key = rrset;
|
ref.key = rrset;
|
||||||
ref.id = rrset->id;
|
ref.id = rrset->id;
|
||||||
/* ignore ret: it was in the cache, ref updated */
|
/* ignore ret: if it was in the cache, ref updated */
|
||||||
(void)rrset_cache_update(env->rrset_cache, &ref, env->alloc, *env->now);
|
(void)rrset_cache_update(env->rrset_cache, &ref, env->alloc, *env->now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** fetch NS record from reply, if any */
|
||||||
|
static struct ub_packed_rrset_key*
|
||||||
|
reply_get_NS_rrset(struct reply_info* rep)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for(i=0; i<rep->rrset_count; i++) {
|
||||||
|
if(rep->rrsets[i]->rk.type == htons(LDNS_RR_TYPE_NS)) {
|
||||||
|
return rep->rrsets[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
iter_store_parentside_NS(struct module_env* env, struct reply_info* rep)
|
||||||
|
{
|
||||||
|
struct ub_packed_rrset_key* rrset = reply_get_NS_rrset(rep);
|
||||||
|
if(rrset) {
|
||||||
|
log_rrset_key(VERB_ALGO, "store parent-side NS", rrset);
|
||||||
|
iter_store_parentside_rrset(env, rrset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void iter_store_parentside_neg(struct module_env* env,
|
||||||
|
struct query_info* qinfo, struct reply_info* rep)
|
||||||
|
{
|
||||||
|
/* TTL: NS from referral in iq->deleg_msg,
|
||||||
|
* or first RR from iq->response,
|
||||||
|
* or servfail5secs if !iq->response */
|
||||||
|
uint32_t ttl = NORR_TTL;
|
||||||
|
struct ub_packed_rrset_key* neg;
|
||||||
|
struct packed_rrset_data* newd;
|
||||||
|
if(rep) {
|
||||||
|
struct ub_packed_rrset_key* rrset = reply_get_NS_rrset(rep);
|
||||||
|
if(!rrset && rep->rrset_count != 0) rrset = rep->rrsets[0];
|
||||||
|
if(rrset) ttl = ub_packed_rrset_ttl(rrset);
|
||||||
|
}
|
||||||
|
/* create empty rrset to store */
|
||||||
|
neg = (struct ub_packed_rrset_key*)regional_alloc(env->scratch,
|
||||||
|
sizeof(struct ub_packed_rrset_key));
|
||||||
|
if(!neg) {
|
||||||
|
log_err("out of memory in store_parentside_neg");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(&neg->entry, 0, sizeof(neg->entry));
|
||||||
|
neg->entry.key = neg;
|
||||||
|
neg->rk.type = htons(qinfo->qtype);
|
||||||
|
neg->rk.rrset_class = htons(qinfo->qclass);
|
||||||
|
neg->rk.flags = 0;
|
||||||
|
neg->rk.dname = regional_alloc_init(env->scratch, qinfo->qname,
|
||||||
|
qinfo->qname_len);
|
||||||
|
if(!neg->rk.dname) {
|
||||||
|
log_err("out of memory in store_parentside_neg");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
neg->rk.dname_len = qinfo->qname_len;
|
||||||
|
neg->entry.hash = rrset_key_hash(&neg->rk);
|
||||||
|
newd = (struct packed_rrset_data*)regional_alloc_zero(env->scratch,
|
||||||
|
sizeof(struct packed_rrset_data) + sizeof(size_t) +
|
||||||
|
sizeof(uint8_t*) + sizeof(uint32_t) + sizeof(uint16_t));
|
||||||
|
if(!newd) {
|
||||||
|
log_err("out of memory in store_parentside_neg");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
neg->entry.data = newd;
|
||||||
|
newd->ttl = ttl;
|
||||||
|
/* entry must have one RR, otherwise not valid in cache.
|
||||||
|
* put in one RR with empty rdata: those are ignored as nameserver */
|
||||||
|
newd->count = 1;
|
||||||
|
newd->rrsig_count = 0;
|
||||||
|
newd->trust = rrset_trust_ans_noAA;
|
||||||
|
newd->rr_len = (size_t*)((uint8_t*)newd +
|
||||||
|
sizeof(struct packed_rrset_data));
|
||||||
|
newd->rr_len[0] = 0 /* zero len rdata */ + sizeof(uint16_t);
|
||||||
|
packed_rrset_ptr_fixup(newd);
|
||||||
|
newd->rr_ttl[0] = newd->ttl;
|
||||||
|
ldns_write_uint16(newd->rr_data[0], 0 /* zero len rdata */);
|
||||||
|
/* store it */
|
||||||
|
log_rrset_key(VERB_ALGO, "store parent-side negative", neg);
|
||||||
|
iter_store_parentside_rrset(env, neg);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
iter_lookup_inzone_glue(struct module_env* env, struct delegpt* dp,
|
iter_lookup_parent_NS_from_cache(struct module_env* env, struct delegpt* dp,
|
||||||
struct regional* region, struct query_info* qinfo)
|
struct regional* region, struct query_info* qinfo)
|
||||||
{
|
{
|
||||||
struct ub_packed_rrset_key* akey;
|
struct ub_packed_rrset_key* akey;
|
||||||
akey = rrset_cache_lookup(env->rrset_cache, qinfo->qname,
|
akey = rrset_cache_lookup(env->rrset_cache, dp->name,
|
||||||
qinfo->qname_len, qinfo->qtype, qinfo->qclass,
|
dp->namelen, LDNS_RR_TYPE_NS, qinfo->qclass,
|
||||||
PACKED_RRSET_PARENT_SIDE, *env->now, 0);
|
PACKED_RRSET_PARENT_SIDE, *env->now, 0);
|
||||||
if(akey) {
|
if(akey) {
|
||||||
if(qinfo->qtype == LDNS_RR_TYPE_A) {
|
log_rrset_key(VERB_ALGO, "found parent-side NS in cache", akey);
|
||||||
if(!delegpt_add_rrset_A(dp, region, akey, 1, 1)) {
|
dp->has_parent_side_NS = 1;
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
/* and mark the new names as lame */
|
||||||
return 0;
|
if(!delegpt_rrset_add_ns(dp, region, akey, 1)) {
|
||||||
}
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
} else if(qinfo->qtype == LDNS_RR_TYPE_AAAA) {
|
return 0;
|
||||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, 1)) {
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
||||||
|
struct delegpt* dp, struct regional* region, struct query_info* qinfo)
|
||||||
|
{
|
||||||
|
struct ub_packed_rrset_key* akey;
|
||||||
|
struct delegpt_ns* ns;
|
||||||
|
size_t num = delegpt_count_targets(dp);
|
||||||
|
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||||
|
/* get cached parentside A */
|
||||||
|
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||||
|
ns->namelen, LDNS_RR_TYPE_A, qinfo->qclass,
|
||||||
|
PACKED_RRSET_PARENT_SIDE, *env->now, 0);
|
||||||
|
if(akey) {
|
||||||
|
log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
||||||
|
ns->done_pside4 = 1;
|
||||||
|
/* a negative-cache-element has no addresses it adds */
|
||||||
|
if(!delegpt_add_rrset_A(dp, region, akey, 1, 1))
|
||||||
|
log_err("malloc failure in lookup_parent_glue");
|
||||||
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
|
}
|
||||||
|
/* get cached parentside AAAA */
|
||||||
|
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||||
|
ns->namelen, LDNS_RR_TYPE_AAAA, qinfo->qclass,
|
||||||
|
PACKED_RRSET_PARENT_SIDE, *env->now, 0);
|
||||||
|
if(akey) {
|
||||||
|
log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
||||||
|
ns->done_pside6 = 1;
|
||||||
|
/* a negative-cache-element has no addresses it adds */
|
||||||
|
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, 1))
|
||||||
|
log_err("malloc failure in lookup_parent_glue");
|
||||||
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* see if new (but lame) addresses have become available */
|
||||||
|
return delegpt_count_targets(dp) != num;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
|
iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
|
||||||
uint16_t* c)
|
uint16_t* c)
|
||||||
|
|
|
||||||
|
|
@ -145,17 +145,13 @@ int iter_ns_probability(struct ub_randstate* rnd, int n, int m);
|
||||||
void iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp);
|
void iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if query is in-zone glue and we suspect that it exists.
|
* Mark targets that result in a dependency cycle as done, so they
|
||||||
* Suspicion that it exists, is if there is no A or AAAA in cache (since
|
* will not get selected as targets. For the parent-side lookups.
|
||||||
* one of them is expected for an NS record) or the qtype is in cache but
|
* @param qstate: query state.
|
||||||
* was recently expired (so we have seen this data recently).
|
* @param dp: delegpt to mark ns in.
|
||||||
* @param qinfo: query info.
|
|
||||||
* @param dp: delegation point we are at.
|
|
||||||
* @param env: environment with rrset cache.
|
|
||||||
* @return true if suspect that this glue exists.
|
|
||||||
*/
|
*/
|
||||||
int iter_suspect_exists(struct query_info* qinfo, struct delegpt* dp,
|
void iter_mark_pside_cycle_targets(struct module_qstate* qstate,
|
||||||
struct module_env* env);
|
struct delegpt* dp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if delegation is useful or offers immediately no targets for
|
* See if delegation is useful or offers immediately no targets for
|
||||||
|
|
@ -217,26 +213,63 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
|
||||||
int reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* buf);
|
int reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store in-zone glue in seperate rrset cache entries for later last-resort
|
* Store parent-side rrset in seperate rrset cache entries for later
|
||||||
* lookups in case the child-side versions of this information fails.
|
* last-resort * lookups in case the child-side versions of this information
|
||||||
|
* fails.
|
||||||
* @param env: environment with cache, time, ...
|
* @param env: environment with cache, time, ...
|
||||||
* @param qinfo: query info. must match the information stored to avoid
|
* @param rrset: the rrset to store (copied).
|
||||||
* Kaminsky-style trouble.
|
* Failure to store is logged, but otherwise ignored.
|
||||||
* @param rep: reply with possibly A or AAAA content to store.
|
|
||||||
*/
|
*/
|
||||||
void iter_store_inzone_glue(struct module_env* env, struct query_info* qinfo,
|
void iter_store_parentside_rrset(struct module_env* env,
|
||||||
struct reply_info* rep);
|
struct ub_packed_rrset_key* rrset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find in-zone glue from rrset cache again.
|
* Store parent-side NS records from a referral message
|
||||||
* @param env: query env with rrset cache and time.
|
* @param env: environment with cache, time, ...
|
||||||
* @param dp: delegation point to store result in.
|
* @param rep: response with NS rrset.
|
||||||
* @param region: region to alloc result in.
|
* Failure to store is logged, but otherwise ignored.
|
||||||
* @param qinfo: query into that is pertinent.
|
|
||||||
* @return false on malloc failure.
|
|
||||||
*/
|
*/
|
||||||
int iter_lookup_inzone_glue(struct module_env* env, struct delegpt* dp,
|
void iter_store_parentside_NS(struct module_env* env, struct reply_info* rep);
|
||||||
struct regional* region, struct query_info* qinfo);
|
|
||||||
|
/**
|
||||||
|
* Store parent-side negative element, the parentside rrset does not exist,
|
||||||
|
* creates an rrset with empty rdata in the rrset cache with PARENTSIDE flag.
|
||||||
|
* @param env: environment with cache, time, ...
|
||||||
|
* @param qinfo: the identity of the rrset that is missing.
|
||||||
|
* @param rep: delegation response or answer response, to glean TTL from.
|
||||||
|
* (malloc) failure is logged but otherwise ignored.
|
||||||
|
*/
|
||||||
|
void iter_store_parentside_neg(struct module_env* env,
|
||||||
|
struct query_info* qinfo, struct reply_info* rep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add parent NS record if that exists in the cache. This is both new
|
||||||
|
* information and acts like a timeout throttle on retries.
|
||||||
|
* @param env: query env with rrset cache and time.
|
||||||
|
* @param dp: delegation point to store result in. Also this dp is used to
|
||||||
|
* see which NS name is needed.
|
||||||
|
* @param region: region to alloc result in.
|
||||||
|
* @param qinfo: pertinent information, the qclass.
|
||||||
|
* @return false on malloc failure.
|
||||||
|
* if true, the routine worked and if such cached information
|
||||||
|
* existed dp->has_parent_side_NS is set true.
|
||||||
|
*/
|
||||||
|
int iter_lookup_parent_NS_from_cache(struct module_env* env,
|
||||||
|
struct delegpt* dp, struct regional* region, struct query_info* qinfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add parent-side glue if that exists in the cache. This is both new
|
||||||
|
* information and acts like a timeout throttle on retries to fetch them.
|
||||||
|
* @param env: query env with rrset cache and time.
|
||||||
|
* @param dp: delegation point to store result in. Also this dp is used to
|
||||||
|
* see which NS name is needed.
|
||||||
|
* @param region: region to alloc result in.
|
||||||
|
* @param qinfo: pertinent information, the qclass.
|
||||||
|
* @return: true, it worked, no malloc failures, and new addresses (lame)
|
||||||
|
* have been added, giving extra options as query targets.
|
||||||
|
*/
|
||||||
|
int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
||||||
|
struct delegpt* dp, struct regional* region, struct query_info* qinfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup next root-hint or root-forward entry.
|
* Lookup next root-hint or root-forward entry.
|
||||||
|
|
|
||||||
|
|
@ -1210,6 +1210,58 @@ processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
return next_state(iq, QUERYTARGETS_STATE);
|
return next_state(iq, QUERYTARGETS_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a basic query, generate a parent-side "target" query.
|
||||||
|
* These are subordinate queries for missing delegation point target addresses,
|
||||||
|
* for which only the parent of the delegation provides correct IP addresses.
|
||||||
|
*
|
||||||
|
* @param qstate: query state.
|
||||||
|
* @param iq: iterator query state.
|
||||||
|
* @param id: module id.
|
||||||
|
* @param name: target qname.
|
||||||
|
* @param namelen: target qname length.
|
||||||
|
* @param qtype: target qtype (either A or AAAA).
|
||||||
|
* @param qclass: target qclass.
|
||||||
|
* @return true on success, false on failure.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
generate_parentside_target_query(struct module_qstate* qstate,
|
||||||
|
struct iter_qstate* iq, int id, uint8_t* name, size_t namelen,
|
||||||
|
uint16_t qtype, uint16_t qclass)
|
||||||
|
{
|
||||||
|
struct module_qstate* subq;
|
||||||
|
if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
|
||||||
|
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
|
||||||
|
return 0;
|
||||||
|
if(subq) {
|
||||||
|
struct iter_qstate* subiq =
|
||||||
|
(struct iter_qstate*)subq->minfo[id];
|
||||||
|
/* blacklist the cache - we want to fetch parent stuff */
|
||||||
|
sock_list_insert(&subq->blacklist, NULL, 0, subq->region);
|
||||||
|
subiq->query_for_pside_glue = 1;
|
||||||
|
if(dname_subdomain_c(name, iq->dp->name)) {
|
||||||
|
subiq->dp = delegpt_copy(iq->dp, subq->region);
|
||||||
|
subiq->dnssec_expected = iter_indicates_dnssec(
|
||||||
|
qstate->env, subiq->dp, NULL,
|
||||||
|
subq->qinfo.qclass);
|
||||||
|
subiq->refetch_glue = 1;
|
||||||
|
} else {
|
||||||
|
subiq->dp = dns_cache_find_delegation(qstate->env,
|
||||||
|
name, namelen, qtype, qclass, subq->region,
|
||||||
|
&subiq->deleg_msg, *qstate->env->now);
|
||||||
|
/* if no dp, then it's from root, refetch unneeded */
|
||||||
|
if(subiq->dp) {
|
||||||
|
subiq->dnssec_expected = iter_indicates_dnssec(
|
||||||
|
qstate->env, subiq->dp, NULL,
|
||||||
|
subq->qinfo.qclass);
|
||||||
|
subiq->refetch_glue = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_nametypeclass(VERB_QUERY, "new pside target", name, qtype, qclass);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a basic query, generate a "target" query. These are subordinate
|
* Given a basic query, generate a "target" query. These are subordinate
|
||||||
* queries for missing delegation point target addresses.
|
* queries for missing delegation point target addresses.
|
||||||
|
|
@ -1231,18 +1283,6 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
|
if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
|
||||||
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
|
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
|
||||||
return 0;
|
return 0;
|
||||||
if(subq) {
|
|
||||||
struct iter_qstate* subiq =
|
|
||||||
(struct iter_qstate*)subq->minfo[id];
|
|
||||||
if(dname_subdomain_c(name, iq->dp->name)) {
|
|
||||||
verbose(VERB_ALGO, "refetch of target glue");
|
|
||||||
subiq->refetch_glue = 1;
|
|
||||||
subiq->dp = delegpt_copy(iq->dp, subq->region);
|
|
||||||
subiq->dnssec_expected = iter_indicates_dnssec(
|
|
||||||
qstate->env, subiq->dp, NULL,
|
|
||||||
subq->qinfo.qclass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass);
|
log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1331,6 +1371,99 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by processQueryTargets when it would like extra targets to query
|
||||||
|
* but it seems to be out of options. At last resort some less appealing
|
||||||
|
* options are explored. If there are no more options, the result is SERVFAIL
|
||||||
|
*
|
||||||
|
* @param qstate: query state.
|
||||||
|
* @param iq: iterator query state.
|
||||||
|
* @param ie: iterator shared global environment.
|
||||||
|
* @param id: module id.
|
||||||
|
* @return true if the event requires more request processing immediately,
|
||||||
|
* false if not.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
|
struct iter_env* ie, int id)
|
||||||
|
{
|
||||||
|
struct delegpt_ns* ns;
|
||||||
|
int query_count = 0;
|
||||||
|
verbose(VERB_ALGO, "No more query targets, attempting last resort");
|
||||||
|
log_assert(iq->dp);
|
||||||
|
|
||||||
|
if(!iq->dp->has_parent_side_NS) {
|
||||||
|
if(!iter_lookup_parent_NS_from_cache(qstate->env, iq->dp,
|
||||||
|
qstate->region, &qstate->qinfo)
|
||||||
|
|| !iq->dp->has_parent_side_NS) {
|
||||||
|
/* if: malloc failure in lookup go up to try */
|
||||||
|
/* if: no parent NS in cache - go up one level */
|
||||||
|
verbose(VERB_ALGO, "try to grab parent NS");
|
||||||
|
iq->store_parent_NS = 1;
|
||||||
|
iq->deleg_msg = NULL;
|
||||||
|
iq->refetch_glue = 1;
|
||||||
|
iq->query_restart_count++;
|
||||||
|
return next_state(iq, INIT_REQUEST_STATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* try to fill out parent glue from cache */
|
||||||
|
if(iter_lookup_parent_glue_from_cache(qstate->env, iq->dp,
|
||||||
|
qstate->region, &qstate->qinfo)) {
|
||||||
|
/* got parent stuff from cache, see if we can continue */
|
||||||
|
verbose(VERB_ALGO, "try parent-side glue from cache");
|
||||||
|
return next_state(iq, QUERYTARGETS_STATE);
|
||||||
|
}
|
||||||
|
/* query for an extra name added by the parent-NS record */
|
||||||
|
if(delegpt_count_missing_targets(iq->dp) > 0) {
|
||||||
|
int qs = 0;
|
||||||
|
verbose(VERB_ALGO, "try parent-side target name");
|
||||||
|
if(!query_for_targets(qstate, iq, ie, id, 1, &qs)) {
|
||||||
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
}
|
||||||
|
iq->num_target_queries += qs;
|
||||||
|
if(qs != 0)
|
||||||
|
return 0; /* and wait for them */
|
||||||
|
}
|
||||||
|
/* mark cycle targets for parent-side lookups */
|
||||||
|
iter_mark_pside_cycle_targets(qstate, iq->dp);
|
||||||
|
/* see if we can issue queries to get nameserver addresses */
|
||||||
|
/* this lookup is not randomized, but sequential. */
|
||||||
|
for(ns = iq->dp->nslist; ns; ns = ns->next) {
|
||||||
|
/* query for parent-side A and AAAA for nameservers */
|
||||||
|
if(ie->supports_ipv6 && !ns->done_pside6) {
|
||||||
|
/* Send the AAAA request. */
|
||||||
|
if(!generate_parentside_target_query(qstate, iq, id,
|
||||||
|
ns->name, ns->namelen,
|
||||||
|
LDNS_RR_TYPE_AAAA, iq->qchase.qclass))
|
||||||
|
return error_response(qstate, id,
|
||||||
|
LDNS_RCODE_SERVFAIL);
|
||||||
|
ns->done_pside6 = 1;
|
||||||
|
query_count++;
|
||||||
|
}
|
||||||
|
if(!ns->done_pside4) {
|
||||||
|
/* Send the A request. */
|
||||||
|
if(!generate_parentside_target_query(qstate, iq, id,
|
||||||
|
ns->name, ns->namelen,
|
||||||
|
LDNS_RR_TYPE_A, iq->qchase.qclass))
|
||||||
|
return error_response(qstate, id,
|
||||||
|
LDNS_RCODE_SERVFAIL);
|
||||||
|
ns->done_pside4 = 1;
|
||||||
|
query_count++;
|
||||||
|
}
|
||||||
|
if(query_count != 0) { /* suspend to await results */
|
||||||
|
verbose(VERB_ALGO, "try parent-side glue lookup");
|
||||||
|
iq->num_target_queries += query_count;
|
||||||
|
qstate->ext_state[id] = module_wait_subquery;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verbose(VERB_QUERY, "out of query targets -- returning SERVFAIL");
|
||||||
|
/* fail -- no more targets, no more hope of targets, no hope
|
||||||
|
* of a response. */
|
||||||
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the request event state where the request will be sent to one of
|
* This is the request event state where the request will be sent to one of
|
||||||
* its current query targets. This state also handles issuing target lookup
|
* its current query targets. This state also handles issuing target lookup
|
||||||
|
|
@ -1493,39 +1626,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
/* Since a target query might have been made, we
|
/* Since a target query might have been made, we
|
||||||
* need to check again. */
|
* need to check again. */
|
||||||
if(iq->num_target_queries == 0) {
|
if(iq->num_target_queries == 0) {
|
||||||
/* is it glue and we suspect that it exists?*/
|
return processLastResort(qstate, iq, ie, id);
|
||||||
if(iter_suspect_exists(&iq->qchase, iq->dp,
|
|
||||||
qstate->env)) {
|
|
||||||
/* try at parent */
|
|
||||||
iq->deleg_msg = NULL;
|
|
||||||
iq->refetch_glue = 1;
|
|
||||||
iq->query_restart_count++;
|
|
||||||
return next_state(iq,
|
|
||||||
INIT_REQUEST_STATE);
|
|
||||||
}
|
|
||||||
/* is the current dp useless, like it would
|
|
||||||
* be classified useless if picked from the
|
|
||||||
* cache like this? If so, go back up */
|
|
||||||
if(iter_dp_is_useless(&qstate->qinfo,
|
|
||||||
qstate->query_flags, iq->dp) &&
|
|
||||||
!iq->dp->target_list) {
|
|
||||||
/* extra target list check because
|
|
||||||
* those become available again when
|
|
||||||
* lookup up from the cache */
|
|
||||||
verbose(VERB_QUERY, "delegation is "
|
|
||||||
"useless, try higher up");
|
|
||||||
iq->deleg_msg = NULL;
|
|
||||||
iq->query_restart_count++;
|
|
||||||
return next_state(iq,
|
|
||||||
INIT_REQUEST_STATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
verbose(VERB_QUERY, "out of query targets -- "
|
|
||||||
"returning SERVFAIL");
|
|
||||||
/* fail -- no more targets, no more hope
|
|
||||||
* of targets, no hope of a response. */
|
|
||||||
return error_response_cache(qstate, id,
|
|
||||||
LDNS_RCODE_SERVFAIL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1709,15 +1810,24 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
iq->response->rep, 1, 0))
|
iq->response->rep, 1, 0))
|
||||||
return error_response(qstate, id,
|
return error_response(qstate, id,
|
||||||
LDNS_RCODE_SERVFAIL);
|
LDNS_RCODE_SERVFAIL);
|
||||||
|
if(iq->store_parent_NS)
|
||||||
|
iter_store_parentside_NS(qstate->env,
|
||||||
|
iq->response->rep);
|
||||||
if(qstate->env->neg_cache)
|
if(qstate->env->neg_cache)
|
||||||
val_neg_addreferral(qstate->env->neg_cache,
|
val_neg_addreferral(qstate->env->neg_cache,
|
||||||
iq->response->rep, iq->dp->name);
|
iq->response->rep, iq->dp->name);
|
||||||
}
|
}
|
||||||
/* store parent-side-in-zone-glue, if directly queried for */
|
/* store parent-side-in-zone-glue, if directly queried for */
|
||||||
if((qstate->qinfo.qtype == LDNS_RR_TYPE_A
|
if(iq->query_for_pside_glue && !iq->pside_glue) {
|
||||||
|| qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)) {
|
iq->pside_glue = reply_find_rrset(iq->response->rep,
|
||||||
iter_store_inzone_glue(qstate->env,
|
iq->qchase.qname, iq->qchase.qname_len,
|
||||||
&iq->response->qinfo, iq->response->rep);
|
iq->qchase.qtype, iq->qchase.qclass);
|
||||||
|
if(iq->pside_glue) {
|
||||||
|
log_rrset_key(VERB_ALGO, "found parent-side "
|
||||||
|
"glue", iq->pside_glue);
|
||||||
|
iter_store_parentside_rrset(qstate->env,
|
||||||
|
iq->pside_glue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the event state, setting the current delegation
|
/* Reset the event state, setting the current delegation
|
||||||
|
|
@ -2007,10 +2117,17 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
||||||
* (regardless if it succeeded or not). */
|
* (regardless if it succeeded or not). */
|
||||||
foriq->num_target_queries--;
|
foriq->num_target_queries--;
|
||||||
|
|
||||||
/* perhaps we picked up interested cached addressed, like lame ones */
|
/* if iq->query_for_pside_glue then add the pside_glue (marked lame) */
|
||||||
if(!iter_lookup_inzone_glue(forq->env, foriq->dp, forq->region,
|
if(iq->pside_glue) {
|
||||||
&iq->qchase))
|
/* if the pside_glue is NULL, then it could not be found,
|
||||||
log_err("out of memory adding lame glue");
|
* the done_pside is already set when created and a cache
|
||||||
|
* entry created in processFinished so nothing to do here */
|
||||||
|
log_rrset_key(VERB_ALGO, "add parentside glue to dp",
|
||||||
|
iq->pside_glue);
|
||||||
|
if(!delegpt_add_rrset(foriq->dp, forq->region,
|
||||||
|
iq->pside_glue, 1))
|
||||||
|
log_err("out of memory adding pside glue");
|
||||||
|
}
|
||||||
|
|
||||||
/* This response is relevant to the current query, so we
|
/* This response is relevant to the current query, so we
|
||||||
* add (attempt to add, anyway) this target(s) and reactivate
|
* add (attempt to add, anyway) this target(s) and reactivate
|
||||||
|
|
@ -2023,11 +2140,14 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
||||||
/* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */
|
/* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */
|
||||||
if(!delegpt_find_ns(foriq->dp, rrset->rk.dname,
|
if(!delegpt_find_ns(foriq->dp, rrset->rk.dname,
|
||||||
rrset->rk.dname_len)) {
|
rrset->rk.dname_len)) {
|
||||||
|
/* if dpns->lame then set newcname ns lame too */
|
||||||
if(!delegpt_add_ns(foriq->dp, forq->region,
|
if(!delegpt_add_ns(foriq->dp, forq->region,
|
||||||
rrset->rk.dname))
|
rrset->rk.dname, (int)dpns->lame))
|
||||||
log_err("out of memory adding cnamed-ns");
|
log_err("out of memory adding cnamed-ns");
|
||||||
}
|
}
|
||||||
if(!delegpt_add_rrset(foriq->dp, forq->region, rrset))
|
/* if dpns->lame then set the address(es) lame too */
|
||||||
|
if(!delegpt_add_rrset(foriq->dp, forq->region, rrset,
|
||||||
|
(int)dpns->lame))
|
||||||
log_err("out of memory adding targets");
|
log_err("out of memory adding targets");
|
||||||
verbose(VERB_ALGO, "added target response");
|
verbose(VERB_ALGO, "added target response");
|
||||||
delegpt_log(VERB_ALGO, foriq->dp);
|
delegpt_log(VERB_ALGO, foriq->dp);
|
||||||
|
|
@ -2202,6 +2322,11 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
log_query_info(VERB_QUERY, "finishing processing for",
|
log_query_info(VERB_QUERY, "finishing processing for",
|
||||||
&qstate->qinfo);
|
&qstate->qinfo);
|
||||||
|
|
||||||
|
/* store negative cache element for parent side glue. */
|
||||||
|
if(iq->query_for_pside_glue && !iq->pside_glue)
|
||||||
|
iter_store_parentside_neg(qstate->env, &qstate->qinfo,
|
||||||
|
iq->deleg_msg?iq->deleg_msg->rep:
|
||||||
|
(iq->response?iq->response->rep:NULL));
|
||||||
if(!iq->response) {
|
if(!iq->response) {
|
||||||
verbose(VERB_ALGO, "No response is set, servfail");
|
verbose(VERB_ALGO, "No response is set, servfail");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,24 @@ struct iter_qstate {
|
||||||
/** the number of times this query as followed a referral. */
|
/** the number of times this query as followed a referral. */
|
||||||
int referral_count;
|
int referral_count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The query must store NS records from referrals as parentside RRs
|
||||||
|
* Enabled once it hits resolution problems, to throttle retries.
|
||||||
|
*/
|
||||||
|
int store_parent_NS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The query is for parent-side glue(A or AAAA) for a nameserver.
|
||||||
|
* If the item is seen as glue in a referral, and pside_glue is NULL,
|
||||||
|
* then it is stored in pside_glue for later.
|
||||||
|
* If it was never seen, at the end, then a negative caching element
|
||||||
|
* must be created.
|
||||||
|
* The (data or negative) RR cache element then throttles retries.
|
||||||
|
*/
|
||||||
|
int query_for_pside_glue;
|
||||||
|
/** the parent-side-glue element (NULL if none, its first match) */
|
||||||
|
struct ub_packed_rrset_key* pside_glue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* expected dnssec information for this iteration step.
|
* expected dnssec information for this iteration step.
|
||||||
* If dnssec rrsigs are expected and not given, the server is marked
|
* If dnssec rrsigs are expected and not given, the server is marked
|
||||||
|
|
|
||||||
44
services/cache/dns.c
vendored
44
services/cache/dns.c
vendored
|
|
@ -213,27 +213,6 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* see if we have parent-side-glue (dispreferred) */
|
|
||||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
|
||||||
ns->namelen, LDNS_RR_TYPE_A, qclass,
|
|
||||||
PACKED_RRSET_PARENT_SIDE, now, 0);
|
|
||||||
if(akey) {
|
|
||||||
if(!delegpt_add_rrset_A(dp, region, akey, 1, 1)) {
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
}
|
|
||||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
|
||||||
ns->namelen, LDNS_RR_TYPE_AAAA, qclass,
|
|
||||||
PACKED_RRSET_PARENT_SIDE, now, 0);
|
|
||||||
if(akey) {
|
|
||||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, 1)) {
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -284,27 +263,6 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* see if we have parent-side-glue (dispreferred) */
|
|
||||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
|
||||||
ns->namelen, LDNS_RR_TYPE_A, qclass,
|
|
||||||
PACKED_RRSET_PARENT_SIDE, now, 0);
|
|
||||||
if(akey) {
|
|
||||||
if(!delegpt_add_rrset_A(dp, region, akey, 1, 1)) {
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
}
|
|
||||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
|
||||||
ns->namelen, LDNS_RR_TYPE_AAAA, qclass,
|
|
||||||
PACKED_RRSET_PARENT_SIDE, now, 0);
|
|
||||||
if(akey) {
|
|
||||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, 1)) {
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -420,7 +378,7 @@ dns_cache_find_delegation(struct module_env* env, uint8_t* qname,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!delegpt_rrset_add_ns(dp, region, nskey))
|
if(!delegpt_rrset_add_ns(dp, region, nskey, 0))
|
||||||
log_err("find_delegation: addns out of memory");
|
log_err("find_delegation: addns out of memory");
|
||||||
lock_rw_unlock(&nskey->entry.lock); /* first unlock before next lookup*/
|
lock_rw_unlock(&nskey->entry.lock); /* first unlock before next lookup*/
|
||||||
/* find and add DS/NSEC (if any) */
|
/* find and add DS/NSEC (if any) */
|
||||||
|
|
|
||||||
15
testdata/autotrust_init_fail.rpl
vendored
15
testdata/autotrust_init_fail.rpl
vendored
|
|
@ -76,6 +76,21 @@ example.com. 3600 IN RRSIG NS 5 2 3600 20090924111500 20090821111500 30899 examp
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qname qtype
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR AA
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. 3600 IN A 1.2.3.4
|
||||||
|
ns.example.com. 3600 IN RRSIG A 5 3 3600 20090924111500 20090821111500 30899 example.com. JsXbS18oyc0zkVaOWGSFdIQuOsZKflT0GraT9afDPoWLCgH4ApF7jNgfJV7Pqy1sTBRajME5IUAhpANwGBuW4A== ;{id = 30899}
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 3600 IN NS ns.example.com.
|
||||||
|
example.com. 3600 IN RRSIG NS 5 2 3600 20090924111500 20090821111500 30899 example.com. J5wxRq0jgwQL6yy530kvo9cHqNAUHV8IF4dvaYZL0bNraO2Oe6dVXqlJl4+cxNHI2TMsstwFPr2Zz8tv6Az2mQ== ;{id = 30899}
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qname qtype
|
MATCH opcode qname qtype
|
||||||
ADJUST copy_id
|
ADJUST copy_id
|
||||||
|
|
|
||||||
15
testdata/autotrust_probefail.rpl
vendored
15
testdata/autotrust_probefail.rpl
vendored
|
|
@ -77,6 +77,21 @@ ns.example.com. IN AAAA
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qname qtype
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR AA
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. 3600 IN A 1.2.3.4
|
||||||
|
ns.example.com. 3600 IN RRSIG A 5 3 3600 20090924111500 20090821111500 30899 example.com. JsXbS18oyc0zkVaOWGSFdIQuOsZKflT0GraT9afDPoWLCgH4ApF7jNgfJV7Pqy1sTBRajME5IUAhpANwGBuW4A== ;{id = 30899}
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 3600 IN NS ns.example.com.
|
||||||
|
example.com. 3600 IN RRSIG NS 5 2 3600 20090924111500 20090821111500 30899 example.com. J5wxRq0jgwQL6yy530kvo9cHqNAUHV8IF4dvaYZL0bNraO2Oe6dVXqlJl4+cxNHI2TMsstwFPr2Zz8tv6Az2mQ== ;{id = 30899}
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qname qtype
|
MATCH opcode qname qtype
|
||||||
ADJUST copy_id
|
ADJUST copy_id
|
||||||
|
|
|
||||||
14
testdata/autotrust_valid_use.rpl
vendored
14
testdata/autotrust_valid_use.rpl
vendored
|
|
@ -141,6 +141,20 @@ RANGE_END
|
||||||
; ns.example.com. KSK 55582 and 60946 (signatures updated)
|
; ns.example.com. KSK 55582 and 60946 (signatures updated)
|
||||||
RANGE_BEGIN 41 50
|
RANGE_BEGIN 41 50
|
||||||
ADDRESS 1.2.3.4
|
ADDRESS 1.2.3.4
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qname qtype
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR AA
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. 3600 IN A 1.2.3.4
|
||||||
|
ns.example.com. 3600 IN RRSIG A 5 3 3600 20090924111500 20090821111500 30899 example.com. JsXbS18oyc0zkVaOWGSFdIQuOsZKflT0GraT9afDPoWLCgH4ApF7jNgfJV7Pqy1sTBRajME5IUAhpANwGBuW4A== ;{id = 30899}
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 3600 IN NS ns.example.com.
|
||||||
|
example.com. 3600 IN RRSIG NS 5 2 3600 20090924111500 20090821111500 30899 example.com. J5wxRq0jgwQL6yy530kvo9cHqNAUHV8IF4dvaYZL0bNraO2Oe6dVXqlJl4+cxNHI2TMsstwFPr2Zz8tv6Az2mQ== ;{id = 30899}
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qname qtype
|
MATCH opcode qname qtype
|
||||||
|
|
|
||||||
9
testdata/iter_lame_aaaa.rpl
vendored
9
testdata/iter_lame_aaaa.rpl
vendored
|
|
@ -78,6 +78,15 @@ ns.example.com. IN AAAA
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode qtype qname
|
||||||
ADJUST copy_id
|
ADJUST copy_id
|
||||||
|
|
|
||||||
10
testdata/iter_lamescrub.rpl
vendored
10
testdata/iter_lamescrub.rpl
vendored
|
|
@ -41,6 +41,16 @@ SECTION QUESTION
|
||||||
a.gtld-servers.net. IN AAAA
|
a.gtld-servers.net. IN AAAA
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
ENTRY_BEGIN
|
||||||
|
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
a.gtld-servers.net. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
RANGE_END
|
RANGE_END
|
||||||
|
|
||||||
; a.gtld-servers.net.
|
; a.gtld-servers.net.
|
||||||
|
|
|
||||||
23
testdata/iter_primenoglue.rpl
vendored
23
testdata/iter_primenoglue.rpl
vendored
|
|
@ -177,6 +177,29 @@ SECTION ADDITIONAL
|
||||||
A.ROOT-SERVERS.NET. IN A 198.41.0.4
|
A.ROOT-SERVERS.NET. IN A 198.41.0.4
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qname qtype
|
||||||
|
ADJUST copy_id copy_query
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
A.ROOT-SERVERS.NET. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
A.ROOT-SERVERS.NET. IN A 198.41.0.4
|
||||||
|
SECTION AUTHORITY
|
||||||
|
ROOT-SERVERS.NET. IN NS A.ROOT-SERVERS.NET.
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qname qtype
|
||||||
|
ADJUST copy_id copy_query
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
A.ROOT-SERVERS.NET. IN AAAA
|
||||||
|
SECTION ANSWER
|
||||||
|
SECTION AUTHORITY
|
||||||
|
ROOT-SERVERS.NET. IN NS A.ROOT-SERVERS.NET.
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode qtype qname
|
||||||
ADJUST copy_id
|
ADJUST copy_id
|
||||||
|
|
|
||||||
12
testdata/iter_privaddr.rpl
vendored
12
testdata/iter_privaddr.rpl
vendored
|
|
@ -101,6 +101,18 @@ SECTION ADDITIONAL
|
||||||
ns.example.com. IN A 1.2.3.4
|
ns.example.com. IN A 1.2.3.4
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode qtype qname
|
||||||
ADJUST copy_id
|
ADJUST copy_id
|
||||||
|
|
|
||||||
14
testdata/val_dnametoolong.rpl
vendored
14
testdata/val_dnametoolong.rpl
vendored
|
|
@ -121,6 +121,20 @@ ns.example.com. IN A 1.2.3.4
|
||||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode qtype qname
|
||||||
ADJUST copy_id
|
ADJUST copy_id
|
||||||
|
|
|
||||||
16
testdata/val_ds_cname.rpl
vendored
16
testdata/val_ds_cname.rpl
vendored
|
|
@ -80,6 +80,22 @@ RANGE_END
|
||||||
; ns.example.com.
|
; ns.example.com.
|
||||||
RANGE_BEGIN 0 100
|
RANGE_BEGIN 0 100
|
||||||
ADDRESS 1.2.3.4
|
ADDRESS 1.2.3.4
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN AAAA
|
||||||
|
SECTION ANSWER
|
||||||
|
; not legal NOERROR/NODATA response, but leniently accepted (not validated)
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode qtype qname
|
||||||
ADJUST copy_id
|
ADJUST copy_id
|
||||||
|
|
|
||||||
14
testdata/val_faildnskey.rpl
vendored
14
testdata/val_faildnskey.rpl
vendored
|
|
@ -86,6 +86,20 @@ ns.example.com. IN A 1.2.3.4
|
||||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
; response to DNSKEY priming query
|
; response to DNSKEY priming query
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode qtype qname
|
||||||
|
|
|
||||||
15
testdata/val_faildnskey_ok.rpl
vendored
15
testdata/val_faildnskey_ok.rpl
vendored
|
|
@ -86,6 +86,21 @@ ns.example.com. IN A 1.2.3.4
|
||||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
|
||||||
; response to DNSKEY priming query
|
; response to DNSKEY priming query
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode qtype qname
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,14 @@ sec_status_to_string(enum sec_status s)
|
||||||
return "unknown_sec_status_value";
|
return "unknown_sec_status_value";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void log_rrset_key(enum verbosity_value v, const char* str,
|
||||||
|
struct ub_packed_rrset_key* rrset)
|
||||||
|
{
|
||||||
|
if(verbosity >= v)
|
||||||
|
log_nametypeclass(v, str, rrset->rk.dname,
|
||||||
|
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
ub_packed_rrset_ttl(struct ub_packed_rrset_key* key)
|
ub_packed_rrset_ttl(struct ub_packed_rrset_key* key)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,15 @@ const char* rrset_trust_to_string(enum rrset_trust s);
|
||||||
*/
|
*/
|
||||||
const char* sec_status_to_string(enum sec_status s);
|
const char* sec_status_to_string(enum sec_status s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print string with neat domain name, type, class from rrset.
|
||||||
|
* @param v: at what verbosity level to print this.
|
||||||
|
* @param str: string of message.
|
||||||
|
* @param rrset: structure with name, type and class.
|
||||||
|
*/
|
||||||
|
void log_rrset_key(enum verbosity_value v, const char* str,
|
||||||
|
struct ub_packed_rrset_key* rrset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate rrset in region - no more locks needed
|
* Allocate rrset in region - no more locks needed
|
||||||
* @param key: a (just from rrset cache looked up) rrset key + valid,
|
* @param key: a (just from rrset cache looked up) rrset key + valid,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue