aboutsummaryrefslogtreecommitdiff
path: root/services/cache/dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'services/cache/dns.c')
-rw-r--r--services/cache/dns.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/services/cache/dns.c b/services/cache/dns.c
index 7ab63bacf492..351b3568c80b 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.c
@@ -1056,8 +1056,9 @@ dns_cache_lookup(struct module_env* env,
int
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
- struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
- struct regional* region, uint32_t flags, time_t qstarttime)
+ struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
+ struct regional* region, uint32_t flags, time_t qstarttime,
+ int is_valrec)
{
struct reply_info* rep = NULL;
if(SERVE_EXPIRED) {
@@ -1065,7 +1066,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
* useful expired record exists. */
struct msgreply_entry* e = msg_cache_lookup(env,
msgqinf->qname, msgqinf->qname_len, msgqinf->qtype,
- msgqinf->qclass, flags, 0, 0);
+ msgqinf->qclass, flags, 0, 1);
if(e) {
struct reply_info* cached = e->entry.data;
if(cached->ttl < *env->now
@@ -1079,7 +1080,43 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
* one and let the validator manage caching. */
&& cached->security != sec_status_bogus
&& (env->need_to_validate &&
- msgrep->security == sec_status_unchecked)) {
+ msgrep->security == sec_status_unchecked)
+ /* Exceptions to that rule are:
+ * o recursions that don't need validation but
+ * need to update the cache for coherence
+ * (delegation information while iterating,
+ * DNSKEY and DS lookups from validator)
+ * o explicit RRSIG queries that are not
+ * validated. */
+ && !is_valrec
+ && msgqinf->qtype != LDNS_RR_TYPE_RRSIG) {
+ if((int)FLAGS_GET_RCODE(msgrep->flags) !=
+ LDNS_RCODE_NOERROR &&
+ (int)FLAGS_GET_RCODE(msgrep->flags) !=
+ LDNS_RCODE_NXDOMAIN) {
+ /* The current response has an
+ * erroneous rcode. Adjust norec time
+ * so that additional lookups are not
+ * performed for some time. */
+ verbose(VERB_ALGO, "set "
+ "serve-expired-norec-ttl for "
+ "response in cache");
+ cached->serve_expired_norec_ttl =
+ NORR_TTL + *env->now;
+ if(env->cfg->serve_expired_ttl_reset &&
+ cached->serve_expired_ttl
+ < *env->now +
+ env->cfg->serve_expired_ttl) {
+ /* Reset serve-expired-ttl for
+ * valid response in cache. */
+ verbose(VERB_ALGO, "reset "
+ "serve-expired-ttl "
+ "for response in cache");
+ cached->serve_expired_ttl =
+ *env->now +
+ env->cfg->serve_expired_ttl;
+ }
+ }
verbose(VERB_ALGO, "a validated expired entry "
"could be overwritten, skip caching "
"the new message at this stage");