Commit 29480279 authored by Michael Graff's avatar Michael Graff
Browse files

Fix a lot of negative caching issues. I believe the code will use

ncache responses from fetches and database lookups correctly now, but
there needs to be a little more cleanup here and there.  Bugs exist.
parent 86a30f82
......@@ -25,6 +25,11 @@
*
*/
/*
* After we have cleaned all buckets, dump the database contents.
*/
#define DUMP_ADB_AFTER_CLEANING
#include <config.h>
#include <stdio.h>
......@@ -352,6 +357,10 @@ static isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t, isc_boolean_t);
#define CLEAN_LEVEL 100
#define DEF_LEVEL 5
#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
(r) == DNS_R_NCACHENXRRSET)
static void
DP(int level, char *format, ...)
{
......@@ -462,12 +471,17 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
UNLOCK(&adb->entrylocks[addr_bucket]);
if (new_addresses_added) {
if (rdtype == dns_rdatatype_a)
if (rdtype == dns_rdatatype_a) {
DP(1, "expire_v4 set to MIN(%u,%u) import_rdataset",
adbname->expire_v4, now + rdataset->ttl);
adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
now + rdataset->ttl);
else
} else {
DP(1, "expire_v6 set to MIN(%u,%u) import_rdataset",
adbname->expire_v6, now + rdataset->ttl);
adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
now + rdataset->ttl);
}
/*
* Lie a little here. This is more or less so code that cares
......@@ -538,6 +552,8 @@ import_a6(dns_a6context_t *a6ctx)
if (addr_bucket != DNS_ADB_INVALIDBUCKET)
UNLOCK(&adb->entrylocks[addr_bucket]);
DP(1, "expire_v6 set to MIN(%u,%u) in import_v6",
name->expire_v6, a6ctx->expiration);
name->expire_v6 = ISC_MIN(name->expire_v6, a6ctx->expiration);
if (address_added)
......@@ -1739,6 +1755,7 @@ cleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now)
dns_adbname_t *next_name;
DP(CLEAN_LEVEL, "cleaning bucket %d", bucket);
LOCK(&adb->namelocks[bucket]);
if (adb->name_sd[bucket]) {
UNLOCK(&adb->namelocks[bucket]);
......@@ -1785,8 +1802,12 @@ timer_cleanup(isc_task_t *task, isc_event_t *ev)
* Set the next bucket to be cleaned.
*/
adb->next_namebucket++;
if (adb->next_namebucket >= NBUCKETS)
if (adb->next_namebucket >= NBUCKETS) {
adb->next_namebucket = 0;
#ifdef DUMP_ADB_AFTER_CLEANING
dump_adb(adb, stdout);
#endif
}
#if 0
/*
......@@ -2195,6 +2216,13 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
goto v6;
}
/*
* Listen to negative cache hints, and don't start
* another query.
*/
if (NCACHE_RESULT(result))
goto v6;
/*
* Try to start fetches for v4.
*/
......@@ -2219,6 +2247,13 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
goto copy;
}
/*
* Listen to negative cache hints, and don't start
* another query.
*/
if (NCACHE_RESULT(result))
goto copy;
/*
* Try to start fetches for a6.
*/
......@@ -2899,10 +2934,10 @@ dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now,
*/
if (rdtype == dns_rdatatype_a) {
adbname->expire_v4 = rdataset.ttl + now;
DP(3, "adb name %p: Caching negative entry for A (ttl %u)",
DP(1, "adb name %p: Caching negative entry for A (ttl %u)",
adbname, rdataset.ttl);
} else {
DP(3, "adb name %p: Caching negative entry for AAAA (ttl %u)",
DP(1, "adb name %p: Caching negative entry for AAAA (ttl %u)",
adbname, rdataset.ttl);
adbname->expire_v6 = rdataset.ttl + now;
}
......@@ -2954,7 +2989,10 @@ dbfind_a6(dns_adbname_t *adbname, isc_stdtime_t now, isc_boolean_t use_hints)
* We found a negative cache entry. Pull the TTL from it
* so we won't ask again for a while.
*/
adbname->expire_v6 = rdataset.ttl + now;
DP(1, "adb name %p: Caching negative entry for A6 (ttl %u)",
adbname, rdataset.ttl);
adbname->expire_v6 = ISC_MIN(rdataset.ttl + now,
adbname->expire_v6);
}
if (dns_rdataset_isassociated(&rdataset))
......@@ -3043,6 +3081,26 @@ fetch_callback(isc_task_t *task, isc_event_t *ev)
return;
}
/*
* If we got a negative cache response, remember it.
*/
if (NCACHE_RESULT(dev->result)) {
if (address_type == DNS_ADBFIND_INET) {
DP(1, "adb fetch name %p: "
"Caching negative entry for A (ttl %u)",
name, dev->rdataset->ttl);
name->expire_v4 = ISC_MIN(name->expire_v4,
dev->rdataset->ttl + now);
} else {
DP(1, "adb fetch name %p: "
"Caching negative entry for AAAA (ttl %u)",
name, dev->rdataset->ttl);
name->expire_v6 = ISC_MIN(name->expire_v6,
dev->rdataset->ttl + now);
}
goto out;
}
/*
* Did we get back junk? If so, and there are no more fetches
* sitting out there, tell all the finds about it.
......@@ -3053,6 +3111,8 @@ fetch_callback(isc_task_t *task, isc_event_t *ev)
name->expire_v4 = ISC_MIN(name->expire_v4, now + 300);
else
name->expire_v6 = ISC_MIN(name->expire_v6, now + 300);
DP(1, "got junk in fetch for name %p (%s)",
name, isc_result_totext(dev->result));
goto out;
}
......@@ -3163,6 +3223,17 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
DP(DEF_LEVEL, "name %p: A6 failed, result %u",
name, dev->result);
/*
* If we got a negative cache response, remember it.
*/
if (NCACHE_RESULT(dev->result)) {
DP(1, "adb fetch name %p: "
"Caching negative entry for A6 (ttl %u)",
name, dev->rdataset->ttl);
name->expire_v6 = ISC_MIN(name->expire_v6,
dev->rdataset->ttl + now);
}
if (FETCH_USEHINTS(fetch))
use_hints = ISC_TRUE;
else
......@@ -3187,6 +3258,13 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
goto out;
}
/*
* Listen to negative cache hints, and don't start
* another query.
*/
if (NCACHE_RESULT(result))
goto out;
/*
* Try to start fetches for AAAA.
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment