]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
dns_slabheader_fromrdataset() -> dns_rdataset_getheader()
authorEvan Hunt <each@isc.org>
Sat, 8 Feb 2025 23:41:31 +0000 (15:41 -0800)
committerEvan Hunt <each@isc.org>
Wed, 19 Feb 2025 22:58:32 +0000 (14:58 -0800)
The function name dns_slabheader_fromrdataset() was too similar
to dns_rdataslab_fromrdataset(). Instead, we now have an rdataset
method 'getheader' which is implemented for slab-type rdatasets.

A new NOHEADER rdataset attribute is set for rdatasets using
raw slabs (i.e., noqname and closest encloser proofs); when
called on rdatasets with that flag set, dns_rdataset_getheader()
returns NULL.

lib/dns/include/dns/rdataset.h
lib/dns/include/dns/rdataslab.h
lib/dns/include/dns/types.h
lib/dns/qpzone.c
lib/dns/rdataset.c
lib/dns/rdataslab.c

index 027d70cc040b55b18086a29e06fc714e5ea4c512..f386679cd8f4017c7af8d1d410edf0aac479998c 100644 (file)
@@ -50,6 +50,7 @@
 #include <isc/magic.h>
 #include <isc/stdtime.h>
 
+#include <dns/rdataslab.h>
 #include <dns/rdatastruct.h>
 #include <dns/types.h>
 
@@ -73,7 +74,7 @@ typedef enum {
        dns_rdatasetadditional_fromglue
 } dns_rdatasetadditional_t;
 
