mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
Propagate stale attribute when updating stats (#39141)
Squashed commit of the following: commit 9b5b9fa30fbeba8ee1e95cb1028017230ed4db02 Author: Mukund Sivaraman <muks@isc.org> Date: Tue Apr 7 19:30:54 2015 +0530 Remove double function prototypes commit f3bb8cc60ae476eaa871ba10330b16425ced2d7c Author: Mukund Sivaraman <muks@isc.org> Date: Tue Apr 7 19:30:34 2015 +0530 Unify several copies of redundant code into a helper function commit 4899fb9b2f36fc5d159fa877c0780a442a7cbdb3 Author: Mukund Sivaraman <muks@isc.org> Date: Thu Apr 2 00:23:53 2015 +0530 Propagate stale attribute when updating stats
This commit is contained in:
parent
215049febb
commit
59a9cb54c1
4
CHANGES
4
CHANGES
@ -1,3 +1,7 @@
|
|||||||
|
4136. [bug] Stale statistics counters with the leading
|
||||||
|
'#' prefix (such as #NXDOMAIN) were not being
|
||||||
|
updated correctly. This has been fixed. [RT #39141]
|
||||||
|
|
||||||
4135. [cleanup] Log expired NTA at startup. [RT #39680]
|
4135. [cleanup] Log expired NTA at startup. [RT #39680]
|
||||||
|
|
||||||
4134. [cleanup] Include client-ip rules when logging the number
|
4134. [cleanup] Include client-ip rules when logging the number
|
||||||
|
@ -905,7 +905,7 @@ dns_zone_getnotifysrc4(dns_zone_t *zone);
|
|||||||
isc_dscp_t
|
isc_dscp_t
|
||||||
dns_zone_getnotifysrc4dscp(dns_zone_t *zone);
|
dns_zone_getnotifysrc4dscp(dns_zone_t *zone);
|
||||||
/*%/
|
/*%/
|
||||||
* Get the DCSP value associated with the notify source.
|
* Get the DSCP value associated with the notify source.
|
||||||
*
|
*
|
||||||
* Require:
|
* Require:
|
||||||
*\li 'zone' to be a valid zone.
|
*\li 'zone' to be a valid zone.
|
||||||
@ -923,15 +923,6 @@ dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp);
|
|||||||
*\li #ISC_R_SUCCESS
|
*\li #ISC_R_SUCCESS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isc_dscp_t
|
|
||||||
dns_zone_getnotifysrc4dscp(dns_zone_t *zone);
|
|
||||||
/*%/
|
|
||||||
* Get the DSCP value associated with the notify source.
|
|
||||||
*
|
|
||||||
* Require:
|
|
||||||
*\li 'zone' to be a valid zone.
|
|
||||||
*/
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
|
dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
|
||||||
/*%<
|
/*%<
|
||||||
@ -958,7 +949,7 @@ dns_zone_getnotifysrc6(dns_zone_t *zone);
|
|||||||
isc_dscp_t
|
isc_dscp_t
|
||||||
dns_zone_getnotifysrc6dscp(dns_zone_t *zone);
|
dns_zone_getnotifysrc6dscp(dns_zone_t *zone);
|
||||||
/*%/
|
/*%/
|
||||||
* Get the DCSP value associated with the notify source.
|
* Get the DSCP value associated with the notify source.
|
||||||
*
|
*
|
||||||
* Require:
|
* Require:
|
||||||
*\li 'zone' to be a valid zone.
|
*\li 'zone' to be a valid zone.
|
||||||
@ -976,15 +967,6 @@ dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp);
|
|||||||
*\li #ISC_R_SUCCESS
|
*\li #ISC_R_SUCCESS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isc_dscp_t
|
|
||||||
dns_zone_getnotifysrc6dscp(dns_zone_t *zone);
|
|
||||||
/*%/
|
|
||||||
* Get the DSCP value associated with the notify source.
|
|
||||||
*
|
|
||||||
* Require:
|
|
||||||
*\li 'zone' to be a valid zone.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl);
|
dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl);
|
||||||
/*%<
|
/*%<
|
||||||
|
288
lib/dns/rbtdb.c
288
lib/dns/rbtdb.c
@ -511,6 +511,8 @@ struct acachectl {
|
|||||||
(((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
|
(((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
|
||||||
#define NXDOMAIN(header) \
|
#define NXDOMAIN(header) \
|
||||||
(((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
|
(((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
|
||||||
|
#define STALE(header) \
|
||||||
|
(((header)->attributes & RDATASET_ATTR_STALE) != 0)
|
||||||
#define RESIGN(header) \
|
#define RESIGN(header) \
|
||||||
(((header)->attributes & RDATASET_ATTR_RESIGN) != 0)
|
(((header)->attributes & RDATASET_ATTR_RESIGN) != 0)
|
||||||
#define OPTOUT(header) \
|
#define OPTOUT(header) \
|
||||||
@ -1018,6 +1020,9 @@ update_rrsetstats(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
|
|||||||
} else
|
} else
|
||||||
base = RBTDB_RDATATYPE_BASE(header->type);
|
base = RBTDB_RDATATYPE_BASE(header->type);
|
||||||
|
|
||||||
|
if (STALE(header))
|
||||||
|
statattributes |= DNS_RDATASTATSTYPE_ATTR_STALE;
|
||||||
|
|
||||||
type = DNS_RDATASTATSTYPE_VALUE(base, statattributes);
|
type = DNS_RDATASTATSTYPE_VALUE(base, statattributes);
|
||||||
if (increment)
|
if (increment)
|
||||||
dns_rdatasetstats_increment(rbtdb->rrsetstats, type);
|
dns_rdatasetstats_increment(rbtdb->rrsetstats, type);
|
||||||
@ -4535,6 +4540,61 @@ zone_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
|
|||||||
return (ISC_R_NOTIMPLEMENTED);
|
return (ISC_R_NOTIMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_boolean_t
|
||||||
|
check_stale_rdataset(dns_rbtnode_t *node, rdatasetheader_t *header,
|
||||||
|
isc_rwlocktype_t *locktype, nodelock_t *lock,
|
||||||
|
rbtdb_search_t *search, rdatasetheader_t **header_prev)
|
||||||
|
{
|
||||||
|
if (header->rdh_ttl < search->now) {
|
||||||
|
/*
|
||||||
|
* This rdataset is stale. If no one else is using the
|
||||||
|
* node, we can clean it up right now, otherwise we mark
|
||||||
|
* it as stale, and the node as dirty, so it will get
|
||||||
|
* cleaned up later.
|
||||||
|
*/
|
||||||
|
if ((header->rdh_ttl < search->now - RBTDB_VIRTUAL) &&
|
||||||
|
(*locktype == isc_rwlocktype_write ||
|
||||||
|
NODE_TRYUPGRADE(lock) == 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.
|
||||||
|
*/
|
||||||
|
*locktype = isc_rwlocktype_write;
|
||||||
|
|
||||||
|
if (dns_rbtnode_refcurrent(node) == 0) {
|
||||||
|
isc_mem_t *mctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* header->down can be non-NULL if the
|
||||||
|
* refcount has just decremented to 0
|
||||||
|
* but decrement_reference() has not
|
||||||
|
* performed clean_cache_node(), in
|
||||||
|
* which case we need to purge the stale
|
||||||
|
* headers first.
|
||||||
|
*/
|
||||||
|
mctx = search->rbtdb->common.mctx;
|
||||||
|
clean_stale_headers(search->rbtdb, mctx, header);
|
||||||
|
if (*header_prev != NULL)
|
||||||
|
(*header_prev)->next = header->next;
|
||||||
|
else
|
||||||
|
node->data = header->next;
|
||||||
|
free_rdataset(search->rbtdb, mctx, header);
|
||||||
|
} else {
|
||||||
|
mark_stale_header(search->rbtdb, header);
|
||||||
|
*header_prev = header;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
*header_prev = header;
|
||||||
|
return (ISC_TRUE);
|
||||||
|
}
|
||||||
|
return (ISC_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
|
cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
|
||||||
rbtdb_search_t *search = arg;
|
rbtdb_search_t *search = arg;
|
||||||
@ -4565,57 +4625,10 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
|
|||||||
header_prev = NULL;
|
header_prev = NULL;
|
||||||
for (header = node->data; header != NULL; header = header_next) {
|
for (header = node->data; header != NULL; header = header_next) {
|
||||||
header_next = header->next;
|
header_next = header->next;
|
||||||
if (header->rdh_ttl < search->now) {
|
if (check_stale_rdataset(node, header,
|
||||||
/*
|
&locktype, lock, search,
|
||||||
* This rdataset is stale. If no one else is
|
&header_prev)) {
|
||||||
* using the node, we can clean it up right
|
/* Do nothing. */
|
||||||
* now, otherwise we mark it as stale, and
|
|
||||||
* the node as dirty, so it will get cleaned
|
|
||||||
* up later.
|
|
||||||
*/
|
|
||||||
if ((header->rdh_ttl < search->now - RBTDB_VIRTUAL) &&
|
|
||||||
(locktype == isc_rwlocktype_write ||
|
|
||||||
NODE_TRYUPGRADE(lock) == 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.
|
|
||||||
*/
|
|
||||||
locktype = isc_rwlocktype_write;
|
|
||||||
|
|
||||||
if (dns_rbtnode_refcurrent(node) == 0) {
|
|
||||||
isc_mem_t *mctx;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* header->down can be non-NULL if the
|
|
||||||
* refcount has just decremented to 0
|
|
||||||
* but decrement_reference() has not
|
|
||||||
* performed clean_cache_node(), in
|
|
||||||
* which case we need to purge the
|
|
||||||
* stale headers first.
|
|
||||||
*/
|
|
||||||
mctx = search->rbtdb->common.mctx;
|
|
||||||
clean_stale_headers(search->rbtdb,
|
|
||||||
mctx,
|
|
||||||
header);
|
|
||||||
if (header_prev != NULL)
|
|
||||||
header_prev->next =
|
|
||||||
header->next;
|
|
||||||
else
|
|
||||||
node->data = header->next;
|
|
||||||
free_rdataset(search->rbtdb, mctx,
|
|
||||||
header);
|
|
||||||
} else {
|
|
||||||
mark_stale_header(search->rbtdb,
|
|
||||||
header);
|
|
||||||
header_prev = header;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
header_prev = header;
|
|
||||||
} else if (header->type == dns_rdatatype_dname &&
|
} else if (header->type == dns_rdatatype_dname &&
|
||||||
EXISTS(header)) {
|
EXISTS(header)) {
|
||||||
dname_header = header;
|
dname_header = header;
|
||||||
@ -4684,51 +4697,12 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
|
|||||||
found = NULL;
|
found = NULL;
|
||||||
foundsig = NULL;
|
foundsig = NULL;
|
||||||
header_prev = NULL;
|
header_prev = NULL;
|
||||||
for (header = node->data;
|
for (header = node->data; header != NULL; header = header_next) {
|
||||||
header != NULL;
|
|
||||||
header = header_next) {
|
|
||||||
header_next = header->next;
|
header_next = header->next;
|
||||||
if (header->rdh_ttl < search->now) {
|
if (check_stale_rdataset(node, header,
|
||||||
/*
|
&locktype, lock, search,
|
||||||
* This rdataset is stale. If no one else is
|
&header_prev)) {
|
||||||
* using the node, we can clean it up right
|
/* Do nothing. */
|
||||||
* now, otherwise we mark it as stale, and
|
|
||||||
* the node as dirty, so it will get cleaned
|
|
||||||
* up later.
|
|
||||||
*/
|
|
||||||
if ((header->rdh_ttl < search->now -
|
|
||||||
RBTDB_VIRTUAL) &&
|
|
||||||
(locktype == isc_rwlocktype_write ||
|
|
||||||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
|
|
||||||
/*
|
|
||||||
* We update the node's status only
|
|
||||||
* when we can get write access.
|
|
||||||
*/
|
|
||||||
locktype = isc_rwlocktype_write;
|
|
||||||
|
|
||||||
if (dns_rbtnode_refcurrent(node)
|
|
||||||
== 0) {
|
|
||||||
isc_mem_t *m;
|
|
||||||
|
|
||||||
m = search->rbtdb->common.mctx;
|
|
||||||
clean_stale_headers(
|
|
||||||
search->rbtdb,
|
|
||||||
m, header);
|
|
||||||
if (header_prev != NULL)
|
|
||||||
header_prev->next =
|
|
||||||
header->next;
|
|
||||||
else
|
|
||||||
node->data =
|
|
||||||
header->next;
|
|
||||||
free_rdataset(rbtdb, m,
|
|
||||||
header);
|
|
||||||
} else {
|
|
||||||
mark_stale_header(rbtdb,
|
|
||||||
header);
|
|
||||||
header_prev = header;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
header_prev = header;
|
|
||||||
} else if (EXISTS(header)) {
|
} else if (EXISTS(header)) {
|
||||||
/*
|
/*
|
||||||
* We've found an extant rdataset. See if
|
* We've found an extant rdataset. See if
|
||||||
@ -4860,49 +4834,11 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
|||||||
foundsig = NULL;
|
foundsig = NULL;
|
||||||
empty_node = ISC_TRUE;
|
empty_node = ISC_TRUE;
|
||||||
header_prev = NULL;
|
header_prev = NULL;
|
||||||
for (header = node->data;
|
for (header = node->data; header != NULL; header = header_next) {
|
||||||
header != NULL;
|
|
||||||
header = header_next) {
|
|
||||||
header_next = header->next;
|
header_next = header->next;
|
||||||
if (header->rdh_ttl < now) {
|
if (check_stale_rdataset(node, header,
|
||||||
/*
|
&locktype, lock, search,
|
||||||
* This rdataset is stale. If no one else is
|
&header_prev)) {
|
||||||
* using the node, we can clean it up right
|
|
||||||
* now, otherwise we mark it as stale, and the
|
|
||||||
* node as dirty, so it will get cleaned up
|
|
||||||
* later.
|
|
||||||
*/
|
|
||||||
if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
|
|
||||||
(locktype == isc_rwlocktype_write ||
|
|
||||||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
|
|
||||||
/*
|
|
||||||
* We update the node's status only
|
|
||||||
* when we can get write access.
|
|
||||||
*/
|
|
||||||
locktype = isc_rwlocktype_write;
|
|
||||||
|
|
||||||
if (dns_rbtnode_refcurrent(node)
|
|
||||||
== 0) {
|
|
||||||
isc_mem_t *m;
|
|
||||||
|
|
||||||
m = search->rbtdb->common.mctx;
|
|
||||||
clean_stale_headers(
|
|
||||||
search->rbtdb,
|
|
||||||
m, header);
|
|
||||||
if (header_prev != NULL)
|
|
||||||
header_prev->next =
|
|
||||||
header->next;
|
|
||||||
else
|
|
||||||
node->data = header->next;
|
|
||||||
free_rdataset(search->rbtdb, m,
|
|
||||||
header);
|
|
||||||
} else {
|
|
||||||
mark_stale_header(search->rbtdb,
|
|
||||||
header);
|
|
||||||
header_prev = header;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
header_prev = header;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (NONEXISTENT(header) ||
|
if (NONEXISTENT(header) ||
|
||||||
@ -5085,41 +5021,10 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
|||||||
header_prev = NULL;
|
header_prev = NULL;
|
||||||
for (header = node->data; header != NULL; header = header_next) {
|
for (header = node->data; header != NULL; header = header_next) {
|
||||||
header_next = header->next;
|
header_next = header->next;
|
||||||
if (header->rdh_ttl < now) {
|
if (check_stale_rdataset(node, header,
|
||||||
/*
|
&locktype, lock, &search,
|
||||||
* This rdataset is stale. If no one else is using the
|
&header_prev)) {
|
||||||
* node, we can clean it up right now, otherwise we
|
/* Do nothing. */
|
||||||
* mark it as stale, and the node as dirty, so it will
|
|
||||||
* get cleaned up later.
|
|
||||||
*/
|
|
||||||
if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
|
|
||||||
(locktype == isc_rwlocktype_write ||
|
|
||||||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
|
|
||||||
/*
|
|
||||||
* We update the node's status only when we
|
|
||||||
* can get write access.
|
|
||||||
*/
|
|
||||||
locktype = isc_rwlocktype_write;
|
|
||||||
|
|
||||||
if (dns_rbtnode_refcurrent(node) == 0) {
|
|
||||||
isc_mem_t *mctx;
|
|
||||||
|
|
||||||
mctx = search.rbtdb->common.mctx;
|
|
||||||
clean_stale_headers(search.rbtdb, mctx,
|
|
||||||
header);
|
|
||||||
if (header_prev != NULL)
|
|
||||||
header_prev->next =
|
|
||||||
header->next;
|
|
||||||
else
|
|
||||||
node->data = header->next;
|
|
||||||
free_rdataset(search.rbtdb, mctx,
|
|
||||||
header);
|
|
||||||
} else {
|
|
||||||
mark_stale_header(search.rbtdb, header);
|
|
||||||
header_prev = header;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
header_prev = header;
|
|
||||||
} else if (EXISTS(header)) {
|
} else if (EXISTS(header)) {
|
||||||
/*
|
/*
|
||||||
* We now know that there is at least one active
|
* We now know that there is at least one active
|
||||||
@ -5391,41 +5296,10 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
|
|||||||
header_prev = NULL;
|
header_prev = NULL;
|
||||||
for (header = node->data; header != NULL; header = header_next) {
|
for (header = node->data; header != NULL; header = header_next) {
|
||||||
header_next = header->next;
|
header_next = header->next;
|
||||||
if (header->rdh_ttl < now) {
|
if (check_stale_rdataset(node, header,
|
||||||
/*
|
&locktype, lock, &search,
|
||||||
* This rdataset is stale. If no one else is using the
|
&header_prev)) {
|
||||||
* node, we can clean it up right now, otherwise we
|
/* Do nothing. */
|
||||||
* mark it as stale, and the node as dirty, so it will
|
|
||||||
* get cleaned up later.
|
|
||||||
*/
|
|
||||||
if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
|
|
||||||
(locktype == isc_rwlocktype_write ||
|
|
||||||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
|
|
||||||
/*
|
|
||||||
* We update the node's status only when we
|
|
||||||
* can get write access.
|
|
||||||
*/
|
|
||||||
locktype = isc_rwlocktype_write;
|
|
||||||
|
|
||||||
if (dns_rbtnode_refcurrent(node) == 0) {
|
|
||||||
isc_mem_t *mctx;
|
|
||||||
|
|
||||||
mctx = search.rbtdb->common.mctx;
|
|
||||||
clean_stale_headers(search.rbtdb, mctx,
|
|
||||||
header);
|
|
||||||
if (header_prev != NULL)
|
|
||||||
header_prev->next =
|
|
||||||
header->next;
|
|
||||||
else
|
|
||||||
node->data = header->next;
|
|
||||||
free_rdataset(search.rbtdb, mctx,
|
|
||||||
header);
|
|
||||||
} else {
|
|
||||||
mark_stale_header(search.rbtdb, header);
|
|
||||||
header_prev = header;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
header_prev = header;
|
|
||||||
} else if (EXISTS(header)) {
|
} else if (EXISTS(header)) {
|
||||||
/*
|
/*
|
||||||
* If we found a type we were looking for, remember
|
* If we found a type we were looking for, remember
|
||||||
|
Loading…
x
Reference in New Issue
Block a user