2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

clarify dns_rdataslab_fromrdataset()

there are now two functions for creating an rdataslab from an
rdataset: dns_rdataslab_fromrdataset() creates a full slab (including
space for a slab header), and dns_rdataslab_raw_fromrdataset() creates
a raw slab.
This commit is contained in:
Evan Hunt
2025-02-07 20:07:53 -08:00
parent f1ab7f199b
commit b4bde9bef4
4 changed files with 44 additions and 24 deletions

View File

@@ -173,11 +173,17 @@ extern dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods;
isc_result_t isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
isc_region_t *region, unsigned int reservelen, isc_region_t *region, uint32_t limit);
uint32_t limit); isc_result_t
dns_rdataslab_raw_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
isc_region_t *region, uint32_t limit);
/*%< /*%<
* Slabify a rdataset. The slab area will be allocated and returned * Allocate space for a slab to hold the data in rdataset, and copy the
* in 'region'. * data into it. The resulting slab will be returned in 'region'.
*
* The dns_rdataslab_raw_fromrdataset() function allocates and fills only
* the memory needed for a raw slab. dns_rdataslab_fromrdataset() also
* allocates space for a dns_slabheader object.
* *
* Requires: * Requires:
*\li 'rdataset' is valid. *\li 'rdataset' is valid.

View File

@@ -3090,12 +3090,13 @@ addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig); result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0, maxrrperset); result = dns_rdataslab_raw_fromrdataset(&neg, mctx, &r1, maxrrperset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto cleanup; goto cleanup;
} }
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0, maxrrperset); result = dns_rdataslab_raw_fromrdataset(&negsig, mctx, &r2,
maxrrperset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto cleanup; goto cleanup;
} }
@@ -3129,12 +3130,13 @@ addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig); result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0, maxrrperset); result = dns_rdataslab_raw_fromrdataset(&neg, mctx, &r1, maxrrperset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto cleanup; goto cleanup;
} }
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0, maxrrperset); result = dns_rdataslab_raw_fromrdataset(&negsig, mctx, &r2,
maxrrperset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto cleanup; goto cleanup;
} }
@@ -3184,8 +3186,7 @@ qpcache_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
REQUIRE(version == NULL); REQUIRE(version == NULL);
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx, result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
&region, sizeof(dns_slabheader_t), &region, qpdb->maxrrperset);
qpdb->maxrrperset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
if (result == DNS_R_TOOMANYRECORDS) { if (result == DNS_R_TOOMANYRECORDS) {
dns__db_logtoomanyrecords((dns_db_t *)qpdb, dns__db_logtoomanyrecords((dns_db_t *)qpdb,

View File

@@ -2241,8 +2241,7 @@ loading_addrdataset(void *arg, const dns_name_t *name,
loading_addnode(loadctx, name, rdataset->type, rdataset->covers, &node); loading_addnode(loadctx, name, rdataset->type, rdataset->covers, &node);
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx, result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
&region, sizeof(dns_slabheader_t), &region, qpdb->maxrrperset);
qpdb->maxrrperset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
if (result == DNS_R_TOOMANYRECORDS) { if (result == DNS_R_TOOMANYRECORDS) {
dns__db_logtoomanyrecords((dns_db_t *)qpdb, name, dns__db_logtoomanyrecords((dns_db_t *)qpdb, name,
@@ -4724,8 +4723,7 @@ qpzone_addrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
rdataset->covers != dns_rdatatype_nsec3)); rdataset->covers != dns_rdatatype_nsec3));
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx, result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
&region, sizeof(dns_slabheader_t), &region, qpdb->maxrrperset);
qpdb->maxrrperset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
if (result == DNS_R_TOOMANYRECORDS) { if (result == DNS_R_TOOMANYRECORDS) {
dns__db_logtoomanyrecords((dns_db_t *)qpdb, &node->name, dns__db_logtoomanyrecords((dns_db_t *)qpdb, &node->name,
@@ -4854,8 +4852,7 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
dns_name_copy(&node->name, nodename); dns_name_copy(&node->name, nodename);
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx, result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
&region, sizeof(dns_slabheader_t), &region, 0);
0);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
return result; return result;
} }

View File

@@ -47,7 +47,7 @@
* The rdataslab structure allows iteration to occur in both load order * The rdataslab structure allows iteration to occur in both load order
* and DNSSEC order. The structure is as follows: * and DNSSEC order. The structure is as follows:
* *
* header (reservelen bytes) * header (dns_slabheader_t)
* record count (2 bytes) * record count (2 bytes)
* offset table (4 x record count bytes in load order) * offset table (4 x record count bytes in load order)
* data records * data records
@@ -56,6 +56,8 @@
* meta data (1 byte for RRSIG's) * meta data (1 byte for RRSIG's)
* data (data length bytes) * data (data length bytes)
* *
* A "raw" rdataslab is the same but without the header.
*
* DNSSEC order traversal is performed by walking the data records. * DNSSEC order traversal is performed by walking the data records.
* *
* The order is stored with record to allow for efficient reconstruction * The order is stored with record to allow for efficient reconstruction
@@ -118,10 +120,9 @@ compare_rdata(const void *p1, const void *p2) {
return dns_rdata_compare(p1, p2); return dns_rdata_compare(p1, p2);
} }
isc_result_t static isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, makeslab(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region,
isc_region_t *region, unsigned int reservelen, uint32_t maxrrperset, bool raw) {
uint32_t maxrrperset) {
/* /*
* Use &removed as a sentinel pointer for duplicate * Use &removed as a sentinel pointer for duplicate
* rdata as rdata.data == NULL is valid. * rdata as rdata.data == NULL is valid.
@@ -129,6 +130,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
static unsigned char removed; static unsigned char removed;
dns_rdata_t *rdata = NULL; dns_rdata_t *rdata = NULL;
unsigned char *rawbuf = NULL; unsigned char *rawbuf = NULL;
unsigned int headerlen = raw ? 0 : sizeof(dns_slabheader_t);
unsigned int buflen; unsigned int buflen;
isc_result_t result; isc_result_t result;
unsigned int nitems; unsigned int nitems;
@@ -136,7 +138,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
unsigned int length; unsigned int length;
unsigned int i; unsigned int i;
buflen = reservelen + 2; buflen = headerlen + 2;
nitems = dns_rdataset_count(rdataset); nitems = dns_rdataset_count(rdataset);
@@ -151,7 +153,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
rawbuf = isc_mem_get(mctx, buflen); rawbuf = isc_mem_get(mctx, buflen);
region->base = rawbuf; region->base = rawbuf;
region->length = buflen; region->length = buflen;
rawbuf += reservelen; rawbuf += headerlen;
*rawbuf++ = 0; *rawbuf++ = 0;
*rawbuf = 0; *rawbuf = 0;
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
@@ -231,6 +233,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
* Don't forget the last item! * Don't forget the last item!
*/ */
buflen += (2 + rdata[i - 1].length); buflen += (2 + rdata[i - 1].length);
/* /*
* Provide space to store the per RR meta data. * Provide space to store the per RR meta data.
*/ */
@@ -259,7 +262,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
region->base = rawbuf; region->base = rawbuf;
region->length = buflen; region->length = buflen;
rawbuf += reservelen; rawbuf += headerlen;
put_uint16(rawbuf, nitems); put_uint16(rawbuf, nitems);
@@ -272,6 +275,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
length++; length++;
} }
INSIST(length <= 0xffff); INSIST(length <= 0xffff);
put_uint16(rawbuf, length); put_uint16(rawbuf, length);
/* /*
@@ -295,6 +299,18 @@ free_rdatas:
return result; return result;
} }
isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
isc_region_t *region, uint32_t maxrrperset) {
return makeslab(rdataset, mctx, region, maxrrperset, false);
}
isc_result_t
dns_rdataslab_raw_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
isc_region_t *region, uint32_t maxrrperset) {
return makeslab(rdataset, mctx, region, maxrrperset, true);
}
unsigned int unsigned int
dns_rdataslab_sizeraw(unsigned char *slab) { dns_rdataslab_sizeraw(unsigned char *slab) {
REQUIRE(slab != NULL); REQUIRE(slab != NULL);