Merge branch 'ondrej/fix-adb-entries-cleaning' into 'main'
Always set ADB entry expiration to now + ADB_ENTRY_WINDOW See merge request isc-projects/bind9!8934
This commit is contained in:
121
lib/dns/adb.c
121
lib/dns/adb.c
@@ -65,7 +65,7 @@
|
||||
*/
|
||||
#define ADB_CACHE_MINIMUM 10 /*%< seconds */
|
||||
#define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */
|
||||
#define ADB_ENTRY_WINDOW 1800 /*%< seconds */
|
||||
#define ADB_ENTRY_WINDOW 60 /*%< seconds */
|
||||
|
||||
#ifndef ADB_HASH_BITS
|
||||
#define ADB_HASH_BITS 12
|
||||
@@ -236,7 +236,7 @@ struct dns_adbentry {
|
||||
unsigned char *cookie;
|
||||
uint16_t cookielen;
|
||||
|
||||
_Atomic(isc_stdtime_t) expires;
|
||||
isc_stdtime_t expires;
|
||||
_Atomic(isc_stdtime_t) lastage;
|
||||
/*%<
|
||||
* A nonzero 'expires' field indicates that the entry should
|
||||
@@ -279,7 +279,7 @@ new_adbnamehook(dns_adb_t *adb);
|
||||
static void
|
||||
free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehookp);
|
||||
static dns_adbentry_t *
|
||||
new_adbentry(dns_adb_t *adb, const isc_sockaddr_t *addr);
|
||||
new_adbentry(dns_adb_t *adb, const isc_sockaddr_t *addr, isc_stdtime_t now);
|
||||
static void
|
||||
destroy_adbentry(dns_adbentry_t *entry);
|
||||
static bool
|
||||
@@ -441,6 +441,15 @@ enum {
|
||||
((r) == DNS_R_NCACHENXDOMAIN || (r) == DNS_R_NCACHENXRRSET)
|
||||
#define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || (r) == DNS_R_NXRRSET)
|
||||
|
||||
/*
|
||||
* Due to the ttlclamp(), the TTL is never 0 unless the trust is ultimate,
|
||||
* in which case we need to set the expiration to have immediate effect.
|
||||
*/
|
||||
#define ADJUSTED_EXPIRE(expire, now, ttl) \
|
||||
((ttl != 0) \
|
||||
? ISC_MIN(expire, ISC_MAX(now + ADB_ENTRY_WINDOW, now + ttl)) \
|
||||
: INT_MAX)
|
||||
|
||||
/*
|
||||
* Error states.
|
||||
*/
|
||||
@@ -542,6 +551,18 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
||||
|
||||
rdtype = rdataset->type;
|
||||
|
||||
switch (rdataset->trust) {
|
||||
case dns_trust_glue:
|
||||
case dns_trust_additional:
|
||||
rdataset->ttl = ADB_CACHE_MINIMUM;
|
||||
break;
|
||||
case dns_trust_ultimate:
|
||||
rdataset->ttl = 0;
|
||||
break;
|
||||
default:
|
||||
rdataset->ttl = ttlclamp(rdataset->ttl);
|
||||
}
|
||||
|
||||
REQUIRE(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
|
||||
|
||||
for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
|
||||
@@ -574,14 +595,8 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
again:
|
||||
entry = get_attached_and_locked_entry(adb, now, &sockaddr);
|
||||
|
||||
if (ENTRY_DEAD(entry)) {
|
||||
UNLOCK(&entry->lock);
|
||||
dns_adbentry_detach(&entry);
|
||||
goto again;
|
||||
}
|
||||
INSIST(!ENTRY_DEAD(entry));
|
||||
|
||||
dns_adbnamehook_t *anh = NULL;
|
||||
for (anh = ISC_LIST_HEAD(*hookhead); anh != NULL;
|
||||
@@ -605,36 +620,18 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
||||
}
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
||||
switch (rdataset->trust) {
|
||||
case dns_trust_glue:
|
||||
case dns_trust_additional:
|
||||
rdataset->ttl = ADB_CACHE_MINIMUM;
|
||||
break;
|
||||
case dns_trust_ultimate:
|
||||
rdataset->ttl = 0;
|
||||
break;
|
||||
default:
|
||||
rdataset->ttl = ttlclamp(rdataset->ttl);
|
||||
}
|
||||
|
||||
switch (rdtype) {
|
||||
case dns_rdatatype_a:
|
||||
DP(NCACHE_LEVEL,
|
||||
"expire_v4 set to MIN(%u,%u,%u) import_rdataset",
|
||||
adbname->expire_v4, now + ADB_ENTRY_WINDOW,
|
||||
now + rdataset->ttl);
|
||||
adbname->expire_v4 = ISC_MIN(
|
||||
adbname->expire_v4,
|
||||
ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
|
||||
adbname->expire_v4 = ADJUSTED_EXPIRE(adbname->expire_v4, now,
|
||||
rdataset->ttl);
|
||||
DP(NCACHE_LEVEL, "expire_v4 set to %u import_rdataset",
|
||||
adbname->expire_v4);
|
||||
break;
|
||||
case dns_rdatatype_aaaa:
|
||||
DP(NCACHE_LEVEL,
|
||||
"expire_v6 set to MIN(%u,%u,%u) import_rdataset",
|
||||
adbname->expire_v6, now + ADB_ENTRY_WINDOW,
|
||||
now + rdataset->ttl);
|
||||
adbname->expire_v6 = ISC_MIN(
|
||||
adbname->expire_v6,
|
||||
ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
|
||||
adbname->expire_v6 = ADJUSTED_EXPIRE(adbname->expire_v6, now,
|
||||
rdataset->ttl);
|
||||
DP(NCACHE_LEVEL, "expire_v6 set to %u import_rdataset",
|
||||
adbname->expire_v6);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@@ -1055,7 +1052,7 @@ free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
|
||||
}
|
||||
|
||||
static dns_adbentry_t *
|
||||
new_adbentry(dns_adb_t *adb, const isc_sockaddr_t *addr) {
|
||||
new_adbentry(dns_adb_t *adb, const isc_sockaddr_t *addr, isc_stdtime_t now) {
|
||||
dns_adbentry_t *entry = NULL;
|
||||
|
||||
entry = isc_mem_get(adb->mctx, sizeof(*entry));
|
||||
@@ -1066,6 +1063,7 @@ new_adbentry(dns_adb_t *adb, const isc_sockaddr_t *addr) {
|
||||
.quota = adb->quota,
|
||||
.references = ISC_REFCOUNT_INITIALIZER(1),
|
||||
.adb = dns_adb_ref(adb),
|
||||
.expires = now + ADB_ENTRY_WINDOW,
|
||||
.magic = DNS_ADBENTRY_MAGIC,
|
||||
};
|
||||
|
||||
@@ -1396,7 +1394,7 @@ get_attached_and_locked_entry(dns_adb_t *adb, isc_stdtime_t now,
|
||||
INSIST(locktype == isc_rwlocktype_write);
|
||||
|
||||
/* Allocate a new entry and add it to the hash table. */
|
||||
adbentry = new_adbentry(adb, addr);
|
||||
adbentry = new_adbentry(adb, addr, now);
|
||||
|
||||
void *found = NULL;
|
||||
result = isc_hashmap_add(adb->entries, hashval, match_adbentry,
|
||||
@@ -1579,9 +1577,7 @@ entry_expired(dns_adbentry_t *adbentry, isc_stdtime_t now) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (atomic_load(&adbentry->expires) == 0 ||
|
||||
atomic_load(&adbentry->expires) > now)
|
||||
{
|
||||
if (!EXPIRE_OK(adbentry->expires, now)) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
@@ -2453,10 +2449,7 @@ dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, bool debug,
|
||||
}
|
||||
fprintf(f, "]");
|
||||
}
|
||||
if (atomic_load(&entry->expires) != 0) {
|
||||
fprintf(f, " [ttl %d]",
|
||||
(int)(atomic_load(&entry->expires) - now));
|
||||
}
|
||||
fprintf(f, " [ttl %d]", entry->expires - now);
|
||||
|
||||
if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) {
|
||||
uint_fast32_t quota = atomic_load_relaxed(&entry->quota);
|
||||
@@ -2746,7 +2739,8 @@ dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
|
||||
result = DNS_R_ALIAS;
|
||||
DP(NCACHE_LEVEL, "adb name %p: caching alias target",
|
||||
adbname);
|
||||
adbname->expire_target = rdataset.ttl + now;
|
||||
adbname->expire_target = ADJUSTED_EXPIRE(
|
||||
adbname->expire_target, now, rdataset.ttl);
|
||||
}
|
||||
if (rdtype == dns_rdatatype_a) {
|
||||
adbname->fetch_err = FIND_ERR_SUCCESS;
|
||||
@@ -2828,12 +2822,12 @@ fetch_callback(void *arg) {
|
||||
if (NCACHE_RESULT(resp->result)) {
|
||||
resp->rdataset->ttl = ttlclamp(resp->rdataset->ttl);
|
||||
if (address_type == DNS_ADBFIND_INET) {
|
||||
name->expire_v4 = ADJUSTED_EXPIRE(name->expire_v4, now,
|
||||
resp->rdataset->ttl);
|
||||
DP(NCACHE_LEVEL,
|
||||
"adb fetch name %p: "
|
||||
"caching negative entry for A (ttl %u)",
|
||||
name, resp->rdataset->ttl);
|
||||
name->expire_v4 = ISC_MIN(name->expire_v4,
|
||||
resp->rdataset->ttl + now);
|
||||
name, name->expire_v4);
|
||||
if (resp->result == DNS_R_NCACHENXDOMAIN) {
|
||||
name->fetch_err = FIND_ERR_NXDOMAIN;
|
||||
} else {
|
||||
@@ -2841,12 +2835,12 @@ fetch_callback(void *arg) {
|
||||
}
|
||||
inc_resstats(adb, dns_resstatscounter_gluefetchv4fail);
|
||||
} else {
|
||||
name->expire_v6 = ADJUSTED_EXPIRE(name->expire_v6, now,
|
||||
resp->rdataset->ttl);
|
||||
DP(NCACHE_LEVEL,
|
||||
"adb fetch name %p: "
|
||||
"caching negative entry for AAAA (ttl %u)",
|
||||
name, resp->rdataset->ttl);
|
||||
name->expire_v6 = ISC_MIN(name->expire_v6,
|
||||
resp->rdataset->ttl + now);
|
||||
name, name->expire_v6);
|
||||
if (resp->result == DNS_R_NCACHENXDOMAIN) {
|
||||
name->fetch6_err = FIND_ERR_NXDOMAIN;
|
||||
} else {
|
||||
@@ -2869,7 +2863,8 @@ fetch_callback(void *arg) {
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
DP(NCACHE_LEVEL,
|
||||
"adb fetch name %p: caching alias target", name);
|
||||
name->expire_target = resp->rdataset->ttl + now;
|
||||
name->expire_target = ADJUSTED_EXPIRE(
|
||||
name->expire_target, now, resp->rdataset->ttl);
|
||||
}
|
||||
goto check_result;
|
||||
}
|
||||
@@ -3027,10 +3022,8 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt,
|
||||
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||
REQUIRE(factor <= 10);
|
||||
|
||||
dns_adbentry_t *entry = addr->entry;
|
||||
|
||||
isc_stdtime_t now = 0;
|
||||
if (atomic_load(&entry->expires) == 0 || factor == DNS_ADB_RTTADJAGE) {
|
||||
if (factor == DNS_ADB_RTTADJAGE) {
|
||||
now = isc_stdtime_now();
|
||||
}
|
||||
|
||||
@@ -3065,10 +3058,6 @@ adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
|
||||
atomic_store(&addr->entry->srtt, new_srtt);
|
||||
addr->srtt = new_srtt;
|
||||
}
|
||||
|
||||
(void)atomic_compare_exchange_strong(&addr->entry->expires,
|
||||
&(isc_stdtime_t){ 0 },
|
||||
now + ADB_ENTRY_WINDOW);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3077,7 +3066,6 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits,
|
||||
REQUIRE(DNS_ADB_VALID(adb));
|
||||
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||
|
||||
isc_stdtime_t now;
|
||||
dns_adbentry_t *entry = addr->entry;
|
||||
|
||||
unsigned int flags = atomic_load(&entry->flags);
|
||||
@@ -3087,11 +3075,6 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits,
|
||||
/* repeat */
|
||||
}
|
||||
|
||||
if (atomic_load(&entry->expires) == 0) {
|
||||
now = isc_stdtime_now();
|
||||
atomic_store(&entry->expires, now + ADB_ENTRY_WINDOW);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that we do not update the other bits in addr->flags with
|
||||
* the most recent values from addr->entry->flags.
|
||||
@@ -3352,7 +3335,6 @@ dns_adb_findaddrinfo(dns_adb_t *adb, const isc_sockaddr_t *sa,
|
||||
}
|
||||
|
||||
entry = get_attached_and_locked_entry(adb, now, sa);
|
||||
INSIST(entry != NULL);
|
||||
|
||||
UNLOCK(&entry->lock);
|
||||
|
||||
@@ -3369,7 +3351,6 @@ void
|
||||
dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
|
||||
dns_adbaddrinfo_t *addr = NULL;
|
||||
dns_adbentry_t *entry = NULL;
|
||||
isc_stdtime_t now;
|
||||
|
||||
REQUIRE(DNS_ADB_VALID(adb));
|
||||
REQUIRE(addrp != NULL);
|
||||
@@ -3383,10 +3364,6 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
|
||||
|
||||
REQUIRE(DNS_ADBENTRY_VALID(entry));
|
||||
|
||||
now = isc_stdtime_now();
|
||||
(void)atomic_compare_exchange_strong(
|
||||
&entry->expires, &(isc_stdtime_t){ 0 }, now + ADB_ENTRY_WINDOW);
|
||||
|
||||
free_adbaddrinfo(adb, &addr);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user