diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index 027d70cc04..f386679cd8 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -50,6 +50,7 @@ #include #include +#include #include #include @@ -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. + */ diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h index b288687109..9170ef4b78 100644 --- a/lib/dns/include/dns/rdataslab.h +++ b/lib/dns/include/dns/rdataslab.h @@ -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); /*% diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index bc04362c23..0a8fdea921 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -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; diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 8b3d67c705..de9f1a79a9 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -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; diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c index dc6fc4d867..7507c02985 100644 --- a/lib/dns/rdataset.c +++ b/lib/dns/rdataset.c @@ -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; +} diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index c316fe5dd6..cdc439ab19 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -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; }