-typedef struct dns_rdatasetmethods {
+struct dns_rdatasetmethods {
        void (*disassociate)(dns_rdataset_t *rdataset DNS__DB_FLARG);
        isc_result_t (*first)(dns_rdataset_t *rdataset);
        isc_result_t (*next)(dns_rdataset_t *rdataset);
@@ -98,7 +99,8 @@ typedef struct dns_rdatasetmethods {
        void (*getownercase)(const dns_rdataset_t *rdataset, dns_name_t *name);
        isc_result_t (*addglue)(dns_rdataset_t  *rdataset,
                                dns_dbversion_t *version, dns_message_t *msg);
-} dns_rdatasetmethods_t;
+       dns_slabheader_t *(*getheader)(const dns_rdataset_t *rdataset);
+};
 
 #define DNS_RDATASET_MAGIC     ISC_MAGIC('D', 'N', 'S', 'R')
 #define DNS_RDATASET_VALID(set) ISC_MAGIC_VALID(set, DNS_RDATASET_MAGIC)
@@ -153,7 +155,7 @@ struct dns_rdataset {
         * the code referred to in the rdataset methods table. The names of
         * the structures roughly correspond to the file containing the
         * implementation, except that `rdlist` is used by `rdatalist.c`,
-        * `sdb.c`, and `sdlz.c`.
+        * and `sdlz.c`, and `slab` by `rdataslab.c`.
         *
         * Pointers in these structs use incomplete structure types,
         * because the structure definitions and corresponding typedef
@@ -179,11 +181,11 @@ struct dns_rdataset {
 
                /*
                 * A slab rdataset provides access to an rdataslab. In
-                * an rbtdb database, 'raw' will generally point to the
+                * a QP database, 'raw' will generally point to the
                 * memory immediately following a slabheader. (There
                 * is an exception in the case of rdatasets returned by
                 * the `getnoqname` and `getclosest` methods; see
-                * comments in rbtdb.c for details.)
+                * comments in rdataslab.c for details.)
                 */
                struct {
                        struct dns_db          *db;
@@ -255,7 +257,7 @@ struct dns_rdataset {
 #define DNS_RDATASETATTR_CHECKNAMES   0x00008000 /*%< Used by resolver. */
 #define DNS_RDATASETATTR_REQUIRED     0x00010000
 #define DNS_RDATASETATTR_REQUIREDGLUE DNS_RDATASETATTR_REQUIRED
-#define DNS_RDATASETATTR_UNUSED1      0x00020000
+#define DNS_RDATASETATTR_NOHEADER     0x00020000
 #define DNS_RDATASETATTR_RESIGN              0x00040000
 #define DNS_RDATASETATTR_CLOSEST      0x00080000
 #define DNS_RDATASETATTR_OPTOUT              0x00100000 /*%< OPTOUT proof */
@@ -663,3 +665,14 @@ dns_trust_totext(dns_trust_t trust);
 /*%<
  * Display trust in textual form.
  */
+
+dns_slabheader_t *
+dns_rdataset_getheader(const dns_rdataset_t *rdataset);
+/*%<
+ * Return a pointer to the slabheader for a slab rdataset. If 'rdataset'
+ * is not a slab rdataset or if the slab is raw (lacking a header), return
+ * NULL.
+ *
+ * Requires:
+ * \li 'rdataset' is a valid rdataset.
+ */
index b28868710971795aeba0386af3de8d6b906fb616..9170ef4b78783884bc6f63758f81a92662118617 100644 (file)
@@ -288,12 +288,6 @@ dns_rdataslab_equalx(dns_slabheader_t *header1, dns_slabheader_t *header2,
  *\li  true if the slabs are equal, #false otherwise.
  */
 
-dns_slabheader_t *
-dns_slabheader_fromrdataset(const dns_rdataset_t *rdataset);
-/*%
- * Returns the address of the slab header for a slab-type rdataset.
- */
-
 void *
 dns_slabheader_raw(dns_slabheader_t *header);
 /*%
index bc04362c23969638b4ea2c126d63fe816c8f2cef..0a8fdea9219c85b145f308313f0587bc5f24d202 100644 (file)
@@ -141,18 +141,19 @@ typedef uint16_t            dns_rdataclass_t;
 typedef struct dns_rdatalist     dns_rdatalist_t;
 typedef struct dns_rdataset      dns_rdataset_t;
 typedef ISC_LIST(dns_rdataset_t) dns_rdatasetlist_t;
-typedef struct dns_rdatasetiter dns_rdatasetiter_t;
-typedef uint16_t               dns_rdatatype_t;
-typedef struct dns_remote      dns_remote_t;
-typedef struct dns_request     dns_request_t;
-typedef struct dns_requestmgr  dns_requestmgr_t;
-typedef struct dns_resolver    dns_resolver_t;
-typedef struct dns_qpnode      dns_qpnode_t;
-typedef uint8_t                        dns_secalg_t;
-typedef uint8_t                        dns_secproto_t;
-typedef struct dns_signature   dns_signature_t;
-typedef struct dns_skr         dns_skr_t;
-typedef struct dns_slabheader  dns_slabheader_t;
+typedef struct dns_rdatasetiter           dns_rdatasetiter_t;
+typedef struct dns_rdatasetmethods dns_rdatasetmethods_t;
+typedef uint16_t                  dns_rdatatype_t;
+typedef struct dns_remote         dns_remote_t;
+typedef struct dns_request        dns_request_t;
+typedef struct dns_requestmgr     dns_requestmgr_t;
+typedef struct dns_resolver       dns_resolver_t;
+typedef struct dns_qpnode         dns_qpnode_t;
+typedef uint8_t                           dns_secalg_t;
+typedef uint8_t                           dns_secproto_t;
+typedef struct dns_signature      dns_signature_t;
+typedef struct dns_skr            dns_skr_t;
+typedef struct dns_slabheader     dns_slabheader_t;
 typedef ISC_LIST(dns_slabheader_t) dns_slabheaderlist_t;
 typedef struct dns_ssurule       dns_ssurule_t;
 typedef struct dns_ssutable      dns_ssutable_t;
index 8b3d67c705d4cb01878a7226bda51c024cff1618..de9f1a79a9bae2fcf8b38e8741aa9f68f424cb73 100644 (file)
@@ -2476,7 +2476,7 @@ setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
        REQUIRE(rdataset != NULL);
        REQUIRE(rdataset->methods == &dns_rdataslab_rdatasetmethods);
 
-       header = dns_slabheader_fromrdataset(rdataset);
+       header = dns_rdataset_getheader(rdataset);
 
        nlock = &qpdb->buckets[HEADERNODE(header)->locknum].lock;
        NODE_WRLOCK(nlock, &nlocktype);
@@ -5293,7 +5293,7 @@ addglue_to_message(dns_glue_t *ge, dns_message_t *msg) {
 static dns_gluelist_t *
 create_gluelist(qpzonedb_t *qpdb, qpz_version_t *version, qpznode_t *node,
                dns_rdataset_t *rdataset) {
-       dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
+       dns_slabheader_t *header = dns_rdataset_getheader(rdataset);
        dns_glue_additionaldata_ctx_t ctx = {
                .db = (dns_db_t *)qpdb,
                .version = (dns_dbversion_t *)version,
@@ -5322,7 +5322,7 @@ addglue(dns_db_t *db, dns_dbversion_t *dbversion, dns_rdataset_t *rdataset,
        qpzonedb_t *qpdb = (qpzonedb_t *)db;
        qpz_version_t *version = (qpz_version_t *)dbversion;
        qpznode_t *node = (qpznode_t *)rdataset->slab.node;
-       dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
+       dns_slabheader_t *header = dns_rdataset_getheader(rdataset);
        dns_glue_t *glue = NULL;
        isc_statscounter_t counter = dns_gluecachestatscounter_hits_absent;
 
index dc6fc4d8679fdb6b99bd8a5e1d65c70155962c73..7507c02985c4d0b901a83c731ad142d879269ed4 100644 (file)
@@ -648,3 +648,16 @@ dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
        rdataset->ttl = ttl;
        sigrdataset->ttl = ttl;
 }
+
+dns_slabheader_t *
+dns_rdataset_getheader(const dns_rdataset_t *rdataset) {
+       REQUIRE(DNS_RDATASET_VALID(rdataset));
+
+       if (rdataset->methods->getheader != NULL &&
+           (rdataset->attributes & DNS_RDATASETATTR_NOHEADER) == 0)
+       {
+               return (rdataset->methods->getheader)(rdataset);
+       }
+
+       return NULL;
+}
index c316fe5dd6ce3b3250d53f096b3e6a9b408f09a6..cdc439ab19284026d19d44fa1aed5dcbeaddbe09 100644 (file)
@@ -113,6 +113,8 @@ static void
 rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name);
 static void
 rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name);
+static dns_slabheader_t *
+rdataset_getheader(const dns_rdataset_t *rdataset);
 
 /*% Note: the "const void *" are just to make qsort happy.  */
 static int
@@ -815,12 +817,6 @@ dns_rdataslab_equalx(dns_slabheader_t *slab1, dns_slabheader_t *slab2,
        return true;
 }
 
-dns_slabheader_t *
-dns_slabheader_fromrdataset(const dns_rdataset_t *rdataset) {
-       dns_slabheader_t *header = (dns_slabheader_t *)rdataset->slab.raw;
-       return header - 1;
-}
-
 void *
 dns_slabheader_raw(dns_slabheader_t *header) {
        return header + 1;
@@ -926,6 +922,33 @@ dns_slabheader_freeproof(isc_mem_t *mctx, dns_slabheader_proof_t **proof) {
        *proof = NULL;
 }
 
+dns_slabheader_t *
+dns_slabheader_top(dns_slabheader_t *header) {
+       dns_typepair_t type, negtype;
+       dns_rdatatype_t rdtype, covers;
+
+       type = header->type;
+       rdtype = DNS_TYPEPAIR_TYPE(header->type);
+       if (NEGATIVE(header)) {
+               covers = DNS_TYPEPAIR_COVERS(header->type);
+               negtype = DNS_TYPEPAIR_VALUE(covers, 0);
+       } else {
+               negtype = DNS_TYPEPAIR_VALUE(0, rdtype);
+       }
+
+       /*
+        * Find the start of the header chain for the next type
+        * by walking back up the list.
+        */
+       while (header->up != NULL &&
+              (header->up->type == type || header->up->type == negtype))
+       {
+               header = header->up;
+       }
+
+       return header;
+}
+
 dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods = {
        .disassociate = rdataset_disassociate,
        .first = rdataset_first,
@@ -940,6 +963,7 @@ dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods = {
        .clearprefetch = rdataset_clearprefetch,
        .setownercase = rdataset_setownercase,
        .getownercase = rdataset_getownercase,
+       .getheader = rdataset_getheader,
 };
 
 /* Fixed RRSet helper macros */
@@ -1066,9 +1090,10 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
         * Usually, rdataset->slab.raw refers the data following a
         * dns_slabheader, but in this case it points to a bare
         * rdataslab belonging to the dns_slabheader's `noqname` field.
-        * The DNS_RDATASETATTR_KEEPCASE attribute is set to prevent
-        * setownercase and getownercase methods from affecting the
-        * case of NSEC/NSEC3 owner names.
+        * The DNS_RDATASETATTR_NOHEADER attribute is set so that
+        * dns_rdataset_getheader() will return NULL, and the _KEEPCASE
+        * attribute is set to prevent setownercase and getownercase
+        * methods from affecting the case of NSEC/NSEC3 owner names.
         */
        dns__db_attachnode(db, node,
                           &(dns_dbnode_t *){ NULL } DNS__DB_FLARG_PASS);
@@ -1083,7 +1108,8 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
                .slab.raw = noqname->neg,
                .link = nsec->link,
                .count = nsec->count,
-               .attributes = nsec->attributes | DNS_RDATASETATTR_KEEPCASE,
+               .attributes = nsec->attributes | DNS_RDATASETATTR_KEEPCASE |
+                             DNS_RDATASETATTR_NOHEADER,
                .magic = nsec->magic,
        };
 
@@ -1101,7 +1127,8 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
                .slab.raw = noqname->negsig,
                .link = nsecsig->link,
                .count = nsecsig->count,
-               .attributes = nsecsig->attributes | DNS_RDATASETATTR_KEEPCASE,
+               .attributes = nsecsig->attributes | DNS_RDATASETATTR_KEEPCASE |
+                             DNS_RDATASETATTR_NOHEADER,
                .magic = nsecsig->magic,
        };
 
@@ -1136,7 +1163,8 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
                .slab.raw = closest->neg,
                .link = nsec->link,
                .count = nsec->count,
-               .attributes = nsec->attributes | DNS_RDATASETATTR_KEEPCASE,
+               .attributes = nsec->attributes | DNS_RDATASETATTR_KEEPCASE |
+                             DNS_RDATASETATTR_NOHEADER,
                .magic = nsec->magic,
        };
 
@@ -1154,7 +1182,8 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
                .slab.raw = closest->negsig,
                .link = nsecsig->link,
                .count = nsecsig->count,
-               .attributes = nsecsig->attributes | DNS_RDATASETATTR_KEEPCASE,
+               .attributes = nsecsig->attributes | DNS_RDATASETATTR_KEEPCASE |
+                             DNS_RDATASETATTR_NOHEADER,
                .magic = nsecsig->magic,
        };
 
@@ -1165,7 +1194,7 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
 
 static void
 rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
-       dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
+       dns_slabheader_t *header = dns_rdataset_getheader(rdataset);
 
        dns_db_locknode(header->db, header->node, isc_rwlocktype_write);
        header->trust = rdataset->trust = trust;
@@ -1174,14 +1203,14 @@ rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
 
 static void
 rdataset_expire(dns_rdataset_t *rdataset DNS__DB_FLARG) {
-       dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
+       dns_slabheader_t *header = dns_rdataset_getheader(rdataset);
 
        dns_db_expiredata(header->db, header->node, header);
 }
 
 static void
 rdataset_clearprefetch(dns_rdataset_t *rdataset) {
-       dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
+       dns_slabheader_t *header = dns_rdataset_getheader(rdataset);
 
        dns_db_locknode(header->db, header->node, isc_rwlocktype_write);
        DNS_SLABHEADER_CLRATTR(header, DNS_SLABHEADERATTR_PREFETCH);
@@ -1190,7 +1219,7 @@ rdataset_clearprefetch(dns_rdataset_t *rdataset) {
 
 static void
 rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
-       dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
+       dns_slabheader_t *header = dns_rdataset_getheader(rdataset);
 
        dns_db_locknode(header->db, header->node, isc_rwlocktype_write);
        dns_slabheader_setownercase(header, name);
@@ -1199,7 +1228,7 @@ rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
 
 static void
 rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
-       dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
+       dns_slabheader_t *header = dns_rdataset_getheader(rdataset);
        uint8_t mask = (1 << 7);
        uint8_t bits = 0;
 
@@ -1229,29 +1258,8 @@ unlock:
        dns_db_unlocknode(header->db, header->node, isc_rwlocktype_read);
 }
 
-dns_slabheader_t *
-dns_slabheader_top(dns_slabheader_t *header) {
-       dns_typepair_t type, negtype;
-       dns_rdatatype_t rdtype, covers;
-
-       type = header->type;
-       rdtype = DNS_TYPEPAIR_TYPE(header->type);
-       if (NEGATIVE(header)) {
-               covers = DNS_TYPEPAIR_COVERS(header->type);
-               negtype = DNS_TYPEPAIR_VALUE(covers, 0);
-       } else {
-               negtype = DNS_TYPEPAIR_VALUE(0, rdtype);
-       }
-
-       /*
-        * Find the start of the header chain for the next type
-        * by walking back up the list.
-        */
-       while (header->up != NULL &&
-              (header->up->type == type || header->up->type == negtype))
-       {
-               header = header->up;
-       }
-
-       return header;
+static dns_slabheader_t *
+rdataset_getheader(const dns_rdataset_t *rdataset) {
+       dns_slabheader_t *header = (dns_slabheader_t *)rdataset->slab.raw;
+       return header - 1;
 }