From: Mark Andrews Date: Mon, 21 Nov 2022 00:59:45 +0000 (+1100) Subject: Remove different zero TTL handling for rdataset iterator X-Git-Tag: v9.19.8~7^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1a39328feb488c1d406a1b2d15dc6e0f882dce55;p=thirdparty%2Fbind9.git Remove different zero TTL handling for rdataset iterator Zero TTL handling does not need to be different for 'rdatasetiter_first' and 'rdatasetiter_next' and it interacts badly with 'bind_rdatadataset' which makes different determinations. --- diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 388e7540376..f765518f11e 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -8840,6 +8840,35 @@ rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { *iteratorp = NULL; } +static bool +iterator_active(dns_rbtdb_t *rbtdb, rbtdb_rdatasetiter_t *rbtiterator, + rdatasetheader_t *header) { + dns_ttl_t stale_ttl = header->rdh_ttl + STALE_TTL(header, rbtdb); + + /* + * Is this a "this rdataset doesn't exist" record? + */ + if (NONEXISTENT(header)) { + return (false); + } + + /* + * If this is a zone or this header still active then return it. + */ + if (!IS_CACHE(rbtdb) || ACTIVE(header, rbtiterator->common.now)) { + return (true); + } + + /* + * If we are not returning stale records or the rdataset is + * too old don't return it. + */ + if (!STALEOK(rbtiterator) || (rbtiterator->common.now > stale_ttl)) { + return (false); + } + return (true); +} + static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator) { rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator; @@ -8847,27 +8876,14 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator) { dns_rbtnode_t *rbtnode = rbtiterator->common.node; rbtdb_version_t *rbtversion = rbtiterator->common.version; rdatasetheader_t *header, *top_next; - rbtdb_serial_t serial; - isc_stdtime_t now; + rbtdb_serial_t serial = IS_CACHE(rbtdb) ? 1 : rbtversion->serial; isc_rwlocktype_t nlocktype = isc_rwlocktype_none; - if (IS_CACHE(rbtdb)) { - serial = 1; - now = rbtiterator->common.now; - } else { - serial = rbtversion->serial; - now = 0; - } - NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype); for (header = rbtnode->data; 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(rbtiterator)) { if (!NONEXISTENT(header)) { break; @@ -8875,17 +8891,9 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator) { 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? - * - * Note: unlike everywhere else, we - * check for now > header->rdh_ttl instead - * of ">=". This allows ANY and RRSIG - * queries for 0 TTL rdatasets to work. - */ - if (NONEXISTENT(header) || - (now != 0 && now > stale_ttl)) { + if (!iterator_active(rbtdb, rbtiterator, + header)) + { header = NULL; } break; @@ -8916,8 +8924,7 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { dns_rbtnode_t *rbtnode = rbtiterator->common.node; rbtdb_version_t *rbtversion = rbtiterator->common.version; rdatasetheader_t *header, *top_next; - rbtdb_serial_t serial; - isc_stdtime_t now; + rbtdb_serial_t serial = IS_CACHE(rbtdb) ? 1 : rbtversion->serial; rbtdb_rdatatype_t type, negtype; dns_rdatatype_t rdtype, covers; isc_rwlocktype_t nlocktype = isc_rwlocktype_none; @@ -8928,14 +8935,6 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { return (ISC_R_NOMORE); } - if (IS_CACHE(rbtdb)) { - serial = 1; - now = rbtiterator->common.now; - } else { - serial = rbtversion->serial; - now = 0; - } - NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype); type = header->type; @@ -8969,10 +8968,6 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { 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; @@ -8980,17 +8975,9 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { 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)) { + if (!iterator_active(rbtdb, rbtiterator, + header)) + { header = NULL; } break;