aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/services/cache/dns.c
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2018-05-12 15:20:39 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2018-05-12 15:20:39 +0000
commit0fb349906ef68608577702ca46e86aafdd7456b2 (patch)
treefe60861b9872307bc1d5cc628519abd19de3bade /contrib/unbound/services/cache/dns.c
parent57bddd215c419a01611bca0d1b1d545a64a7e731 (diff)
parent4289761a7b61df4b64c11ada446a187df61e6a1e (diff)
downloadsrc-0fb349906ef68608577702ca46e86aafdd7456b2.tar.gz
src-0fb349906ef68608577702ca46e86aafdd7456b2.zip
Upgrade Unbound to 1.7.1.
Notes
Notes: svn path=/head/; revision=333568
Diffstat (limited to 'contrib/unbound/services/cache/dns.c')
-rw-r--r--contrib/unbound/services/cache/dns.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/contrib/unbound/services/cache/dns.c b/contrib/unbound/services/cache/dns.c
index 411793c6c270..35adc35b57ee 100644
--- a/contrib/unbound/services/cache/dns.c
+++ b/contrib/unbound/services/cache/dns.c
@@ -108,6 +108,48 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
}
}
+/** delete message from message cache */
+static void
+msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
+ uint16_t qtype, uint16_t qclass, uint16_t flags)
+{
+ struct query_info k;
+ hashvalue_type h;
+
+ k.qname = qname;
+ k.qname_len = qnamelen;
+ k.qtype = qtype;
+ k.qclass = qclass;
+ k.local_alias = NULL;
+ h = query_info_hash(&k, flags);
+ slabhash_remove(env->msg_cache, h, &k);
+}
+
+/** remove servfail msg cache entry */
+static void
+msg_del_servfail(struct module_env* env, struct query_info* qinfo,
+ uint32_t flags)
+{
+ struct msgreply_entry* e;
+ /* see if the entry is servfail, and then remove it, so that
+ * lookups move from the cacheresponse stage to the recursionresponse
+ * stage */
+ e = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
+ qinfo->qtype, qinfo->qclass, flags, 0, 0);
+ if(!e) return;
+ /* we don't check for the ttl here, also expired servfail entries
+ * are removed. If the user uses serve-expired, they would still be
+ * used to answer from cache */
+ if(FLAGS_GET_RCODE(((struct reply_info*)e->entry.data)->flags)
+ != LDNS_RCODE_SERVFAIL) {
+ lock_rw_unlock(&e->entry.lock);
+ return;
+ }
+ lock_rw_unlock(&e->entry.lock);
+ msg_cache_remove(env, qinfo->qname, qinfo->qname_len, qinfo->qtype,
+ qinfo->qclass, flags);
+}
+
void
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
@@ -132,6 +174,12 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
* which could be useful for delegation information */
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
free(rep);
+ /* if the message is SERVFAIL in cache, remove that SERVFAIL,
+ * so that the TTL 0 response can be returned for future
+ * responses (i.e. don't get answered by the servfail from
+ * cache, but instead go to recursion to get this TTL0
+ * response). */
+ msg_del_servfail(env, qinfo, flags);
return;
}