]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove different zero TTL handling for rdataset iterator
authorMark Andrews <marka@isc.org>
Mon, 21 Nov 2022 00:59:45 +0000 (11:59 +1100)
committerMark Andrews <marka@isc.org>
Wed, 7 Dec 2022 22:20:02 +0000 (22:20 +0000)
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.

lib/dns/rbtdb.c

index 388e754037664ce9a27ed611c6c03c84777b2ae4..f765518f11e0c026fa35453a9caa26b128633d22 100644 (file)
@@ -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;