mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Fix prefetch and stickyness.
git-svn-id: file:///svn/unbound/trunk@2632 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
682ff957ed
commit
773d8e3b84
12 changed files with 291 additions and 42 deletions
|
|
@ -765,7 +765,7 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||||
if(!go_on)
|
if(!go_on)
|
||||||
return 1; /* skip this one, not all references satisfied */
|
return 1; /* skip this one, not all references satisfied */
|
||||||
|
|
||||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, NULL)) {
|
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) {
|
||||||
log_warn("error out of memory");
|
log_warn("error out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
16 February 2012: Wouter
|
16 February 2012: Wouter
|
||||||
- iter_hints is now thread-owned in module env, and thus threadsafe.
|
- iter_hints is now thread-owned in module env, and thus threadsafe.
|
||||||
|
- Fix prefetch and sticky NS, now the prefetch works. It picks
|
||||||
|
nameservers that 'would be valid in the future', and if this makes
|
||||||
|
the NS timeout, it updates that NS by asking delegation from the
|
||||||
|
parent again. If child NS has longer TTL, that TTL does not get
|
||||||
|
refreshed from the lookup to the child nameserver.
|
||||||
|
|
||||||
15 February 2012: Wouter
|
15 February 2012: Wouter
|
||||||
- Fix forward-zone memory, uses malloc and frees original root dp.
|
- Fix forward-zone memory, uses malloc and frees original root dp.
|
||||||
|
|
|
||||||
|
|
@ -419,11 +419,11 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
|
||||||
|
|
||||||
int
|
int
|
||||||
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
|
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
struct reply_info* msgrep, int is_referral, uint32_t leeway,
|
struct reply_info* msgrep, int is_referral, uint32_t leeway, int pside,
|
||||||
struct regional* region)
|
struct regional* region)
|
||||||
{
|
{
|
||||||
return dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
|
return dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
|
||||||
region);
|
pside, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -121,11 +121,13 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
|
||||||
* @param is_referral: If true, then the given message to be stored is a
|
* @param is_referral: If true, then the given message to be stored is a
|
||||||
* referral. The cache implementation may use this as a hint.
|
* referral. The cache implementation may use this as a hint.
|
||||||
* @param leeway: prefetch TTL leeway to expire old rrsets quicker.
|
* @param leeway: prefetch TTL leeway to expire old rrsets quicker.
|
||||||
|
* @param pside: true if dp is parentside, thus message is 'fresh' and NS
|
||||||
|
* can be prefetch-updates.
|
||||||
* @param region: to copy modified (cache is better) rrs back to.
|
* @param region: to copy modified (cache is better) rrs back to.
|
||||||
* @return 0 on alloc error (out of memory).
|
* @return 0 on alloc error (out of memory).
|
||||||
*/
|
*/
|
||||||
int iter_dns_store(struct module_env* env, struct query_info* qinf,
|
int iter_dns_store(struct module_env* env, struct query_info* qinf,
|
||||||
struct reply_info* rep, int is_referral, uint32_t leeway,
|
struct reply_info* rep, int is_referral, uint32_t leeway, int pside,
|
||||||
struct regional* region);
|
struct regional* region);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||||
/* do not waste time trying to validate this servfail */
|
/* do not waste time trying to validate this servfail */
|
||||||
err.security = sec_status_indeterminate;
|
err.security = sec_status_indeterminate;
|
||||||
verbose(VERB_ALGO, "store error response in message cache");
|
verbose(VERB_ALGO, "store error response in message cache");
|
||||||
if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, NULL)) {
|
if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL)) {
|
||||||
log_err("error_response_cache: could not store error (nomem)");
|
log_err("error_response_cache: could not store error (nomem)");
|
||||||
}
|
}
|
||||||
return error_response(qstate, id, rcode);
|
return error_response(qstate, id, rcode);
|
||||||
|
|
@ -1040,7 +1040,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
if(delname)
|
if(delname)
|
||||||
iq->dp = dns_cache_find_delegation(qstate->env, delname,
|
iq->dp = dns_cache_find_delegation(qstate->env, delname,
|
||||||
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
|
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
|
||||||
qstate->region, &iq->deleg_msg, *qstate->env->now);
|
qstate->region, &iq->deleg_msg,
|
||||||
|
*qstate->env->now+qstate->prefetch_leeway);
|
||||||
else iq->dp = NULL;
|
else iq->dp = NULL;
|
||||||
|
|
||||||
/* If the cache has returned nothing, then we have a
|
/* If the cache has returned nothing, then we have a
|
||||||
|
|
@ -1258,7 +1259,8 @@ generate_parentside_target_query(struct module_qstate* qstate,
|
||||||
} else {
|
} else {
|
||||||
subiq->dp = dns_cache_find_delegation(qstate->env,
|
subiq->dp = dns_cache_find_delegation(qstate->env,
|
||||||
name, namelen, qtype, qclass, subq->region,
|
name, namelen, qtype, qclass, subq->region,
|
||||||
&subiq->deleg_msg, *qstate->env->now);
|
&subiq->deleg_msg,
|
||||||
|
*qstate->env->now+subq->prefetch_leeway);
|
||||||
/* if no dp, then it's from root, refetch unneeded */
|
/* if no dp, then it's from root, refetch unneeded */
|
||||||
if(subiq->dp) {
|
if(subiq->dp) {
|
||||||
subiq->dnssec_expected = iter_indicates_dnssec(
|
subiq->dnssec_expected = iter_indicates_dnssec(
|
||||||
|
|
@ -1830,6 +1832,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
}
|
}
|
||||||
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||||
|
iq->dp&&iq->dp->has_parent_side_NS,
|
||||||
qstate->region))
|
qstate->region))
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
/* close down outstanding requests to be discarded */
|
/* close down outstanding requests to be discarded */
|
||||||
|
|
@ -1869,7 +1872,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
/* Store the referral under the current query */
|
/* Store the referral under the current query */
|
||||||
/* no prefetch-leeway, since its not the answer */
|
/* no prefetch-leeway, since its not the answer */
|
||||||
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
iq->response->rep, 1, 0, NULL))
|
iq->response->rep, 1, 0, 0, NULL))
|
||||||
return error_response(qstate, id,
|
return error_response(qstate, id,
|
||||||
LDNS_RCODE_SERVFAIL);
|
LDNS_RCODE_SERVFAIL);
|
||||||
if(iq->store_parent_NS)
|
if(iq->store_parent_NS)
|
||||||
|
|
@ -1955,7 +1958,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* the partial query answer (CNAME only). */
|
* the partial query answer (CNAME only). */
|
||||||
/* prefetchleeway applied because this updates answer parts */
|
/* prefetchleeway applied because this updates answer parts */
|
||||||
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
iq->response->rep, 1, qstate->prefetch_leeway, NULL))
|
iq->response->rep, 1, qstate->prefetch_leeway,
|
||||||
|
iq->dp&&iq->dp->has_parent_side_NS,
|
||||||
|
NULL))
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
/* set the current request's qname to the new value. */
|
/* set the current request's qname to the new value. */
|
||||||
iq->qchase.qname = sname;
|
iq->qchase.qname = sname;
|
||||||
|
|
@ -2432,6 +2437,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
if(qstate->query_flags&BIT_RD) {
|
if(qstate->query_flags&BIT_RD) {
|
||||||
if(!iter_dns_store(qstate->env, &qstate->qinfo,
|
if(!iter_dns_store(qstate->env, &qstate->qinfo,
|
||||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||||
|
iq->dp&&iq->dp->has_parent_side_NS,
|
||||||
qstate->region))
|
qstate->region))
|
||||||
return error_response(qstate, id,
|
return error_response(qstate, id,
|
||||||
LDNS_RCODE_SERVFAIL);
|
LDNS_RCODE_SERVFAIL);
|
||||||
|
|
|
||||||
20
services/cache/dns.c
vendored
20
services/cache/dns.c
vendored
|
|
@ -60,12 +60,15 @@
|
||||||
* updated with a new full TTL.
|
* updated with a new full TTL.
|
||||||
* Type NS does not get this, because it must not be refreshed from the
|
* Type NS does not get this, because it must not be refreshed from the
|
||||||
* child domain, but keep counting down properly.
|
* child domain, but keep counting down properly.
|
||||||
|
* @param pside: if from parentside discovered NS, so that its NS is okay
|
||||||
|
* in a prefetch situation to be updated (without becoming sticky).
|
||||||
* @param qrep: update rrsets here if cache is better
|
* @param qrep: update rrsets here if cache is better
|
||||||
* @param region: for qrep allocs.
|
* @param region: for qrep allocs.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now,
|
store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now,
|
||||||
uint32_t leeway, struct reply_info* qrep, struct regional* region)
|
uint32_t leeway, int pside, struct reply_info* qrep,
|
||||||
|
struct regional* region)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
/* see if rrset already exists in cache, if not insert it. */
|
/* see if rrset already exists in cache, if not insert it. */
|
||||||
|
|
@ -75,7 +78,7 @@ store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now,
|
||||||
/* update ref if it was in the cache */
|
/* update ref if it was in the cache */
|
||||||
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
|
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
|
||||||
env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
|
env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
|
||||||
LDNS_RR_TYPE_NS)?0:leeway))) {
|
LDNS_RR_TYPE_NS && !pside)?0:leeway))) {
|
||||||
case 0: /* ref unchanged, item inserted */
|
case 0: /* ref unchanged, item inserted */
|
||||||
break;
|
break;
|
||||||
case 2: /* ref updated, cache is superior */
|
case 2: /* ref updated, cache is superior */
|
||||||
|
|
@ -102,7 +105,7 @@ store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now,
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||||
hashvalue_t hash, struct reply_info* rep, uint32_t leeway,
|
hashvalue_t hash, struct reply_info* rep, uint32_t leeway, int pside,
|
||||||
struct reply_info* qrep, struct regional* region)
|
struct reply_info* qrep, struct regional* region)
|
||||||
{
|
{
|
||||||
struct msgreply_entry* e;
|
struct msgreply_entry* e;
|
||||||
|
|
@ -118,7 +121,7 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||||
/* there was a reply_info_sortref(rep) here but it seems to be
|
/* there was a reply_info_sortref(rep) here but it seems to be
|
||||||
* unnecessary, because the cache gets locked per rrset. */
|
* unnecessary, because the cache gets locked per rrset. */
|
||||||
reply_info_set_ttls(rep, *env->now);
|
reply_info_set_ttls(rep, *env->now);
|
||||||
store_rrsets(env, rep, *env->now, leeway, qrep, region);
|
store_rrsets(env, rep, *env->now, leeway, pside, qrep, region);
|
||||||
if(ttl == 0) {
|
if(ttl == 0) {
|
||||||
/* we do not store the message, but we did store the RRs,
|
/* we do not store the message, but we did store the RRs,
|
||||||
* which could be useful for delegation information */
|
* which could be useful for delegation information */
|
||||||
|
|
@ -736,7 +739,7 @@ dns_cache_lookup(struct module_env* env,
|
||||||
|
|
||||||
int
|
int
|
||||||
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
struct reply_info* msgrep, int is_referral, uint32_t leeway,
|
struct reply_info* msgrep, int is_referral, uint32_t leeway, int pside,
|
||||||
struct regional* region)
|
struct regional* region)
|
||||||
{
|
{
|
||||||
struct reply_info* rep = NULL;
|
struct reply_info* rep = NULL;
|
||||||
|
|
@ -761,8 +764,8 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
/* no leeway for typeNS */
|
/* no leeway for typeNS */
|
||||||
(void)rrset_cache_update(env->rrset_cache, &ref,
|
(void)rrset_cache_update(env->rrset_cache, &ref,
|
||||||
env->alloc, *env->now +
|
env->alloc, *env->now +
|
||||||
((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS)?
|
((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS
|
||||||
0:leeway));
|
&& !pside) ? 0:leeway));
|
||||||
}
|
}
|
||||||
free(rep);
|
free(rep);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -783,7 +786,8 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
rep->flags |= (BIT_RA | BIT_QR);
|
rep->flags |= (BIT_RA | BIT_QR);
|
||||||
rep->flags &= ~(BIT_AA | BIT_CD);
|
rep->flags &= ~(BIT_AA | BIT_CD);
|
||||||
h = query_info_hash(&qinf);
|
h = query_info_hash(&qinf);
|
||||||
dns_cache_store_msg(env, &qinf, h, rep, leeway, msgrep, region);
|
dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
|
||||||
|
region);
|
||||||
/* qname is used inside query_info_entrysetup, and set to
|
/* qname is used inside query_info_entrysetup, and set to
|
||||||
* NULL. If it has not been used, free it. free(0) is safe. */
|
* NULL. If it has not been used, free it. free(0) is safe. */
|
||||||
free(qinf.qname);
|
free(qinf.qname);
|
||||||
|
|
|
||||||
10
services/cache/dns.h
vendored
10
services/cache/dns.h
vendored
|
|
@ -74,12 +74,15 @@ struct dns_msg {
|
||||||
* It will store only the RRsets, not the message.
|
* It will store only the RRsets, not the message.
|
||||||
* @param leeway: TTL value, if not 0, other rrsets are considered expired
|
* @param leeway: TTL value, if not 0, other rrsets are considered expired
|
||||||
* that many seconds before actual TTL expiry.
|
* that many seconds before actual TTL expiry.
|
||||||
|
* @param pside: if true, information came from a server which was fetched
|
||||||
|
* from the parentside of the zonecut. This means that the type NS
|
||||||
|
* can be updated to full TTL even in prefetch situations.
|
||||||
* @param region: region to allocate better entries from cache into.
|
* @param region: region to allocate better entries from cache into.
|
||||||
* (used when is_referral is false).
|
* (used when is_referral is false).
|
||||||
* @return 0 on alloc error (out of memory).
|
* @return 0 on alloc error (out of memory).
|
||||||
*/
|
*/
|
||||||
int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
||||||
struct reply_info* rep, int is_referral, uint32_t leeway,
|
struct reply_info* rep, int is_referral, uint32_t leeway, int pside,
|
||||||
struct regional* region);
|
struct regional* region);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -95,11 +98,14 @@ int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
||||||
* Adjusts the reply info TTLs to absolute time.
|
* Adjusts the reply info TTLs to absolute time.
|
||||||
* @param leeway: TTL value, if not 0, other rrsets are considered expired
|
* @param leeway: TTL value, if not 0, other rrsets are considered expired
|
||||||
* that many seconds before actual TTL expiry.
|
* that many seconds before actual TTL expiry.
|
||||||
|
* @param pside: if true, information came from a server which was fetched
|
||||||
|
* from the parentside of the zonecut. This means that the type NS
|
||||||
|
* can be updated to full TTL even in prefetch situations.
|
||||||
* @param qrep: message that can be altered with better rrs from cache.
|
* @param qrep: message that can be altered with better rrs from cache.
|
||||||
* @param region: to allocate into for qmsg.
|
* @param region: to allocate into for qmsg.
|
||||||
*/
|
*/
|
||||||
void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||||
hashvalue_t hash, struct reply_info* rep, uint32_t leeway,
|
hashvalue_t hash, struct reply_info* rep, uint32_t leeway, int pside,
|
||||||
struct reply_info* qrep, struct regional* region);
|
struct reply_info* qrep, struct regional* region);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
4
testdata/iter_prefetch.rpl
vendored
4
testdata/iter_prefetch.rpl
vendored
|
|
@ -217,8 +217,8 @@ www.example.com. IN A
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
www.example.com. 3600 IN A 10.20.30.40
|
www.example.com. 3600 IN A 10.20.30.40
|
||||||
SECTION AUTHORITY
|
SECTION AUTHORITY
|
||||||
; NS rrset TTL not updated to avoid sticky-NS (ghost domain) problem.
|
; NS rrset picked up from parent-NS (the child-NS timed out at now+prefetch)
|
||||||
example.com. 360 IN NS ns.example.com.
|
example.com. 3600 IN NS ns.example.com.
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
ns.example.com. 3600 IN A 1.2.3.4
|
ns.example.com. 3600 IN A 1.2.3.4
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
|
||||||
18
testdata/iter_prefetch_change2.rpl
vendored
18
testdata/iter_prefetch_change2.rpl
vendored
|
|
@ -256,11 +256,11 @@ REPLY QR RD RA NOERROR
|
||||||
SECTION QUESTION
|
SECTION QUESTION
|
||||||
www.example.com. IN A
|
www.example.com. IN A
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
www.example.com. 300 IN A 10.1.1.1
|
www.example.com. 86400 IN A 10.2.2.2
|
||||||
SECTION AUTHORITY
|
SECTION AUTHORITY
|
||||||
example.com. 30 IN NS old-ns.example.com.
|
example.com. 86400 IN NS new-ns.example.com.
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
old-ns.example.com. 300 IN A 192.168.0.1
|
new-ns.example.com. 86400 IN A 172.16.0.1
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
; the NS record times out after 31 seconds.
|
; the NS record times out after 31 seconds.
|
||||||
|
|
@ -281,11 +281,11 @@ REPLY QR RD RA NOERROR
|
||||||
SECTION QUESTION
|
SECTION QUESTION
|
||||||
www.example.com. IN A
|
www.example.com. IN A
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
www.example.com. 86400 IN A 10.2.2.2
|
www.example.com. 86369 IN A 10.2.2.2
|
||||||
SECTION AUTHORITY
|
SECTION AUTHORITY
|
||||||
example.com. 86400 IN NS new-ns.example.com.
|
example.com. 86369 IN NS new-ns.example.com.
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
new-ns.example.com. 86369 IN A 172.16.0.1
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
; a reply from cache
|
; a reply from cache
|
||||||
|
|
@ -303,11 +303,11 @@ REPLY QR RD RA NOERROR
|
||||||
SECTION QUESTION
|
SECTION QUESTION
|
||||||
www.example.com. IN A
|
www.example.com. IN A
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
www.example.com. 86400 IN A 10.2.2.2
|
www.example.com. 86369 IN A 10.2.2.2
|
||||||
SECTION AUTHORITY
|
SECTION AUTHORITY
|
||||||
example.com. 86400 IN NS new-ns.example.com.
|
example.com. 86369 IN NS new-ns.example.com.
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
new-ns.example.com. 86369 IN A 172.16.0.1
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
SCENARIO_END
|
SCENARIO_END
|
||||||
|
|
|
||||||
227
testdata/iter_prefetch_childns.rpl
vendored
Normal file
227
testdata/iter_prefetch_childns.rpl
vendored
Normal file
|
|
@ -0,0 +1,227 @@
|
||||||
|
; config options
|
||||||
|
server:
|
||||||
|
target-fetch-policy: "0 0 0 0 0"
|
||||||
|
prefetch: "yes"
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "."
|
||||||
|
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||||
|
CONFIG_END
|
||||||
|
|
||||||
|
SCENARIO_BEGIN Test resolver prefetch from child nameserver
|
||||||
|
; child NS record has longer TTL than A record and is thus valid for prefetch.
|
||||||
|
|
||||||
|
; K.ROOT-SERVERS.NET.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 193.0.14.129
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
. IN NS K.ROOT-SERVERS.NET.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; a.gtld-servers.net.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 192.5.6.30
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; ns.example.com.
|
||||||
|
RANGE_BEGIN 0 40
|
||||||
|
ADDRESS 1.2.3.4
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. 1800 IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 3600 IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. 3600 IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; ns.example.com.
|
||||||
|
RANGE_BEGIN 50 100
|
||||||
|
ADDRESS 1.2.3.4
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. 1800 IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 3600 IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. 3600 IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
STEP 1 QUERY
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; recursion happens here.
|
||||||
|
STEP 10 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all ttl
|
||||||
|
REPLY QR RD RA NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. 1800 IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 3600 IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. 3600 IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; after 900 secs still the cached answer
|
||||||
|
STEP 20 TIME_PASSES ELAPSE 900
|
||||||
|
|
||||||
|
STEP 30 QUERY
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
ENTRY_END
|
||||||
|
; recursion happens here.
|
||||||
|
STEP 40 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all ttl
|
||||||
|
REPLY QR RD RA NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. 900 IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 2700 IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. 2700 IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; after 720 we are 180 seconds before the expiry
|
||||||
|
; (the authority changes behind the scenes to detect new lookup)
|
||||||
|
STEP 50 TIME_PASSES ELAPSE 720
|
||||||
|
|
||||||
|
STEP 60 QUERY
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
ENTRY_END
|
||||||
|
; recursion happens here.
|
||||||
|
STEP 70 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all ttl
|
||||||
|
REPLY QR RD RA NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. 180 IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. 1980 IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. 1980 IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
STEP 80 TRAFFIC
|
||||||
|
; let traffic flow for prefetch to happen
|
||||||
|
|
||||||
|
; above a cache reply with 10% of the original TTL
|
||||||
|
; but the actual cache is changed, try to get that
|
||||||
|
STEP 120 QUERY
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
ENTRY_END
|
||||||
|
; recursion happens here.
|
||||||
|
STEP 130 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all ttl
|
||||||
|
REPLY QR RD RA NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. 1800 IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
; The NS rrset (from the child-side NS) is not updated but keeps counting down
|
||||||
|
example.com. 1980 IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. 1980 IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
SCENARIO_END
|
||||||
17
testdata/iter_prefetch_ns.rpl
vendored
17
testdata/iter_prefetch_ns.rpl
vendored
|
|
@ -26,11 +26,11 @@ K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH opcode qtype qname
|
MATCH opcode subdomain
|
||||||
ADJUST copy_id
|
ADJUST copy_id copy_query
|
||||||
REPLY QR NOERROR
|
REPLY QR NOERROR
|
||||||
SECTION QUESTION
|
SECTION QUESTION
|
||||||
www.example.com. IN A
|
example.com. IN A
|
||||||
SECTION AUTHORITY
|
SECTION AUTHORITY
|
||||||
com. IN NS a.gtld-servers.net.
|
com. IN NS a.gtld-servers.net.
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
|
|
@ -273,6 +273,8 @@ SECTION QUESTION
|
||||||
example.com. IN NS
|
example.com. IN NS
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
; recursion happens here.
|
; recursion happens here.
|
||||||
|
|
||||||
|
; because the prefetch+current makes old-NS expired, new delegation is picked up
|
||||||
STEP 91 CHECK_ANSWER
|
STEP 91 CHECK_ANSWER
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
MATCH all ttl
|
MATCH all ttl
|
||||||
|
|
@ -280,19 +282,14 @@ REPLY QR RD RA NOERROR
|
||||||
SECTION QUESTION
|
SECTION QUESTION
|
||||||
example.com. IN NS
|
example.com. IN NS
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
; this record is unchanged even though it now points to the
|
example.com. 3600 IN NS ns.example.com.
|
||||||
; new registrant. Thus it keeps counting down.
|
|
||||||
example.com. 360 IN NS ns.example.com.
|
|
||||||
SECTION AUTHORITY
|
SECTION AUTHORITY
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
ns.example.com. 3600 IN A 8.8.8.8
|
ns.example.com. 3600 IN A 8.8.8.8
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
||||||
|
|
||||||
; after 360 + 2000 we are after the change to new owner.
|
|
||||||
STEP 100 TIME_PASSES ELAPSE 2360
|
STEP 100 TIME_PASSES ELAPSE 2360
|
||||||
|
|
||||||
; the NS record should have timed out.
|
|
||||||
STEP 120 QUERY
|
STEP 120 QUERY
|
||||||
ENTRY_BEGIN
|
ENTRY_BEGIN
|
||||||
REPLY RD
|
REPLY RD
|
||||||
|
|
@ -309,7 +306,7 @@ www.example.com. IN A
|
||||||
SECTION ANSWER
|
SECTION ANSWER
|
||||||
www.example.com. 3600 IN A 88.88.88.88
|
www.example.com. 3600 IN A 88.88.88.88
|
||||||
SECTION AUTHORITY
|
SECTION AUTHORITY
|
||||||
example.com. 3600 IN NS ns.example.com.
|
example.com. 1240 IN NS ns.example.com.
|
||||||
SECTION ADDITIONAL
|
SECTION ADDITIONAL
|
||||||
ns.example.com. 1240 IN A 8.8.8.8
|
ns.example.com. 1240 IN A 8.8.8.8
|
||||||
ENTRY_END
|
ENTRY_END
|
||||||
|
|
|
||||||
|
|
@ -1977,15 +1977,17 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
|
|
||||||
/* store results in cache */
|
/* store results in cache */
|
||||||
if(qstate->query_flags&BIT_RD) {
|
if(qstate->query_flags&BIT_RD) {
|
||||||
|
/* if secure, this will override cache anyway, no need
|
||||||
|
* to check if from parentNS */
|
||||||
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
||||||
vq->orig_msg->rep, 0, qstate->prefetch_leeway, NULL)) {
|
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL)) {
|
||||||
log_err("out of memory caching validator results");
|
log_err("out of memory caching validator results");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* for a referral, store the verified RRsets */
|
/* for a referral, store the verified RRsets */
|
||||||
/* and this does not get prefetched, so no leeway */
|
/* and this does not get prefetched, so no leeway */
|
||||||
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
||||||
vq->orig_msg->rep, 1, 0, NULL)) {
|
vq->orig_msg->rep, 1, 0, 0, NULL)) {
|
||||||
log_err("out of memory caching validator results");
|
log_err("out of memory caching validator results");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue