From 893159454f2d12466a63cb548d6a98e4e9d67b59 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 12 May 2017 12:16:41 +0000 Subject: [PATCH] - Adjust servfail by iterator to not store in cache when serve-expired is enabled, to avoid overwriting useful information there. git-svn-id: file:///svn/unbound/trunk@4153 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 4 ++++ iterator/iterator.c | 16 ++++++++++++++++ services/cache/dns.c | 2 +- services/cache/dns.h | 6 ++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/Changelog b/doc/Changelog index 9dccd7f90..004e76f77 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +12 May 2017: Wouter + - Adjust servfail by iterator to not store in cache when serve-expired + is enabled, to avoid overwriting useful information there. + 9 May 2017: Ralph - Add 'c' to getopt() in testbound. - iana portlist update diff --git a/iterator/iterator.c b/iterator/iterator.c index 43b3d30c3..55916d726 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -288,6 +288,22 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) return error_response(qstate, id, rcode); /* if that fails (not in cache), fall through to store err */ } + if(qstate->env->cfg->serve_expired) { + /* if serving expired contents, and such content is + * already available, don't overwrite this servfail */ + struct msgreply_entry* msg; + if((msg=msg_cache_lookup(qstate->env, + qstate->qinfo.qname, qstate->qinfo.qname_len, + qstate->qinfo.qtype, qstate->qinfo.qclass, + qstate->query_flags, 0, 0)) + != NULL) { + lock_rw_unlock(&msg->entry.lock); + return error_response(qstate, id, rcode); + } + /* serving expired contents, but nothing is cached + * at all, so the servfail cache entry is useful + * (stops waste of time on this servfail NORR_TTL) */ + } memset(&err, 0, sizeof(err)); err.flags = (uint16_t)(BIT_QR | BIT_RA); FLAGS_SET_RCODE(err.flags, rcode); diff --git a/services/cache/dns.c b/services/cache/dns.c index a8fde9f28..4543aa5ed 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -182,7 +182,7 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region, } /** lookup message in message cache */ -static struct msgreply_entry* +struct msgreply_entry* msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr) { diff --git a/services/cache/dns.h b/services/cache/dns.h index 0dfb68874..096ddf28d 100644 --- a/services/cache/dns.h +++ b/services/cache/dns.h @@ -208,4 +208,10 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region, int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, time_t adjust, uint16_t flags); +/** lookup message in message cache + * the returned nonNULL entry is locked and has to be unlocked by the caller */ +struct msgreply_entry* msg_cache_lookup(struct module_env* env, + uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, + uint16_t flags, time_t now, int wr); + #endif /* SERVICES_CACHE_DNS_H */