mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-18 23:06:06 -05:00
A few changes for TTL processing:
- Cached messages that reach 0 TTL are considered expired. This prevents Unbound itself from issuing replies with TTL 0 and possibly causing a thundering herd at the last second. Upstream replies of TTL 0 still get the usual pass-through but they are not considered for caching from Unbound or any of its caching modules. - 'serve-expired-reply-ttl' is changed and is now capped by the original TTL value of the record to try and make some sense when replying with expired records. - TTL decoding was updated to adhere to RFC8767 section 4 where a set high-order bit means the value is positive instead of 0.
This commit is contained in:
parent
d521135f66
commit
73e408f1d0
43 changed files with 619 additions and 546 deletions
|
|
@ -401,12 +401,9 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
|||
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
|
||||
LDNS_RCODE_YXDOMAIN)
|
||||
return 0;
|
||||
/* We don't store the reply if its TTL is 0 unless serve-expired is
|
||||
* enabled. Such a reply won't be reusable and simply be a waste for
|
||||
* the backend. It's also compatible with the default behavior of
|
||||
* dns_cache_store_msg(). */
|
||||
if(qstate->return_msg->rep->ttl == 0 &&
|
||||
!qstate->env->cfg->serve_expired)
|
||||
/* We don't store the reply if its TTL is 0. This is probably coming
|
||||
* from upstream and it is not meant to be stored. */
|
||||
if(qstate->return_msg->rep->ttl == 0)
|
||||
return 0;
|
||||
|
||||
/* The EDE is added to the out-list so it is encoded in the cached message */
|
||||
|
|
@ -421,7 +418,7 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
|||
qstate->return_msg->rep);
|
||||
if(!reply_info_answer_encode(&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep, 0, qstate->query_flags,
|
||||
buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0, 1))
|
||||
buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0))
|
||||
return 0;
|
||||
|
||||
/* TTLs in the return_msg are relative to time(0) so we have to
|
||||
|
|
@ -460,7 +457,7 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
|||
* - serve_expired needs to be set
|
||||
* - if SERVE_EXPIRED_TTL is set make sure that the record is not older
|
||||
* than that. */
|
||||
if((time_t)expiry < *qstate->env->now &&
|
||||
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now) &&
|
||||
(!qstate->env->cfg->serve_expired ||
|
||||
(SERVE_EXPIRED_TTL &&
|
||||
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
|
||||
|
|
@ -472,7 +469,8 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
|||
/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is
|
||||
* negative, set the TTL to 0. */
|
||||
static void
|
||||
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
|
||||
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract,
|
||||
time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
|
|
@ -484,13 +482,13 @@ packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
|
|||
data->rr_ttl[i] -= subtract;
|
||||
else data->rr_ttl[i] = 0;
|
||||
}
|
||||
data->ttl_add = (subtract < data->ttl_add) ? (data->ttl_add - subtract) : 0;
|
||||
data->ttl_add = timestamp;
|
||||
}
|
||||
|
||||
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
|
||||
* negative, set the TTLs to 0. */
|
||||
static void
|
||||
adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
|
||||
adjust_msg_ttl(struct dns_msg* msg, time_t adjust, time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
if(adjust >= 0 && msg->rep->ttl > adjust)
|
||||
|
|
@ -502,13 +500,13 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
|
|||
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
|
||||
rep->rrsets[i]->entry.data, adjust);
|
||||
rep->rrsets[i]->entry.data, adjust, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the TTL of the given RRset to fixed value. */
|
||||
static void
|
||||
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
|
||||
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl, time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
|
|
@ -516,12 +514,12 @@ packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
|
|||
for(i=0; i<total; i++) {
|
||||
data->rr_ttl[i] = ttl;
|
||||
}
|
||||
data->ttl_add = 0;
|
||||
data->ttl_add = timestamp;
|
||||
}
|
||||
|
||||
/* Set the TTL of a DNS message and its RRs by to a fixed value. */
|
||||
static void
|
||||
set_msg_ttl(struct dns_msg* msg, time_t ttl)
|
||||
set_msg_ttl(struct dns_msg* msg, time_t ttl, time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
msg->rep->ttl = ttl;
|
||||
|
|
@ -530,14 +528,14 @@ set_msg_ttl(struct dns_msg* msg, time_t ttl)
|
|||
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
packed_rrset_ttl_set((struct packed_rrset_data*)msg->
|
||||
rep->rrsets[i]->entry.data, ttl);
|
||||
rep->rrsets[i]->entry.data, ttl, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/** convert dns message in buffer to return_msg */
|
||||
static int
|
||||
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
||||
int* msg_expired)
|
||||
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
|
||||
{
|
||||
struct msg_parse* prs;
|
||||
struct edns_data edns;
|
||||
|
|
@ -554,6 +552,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
|||
×tamp, sizeof(timestamp));
|
||||
expiry = be64toh(expiry);
|
||||
timestamp = be64toh(timestamp);
|
||||
log_assert(timestamp <= expiry);
|
||||
*msg_expiry = (time_t)expiry;
|
||||
*msg_timestamp = (time_t)timestamp;
|
||||
|
||||
/* parse DNS packet */
|
||||
regional_free_all(qstate->env->scratch);
|
||||
|
|
@ -605,11 +606,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
|||
return 1; /* message from the future (clock skew?) */
|
||||
}
|
||||
adjust = *qstate->env->now - (time_t)timestamp;
|
||||
if(qstate->return_msg->rep->ttl < adjust) {
|
||||
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now)) {
|
||||
verbose(VERB_ALGO, "cachedb msg expired");
|
||||
*msg_expired = 1;
|
||||
/* If serve-expired is enabled, we still use an expired message
|
||||
* setting the TTL to 0. */
|
||||
if(!qstate->env->cfg->serve_expired ||
|
||||
(FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
|
||||
!= LDNS_RCODE_NOERROR &&
|
||||
|
|
@ -618,23 +617,21 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
|||
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
|
||||
!= LDNS_RCODE_YXDOMAIN))
|
||||
return 0; /* message expired */
|
||||
else
|
||||
adjust = -1;
|
||||
/* If serve-expired is enabled, we still use an expired message.
|
||||
* Set the TTL to 0 now and it will be handled specially later
|
||||
* when we need to store it internally. */
|
||||
adjust = -1;
|
||||
}
|
||||
adjust_msg_ttl(qstate->return_msg, adjust, timestamp);
|
||||
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
|
||||
adjust_msg_ttl(qstate->return_msg, adjust);
|
||||
if(qstate->env->cfg->aggressive_nsec) {
|
||||
limit_nsec_ttl(qstate->return_msg);
|
||||
}
|
||||
|
||||
/* Similar to the unbound worker, if serve-expired is enabled and
|
||||
* the msg would be considered to be expired, mark the state so a
|
||||
* refetch will be scheduled. The comparison between 'expiry' and
|
||||
* 'now' should be redundant given how these values were calculated,
|
||||
* but we check it just in case as does good_expiry_and_qinfo(). */
|
||||
if(qstate->env->cfg->serve_expired &&
|
||||
!qstate->env->cfg->serve_expired_client_timeout &&
|
||||
(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
|
||||
* refetch will be scheduled. */
|
||||
if(*msg_expired && !qstate->env->cfg->serve_expired_client_timeout) {
|
||||
qstate->need_refetch = 1;
|
||||
}
|
||||
|
||||
|
|
@ -647,7 +644,7 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
|||
*/
|
||||
static int
|
||||
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
|
||||
int* msg_expired)
|
||||
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
|
||||
{
|
||||
char key[(CACHEDB_HASHSIZE/8)*2+1];
|
||||
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
|
||||
|
|
@ -664,7 +661,8 @@ cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
|
|||
}
|
||||
|
||||
/* parse dns message into return_msg */
|
||||
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired) ) {
|
||||
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired,
|
||||
msg_timestamp, msg_expiry) ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -736,20 +734,24 @@ cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
|
|||
* Store query into the internal cache of unbound.
|
||||
*/
|
||||
static void
|
||||
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
|
||||
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired,
|
||||
time_t msg_timestamp, time_t msg_expiry)
|
||||
{
|
||||
uint32_t store_flags = qstate->query_flags;
|
||||
int serve_expired = qstate->env->cfg->serve_expired;
|
||||
|
||||
if(qstate->env->cfg->serve_expired)
|
||||
store_flags |= DNSCACHE_STORE_ZEROTTL;
|
||||
if(!qstate->return_msg)
|
||||
return;
|
||||
if(serve_expired && msg_expired) {
|
||||
/* Set TTLs to a value such that value + *env->now is
|
||||
* going to be now-3 seconds. Making it expired
|
||||
* in the cache. */
|
||||
set_msg_ttl(qstate->return_msg, (time_t)-3);
|
||||
time_t original_ttl = msg_expiry - msg_timestamp;
|
||||
store_flags |= DNSCACHE_STORE_EXPIRED_MSG_CACHEDB;
|
||||
/* Pass the original TTL of the expired message and signal with
|
||||
* the DNSCACHE_STORE_EXPIRED_MSG_CACHEDB flag that
|
||||
* dns_cache_store_msg() needs to set absolute expired TTLs
|
||||
* based on the original message TTL.
|
||||
* Results as expired message in the cache */
|
||||
set_msg_ttl(qstate->return_msg, original_ttl, 0);
|
||||
verbose(VERB_ALGO, "cachedb expired msg set to be expired now "
|
||||
"(original ttl: %d)", (int)original_ttl);
|
||||
/* The expired entry does not get checked by the validator
|
||||
* and we need a validation value for it. */
|
||||
if(qstate->env->cfg->cachedb_check_when_serve_expired)
|
||||
|
|
@ -767,12 +769,14 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
|
|||
* of cache. */
|
||||
return;
|
||||
}
|
||||
/* set TTLs to zero again */
|
||||
adjust_msg_ttl(qstate->return_msg, -1);
|
||||
/* Send serve expired responses based on the cachedb
|
||||
* returned message, that was just stored in the cache.
|
||||
* It can then continue to work on this query. */
|
||||
mesh_respond_serve_expired(qstate->mesh_info);
|
||||
/* set TTLs as expired for this return_msg in case it is used
|
||||
* later on */
|
||||
set_msg_ttl(qstate->return_msg,
|
||||
EXPIRED_REPLY_TTL_CALC(msg_expiry, msg_timestamp), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -790,6 +794,7 @@ cachedb_handle_query(struct module_qstate* qstate,
|
|||
struct cachedb_env* ie, int id)
|
||||
{
|
||||
int msg_expired = 0;
|
||||
time_t msg_timestamp, msg_expiry;
|
||||
qstate->is_cachedb_answer = 0;
|
||||
/* check if we are enabled, and skip if so */
|
||||
if(!ie->enabled) {
|
||||
|
|
@ -824,13 +829,15 @@ cachedb_handle_query(struct module_qstate* qstate,
|
|||
}
|
||||
|
||||
/* ask backend cache to see if we have data */
|
||||
if(cachedb_extcache_lookup(qstate, ie, &msg_expired)) {
|
||||
if(cachedb_extcache_lookup(qstate, ie, &msg_expired, &msg_timestamp,
|
||||
&msg_expiry)) {
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg(ie->backend->name,
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
/* store this result in internal cache */
|
||||
cachedb_intcache_store(qstate, msg_expired);
|
||||
cachedb_intcache_store(qstate,
|
||||
msg_expired, msg_timestamp, msg_expiry);
|
||||
/* In case we have expired data but there is a client timer for expired
|
||||
* answers, pass execution to next module in order to try updating the
|
||||
* data first.
|
||||
|
|
@ -850,6 +857,8 @@ cachedb_handle_query(struct module_qstate* qstate,
|
|||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
/* No 0TTL answers escaping from external cache. */
|
||||
log_assert(qstate->return_msg->rep->ttl > 0);
|
||||
qstate->is_cachedb_answer = 1;
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
|||
}
|
||||
if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
|
||||
repinfo->c->buffer, 0, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure, 1)) {
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
|
|
@ -746,7 +746,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
|||
*partial_repp = NULL; /* avoid accidental further pass */
|
||||
|
||||
/* Check TTL */
|
||||
if(rep->ttl < timenow) {
|
||||
if(TTL_IS_EXPIRED(rep->ttl, timenow)) {
|
||||
/* Check if we need to serve expired now */
|
||||
if(worker->env.cfg->serve_expired &&
|
||||
/* if serve-expired-client-timeout is set, serve
|
||||
|
|
@ -891,7 +891,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
|||
if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO),
|
||||
*is_secure_answer, 1)) {
|
||||
*is_secure_answer)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo,
|
||||
NULL, NULL, LDNS_RCODE_SERVFAIL, edns, repinfo,
|
||||
worker->scratchpad, worker->env.now_tv))
|
||||
|
|
@ -1929,11 +1929,11 @@ lookup_cache:
|
|||
if((worker->env.cfg->prefetch &&
|
||||
rep->prefetch_ttl <= *worker->env.now) ||
|
||||
(worker->env.cfg->serve_expired &&
|
||||
rep->ttl < *worker->env.now &&
|
||||
TTL_IS_EXPIRED(rep->ttl, *worker->env.now) &&
|
||||
!(*worker->env.now < rep->serve_expired_norec_ttl))) {
|
||||
time_t leeway = rep->ttl - *worker->env.now;
|
||||
if(rep->ttl < *worker->env.now)
|
||||
leeway = 0;
|
||||
time_t leeway =
|
||||
TTL_IS_EXPIRED(rep->ttl, *worker->env.now)
|
||||
? 0 : rep->ttl - *worker->env.now;
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
reply_and_prefetch(worker, lookup_qinfo,
|
||||
|
|
|
|||
|
|
@ -752,6 +752,7 @@ server:
|
|||
# serve-expired-ttl-reset: no
|
||||
#
|
||||
# TTL value to use when replying with expired data.
|
||||
# Capped by the original TTL of the record.
|
||||
# serve-expired-reply-ttl: 30
|
||||
#
|
||||
# Time in milliseconds before replying to the client with expired data.
|
||||
|
|
|
|||
|
|
@ -2306,6 +2306,12 @@ These options are part of the **server:** clause.
|
|||
:ref:`serve-expired-client-timeout<unbound.conf.serve-expired-client-timeout>`
|
||||
is also used then it is RECOMMENDED to use 30 as the value (:rfc:`8767`).
|
||||
|
||||
This value is capped by the original TTL of the record.
|
||||
This means that records with higher original TTL than this value will use
|
||||
this value for expired replies.
|
||||
Records with lower original TTL than this value will use their original TTL
|
||||
for expired replies.
|
||||
|
||||
Default: 30
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ get_rrset_ttl(struct ub_packed_rrset_key* k)
|
|||
/** Copy rrset into region from domain-datanode and packet rrset */
|
||||
static struct ub_packed_rrset_key*
|
||||
auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
|
||||
struct auth_rrset* rrset, struct regional* region, time_t adjust)
|
||||
struct auth_rrset* rrset, struct regional* region)
|
||||
{
|
||||
struct ub_packed_rrset_key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
|
@ -182,7 +182,7 @@ auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
|
|||
key.rk.type = htons(rrset->type);
|
||||
key.rk.rrset_class = htons(z->dclass);
|
||||
key.entry.hash = rrset_key_hash(&key.rk);
|
||||
return packed_rrset_copy_region(&key, region, adjust);
|
||||
return packed_rrset_copy_region(&key, region, 0);
|
||||
}
|
||||
|
||||
/** fix up msg->rep TTL and prefetch ttl */
|
||||
|
|
@ -236,7 +236,7 @@ msg_add_rrset_an(struct auth_zone* z, struct regional* region,
|
|||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->an_numrrsets++;
|
||||
|
|
@ -260,7 +260,7 @@ msg_add_rrset_ns(struct auth_zone* z, struct regional* region,
|
|||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->ns_numrrsets++;
|
||||
|
|
@ -283,7 +283,7 @@ msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
|
|||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->ar_numrrsets++;
|
||||
|
|
@ -3530,7 +3530,7 @@ auth_answer_encode(struct query_info* qinfo, struct module_env* env,
|
|||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2),
|
||||
buf, 0, 0, temp, udpsize, edns,
|
||||
(int)(edns->bits&EDNS_DO), 0, 0)) {
|
||||
(int)(edns->bits&EDNS_DO), 0)) {
|
||||
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
|
||||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
|
|
|
|||
86
services/cache/dns.c
vendored
86
services/cache/dns.c
vendored
|
|
@ -60,10 +60,10 @@
|
|||
* @param rep: contains list of rrsets to store.
|
||||
* @param now: current time.
|
||||
* @param leeway: during prefetch how much leeway to update TTLs.
|
||||
* This makes rrsets (other than type NS) timeout sooner so they get
|
||||
* updated with a new full TTL.
|
||||
* Type NS does not get this, because it must not be refreshed from the
|
||||
* child domain, but keep counting down properly.
|
||||
* This makes rrsets expire sooner so they get updated with a new full
|
||||
* TTL.
|
||||
* Child side type NS does get this but TTL checks are done using the time
|
||||
* the query was created rather than the time the answer was received.
|
||||
* @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
|
||||
|
|
@ -100,11 +100,20 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
|||
rep->ref[i].id != rep->ref[i].key->id)
|
||||
ck = NULL;
|
||||
else ck = packed_rrset_copy_region(
|
||||
rep->ref[i].key, region, now);
|
||||
rep->ref[i].key, region,
|
||||
((ntohs(rep->ref[i].key->rk.type)==
|
||||
LDNS_RR_TYPE_NS && !pside)?qstarttime:now));
|
||||
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||
if(ck) {
|
||||
/* use cached copy if memory allows */
|
||||
qrep->rrsets[i] = ck;
|
||||
ttl = ((struct packed_rrset_data*)
|
||||
ck->entry.data)->ttl;
|
||||
if(ttl < qrep->ttl) {
|
||||
qrep->ttl = ttl;
|
||||
qrep->prefetch_ttl = PREFETCH_TTL_CALC(qrep->ttl);
|
||||
qrep->serve_expired_ttl = qrep->ttl + SERVE_EXPIRED_TTL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* no break: also copy key item */
|
||||
|
|
@ -169,10 +178,12 @@ 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
|
||||
* unnecessary, because the cache gets locked per rrset. */
|
||||
reply_info_set_ttls(rep, *env->now);
|
||||
if((flags & DNSCACHE_STORE_EXPIRED_MSG_CACHEDB)) {
|
||||
reply_info_absolute_ttls(rep, *env->now, *env->now - ttl);
|
||||
} else reply_info_set_ttls(rep, *env->now);
|
||||
store_rrsets(env, rep, *env->now, leeway, pside, qrep, region,
|
||||
qstarttime);
|
||||
if(ttl == 0 && !(flags & DNSCACHE_STORE_ZEROTTL)) {
|
||||
if(ttl == 0) {
|
||||
/* we do not store the message, but we did store the RRs,
|
||||
* which could be useful for delegation information */
|
||||
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
|
||||
|
|
@ -272,8 +283,10 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
|
|||
{
|
||||
if((msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
packed_rrset_copy_region(rrset, region, now))) {
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
msg->rep->ar_numrrsets++;
|
||||
msg->rep->rrset_count++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -456,8 +469,10 @@ find_add_ds(struct module_env* env, struct regional* region,
|
|||
/* add it to auth section. This is the second rrset. */
|
||||
if((msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
packed_rrset_copy_region(rrset, region, now))) {
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
msg->rep->ns_numrrsets++;
|
||||
msg->rep->rrset_count++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
}
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
}
|
||||
|
|
@ -487,6 +502,8 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
|||
return NULL; /* integer overflow protection */
|
||||
msg->rep->flags = BIT_QR; /* with QR, no AA */
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->ttl = MAX_TTL; /* will be updated (brought down) while we add
|
||||
* rrsets to the message */
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->rrsets = (struct ub_packed_rrset_key**)
|
||||
regional_alloc(region,
|
||||
|
|
@ -497,24 +514,28 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
|||
}
|
||||
|
||||
int
|
||||
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, time_t now)
|
||||
{
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
packed_rrset_copy_region(rrset, region, now)))
|
||||
return 0;
|
||||
msg->rep->ns_numrrsets++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
|
||||
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, time_t now)
|
||||
{
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
packed_rrset_copy_region(rrset, region, now)))
|
||||
return 0;
|
||||
msg->rep->an_numrrsets++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -585,6 +606,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
|
|||
sizeof(struct reply_info) - sizeof(struct rrset_ref));
|
||||
if(!msg->rep)
|
||||
return NULL;
|
||||
msg->rep->ttl = MAX_TTL;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->reason_bogus_str = NULL;
|
||||
if(num > RR_COUNT_MAX)
|
||||
|
|
@ -606,13 +628,13 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
|||
size_t i;
|
||||
int is_expired = 0;
|
||||
time_t now_control = now;
|
||||
if(now > r->ttl) {
|
||||
if(TTL_IS_EXPIRED(r->ttl, now)) {
|
||||
/* Check if we are allowed to serve expired */
|
||||
if(!allow_expired || !reply_info_can_answer_expired(r, now))
|
||||
return NULL;
|
||||
/* Change the current time so we can pass the below TTL checks when
|
||||
* serving expired data. */
|
||||
now_control = r->ttl - env->cfg->serve_expired_reply_ttl;
|
||||
/* Change the current time so we can pass the below TTL checks
|
||||
* when serving expired data. */
|
||||
now_control = 0;
|
||||
is_expired = 1;
|
||||
}
|
||||
|
||||
|
|
@ -620,15 +642,6 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
|||
if(!msg) return NULL;
|
||||
msg->rep->flags = r->flags;
|
||||
msg->rep->qdcount = r->qdcount;
|
||||
msg->rep->ttl = is_expired
|
||||
?SERVE_EXPIRED_REPLY_TTL
|
||||
:r->ttl - now;
|
||||
if(r->prefetch_ttl > now)
|
||||
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
|
||||
else
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
msg->rep->serve_expired_norec_ttl = 0;
|
||||
msg->rep->security = r->security;
|
||||
msg->rep->an_numrrsets = r->an_numrrsets;
|
||||
msg->rep->ns_numrrsets = r->ns_numrrsets;
|
||||
|
|
@ -656,13 +669,30 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
|||
return NULL;
|
||||
}
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
struct packed_rrset_data* d;
|
||||
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
|
||||
region, now);
|
||||
if(!msg->rep->rrsets[i]) {
|
||||
rrset_array_unlock(r->ref, r->rrset_count);
|
||||
return NULL;
|
||||
}
|
||||
d = msg->rep->rrsets[i]->entry.data;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
}
|
||||
if(msg->rep->rrset_count < 1) {
|
||||
msg->rep->ttl = is_expired
|
||||
?SERVE_EXPIRED_REPLY_TTL
|
||||
:r->ttl - now;
|
||||
if(r->prefetch_ttl > now)
|
||||
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
|
||||
else
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
} else {
|
||||
/* msg->rep->ttl has been updated through the RRSets above */
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
}
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
msg->rep->serve_expired_norec_ttl = 0;
|
||||
if(env)
|
||||
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
|
||||
r->rrset_count);
|
||||
|
|
@ -701,7 +731,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
|||
struct dns_msg* msg;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
rrset->entry.data;
|
||||
if(now > d->ttl)
|
||||
if(TTL_IS_EXPIRED(d->ttl, now))
|
||||
return NULL;
|
||||
msg = gen_dns_msg(region, q, 1); /* only the CNAME (or other) RRset */
|
||||
if(!msg)
|
||||
|
|
@ -736,7 +766,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
|||
rrset->entry.data;
|
||||
uint8_t* newname, *dtarg = NULL;
|
||||
size_t newlen, dtarglen;
|
||||
if(now > d->ttl)
|
||||
if(TTL_IS_EXPIRED(d->ttl, now))
|
||||
return NULL;
|
||||
/* only allow validated (with DNSSEC) DNAMEs used from cache
|
||||
* for insecure DNAMEs, query again. */
|
||||
|
|
@ -844,6 +874,8 @@ fill_any(struct module_env* env,
|
|||
/* set NOTIMPL for RFC 8482 */
|
||||
msg->rep->flags |= LDNS_RCODE_NOTIMPL;
|
||||
msg->rep->security = sec_status_indeterminate;
|
||||
msg->rep->ttl = 1; /* empty NOTIMPL response will never be
|
||||
* updated with rrsets, set TTL to 1 */
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
|
@ -1069,7 +1101,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
|||
msgqinf->qclass, flags, 0, 1);
|
||||
if(e) {
|
||||
struct reply_info* cached = e->entry.data;
|
||||
if(cached->ttl < *env->now
|
||||
if(TTL_IS_EXPIRED(cached->ttl, *env->now)
|
||||
&& reply_info_could_use_expired(cached, *env->now)
|
||||
/* If we are validating make sure only
|
||||
* validating modules can update such messages.
|
||||
|
|
|
|||
2
services/cache/dns.h
vendored
2
services/cache/dns.h
vendored
|
|
@ -53,7 +53,7 @@ struct delegpt;
|
|||
* Must be an unsigned 32-bit value larger than 0xffff */
|
||||
|
||||
/** Allow caching a DNS message with a zero TTL. */
|
||||
#define DNSCACHE_STORE_ZEROTTL 0x100000
|
||||
#define DNSCACHE_STORE_EXPIRED_MSG_CACHEDB 0x100000
|
||||
|
||||
/**
|
||||
* Region allocated message reply
|
||||
|
|
|
|||
19
services/cache/rrset.c
vendored
19
services/cache/rrset.c
vendored
|
|
@ -131,7 +131,7 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
|
|||
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
|
||||
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
|
||||
/* o if new data is expired, cached data is better */
|
||||
if( newd->ttl < timenow && timenow <= cached->ttl)
|
||||
if( TTL_IS_EXPIRED(newd->ttl, timenow) && !TTL_IS_EXPIRED(cached->ttl, timenow))
|
||||
return 0;
|
||||
/* o store if rrset has been validated
|
||||
* everything better than bogus data
|
||||
|
|
@ -146,13 +146,13 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
|
|||
if( newd->trust > cached->trust ) {
|
||||
/* if the cached rrset is bogus, and new is equal,
|
||||
* do not update the TTL - let it expire. */
|
||||
if(equal && cached->ttl >= timenow &&
|
||||
if(equal && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
|
||||
cached->security == sec_status_bogus)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
/* o item in cache has expired */
|
||||
if( cached->ttl < timenow )
|
||||
if( TTL_IS_EXPIRED(cached->ttl, timenow) )
|
||||
return 1;
|
||||
/* o same trust, but different in data - insert it */
|
||||
if( newd->trust == cached->trust && !equal ) {
|
||||
|
|
@ -300,7 +300,7 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
|
|||
/* check TTL */
|
||||
struct packed_rrset_data* data =
|
||||
(struct packed_rrset_data*)e->data;
|
||||
if(timenow > data->ttl) {
|
||||
if(TTL_IS_EXPIRED(data->ttl, timenow)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -310,17 +310,18 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
rrset_array_lock(struct rrset_ref* ref, size_t count, time_t timenow)
|
||||
{
|
||||
size_t i;
|
||||
struct packed_rrset_data* d;
|
||||
for(i=0; i<count; i++) {
|
||||
if(i>0 && ref[i].key == ref[i-1].key)
|
||||
continue; /* only lock items once */
|
||||
lock_rw_rdlock(&ref[i].key->entry.lock);
|
||||
if(ref[i].id != ref[i].key->id || timenow >
|
||||
((struct packed_rrset_data*)(ref[i].key->entry.data))
|
||||
->ttl) {
|
||||
d = ref[i].key->entry.data;
|
||||
if(ref[i].id != ref[i].key->id ||
|
||||
TTL_IS_EXPIRED(d->ttl, timenow)) {
|
||||
/* failure! rollback our readlocks */
|
||||
rrset_array_unlock(ref, i+1);
|
||||
return 0;
|
||||
|
|
@ -511,7 +512,7 @@ rrset_cache_expired_above(struct rrset_cache* r, uint8_t** qname, size_t*
|
|||
*qnamelen, searchtype, qclass, 0, 0, 0))) {
|
||||
struct packed_rrset_data* data =
|
||||
(struct packed_rrset_data*)rrset->entry.data;
|
||||
if(now > data->ttl) {
|
||||
if(TTL_IS_EXPIRED(data->ttl, now)) {
|
||||
/* it is expired, this is not wanted */
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass);
|
||||
|
|
|
|||
|
|
@ -1332,7 +1332,7 @@ local_encode(struct query_info* qinfo, struct module_env* env,
|
|||
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
|
||||
repinfo, temp, env->now_tv) || !reply_info_answer_encode(qinfo, &rep,
|
||||
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
|
||||
buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0, 0)) {
|
||||
buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
|
||||
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
|
||||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ mesh_serve_expired_lookup(struct module_qstate* qstate,
|
|||
|
||||
key = (struct msgreply_entry*)e->key;
|
||||
data = (struct reply_info*)e->data;
|
||||
if(data->ttl < timenow) *is_expired = 1;
|
||||
if(TTL_IS_EXPIRED(data->ttl, timenow)) *is_expired = 1;
|
||||
msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow,
|
||||
qstate->env->cfg->serve_expired, qstate->env->scratch);
|
||||
if(!msg)
|
||||
|
|
@ -1351,7 +1351,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
|
||||
r->qflags, r->buf, 0, 1,
|
||||
m->s.env->scratch, udp_size, &r->edns,
|
||||
(int)(r->edns.bits & EDNS_DO), secure, 0))
|
||||
(int)(r->edns.bits & EDNS_DO), secure))
|
||||
{
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
|
||||
|
|
@ -1539,7 +1539,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
|
||||
r->qflags, r_buffer, 0, 1, m->s.env->scratch,
|
||||
udp_size, &r->edns, (int)(r->edns.bits & EDNS_DO),
|
||||
secure, 0))
|
||||
secure))
|
||||
{
|
||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
|
||||
|
|
|
|||
|
|
@ -1807,7 +1807,7 @@ rpz_local_encode(struct module_env* env, struct query_info* qinfo,
|
|||
repinfo, temp, env->now_tv) ||
|
||||
!reply_info_answer_encode(qinfo, &rep,
|
||||
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
|
||||
buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0, 0)) {
|
||||
buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
|
||||
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
|
||||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
|
|
|
|||
|
|
@ -1037,7 +1037,7 @@ static void edns_ede_encode_encodedecode(struct query_info* qinfo,
|
|||
/* encode */
|
||||
unit_assert(
|
||||
reply_info_answer_encode(qinfo, rep, 1, rep->flags, pkt,
|
||||
0, 0, region, 65535, edns, 0, 0, 0));
|
||||
0, 0, region, 65535, edns, 0, 0));
|
||||
/* buffer ready for reading; skip after the question section */
|
||||
sldns_buffer_skip(pkt, LDNS_HEADER_SIZE);
|
||||
(void)query_dname_len(pkt);
|
||||
|
|
|
|||
60
testdata/cachedb_expired.crpl
vendored
60
testdata/cachedb_expired.crpl
vendored
|
|
@ -5,7 +5,10 @@ server:
|
|||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-reply-ttl: 123
|
||||
module-config: "cachedb iterator"
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
cachedb:
|
||||
backend: "testframe"
|
||||
|
|
@ -82,7 +85,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -91,7 +94,8 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
; TTL lower than serve-expired-reply-ttl on purpose
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -111,7 +115,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Get another query in cache to make it expired.
|
||||
|
|
@ -130,46 +134,46 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 40 TIME_PASSES ELAPSE 20
|
||||
STEP 40 TIME_PASSES ELAPSE 200
|
||||
|
||||
; cache is expired, and cachedb is expired.
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 30 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; cache is expired, cachedb has no answer
|
||||
STEP 70 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 80 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 90 TRAFFIC
|
||||
|
|
@ -189,7 +193,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; flush the entry from cache
|
||||
|
|
@ -210,30 +214,30 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 150 TIME_PASSES ELAPSE 20
|
||||
STEP 150 TIME_PASSES ELAPSE 200
|
||||
; flush the entry from cache
|
||||
STEP 160 FLUSH_MESSAGE www.example.com. IN A
|
||||
|
||||
; cache has no answer, cachedb is expired
|
||||
STEP 170 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 180 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 190 TRAFFIC
|
||||
|
|
@ -254,7 +258,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; expire the entry in cache
|
||||
|
|
@ -275,30 +279,30 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 250 TIME_PASSES ELAPSE 20
|
||||
STEP 250 TIME_PASSES ELAPSE 200
|
||||
; expire the entry in cache
|
||||
STEP 260 EXPIRE_MESSAGE www.example.com. IN A
|
||||
|
||||
; cache is expired, cachedb is expired
|
||||
STEP 270 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 280 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 290 TRAFFIC
|
||||
|
|
@ -319,7 +323,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
57
testdata/cachedb_expired_client_timeout.crpl
vendored
57
testdata/cachedb_expired_client_timeout.crpl
vendored
|
|
@ -4,12 +4,14 @@ server:
|
|||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-reply-ttl: 30
|
||||
serve-expired-reply-ttl: 123
|
||||
; at least one second, so we can time skip past the timer in the
|
||||
; testbound script steps, but also reply within the time.
|
||||
serve-expired-client-timeout: 1200
|
||||
module-config: "cachedb iterator"
|
||||
discard-timeout: 3000
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
cachedb:
|
||||
backend: "testframe"
|
||||
|
|
@ -86,7 +88,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -95,7 +97,8 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
; TTL lower than serve-expired-reply-ttl on purpose
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -108,7 +111,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.6
|
||||
www.example.com. 200 IN A 1.2.3.6
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -117,7 +120,8 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.7
|
||||
; TTL lower than serve-expired-reply-ttl on purpose
|
||||
www2.example.com. 100 IN A 1.2.3.7
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -132,7 +136,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.8
|
||||
www.example.com. 200 IN A 1.2.3.8
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -141,7 +145,8 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.9
|
||||
; TTL lower than serve-expired-reply-ttl on purpose
|
||||
www2.example.com. 100 IN A 1.2.3.9
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -156,7 +161,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.10
|
||||
www.example.com. 200 IN A 1.2.3.10
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -165,7 +170,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.11
|
||||
www2.example.com. 100 IN A 1.2.3.11
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -188,7 +193,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Get another query in cache.
|
||||
|
|
@ -207,7 +212,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; www.example.com and www2.example.com are in cache, www2 in cachedb.
|
||||
|
|
@ -217,7 +222,7 @@ STEP 40 FLUSH_MESSAGE www2.example.com. IN A
|
|||
; response from cachedb for www2.
|
||||
|
||||
; make 2 seconds pass to decrement the TTL on the response,
|
||||
; the upstream TTL would be 10, cachedb 8.
|
||||
; the upstream TTL would be 200, cachedb 198.
|
||||
STEP 48 TIME_PASSES ELAPSE 2
|
||||
|
||||
STEP 50 QUERY
|
||||
|
|
@ -234,11 +239,11 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 8 IN A 1.2.3.5
|
||||
www2.example.com. 98 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; make both cache and cachedb expired
|
||||
STEP 70 TIME_PASSES ELAPSE 20
|
||||
STEP 70 TIME_PASSES ELAPSE 200
|
||||
|
||||
; www and www2 expired in cache, www2 expired in cachedb.
|
||||
; the query should now try to resolve and complete within the
|
||||
|
|
@ -258,11 +263,11 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.7
|
||||
www2.example.com. 100 IN A 1.2.3.7
|
||||
ENTRY_END
|
||||
|
||||
; expire the data again
|
||||
STEP 100 TIME_PASSES ELAPSE 20
|
||||
STEP 100 TIME_PASSES ELAPSE 200
|
||||
|
||||
; the query should now try to resolve, but the upstream is not
|
||||
; responsive for several testbound steps. When the timer expires,
|
||||
|
|
@ -271,7 +276,7 @@ STEP 100 TIME_PASSES ELAPSE 20
|
|||
; www2 expired in cache and www2 expired in cachedb.
|
||||
STEP 110 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
|
@ -281,26 +286,26 @@ STEP 112 TIME_PASSES ELAPSE 2
|
|||
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 30 IN A 1.2.3.7
|
||||
www2.example.com. 100 IN A 1.2.3.7
|
||||
ENTRY_END
|
||||
|
||||
; make traffic flow to resolve the query, server responds.
|
||||
STEP 130 TRAFFIC
|
||||
|
||||
; expire the data again
|
||||
STEP 140 TIME_PASSES ELAPSE 20
|
||||
STEP 140 TIME_PASSES ELAPSE 200
|
||||
|
||||
; The client query tries to resolve, but gets no immediate answer,
|
||||
; so the expired data is used. But the expired data is in cache and
|
||||
; the query is not in cachedb.
|
||||
STEP 150 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
|
@ -310,12 +315,12 @@ STEP 152 TIME_PASSES ELAPSE 2
|
|||
|
||||
STEP 160 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; make traffic flow to resolve the query, server responds.
|
||||
|
|
@ -337,7 +342,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.11
|
||||
www2.example.com. 100 IN A 1.2.3.11
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
47
testdata/cachedb_expired_reply_ttl.crpl
vendored
47
testdata/cachedb_expired_reply_ttl.crpl
vendored
|
|
@ -5,8 +5,10 @@ server:
|
|||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-reply-ttl: 30
|
||||
serve-expired-reply-ttl: 123
|
||||
module-config: "cachedb iterator"
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
cachedb:
|
||||
backend: "testframe"
|
||||
|
|
@ -83,7 +85,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -92,7 +94,8 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
; TTL lower than serve-expired-reply-ttl on purpose
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -115,7 +118,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Get another query in cache to make it expired.
|
||||
|
|
@ -134,28 +137,28 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 40 TIME_PASSES ELAPSE 20
|
||||
STEP 40 TIME_PASSES ELAPSE 200
|
||||
|
||||
; cache is expired, and cachedb is expired.
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 30 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; got an answer from upstream
|
||||
|
|
@ -173,25 +176,25 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; cache is expired, cachedb has no answer
|
||||
STEP 70 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 80 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 90 TRAFFIC
|
||||
|
|
@ -211,29 +214,29 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; make both cache and cachedb expired.
|
||||
STEP 120 TIME_PASSES ELAPSE 20
|
||||
STEP 120 TIME_PASSES ELAPSE 200
|
||||
STEP 130 FLUSH_MESSAGE www.example.com. IN A
|
||||
|
||||
; cache has no entry and cachedb is expired.
|
||||
STEP 140 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 150 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; the name is resolved
|
||||
|
|
@ -254,7 +257,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
46
testdata/cachedb_subnet_change.crpl
vendored
46
testdata/cachedb_subnet_change.crpl
vendored
|
|
@ -4,7 +4,7 @@ server:
|
|||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-reply-ttl: 30
|
||||
serve-expired-reply-ttl: 123
|
||||
|
||||
; disable the serve expired client timeout.
|
||||
serve-expired-client-timeout: 0
|
||||
|
|
@ -14,6 +14,8 @@ server:
|
|||
; store for edns subnet content for modules to the right of it.
|
||||
; this keeps subnet content out of cachedb as global content.
|
||||
module-config: "subnetcache cachedb iterator"
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
cachedb:
|
||||
backend: "testframe"
|
||||
|
|
@ -105,7 +107,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN CNAME www.initial.com.
|
||||
www.example.com. 200 IN CNAME www.initial.com.
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -118,7 +120,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN CNAME example.foo.com.
|
||||
www.example.com. 200 IN CNAME example.foo.com.
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -131,7 +133,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.initial.com. IN A
|
||||
SECTION ANSWER
|
||||
www.initial.com. 10 IN A 1.2.3.4
|
||||
www.initial.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -144,7 +146,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
example.foo.com. IN A
|
||||
SECTION ANSWER
|
||||
example.foo.com. 10 IN A 1.2.3.5
|
||||
example.foo.com. 200 IN A 1.2.3.5
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 127.0.0.1
|
||||
|
|
@ -166,7 +168,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN CNAME example.foo.com.
|
||||
www.example.com. 200 IN CNAME example.foo.com.
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -179,7 +181,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
example.foo.com. IN A
|
||||
SECTION ANSWER
|
||||
example.foo.com. 10 IN A 1.2.3.6
|
||||
example.foo.com. 200 IN A 1.2.3.6
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 127.0.0.1
|
||||
|
|
@ -211,19 +213,19 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN CNAME www.initial.com.
|
||||
www.initial.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN CNAME www.initial.com.
|
||||
www.initial.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; now valid in cache and valid in cachedb, without subnet.
|
||||
STEP 30 TIME_PASSES ELAPSE 20
|
||||
STEP 30 TIME_PASSES ELAPSE 200
|
||||
|
||||
; now the cache and cachedb have an expired entry.
|
||||
; the upstream is updated to CNAME to a subnet zone A record.
|
||||
|
||||
STEP 40 QUERY ADDRESS 127.0.0.1
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
|
@ -231,13 +233,13 @@ ENTRY_END
|
|||
; the expired answer, while the ECS answer is looked up.
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN CNAME www.initial.com.
|
||||
www.initial.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN CNAME www.initial.com.
|
||||
www.initial.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; check that subnet has the query in cache.
|
||||
|
|
@ -256,12 +258,12 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 8 IN CNAME example.foo.com.
|
||||
example.foo.com. 8 IN A 1.2.3.5
|
||||
www.example.com. 198 IN CNAME example.foo.com.
|
||||
example.foo.com. 198 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; everything is expired, cache, subnetcache and cachedb.
|
||||
STEP 80 TIME_PASSES ELAPSE 20
|
||||
STEP 80 TIME_PASSES ELAPSE 200
|
||||
|
||||
STEP 90 QUERY ADDRESS 127.0.0.1
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -277,8 +279,8 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN CNAME example.foo.com.
|
||||
example.foo.com. 10 IN A 1.2.3.6
|
||||
www.example.com. 200 IN CNAME example.foo.com.
|
||||
example.foo.com. 200 IN A 1.2.3.6
|
||||
ENTRY_END
|
||||
|
||||
; see the entry now in cache, from the subnetcache.
|
||||
|
|
@ -297,8 +299,8 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 8 IN CNAME example.foo.com.
|
||||
example.foo.com. 8 IN A 1.2.3.6
|
||||
www.example.com. 198 IN CNAME example.foo.com.
|
||||
example.foo.com. 198 IN A 1.2.3.6
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
60
testdata/cachedb_val_expired.crpl
vendored
60
testdata/cachedb_val_expired.crpl
vendored
|
|
@ -5,8 +5,11 @@ server:
|
|||
minimal-responses: yes
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-reply-ttl: 123
|
||||
;module-config: "subnetcache validator cachedb iterator"
|
||||
module-config: "validator cachedb iterator"
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
cachedb:
|
||||
backend: "testframe"
|
||||
|
|
@ -83,7 +86,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -92,7 +95,8 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
; TTL lower than serve-expired-reply-ttl on purpose
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -112,7 +116,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Get another query in cache to make it expired.
|
||||
|
|
@ -131,48 +135,48 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 10 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 40 TIME_PASSES ELAPSE 20
|
||||
STEP 40 TIME_PASSES ELAPSE 200
|
||||
|
||||
; cache is expired, and cachedb is expired.
|
||||
; The expired reply, from cachedb, needs a validation status,
|
||||
; because the validator module set that validation is needed.
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. 30 IN A 1.2.3.5
|
||||
www2.example.com. 100 IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
; cache is expired, cachedb has no answer
|
||||
STEP 70 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 80 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 90 TRAFFIC
|
||||
|
|
@ -192,7 +196,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; flush the entry from cache
|
||||
|
|
@ -213,30 +217,30 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 150 TIME_PASSES ELAPSE 20
|
||||
STEP 150 TIME_PASSES ELAPSE 200
|
||||
; flush the entry from cache
|
||||
STEP 160 FLUSH_MESSAGE www.example.com. IN A
|
||||
|
||||
; cache has no answer, cachedb is expired
|
||||
STEP 170 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 180 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 190 TRAFFIC
|
||||
|
|
@ -257,7 +261,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; expire the entry in cache
|
||||
|
|
@ -278,30 +282,30 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; it is now expired
|
||||
STEP 250 TIME_PASSES ELAPSE 20
|
||||
STEP 250 TIME_PASSES ELAPSE 200
|
||||
; expire the entry in cache
|
||||
STEP 260 EXPIRE_MESSAGE www.example.com. IN A
|
||||
|
||||
; cache is expired, cachedb is expired
|
||||
STEP 270 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 280 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 1.2.3.4
|
||||
www.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 290 TRAFFIC
|
||||
|
|
@ -322,7 +326,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 1.2.3.4
|
||||
www.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
21
testdata/fwd_0ttlservfail.rpl
vendored
21
testdata/fwd_0ttlservfail.rpl
vendored
|
|
@ -46,25 +46,10 @@ www.example.com. IN A
|
|||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
; enough to pass by the TTL of the servfail answer in cache
|
||||
; enough to expire the servfail answer in cache
|
||||
STEP 50 TIME_PASSES ELAPSE 5
|
||||
|
||||
; this query triggers a prefetch
|
||||
STEP 210 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 220 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
; Expired SERVFAILS are no longer served from Unbound
|
||||
|
||||
; this query gets the 0ttl answer
|
||||
STEP 230 QUERY
|
||||
|
|
@ -76,7 +61,7 @@ ENTRY_END
|
|||
|
||||
STEP 240 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
|
|
|||
47
testdata/rrset_use_cached.rpl
vendored
47
testdata/rrset_use_cached.rpl
vendored
|
|
@ -5,8 +5,11 @@ server:
|
|||
# We do not want only serve-expired because fetches from that
|
||||
# apply a generous PREFETCH_LEEWAY.
|
||||
serve-expired-client-timeout: 1000
|
||||
serve-expired-reply-ttl: 123
|
||||
# So that we can only have to give one SERVFAIL answer.
|
||||
outbound-msg-retry: 0
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
forward-zone: name: "." forward-addr: 216.0.0.1
|
||||
CONFIG_END
|
||||
|
|
@ -35,11 +38,11 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 5 IN A 10.20.30.40
|
||||
www.example.com. 205 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 210 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 10.20.30.50
|
||||
ns.example.com. 210 IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
STEP 4 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -48,15 +51,15 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 5 IN A 10.20.30.40
|
||||
www.example.com. 205 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 210 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 10.20.30.50
|
||||
ns.example.com. 210 IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the A RRSET to expire.
|
||||
STEP 5 TIME_PASSES ELAPSE 6
|
||||
STEP 5 TIME_PASSES ELAPSE 205
|
||||
|
||||
STEP 6 QUERY
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -80,14 +83,14 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 5 IN A 10.20.30.40
|
||||
www.example.com. 205 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 210 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 10.20.30.50
|
||||
ns.example.com. 210 IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
; The cached NS related RRSETs will not be overwritten by the fresh answer.
|
||||
; The message should have a TTL of 4 instead of 5 from above.
|
||||
; The message should have a TTL of 5 instead of 205 from above.
|
||||
STEP 9 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
|
|
@ -95,11 +98,11 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 5 IN A 10.20.30.40
|
||||
www.example.com. 205 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 4 IN NS ns.example.com.
|
||||
example.com. 5 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 4 IN A 10.20.30.50
|
||||
ns.example.com. 5 IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the NS RRSETs to expire.
|
||||
|
|
@ -107,7 +110,7 @@ STEP 10 TIME_PASSES ELAPSE 5
|
|||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
|
@ -129,23 +132,23 @@ ENTRY_BEGIN
|
|||
ENTRY_END
|
||||
; The SERVFAIL will trigger the serve-expired-client-timeout logic to try and
|
||||
; replace the SERVFAIL with a possible cached (expired) answer.
|
||||
; The A RRSET would be at 0TTL left (not expired) but the message should have
|
||||
; been updated to use a TTL of 4 so expired by now.
|
||||
; The A RRSET would be at 200 left but the message should have
|
||||
; been updated to use a TTL of 5 so expired by now.
|
||||
; If the message TTL was not updated (bug), this message would be treated as
|
||||
; non-expired and the now expired NS related RRSETs would fail sanity checks
|
||||
; for non-expired messages. The result would be SERVFAIL here.
|
||||
STEP 14 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 0 IN A 10.20.30.40
|
||||
www.example.com. 200 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 30 IN NS ns.example.com.
|
||||
example.com. 123 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 30 IN A 10.20.30.50
|
||||
ns.example.com. 123 IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
17
testdata/serve_expired.rpl
vendored
17
testdata/serve_expired.rpl
vendored
|
|
@ -5,6 +5,7 @@ server:
|
|||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-reply-ttl: 123
|
||||
access-control: 127.0.0.1/32 allow_snoop
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
|
@ -44,7 +45,7 @@ RANGE_BEGIN 0 100
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
@ -68,15 +69,15 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 11 TIME_PASSES ELAPSE 3601
|
||||
; Wait for the TTL to expire (for all RRSets; default 3600)
|
||||
STEP 11 TIME_PASSES ELAPSE 3600
|
||||
|
||||
; Query again without RD bit
|
||||
STEP 30 QUERY
|
||||
|
|
@ -94,11 +95,11 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 30 IN A 5.6.7.8
|
||||
example.com. 123 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 30 IN NS ns.example.com.
|
||||
example.com. 123 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 30 IN A 1.2.3.4
|
||||
ns.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Query with RD bit (the record should have been prefetched)
|
||||
|
|
@ -116,7 +117,7 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
|
|||
23
testdata/serve_expired_0ttl_nodata.rpl
vendored
23
testdata/serve_expired_0ttl_nodata.rpl
vendored
|
|
@ -5,6 +5,7 @@ server:
|
|||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-reply-ttl: 123
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
|
|
@ -48,9 +49,9 @@ RANGE_BEGIN 30 100
|
|||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -62,9 +63,9 @@ RANGE_BEGIN 30 100
|
|||
SECTION ANSWER
|
||||
0ttl.example.com. 0 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -106,13 +107,13 @@ ENTRY_BEGIN
|
|||
example.com IN SOA ns.example.com dns.example.com 1 7200 3600 2419200 10
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the NXDOMAIN to expire
|
||||
STEP 31 TIME_PASSES ELAPSE 32
|
||||
; Wait for the NODATA to expire
|
||||
STEP 31 TIME_PASSES ELAPSE 10
|
||||
|
||||
; Query again
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
0ttl.example.com. IN A
|
||||
ENTRY_END
|
||||
|
|
@ -120,8 +121,8 @@ ENTRY_END
|
|||
; Check that we get the cached NODATA
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
0ttl.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
|
|
@ -146,9 +147,9 @@ ENTRY_BEGIN
|
|||
SECTION ANSWER
|
||||
0ttl.example.com. 0 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
4
testdata/serve_expired_0ttl_nxdomain.rpl
vendored
4
testdata/serve_expired_0ttl_nxdomain.rpl
vendored
|
|
@ -107,7 +107,7 @@ ENTRY_BEGIN
|
|||
ENTRY_END
|
||||
|
||||
; Wait for the NXDOMAIN to expire
|
||||
STEP 31 TIME_PASSES ELAPSE 32
|
||||
STEP 31 TIME_PASSES ELAPSE 10
|
||||
|
||||
; Query again
|
||||
STEP 40 QUERY
|
||||
|
|
@ -117,7 +117,7 @@ ENTRY_BEGIN
|
|||
0ttl.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we get the cached NXDOMAIN
|
||||
; Check that we get the newly cached NXDOMAIN
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
|
|
|
|||
2
testdata/serve_expired_0ttl_servfail.rpl
vendored
2
testdata/serve_expired_0ttl_servfail.rpl
vendored
|
|
@ -101,7 +101,7 @@ ENTRY_BEGIN
|
|||
ENTRY_END
|
||||
|
||||
; Wait for the SERVFAIL to expire
|
||||
STEP 31 TIME_PASSES ELAPSE 32
|
||||
STEP 31 TIME_PASSES ELAPSE 10
|
||||
|
||||
; Query again
|
||||
STEP 40 QUERY
|
||||
|
|
|
|||
4
testdata/serve_expired_client_timeout.rpl
vendored
4
testdata/serve_expired_client_timeout.rpl
vendored
|
|
@ -48,7 +48,7 @@ RANGE_BEGIN 0 20
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
@ -72,7 +72,7 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
|
|||
|
|
@ -1,110 +0,0 @@
|
|||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 1
|
||||
serve-expired-reply-ttl: 123
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test that no prefetch is triggered for 0TTL records with serve-expired and client-timeout enabled
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query again right at the 0TTL cached entry
|
||||
; - check that we get the cached answer with no prefetching triggered
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 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
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 10
|
||||
ADDRESS 1.2.3.4
|
||||
; response to A query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Query with RD flag
|
||||
STEP 0 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 1 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire and produce a 0 TTL cached record.
|
||||
STEP 10 TIME_PASSES ELAPSE 10
|
||||
|
||||
; Query again
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; This should come from the cache with no prefetch triggered (earlier bug).
|
||||
STEP 21 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 1 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 3591 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3591 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; If a prefetch triggers the test will fail with 'messages pending'.
|
||||
|
||||
SCENARIO_END
|
||||
|
|
@ -40,9 +40,9 @@ RANGE_BEGIN 0 20
|
|||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
|
|
@ -52,11 +52,11 @@ RANGE_BEGIN 0 20
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -84,11 +84,11 @@ RANGE_BEGIN 50 100
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -108,15 +108,15 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 11 TIME_PASSES ELAPSE 11
|
||||
STEP 11 TIME_PASSES ELAPSE 200
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
|
|
@ -209,11 +209,11 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
75
testdata/serve_expired_reply_ttl.rpl
vendored
75
testdata/serve_expired_reply_ttl.rpl
vendored
|
|
@ -18,8 +18,11 @@ SCENARIO_BEGIN Test serve-expired with reply-ttl
|
|||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query for shorterttl.example.com. IN A
|
||||
; - check that we get an answer for shorterttl.example.com. IN A with the correct TTL
|
||||
; - query again right after the TTL expired
|
||||
; - check that we get the expired cached answer with the configured TTL
|
||||
; - check that we get the expired cached answer for example.com. with the configured TTL
|
||||
; - check that we get the expired cached answer for shorterttl.example.com. with its own original TTL since it is shorter than the configured one
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
|
|
@ -43,7 +46,21 @@ RANGE_BEGIN 0 100
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
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
|
||||
shorterttl.example.com. IN A
|
||||
SECTION ANSWER
|
||||
shorterttl.example.com. 121 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
@ -67,15 +84,37 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 11 TIME_PASSES ELAPSE 3601
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
shorterttl.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
shorterttl.example.com. IN A
|
||||
SECTION ANSWER
|
||||
shorterttl.example.com. 121 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire (for all rrsets; default 3600)
|
||||
STEP 20 TIME_PASSES ELAPSE 3600
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
|
|
@ -100,7 +139,31 @@ ENTRY_BEGIN
|
|||
ns.example.com. 123 A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Query again for shorter ttl
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
shorterttl.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got a stale answer
|
||||
; Note: auth, additional rrsets are already updated from previous recursion.
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
shorterttl.example.com. IN A
|
||||
SECTION ANSWER
|
||||
shorterttl.example.com. 121 A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3600 A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Give time for the pending query to get answered
|
||||
STEP 41 TRAFFIC
|
||||
STEP 61 TRAFFIC
|
||||
|
||||
SCENARIO_END
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ ENTRY_BEGIN
|
|||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire + serve-expired-ttl
|
||||
STEP 11 TIME_PASSES ELAPSE 3611
|
||||
STEP 11 TIME_PASSES ELAPSE 3610
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
|
|
|
|||
6
testdata/serve_expired_ttl_reset.rpl
vendored
6
testdata/serve_expired_ttl_reset.rpl
vendored
|
|
@ -36,7 +36,7 @@ REPLY QR AA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 0.0.0.0
|
||||
www.example.com. 200 IN A 0.0.0.0
|
||||
ENTRY_END
|
||||
|
||||
STEP 3 CHECK_ANSWER
|
||||
|
|
@ -46,11 +46,11 @@ REPLY QR RA RD NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 0.0.0.0
|
||||
www.example.com. 200 IN A 0.0.0.0
|
||||
ENTRY_END
|
||||
|
||||
; Expire the record (+ serve-expired-ttl)
|
||||
STEP 4 TIME_PASSES ELAPSE 12
|
||||
STEP 4 TIME_PASSES ELAPSE 201
|
||||
|
||||
STEP 5 QUERY
|
||||
ENTRY_BEGIN
|
||||
|
|
|
|||
14
testdata/serve_expired_zerottl.rpl
vendored
14
testdata/serve_expired_zerottl.rpl
vendored
|
|
@ -65,11 +65,11 @@ RANGE_BEGIN 11 100
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
|
|
@ -118,15 +118,15 @@ ENTRY_BEGIN
|
|||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
example.com. 200 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ns.example.com. 200 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 30 TIME_PASSES ELAPSE 11
|
||||
STEP 30 TIME_PASSES ELAPSE 200
|
||||
|
||||
; Query with RD flag
|
||||
STEP 40 QUERY
|
||||
|
|
|
|||
|
|
@ -7,12 +7,15 @@ server:
|
|||
target-fetch-policy: "0 0 0 0 0"
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-reply-ttl: 123
|
||||
client-subnet-always-forward: yes
|
||||
module-config: "subnetcache iterator"
|
||||
verbosity: 3
|
||||
access-control: 127.0.0.1 allow_snoop
|
||||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
|
|
@ -100,7 +103,7 @@ RANGE_BEGIN 0 100
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.40
|
||||
www.example.com. 200 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
@ -131,11 +134,11 @@ ns.example.com. IN A 1.2.3.4
|
|||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 3 TIME_PASSES ELAPSE 20
|
||||
STEP 3 TIME_PASSES ELAPSE 200
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
|
@ -143,16 +146,16 @@ ENTRY_END
|
|||
; This record came from the global cache and a prefetch was triggered
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 10.20.30.40
|
||||
www.example.com. 123 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 3580 IN NS ns.example.com.
|
||||
example.com. 3400 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3580 IN A 1.2.3.4
|
||||
ns.example.com. 3400 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 13 CHECK_OUT_QUERY
|
||||
|
|
|
|||
29
testdata/subnet_global_prefetch_expired.crpl
vendored
29
testdata/subnet_global_prefetch_expired.crpl
vendored
|
|
@ -16,7 +16,11 @@ server:
|
|||
serve-expired: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-ttl: 1
|
||||
prefetch: yes
|
||||
serve-expired-client-timeout: 0
|
||||
serve-expired-reply-ttl: 123
|
||||
#prefetch: yes #not needed, expired answers also trigger refetch
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
|
|
@ -113,7 +117,7 @@ RANGE_BEGIN 0 10
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.40
|
||||
www.example.com. 200 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
@ -147,7 +151,7 @@ RANGE_BEGIN 11 100
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.40
|
||||
www.example.com. 200 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
@ -178,7 +182,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
www.example.com. 200 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
@ -186,11 +190,11 @@ ns.example.com. IN A 1.2.3.4
|
|||
ENTRY_END
|
||||
|
||||
; Try to trigger a prefetch with expired data
|
||||
STEP 3 TIME_PASSES ELAPSE 11
|
||||
STEP 3 TIME_PASSES ELAPSE 200
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
|
@ -198,19 +202,18 @@ ENTRY_END
|
|||
; This expired record came from the global cache and a prefetch is triggered.
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 10.20.30.40
|
||||
www.example.com. 123 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 3589 IN NS ns.example.com.
|
||||
example.com. 3400 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3589 IN A 1.2.3.4
|
||||
ns.example.com. 3400 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
;STEP 13 TRAFFIC
|
||||
; Allow enough time to pass so that the expired record from the global cache
|
||||
; cannot be used anymore.
|
||||
STEP 14 TIME_PASSES ELAPSE 1
|
||||
|
|
@ -232,7 +235,7 @@ REPLY QR RD RA NOERROR
|
|||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 9 IN A 10.20.30.40
|
||||
www.example.com. 199 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 3599 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
|
|
|
|||
21
testdata/ttl_zero_cacherep.rpl
vendored
21
testdata/ttl_zero_cacherep.rpl
vendored
|
|
@ -260,27 +260,6 @@ ENTRY_END
|
|||
STEP 140 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
; note that it did not send 0 TTL. The message can be cached by the receiver
|
||||
; during the last second of the TTL.
|
||||
www.example.com. 1 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
STEP 150 TIME_PASSES ELAPSE 1
|
||||
|
||||
STEP 160 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 170 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
|
|
|||
|
|
@ -496,10 +496,18 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
|||
return r;
|
||||
sldns_buffer_write(pkt, &key->rk.type, 2);
|
||||
sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
|
||||
if(data->rr_ttl[j] < adjust)
|
||||
if(key->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) {
|
||||
sldns_buffer_write_u32(pkt, 0);
|
||||
} else if(adjust == 0) {
|
||||
sldns_buffer_write_u32(pkt, data->rr_ttl[i]);
|
||||
} else if(TTL_IS_EXPIRED(data->rr_ttl[j], adjust)) {
|
||||
sldns_buffer_write_u32(pkt,
|
||||
SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0);
|
||||
else sldns_buffer_write_u32(pkt, data->rr_ttl[j]-adjust);
|
||||
EXPIRED_REPLY_TTL_CALC(
|
||||
data->rr_ttl[i], data->ttl_add));
|
||||
} else {
|
||||
sldns_buffer_write_u32(pkt,
|
||||
data->rr_ttl[i] - adjust);
|
||||
}
|
||||
if(c) {
|
||||
if((r=compress_rdata(pkt, data->rr_data[j],
|
||||
data->rr_len[j], region, tree, c,
|
||||
|
|
@ -533,10 +541,18 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
|||
}
|
||||
sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_RRSIG);
|
||||
sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
|
||||
if(data->rr_ttl[i] < adjust)
|
||||
if(key->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) {
|
||||
sldns_buffer_write_u32(pkt, 0);
|
||||
} else if(adjust == 0) {
|
||||
sldns_buffer_write_u32(pkt, data->rr_ttl[i]);
|
||||
} else if(TTL_IS_EXPIRED(data->rr_ttl[i], adjust)) {
|
||||
sldns_buffer_write_u32(pkt,
|
||||
SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0);
|
||||
else sldns_buffer_write_u32(pkt, data->rr_ttl[i]-adjust);
|
||||
EXPIRED_REPLY_TTL_CALC(
|
||||
data->rr_ttl[i], data->ttl_add));
|
||||
} else {
|
||||
sldns_buffer_write_u32(pkt,
|
||||
data->rr_ttl[i] - adjust);
|
||||
}
|
||||
/* rrsig rdata cannot be compressed, perform 100+ byte
|
||||
* memcopy. */
|
||||
sldns_buffer_write(pkt, data->rr_data[i],
|
||||
|
|
@ -993,11 +1009,11 @@ attach_edns_record(sldns_buffer* pkt, struct edns_data* edns)
|
|||
attach_edns_record_max_msg_sz(pkt, edns, edns->udp_size);
|
||||
}
|
||||
|
||||
int
|
||||
reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
int
|
||||
reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
uint16_t id, uint16_t qflags, sldns_buffer* pkt, time_t timenow,
|
||||
int cached, struct regional* region, uint16_t udpsize,
|
||||
struct edns_data* edns, int dnssec, int secure, int cached_ttl)
|
||||
int cached, struct regional* region, uint16_t udpsize,
|
||||
struct edns_data* edns, int dnssec, int secure)
|
||||
{
|
||||
uint16_t flags;
|
||||
unsigned int attach_edns = 0;
|
||||
|
|
@ -1022,17 +1038,6 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
|||
flags &= ~BIT_AD;
|
||||
}
|
||||
log_assert((flags & BIT_QR)); /* QR bit must be on in our replies */
|
||||
if(cached_ttl && rep->ttl - timenow == 0) {
|
||||
/* The last remaining second of the TTL for a cached response
|
||||
* is replied. This makes a 0 in the protocol message. The
|
||||
* response is valid for the cache, but the DNS TTL 0 item
|
||||
* causes the received to drop the contents. Even though the
|
||||
* contents are cachable, so the time used is decremented
|
||||
* to change that into 1 second, and it can be cached, and
|
||||
* used for expired response generation, and does not give
|
||||
* repeated queries during that last second. */
|
||||
timenow --;
|
||||
}
|
||||
if(udpsize < LDNS_HEADER_SIZE)
|
||||
return 0;
|
||||
/* currently edns does not change during calculations;
|
||||
|
|
|
|||
|
|
@ -64,16 +64,12 @@ struct edns_data;
|
|||
* or if edns_present = 0, it is not included.
|
||||
* @param dnssec: if 0 DNSSEC records are omitted from the answer.
|
||||
* @param secure: if 1, the AD bit is set in the reply.
|
||||
* @param cached_ttl: the ttl is from a cache response. So that means it
|
||||
* was some value minus the current time, and not an authoritative
|
||||
* response with an autoritative TTL or a direct upstream response,
|
||||
* that could have upstream TTL 0 items.
|
||||
* @return: 0 on error (server failure).
|
||||
*/
|
||||
int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
uint16_t id, uint16_t qflags, struct sldns_buffer* dest, time_t timenow,
|
||||
int cached, struct regional* region, uint16_t udpsize,
|
||||
struct edns_data* edns, int dnssec, int secure, int cached_ttl);
|
||||
int cached, struct regional* region, uint16_t udpsize,
|
||||
struct edns_data* edns, int dnssec, int secure);
|
||||
|
||||
/**
|
||||
* Regenerate the wireformat from the stored msg reply.
|
||||
|
|
|
|||
|
|
@ -1361,3 +1361,13 @@ msgparse_rrset_remove_rr(const char* str, sldns_buffer* pkt, struct rrset_parse*
|
|||
* the rr->next works fine to continue. */
|
||||
return rrset->rr_count == 0;
|
||||
}
|
||||
|
||||
#ifdef UNBOUND_DEBUG
|
||||
time_t debug_expired_reply_ttl_calc(time_t ttl, time_t ttl_add) {
|
||||
/* Check that we are serving expired when this is called */
|
||||
/* ttl (absolute) should be later than ttl_add */
|
||||
log_assert(SERVE_EXPIRED && ttl_add <= ttl);
|
||||
return (SERVE_EXPIRED_REPLY_TTL < (ttl) - (ttl_add) ?
|
||||
SERVE_EXPIRED_REPLY_TTL : (ttl) - (ttl_add));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -98,6 +98,31 @@ extern time_t SERVE_EXPIRED_REPLY_TTL;
|
|||
/** If we serve the original TTL or decrementing TTLs */
|
||||
extern int SERVE_ORIGINAL_TTL;
|
||||
|
||||
/** calculate the prefetch TTL as 90% of original. Calculation
|
||||
* without numerical overflow (uin32_t) */
|
||||
#define PREFETCH_TTL_CALC(ttl) ((ttl) - (ttl)/10)
|
||||
|
||||
/* caclulate the TTL used for expired answers to somewhat make sense wrt the
|
||||
* original TTL; don't reply with higher TTL than the original */
|
||||
#ifdef UNBOUND_DEBUG
|
||||
time_t debug_expired_reply_ttl_calc(time_t ttl, time_t ttl_add);
|
||||
#define EXPIRED_REPLY_TTL_CALC(ttl, ttl_add) \
|
||||
debug_expired_reply_ttl_calc(ttl, ttl_add)
|
||||
#else
|
||||
#define EXPIRED_REPLY_TTL_CALC(ttl, ttl_add) \
|
||||
(SERVE_EXPIRED_REPLY_TTL < (ttl) - (ttl_add) ? \
|
||||
SERVE_EXPIRED_REPLY_TTL : (ttl) - (ttl_add))
|
||||
#endif
|
||||
|
||||
/** Update the reply_info TTL from an RRSet's TTL, essentially keeping the TTL
|
||||
* sane with all the (progressively added) rrsets to the message */
|
||||
#define UPDATE_TTL_FROM_RRSET(ttl, rrsetttl) \
|
||||
((ttl) = ((ttl) < (rrsetttl)) ? (ttl) : (rrsetttl))
|
||||
|
||||
/** Check if TTL is expired. 0 TTL is considered expired.
|
||||
* Used mainly to identify parts of the code that do this comparison. */
|
||||
#define TTL_IS_EXPIRED(ttl, now) ((ttl) <= (now))
|
||||
|
||||
/**
|
||||
* Data stored in scratch pad memory during parsing.
|
||||
* Stores the data that will enter into the msgreply and packet result.
|
||||
|
|
|
|||
|
|
@ -178,9 +178,9 @@ reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
|
|||
int
|
||||
reply_info_can_answer_expired(struct reply_info* rep, time_t timenow)
|
||||
{
|
||||
log_assert(rep->ttl < timenow);
|
||||
log_assert(TTL_IS_EXPIRED(rep->ttl, timenow));
|
||||
/* Really expired */
|
||||
if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow) return 0;
|
||||
if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow)) return 0;
|
||||
/* Ignore expired failure answers */
|
||||
if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR &&
|
||||
FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN &&
|
||||
|
|
@ -188,12 +188,13 @@ reply_info_can_answer_expired(struct reply_info* rep, time_t timenow)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int reply_info_could_use_expired(struct reply_info* rep, time_t timenow)
|
||||
int
|
||||
reply_info_could_use_expired(struct reply_info* rep, time_t timenow)
|
||||
{
|
||||
log_assert(rep->ttl < timenow);
|
||||
log_assert(TTL_IS_EXPIRED(rep->ttl, timenow));
|
||||
/* Really expired */
|
||||
if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow &&
|
||||
!SERVE_EXPIRED_TTL_RESET) return 0;
|
||||
if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow)
|
||||
&& !SERVE_EXPIRED_TTL_RESET) return 0;
|
||||
/* Ignore expired failure answers */
|
||||
if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR &&
|
||||
FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN &&
|
||||
|
|
@ -229,7 +230,7 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
|
|||
}
|
||||
|
||||
/** find the minimumttl in the rdata of SOA record */
|
||||
static time_t
|
||||
static uint32_t
|
||||
soa_find_minttl(struct rr_parse* rr)
|
||||
{
|
||||
uint16_t rlen = sldns_read_uint16(rr->ttl_data+4);
|
||||
|
|
@ -237,7 +238,7 @@ soa_find_minttl(struct rr_parse* rr)
|
|||
return 0; /* rdata too small for SOA (dname, dname, 5*32bit) */
|
||||
/* minimum TTL is the last 32bit value in the rdata of the record */
|
||||
/* at position ttl_data + 4(ttl) + 2(rdatalen) + rdatalen - 4(timeval)*/
|
||||
return (time_t)sldns_read_uint32(rr->ttl_data+6+rlen-4);
|
||||
return sldns_read_uint32(rr->ttl_data+6+rlen-4);
|
||||
}
|
||||
|
||||
/** do the rdata copy */
|
||||
|
|
@ -247,37 +248,40 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
|
|||
sldns_pkt_section section)
|
||||
{
|
||||
uint16_t pkt_len;
|
||||
uint32_t ttl;
|
||||
const sldns_rr_descriptor* desc;
|
||||
|
||||
*rr_ttl = sldns_read_uint32(rr->ttl_data);
|
||||
ttl = sldns_read_uint32(rr->ttl_data);
|
||||
/* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */
|
||||
if((*rr_ttl & 0x80000000U))
|
||||
*rr_ttl = 0;
|
||||
/* RFC 8767 Section 4. values with high-order bit as positive, not 0.
|
||||
+ * As such, it will be capped by MAX_TTL below. */
|
||||
if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) {
|
||||
/* negative response. see if TTL of SOA record larger than the
|
||||
* minimum-ttl in the rdata of the SOA record */
|
||||
if(*rr_ttl > soa_find_minttl(rr)) *rr_ttl = soa_find_minttl(rr);
|
||||
if(ttl > soa_find_minttl(rr)) ttl = soa_find_minttl(rr);
|
||||
if(!SERVE_ORIGINAL_TTL) {
|
||||
/* If MIN_NEG_TTL is configured skip setting MIN_TTL */
|
||||
if(MIN_NEG_TTL <= 0 && *rr_ttl < MIN_TTL) {
|
||||
*rr_ttl = MIN_TTL;
|
||||
if(MIN_NEG_TTL <= 0 && ttl < MIN_TTL) {
|
||||
ttl = MIN_TTL;
|
||||
}
|
||||
if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL;
|
||||
if(ttl > MAX_TTL) ttl = MAX_TTL;
|
||||
}
|
||||
/* MAX_NEG_TTL overrides the min and max ttl of everything
|
||||
* else; it is for a more specific record */
|
||||
if(*rr_ttl > MAX_NEG_TTL) *rr_ttl = MAX_NEG_TTL;
|
||||
if(ttl > MAX_NEG_TTL) ttl = MAX_NEG_TTL;
|
||||
/* MIN_NEG_TTL overrides the min and max ttl of everything
|
||||
* else if configured; it is for a more specific record */
|
||||
if(MIN_NEG_TTL > 0 && *rr_ttl < MIN_NEG_TTL) {
|
||||
*rr_ttl = MIN_NEG_TTL;
|
||||
if(MIN_NEG_TTL > 0 && ttl < MIN_NEG_TTL) {
|
||||
ttl = MIN_NEG_TTL;
|
||||
}
|
||||
} else if(!SERVE_ORIGINAL_TTL) {
|
||||
if(*rr_ttl < MIN_TTL) *rr_ttl = MIN_TTL;
|
||||
if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL;
|
||||
if(ttl < MIN_TTL) ttl = MIN_TTL;
|
||||
if(ttl > MAX_TTL) ttl = MAX_TTL;
|
||||
}
|
||||
if(*rr_ttl < data->ttl)
|
||||
data->ttl = *rr_ttl;
|
||||
if(ttl < data->ttl)
|
||||
data->ttl = ttl;
|
||||
/* We have concluded the TTL checks */
|
||||
*rr_ttl = (time_t)ttl;
|
||||
|
||||
if(rr->outside_packet) {
|
||||
/* uncompressed already, only needs copy */
|
||||
|
|
@ -481,6 +485,7 @@ parse_copy_decompress_rrset(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
pk->entry.key = (void*)pk;
|
||||
pk->entry.hash = pset->hash;
|
||||
data->trust = get_rrset_trust(msg, pset);
|
||||
pk->rk.flags |= (data->ttl == 0) ? PACKED_RRSET_UPSTREAM_0TTL : 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -617,6 +622,29 @@ reply_info_set_ttls(struct reply_info* rep, time_t timenow)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
reply_info_absolute_ttls(struct reply_info* rep, time_t ttl, time_t ttl_add)
|
||||
{
|
||||
size_t i, j;
|
||||
rep->ttl = ttl;
|
||||
rep->prefetch_ttl = PREFETCH_TTL_CALC(ttl);
|
||||
rep->serve_expired_ttl = ttl + SERVE_EXPIRED_TTL;
|
||||
/* Don't set rep->serve_expired_norec_ttl; this should only be set
|
||||
* on cached records when encountering an error */
|
||||
log_assert(rep->serve_expired_norec_ttl == 0);
|
||||
for(i=0; i<rep->rrset_count; i++) {
|
||||
struct packed_rrset_data* data = (struct packed_rrset_data*)
|
||||
rep->ref[i].key->entry.data;
|
||||
if(i>0 && rep->ref[i].key == rep->ref[i-1].key)
|
||||
continue;
|
||||
data->ttl = ttl;
|
||||
for(j=0; j<data->count + data->rrsig_count; j++) {
|
||||
data->rr_ttl[j] = ttl;
|
||||
}
|
||||
data->ttl_add = ttl_add;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,10 +60,6 @@ struct local_rrset;
|
|||
struct dns_msg;
|
||||
enum comm_point_type;
|
||||
|
||||
/** calculate the prefetch TTL as 90% of original. Calculation
|
||||
* without numerical overflow (uin32_t) */
|
||||
#define PREFETCH_TTL_CALC(ttl) ((ttl) - (ttl)/10)
|
||||
|
||||
/**
|
||||
* Structure to store query information that makes answers to queries
|
||||
* different.
|
||||
|
|
@ -340,6 +336,15 @@ void reply_info_sortref(struct reply_info* rep);
|
|||
*/
|
||||
void reply_info_set_ttls(struct reply_info* rep, time_t timenow);
|
||||
|
||||
/**
|
||||
* Set TTLs inside the replyinfo to the given absolute values.
|
||||
* @param rep: reply info. rrsets must be filled in.
|
||||
* Also refs must be filled in.
|
||||
* @param ttl: absolute ttl value to be set.
|
||||
* @param ttl_add: the current time to be used verbatim for ttl_add in the rrsets.
|
||||
*/
|
||||
void reply_info_absolute_ttls(struct reply_info* rep, time_t ttl, time_t ttl_add);
|
||||
|
||||
/**
|
||||
* Delete reply_info and packed_rrsets (while they are not yet added to the
|
||||
* hashtables.). Returns rrsets to the alloc cache.
|
||||
|
|
|
|||
|
|
@ -336,10 +336,9 @@ packed_rrset_copy_region(struct ub_packed_rrset_key* key,
|
|||
struct ub_packed_rrset_key* ck = regional_alloc(region,
|
||||
sizeof(struct ub_packed_rrset_key));
|
||||
struct packed_rrset_data* d;
|
||||
struct packed_rrset_data* data = (struct packed_rrset_data*)
|
||||
key->entry.data;
|
||||
struct packed_rrset_data* data = key->entry.data;
|
||||
size_t dsize, i;
|
||||
time_t adjust = 0;
|
||||
time_t now_control;
|
||||
if(!ck)
|
||||
return NULL;
|
||||
ck->id = key->id;
|
||||
|
|
@ -352,22 +351,31 @@ packed_rrset_copy_region(struct ub_packed_rrset_key* key,
|
|||
if(!ck->rk.dname)
|
||||
return NULL;
|
||||
dsize = packed_rrset_sizeof(data);
|
||||
d = (struct packed_rrset_data*)regional_alloc_init(region, data, dsize);
|
||||
d = regional_alloc_init(region, data, dsize);
|
||||
if(!d)
|
||||
return NULL;
|
||||
ck->entry.data = d;
|
||||
packed_rrset_ptr_fixup(d);
|
||||
/* make TTLs relative - once per rrset */
|
||||
adjust = SERVE_ORIGINAL_TTL ? data->ttl_add : now;
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(d->rr_ttl[i] < adjust)
|
||||
d->rr_ttl[i] = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0;
|
||||
else d->rr_ttl[i] -= adjust;
|
||||
/* make TTLs relative - once per rr */
|
||||
if(now > 0) {
|
||||
/* NS RRSets may be here with ttl_add higher than now because
|
||||
* of the novel ghost attack mitigation i.e., using the
|
||||
* qstarttime for NS RRSets. In that case make sure that the
|
||||
* returned TTL is not higher than the original one. */
|
||||
log_assert(d->ttl_add <= now ||
|
||||
(ntohs(key->rk.type) == LDNS_RR_TYPE_NS));
|
||||
now_control = SERVE_ORIGINAL_TTL ? data->ttl_add
|
||||
: (d->ttl_add > now ? d->ttl_add : now );
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(TTL_IS_EXPIRED(d->rr_ttl[i], now_control)) {
|
||||
d->rr_ttl[i] = EXPIRED_REPLY_TTL_CALC(d->rr_ttl[i], data->ttl_add);
|
||||
} else d->rr_ttl[i] -= now_control;
|
||||
}
|
||||
if(TTL_IS_EXPIRED(d->ttl, now_control)) {
|
||||
d->ttl = EXPIRED_REPLY_TTL_CALC(d->ttl, data->ttl_add);
|
||||
} else d->ttl -= now_control;
|
||||
d->ttl_add = 0; /* TTLs have been made relative */
|
||||
}
|
||||
if(d->ttl < adjust)
|
||||
d->ttl = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0;
|
||||
else d->ttl -= adjust;
|
||||
d->ttl_add = 0; /* TTLs have been made relative */
|
||||
return ck;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ typedef uint64_t rrset_id_type;
|
|||
#define PACKED_RRSET_RPZ 0x8
|
||||
/** this rrset is A/AAAA and is an unverified glue record */
|
||||
#define PACKED_RRSET_UNVERIFIED_GLUE 0x10
|
||||
/** this rrset has a 0TTL from upstream */
|
||||
#define PACKED_RRSET_UPSTREAM_0TTL 0x20
|
||||
|
||||
/** number of rrs and rrsets for integer overflow protection. More than
|
||||
* this is not really possible (64K packet has much less RRs and RRsets) in
|
||||
|
|
@ -99,6 +101,7 @@ struct packed_rrset_key {
|
|||
* o PACKED_RRSET_FIXEDTTL (not supposed to be cached)
|
||||
* o PACKED_RRSET_RPZ
|
||||
* o PACKED_RRSET_UNVERIFIED_GLUE
|
||||
* o PACKED_RRSET_UPSTREAM_0TTL (not supposed to be cached)
|
||||
*/
|
||||
uint32_t flags;
|
||||
/** the rrset type in network format */
|
||||
|
|
|
|||
|
|
@ -1066,11 +1066,7 @@ grab_nsec(struct rrset_cache* rrset_cache, uint8_t* qname, size_t qname_len,
|
|||
qname, qname_len, qtype, qclass, flags, now, 0);
|
||||
struct packed_rrset_data* d;
|
||||
if(!k) return NULL;
|
||||
d = (struct packed_rrset_data*)k->entry.data;
|
||||
if(d->ttl < now) {
|
||||
lock_rw_unlock(&k->entry.lock);
|
||||
return NULL;
|
||||
}
|
||||
d = k->entry.data;
|
||||
/* only secure or unchecked records that have signatures. */
|
||||
if( ! ( d->security == sec_status_secure ||
|
||||
(d->security == sec_status_unchecked &&
|
||||
|
|
|
|||
|
|
@ -1310,6 +1310,7 @@ val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c,
|
|||
/* DS rrset exists. Return it to the validator immediately*/
|
||||
struct ub_packed_rrset_key* copy = packed_rrset_copy_region(
|
||||
rrset, region, *env->now);
|
||||
struct packed_rrset_data* d = copy->entry.data;
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
if(!copy)
|
||||
return NULL;
|
||||
|
|
@ -1319,6 +1320,7 @@ val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c,
|
|||
msg->rep->rrsets[0] = copy;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->an_numrrsets++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
return msg;
|
||||
}
|
||||
/* lookup in rrset and negative cache for NSEC/NSEC3 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue