]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- New and better fix for Fix #4193: Fix that prefetch failure does
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 27 Nov 2018 10:56:45 +0000 (10:56 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 27 Nov 2018 10:56:45 +0000 (10:56 +0000)
  not overwrite valid cache entry with SERVFAIL.

git-svn-id: file:///svn/unbound/trunk@4982 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iterator.c

index 7adad0590755be9e25c00b3c21e500bfd0286180..3b62e6c6e17741d6c0ede09932a34a241c7cd7ef 100644 (file)
@@ -3,6 +3,8 @@
          other threads from picking up the wrong data.  The module restores
          the previous no_cache_store setting when the the module is finished.
        - Fix #4208: 'stub-no-cache' and 'forward-no-cache' not work.
+       - New and better fix for Fix #4193: Fix that prefetch failure does
+         not overwrite valid cache entry with SERVFAIL.
 
 26 November 2018: Wouter
        - Fix to not set GLOB_NOSORT so the unbound.conf include: files are
index b21ebb63db14a071f83666d16c025c9d16244128..f66381b401fe2256bc2715bf6c1e031e15d57fe3 100644 (file)
@@ -292,7 +292,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
        if(!qstate->no_cache_store) {
                /* store in cache */
                struct reply_info err;
-               if(qstate->prefetch_leeway > 0) {
+               if(qstate->prefetch_leeway > NORR_TTL) {
                        verbose(VERB_ALGO, "error response for prefetch in cache");
                        /* attempt to adjust the cache entry prefetch */
                        if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
@@ -327,6 +327,29 @@ error_response_cache(struct module_qstate* qstate, int id, int 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) */
+               } else {
+                       /* don't overwrite existing (non-expired) data in
+                        * cache with a 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, *qstate->env->now, 0))
+                               != NULL) {
+                               struct reply_info* rep = (struct reply_info*)
+                                       msg->entry.data;
+                               if(FLAGS_GET_RCODE(rep->flags) ==
+                                       LDNS_RCODE_NOERROR ||
+                                       FLAGS_GET_RCODE(rep->flags) ==
+                                       LDNS_RCODE_NXDOMAIN) {
+                                       /* we have a good entry,
+                                        * don't overwrite */
+                                       lock_rw_unlock(&msg->entry.lock);
+                                       return error_response(qstate, id, rcode);
+                               }
+                               lock_rw_unlock(&msg->entry.lock);
+                       }
+                       
                }
                memset(&err, 0, sizeof(err));
                err.flags = (uint16_t)(BIT_QR | BIT_RA);