summaryrefslogtreecommitdiff
path: root/cachedb/cachedb.c
diff options
context:
space:
mode:
Diffstat (limited to 'cachedb/cachedb.c')
-rw-r--r--cachedb/cachedb.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/cachedb/cachedb.c b/cachedb/cachedb.c
index b07743d85259..245daa986967 100644
--- a/cachedb/cachedb.c
+++ b/cachedb/cachedb.c
@@ -390,6 +390,15 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
if(!qstate->return_msg || !qstate->return_msg->rep)
return 0;
+ /* do not store failures like SERVFAIL in the cachedb, this avoids
+ * overwriting expired, valid, content with broken content. */
+ if(FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
+ LDNS_RCODE_NOERROR &&
+ FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
+ LDNS_RCODE_NXDOMAIN &&
+ 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
@@ -542,10 +551,16 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
verbose(VERB_ALGO, "cachedb msg expired");
/* If serve-expired is enabled, we still use an expired message
* setting the TTL to 0. */
- if(qstate->env->cfg->serve_expired)
- adjust = -1;
- else
+ if(!qstate->env->cfg->serve_expired ||
+ (FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
+ != LDNS_RCODE_NOERROR &&
+ FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
+ != LDNS_RCODE_NXDOMAIN &&
+ FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
+ != LDNS_RCODE_YXDOMAIN))
return 0; /* message expired */
+ else
+ adjust = -1;
}
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
adjust_msg_ttl(qstate->return_msg, adjust);