mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Add dns_db_allrdatasets options
'DNS_DB_STALEOK' returns stale rdatasets as well as current rdatasets. 'DNS_DB_EXPIREDOK' returns expired rdatasets as well as current rdatasets. This option is currently only set when DNS_DB_STALEOK is also set.
This commit is contained in:
parent
7695c36a5d
commit
85048ddeee
4 changed files with 100 additions and 36 deletions
|
|
@ -392,8 +392,8 @@ clearnode(dns_db_t *db, dns_dbnode_t *node) {
|
|||
isc_result_t result;
|
||||
dns_rdatasetiter_t *iter = NULL;
|
||||
|
||||
result = dns_db_allrdatasets(db, node, NULL, 0, (isc_stdtime_t)0,
|
||||
&iter);
|
||||
result = dns_db_allrdatasets(db, node, NULL, DNS_DB_STALEOK,
|
||||
(isc_stdtime_t)0, &iter);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -302,6 +302,9 @@ struct dns_dbonupdatelistener {
|
|||
#define DNS_DB_NONSEC3 0x4
|
||||
/*@}*/
|
||||
|
||||
#define DNS_DB_STALEOK 0x01
|
||||
#define DNS_DB_EXPIREDOK 0x02
|
||||
|
||||
/*****
|
||||
***** Methods
|
||||
*****/
|
||||
|
|
@ -1168,6 +1171,9 @@ dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||
*
|
||||
* \li 'options' controls which rdatasets are selected when interating over
|
||||
* the node.
|
||||
* 'DNS_DB_STALEOK' return stale rdatasets as well as current rdatasets.
|
||||
* 'DNS_DB_EXPIREDOK' return expired rdatasets as well as current
|
||||
* rdatasets.
|
||||
*
|
||||
* \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a
|
||||
* cache database, an rdataset will not be found unless it expires after
|
||||
|
|
|
|||
|
|
@ -1669,6 +1669,11 @@ dumptostream(dns_dumpctx_t *dctx) {
|
|||
char *bufmem;
|
||||
dns_name_t *name;
|
||||
dns_fixedname_t fixname;
|
||||
unsigned int options = DNS_DB_STALEOK;
|
||||
|
||||
if ((dctx->tctx.style.flags & DNS_STYLEFLAG_EXPIRED) != 0) {
|
||||
options |= DNS_DB_EXPIREDOK;
|
||||
}
|
||||
|
||||
bufmem = isc_mem_get(dctx->mctx, initial_buffer_length);
|
||||
|
||||
|
|
@ -1707,8 +1712,8 @@ dumptostream(dns_dumpctx_t *dctx) {
|
|||
result = dns_dbiterator_pause(dctx->dbiter);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
result = dns_db_allrdatasets(dctx->db, node, dctx->version, 0,
|
||||
dctx->now, &rdsiter);
|
||||
result = dns_db_allrdatasets(dctx->db, node, dctx->version,
|
||||
options, dctx->now, &rdsiter);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_db_detachnode(dctx->db, &node);
|
||||
goto cleanup;
|
||||
|
|
@ -1916,6 +1921,11 @@ dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db,
|
|||
isc_stdtime_t now;
|
||||
dns_totext_ctx_t ctx;
|
||||
dns_rdatasetiter_t *rdsiter = NULL;
|
||||
unsigned int options = DNS_DB_STALEOK;
|
||||
|
||||
if ((style->flags & DNS_STYLEFLAG_EXPIRED) != 0) {
|
||||
options |= DNS_DB_EXPIREDOK;
|
||||
}
|
||||
|
||||
result = totext_ctx_init(style, NULL, &ctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -1929,7 +1939,7 @@ dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db,
|
|||
|
||||
isc_buffer_init(&buffer, bufmem, initial_buffer_length);
|
||||
|
||||
result = dns_db_allrdatasets(db, node, version, 0, now, &rdsiter);
|
||||
result = dns_db_allrdatasets(db, node, version, options, now, &rdsiter);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
|
|
|||
110
lib/dns/rbtdb.c
110
lib/dns/rbtdb.c
|
|
@ -444,6 +444,12 @@ typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
|
|||
|
||||
#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
|
||||
|
||||
#define EXPIREDOK(rbtiterator) \
|
||||
(((rbtiterator)->common.options & DNS_DB_EXPIREDOK) != 0)
|
||||
|
||||
#define STALEOK(rbtiterator) \
|
||||
(((rbtiterator)->common.options & DNS_DB_STALEOK) != 0)
|
||||
|
||||
/*%
|
||||
* Number of buckets for cache DB entries (locks, LRU lists, TTL heaps).
|
||||
* There is a tradeoff issue about configuring this value: if this is too
|
||||
|
|
@ -8858,7 +8864,17 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator) {
|
|||
for (header = rbtnode->data; header != NULL; header = top_next) {
|
||||
top_next = header->next;
|
||||
do {
|
||||
if (header->serial <= serial && !IGNORE(header)) {
|
||||
dns_ttl_t stale_ttl = header->rdh_ttl;
|
||||
if (STALEOK(rbtiterator)) {
|
||||
stale_ttl += STALE_TTL(header, rbtdb);
|
||||
}
|
||||
if (EXPIREDOK(rbtiterator)) {
|
||||
if (!NONEXISTENT(header)) {
|
||||
break;
|
||||
}
|
||||
header = header->down;
|
||||
} else if (header->serial <= serial && !IGNORE(header))
|
||||
{
|
||||
/*
|
||||
* Is this a "this rdataset doesn't exist"
|
||||
* record? Or is it too old in the cache?
|
||||
|
|
@ -8869,8 +8885,7 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator) {
|
|||
* queries for 0 TTL rdatasets to work.
|
||||
*/
|
||||
if (NONEXISTENT(header) ||
|
||||
(now != 0 && now > header->rdh_ttl))
|
||||
{
|
||||
(now != 0 && now > stale_ttl)) {
|
||||
header = NULL;
|
||||
}
|
||||
break;
|
||||
|
|
@ -8906,6 +8921,7 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) {
|
|||
rbtdb_rdatatype_t type, negtype;
|
||||
dns_rdatatype_t rdtype, covers;
|
||||
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
||||
bool expiredok = EXPIREDOK(rbtiterator);
|
||||
|
||||
header = rbtiterator->current;
|
||||
if (header == NULL) {
|
||||
|
|
@ -8930,37 +8946,69 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) {
|
|||
} else {
|
||||
negtype = RBTDB_RDATATYPE_VALUE(0, rdtype);
|
||||
}
|
||||
for (header = header->next; header != NULL; header = top_next) {
|
||||
top_next = header->next;
|
||||
|
||||
/*
|
||||
* Find the start of the header chain for the next type
|
||||
* by walking back up the list.
|
||||
*/
|
||||
top_next = header->next;
|
||||
while (top_next != NULL &&
|
||||
(top_next->type == type || top_next->type == negtype))
|
||||
{
|
||||
top_next = top_next->next;
|
||||
}
|
||||
if (expiredok) {
|
||||
/*
|
||||
* If not walking back up the down list.
|
||||
* Keep walking down the list if possible or
|
||||
* start the next type.
|
||||
*/
|
||||
if (header->type != type && header->type != negtype) {
|
||||
do {
|
||||
if (header->serial <= serial && !IGNORE(header))
|
||||
{
|
||||
/*
|
||||
* Is this a "this rdataset doesn't
|
||||
* exist" record?
|
||||
*
|
||||
* Note: unlike everywhere else, we
|
||||
* check for now > header->ttl instead
|
||||
* of ">=". This allows ANY and RRSIG
|
||||
* queries for 0 TTL rdatasets to work.
|
||||
*/
|
||||
if (NONEXISTENT(header) ||
|
||||
(now != 0 && now > header->rdh_ttl))
|
||||
{
|
||||
header = NULL;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
header = header->down;
|
||||
}
|
||||
} while (header != NULL);
|
||||
if (header != NULL) {
|
||||
break;
|
||||
header = header->down != NULL ? header->down : top_next;
|
||||
} else {
|
||||
header = top_next;
|
||||
}
|
||||
for (; header != NULL; header = top_next) {
|
||||
top_next = header->next;
|
||||
do {
|
||||
dns_ttl_t stale_ttl = header->rdh_ttl;
|
||||
if (STALEOK(rbtiterator)) {
|
||||
stale_ttl += STALE_TTL(header, rbtdb);
|
||||
}
|
||||
if (expiredok) {
|
||||
if (!NONEXISTENT(header)) {
|
||||
break;
|
||||
}
|
||||
header = header->down;
|
||||
} else if (header->serial <= serial && !IGNORE(header))
|
||||
{
|
||||
/*
|
||||
* Is this a "this rdataset doesn't
|
||||
* exist" record?
|
||||
*
|
||||
* Note: unlike everywhere else, we
|
||||
* check for now > header->ttl instead
|
||||
* of ">=". This allows ANY and RRSIG
|
||||
* queries for 0 TTL rdatasets to work.
|
||||
*/
|
||||
if (NONEXISTENT(header) ||
|
||||
(now != 0 && now > stale_ttl)) {
|
||||
header = NULL;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
header = header->down;
|
||||
}
|
||||
} while (header != NULL);
|
||||
if (header != NULL) {
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Find the start of the header chain for the next type
|
||||
* by walking back up the list.
|
||||
*/
|
||||
while (top_next != NULL &&
|
||||
(top_next->type == type || top_next->type == negtype))
|
||||
{
|
||||
top_next = top_next->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue