mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 21:47:59 +00:00
Refactor check_stale_header() function
The check_stale_header() function now updates header_prev directly so it doesn't have to be handled in the outer loop; it's always set to the correct value of the previous header in the chain.
This commit is contained in:
parent
b24981ea02
commit
53d9ef5bd0
@ -1196,97 +1196,92 @@ static bool
|
|||||||
check_stale_header(qpcnode_t *node, dns_slabheader_t *header,
|
check_stale_header(qpcnode_t *node, dns_slabheader_t *header,
|
||||||
isc_rwlocktype_t *nlocktypep, isc_rwlock_t *nlock,
|
isc_rwlocktype_t *nlocktypep, isc_rwlock_t *nlock,
|
||||||
qpc_search_t *search, dns_slabheader_t **header_prev) {
|
qpc_search_t *search, dns_slabheader_t **header_prev) {
|
||||||
if (!ACTIVE(header, search->now)) {
|
if (ACTIVE(header, search->now)) {
|
||||||
dns_ttl_t stale = header->expire +
|
*header_prev = header;
|
||||||
STALE_TTL(header, search->qpdb);
|
return false;
|
||||||
/*
|
|
||||||
* If this data is in the stale window keep it and if
|
|
||||||
* DNS_DBFIND_STALEOK is not set we tell the caller to
|
|
||||||
* skip this record. We skip the records with ZEROTTL
|
|
||||||
* (these records should not be cached anyway).
|
|
||||||
*/
|
|
||||||
|
|
||||||
DNS_SLABHEADER_CLRATTR(header, DNS_SLABHEADERATTR_STALE_WINDOW);
|
|
||||||
if (!ZEROTTL(header) && KEEPSTALE(search->qpdb) &&
|
|
||||||
stale > search->now)
|
|
||||||
{
|
|
||||||
mark(header, DNS_SLABHEADERATTR_STALE);
|
|
||||||
*header_prev = header;
|
|
||||||
/*
|
|
||||||
* If DNS_DBFIND_STALESTART is set then it means we
|
|
||||||
* failed to resolve the name during recursion, in
|
|
||||||
* this case we mark the time in which the refresh
|
|
||||||
* failed.
|
|
||||||
*/
|
|
||||||
if ((search->options & DNS_DBFIND_STALESTART) != 0) {
|
|
||||||
atomic_store_release(
|
|
||||||
&header->last_refresh_fail_ts,
|
|
||||||
search->now);
|
|
||||||
} else if ((search->options &
|
|
||||||
DNS_DBFIND_STALEENABLED) != 0 &&
|
|
||||||
search->now <
|
|
||||||
(atomic_load_acquire(
|
|
||||||
&header->last_refresh_fail_ts) +
|
|
||||||
search->qpdb->serve_stale_refresh))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If we are within interval between last
|
|
||||||
* refresh failure time + 'stale-refresh-time',
|
|
||||||
* then don't skip this stale entry but use it
|
|
||||||
* instead.
|
|
||||||
*/
|
|
||||||
DNS_SLABHEADER_SETATTR(
|
|
||||||
header,
|
|
||||||
DNS_SLABHEADERATTR_STALE_WINDOW);
|
|
||||||
return false;
|
|
||||||
} else if ((search->options &
|
|
||||||
DNS_DBFIND_STALETIMEOUT) != 0)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We want stale RRset due to timeout, so we
|
|
||||||
* don't skip it.
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (search->options & DNS_DBFIND_STALEOK) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This rdataset is stale. If no one else is using the
|
|
||||||
* node, we can clean it up right now, otherwise we mark
|
|
||||||
* it as ancient, and the node as dirty, so it will get
|
|
||||||
* cleaned up later.
|
|
||||||
*/
|
|
||||||
if ((header->expire < search->now - QPDB_VIRTUAL) &&
|
|
||||||
(*nlocktypep == isc_rwlocktype_write ||
|
|
||||||
NODE_TRYUPGRADE(nlock, nlocktypep) == ISC_R_SUCCESS))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We update the node's status only when we can
|
|
||||||
* get write access; otherwise, we leave others
|
|
||||||
* to this work. Periodical cleaning will
|
|
||||||
* eventually take the job as the last resort.
|
|
||||||
* We won't downgrade the lock, since other
|
|
||||||
* rdatasets are probably stale, too.
|
|
||||||
*/
|
|
||||||
if (isc_refcount_current(&node->references) == 0) {
|
|
||||||
clean_stale_headers(header);
|
|
||||||
if (*header_prev != NULL) {
|
|
||||||
(*header_prev)->next = header->next;
|
|
||||||
} else {
|
|
||||||
node->data = header->next;
|
|
||||||
}
|
|
||||||
dns_slabheader_destroy(&header);
|
|
||||||
} else {
|
|
||||||
mark_ancient(header);
|
|
||||||
*header_prev = header;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*header_prev = header;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
isc_stdtime_t stale = header->expire + STALE_TTL(header, search->qpdb);
|
||||||
|
/*
|
||||||
|
* If this data is in the stale window keep it and if
|
||||||
|
* DNS_DBFIND_STALEOK is not set we tell the caller to
|
||||||
|
* skip this record. We skip the records with ZEROTTL
|
||||||
|
* (these records should not be cached anyway).
|
||||||
|
*/
|
||||||
|
|
||||||
|
DNS_SLABHEADER_CLRATTR(header, DNS_SLABHEADERATTR_STALE_WINDOW);
|
||||||
|
if (!ZEROTTL(header) && KEEPSTALE(search->qpdb) && stale > search->now)
|
||||||
|
{
|
||||||
|
mark(header, DNS_SLABHEADERATTR_STALE);
|
||||||
|
*header_prev = header;
|
||||||
|
/*
|
||||||
|
* If DNS_DBFIND_STALESTART is set then it means we
|
||||||
|
* failed to resolve the name during recursion, in
|
||||||
|
* this case we mark the time in which the refresh
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
if ((search->options & DNS_DBFIND_STALESTART) != 0) {
|
||||||
|
atomic_store_release(&header->last_refresh_fail_ts,
|
||||||
|
search->now);
|
||||||
|
} else if ((search->options & DNS_DBFIND_STALEENABLED) != 0 &&
|
||||||
|
search->now <
|
||||||
|
(atomic_load_acquire(
|
||||||
|
&header->last_refresh_fail_ts) +
|
||||||
|
search->qpdb->serve_stale_refresh))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we are within interval between last
|
||||||
|
* refresh failure time + 'stale-refresh-time',
|
||||||
|
* then don't skip this stale entry but use it
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
DNS_SLABHEADER_SETATTR(header,
|
||||||
|
DNS_SLABHEADERATTR_STALE_WINDOW);
|
||||||
|
return false;
|
||||||
|
} else if ((search->options & DNS_DBFIND_STALETIMEOUT) != 0) {
|
||||||
|
/*
|
||||||
|
* We want stale RRset due to timeout, so we
|
||||||
|
* don't skip it.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (search->options & DNS_DBFIND_STALEOK) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This rdataset is stale. If no one else is using the
|
||||||
|
* node, we can clean it up right now, otherwise we mark
|
||||||
|
* it as ancient, and the node as dirty, so it will get
|
||||||
|
* cleaned up later.
|
||||||
|
*/
|
||||||
|
if ((header->expire < search->now - QPDB_VIRTUAL) &&
|
||||||
|
(*nlocktypep == isc_rwlocktype_write ||
|
||||||
|
NODE_TRYUPGRADE(nlock, nlocktypep) == ISC_R_SUCCESS))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We update the node's status only when we can
|
||||||
|
* get write access; otherwise, we leave others
|
||||||
|
* to this work. Periodical cleaning will
|
||||||
|
* eventually take the job as the last resort.
|
||||||
|
* We won't downgrade the lock, since other
|
||||||
|
* rdatasets are probably stale, too.
|
||||||
|
*/
|
||||||
|
if (isc_refcount_current(&node->references) == 0) {
|
||||||
|
clean_stale_headers(header);
|
||||||
|
if (*header_prev != NULL) {
|
||||||
|
(*header_prev)->next = header->next;
|
||||||
|
} else {
|
||||||
|
node->data = header->next;
|
||||||
|
}
|
||||||
|
dns_slabheader_destroy(&header);
|
||||||
|
} else {
|
||||||
|
mark_ancient(header);
|
||||||
|
*header_prev = header;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*header_prev = header;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@ -1312,19 +1307,17 @@ check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) {
|
|||||||
if (check_stale_header(node, header, &nlocktype, nlock, search,
|
if (check_stale_header(node, header, &nlocktype, nlock, search,
|
||||||
&header_prev))
|
&header_prev))
|
||||||
{
|
{
|
||||||
/* Do nothing. */
|
continue;
|
||||||
} else if (header->type == dns_rdatatype_dname &&
|
}
|
||||||
EXISTS(header) && !ANCIENT(header))
|
|
||||||
|
if (header->type == dns_rdatatype_dname && EXISTS(header) &&
|
||||||
|
!ANCIENT(header))
|
||||||
{
|
{
|
||||||
dname_header = header;
|
dname_header = header;
|
||||||
header_prev = header;
|
|
||||||
} else if (header->type == DNS_SIGTYPE(dns_rdatatype_dname) &&
|
} else if (header->type == DNS_SIGTYPE(dns_rdatatype_dname) &&
|
||||||
EXISTS(header) && !ANCIENT(header))
|
EXISTS(header) && !ANCIENT(header))
|
||||||
{
|
{
|
||||||
sigdname_header = header;
|
sigdname_header = header;
|
||||||
header_prev = header;
|
|
||||||
} else {
|
|
||||||
header_prev = header;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1387,8 +1380,10 @@ find_deepest_zonecut(qpc_search_t *search, qpcnode_t *node,
|
|||||||
if (check_stale_header(node, header, &nlocktype, nlock,
|
if (check_stale_header(node, header, &nlocktype, nlock,
|
||||||
search, &header_prev))
|
search, &header_prev))
|
||||||
{
|
{
|
||||||
/* Do nothing. */
|
continue;
|
||||||
} else if (EXISTS(header) && !ANCIENT(header)) {
|
}
|
||||||
|
|
||||||
|
if (EXISTS(header) && !ANCIENT(header)) {
|
||||||
/*
|
/*
|
||||||
* We've found an extant rdataset. See if
|
* We've found an extant rdataset. See if
|
||||||
* we're interested in it.
|
* we're interested in it.
|
||||||
@ -1406,9 +1401,6 @@ find_deepest_zonecut(qpc_search_t *search, qpcnode_t *node,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
header_prev = header;
|
|
||||||
} else {
|
|
||||||
header_prev = header;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1533,8 +1525,8 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EXISTS(header) || DNS_TYPEPAIR_TYPE(header->type) == 0) {
|
if (!EXISTS(header) || DNS_TYPEPAIR_TYPE(header->type) == 0) {
|
||||||
header_prev = header;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (header->type == matchtype) {
|
if (header->type == matchtype) {
|
||||||
@ -1548,7 +1540,6 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
header_prev = header;
|
|
||||||
}
|
}
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
bindrdataset(search->qpdb, node, found, search->now, nlocktype,
|
bindrdataset(search->qpdb, node, found, search->now, nlocktype,
|
||||||
@ -1724,8 +1715,10 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||||||
if (check_stale_header(node, header, &nlocktype, nlock, &search,
|
if (check_stale_header(node, header, &nlocktype, nlock, &search,
|
||||||
&header_prev))
|
&header_prev))
|
||||||
{
|
{
|
||||||
/* Do nothing. */
|
continue;
|
||||||
} else if (EXISTS(header) && !ANCIENT(header)) {
|
}
|
||||||
|
|
||||||
|
if (EXISTS(header) && !ANCIENT(header)) {
|
||||||
/*
|
/*
|
||||||
* We now know that there is at least one active
|
* We now know that there is at least one active
|
||||||
* non-stale rdataset at this node.
|
* non-stale rdataset at this node.
|
||||||
@ -1811,9 +1804,6 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||||||
*/
|
*/
|
||||||
cnamesig = header;
|
cnamesig = header;
|
||||||
}
|
}
|
||||||
header_prev = header;
|
|
||||||
} else {
|
|
||||||
header_prev = header;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2110,7 +2100,10 @@ qpcache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (EXISTS(header) && !ANCIENT(header)) {
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EXISTS(header) && !ANCIENT(header)) {
|
||||||
if (header->type == dns_rdatatype_ns) {
|
if (header->type == dns_rdatatype_ns) {
|
||||||
found = header;
|
found = header;
|
||||||
if (foundsig != NULL) {
|
if (foundsig != NULL) {
|
||||||
@ -2124,9 +2117,6 @@ qpcache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
header_prev = header;
|
|
||||||
} else {
|
|
||||||
header_prev = header;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user