.mctx = mctx,
.mask = mask,
.set = set,
+ .coff = 0xffff,
};
}
*cctx = (dns_compress_t){ 0 };
}
+void
+dns_compress_setmultiuse(dns_compress_t *cctx, bool multi) {
+ REQUIRE(CCTX_VALID(cctx));
+ if (multi) {
+ cctx->flags |= DNS_COMPRESS_MULTIUSE;
+ } else {
+ cctx->flags &= ~DNS_COMPRESS_MULTIUSE;
+ }
+ cctx->coff = 0xffff;
+}
+
+bool
+dns_compress_getmultiuse(dns_compress_t *cctx) {
+ REQUIRE(CCTX_VALID(cctx));
+ return (cctx->flags & DNS_COMPRESS_MULTIUSE) != 0;
+}
+
void
dns_compress_setpermitted(dns_compress_t *cctx, bool permitted) {
REQUIRE(CCTX_VALID(cctx));
} else {
cctx->flags &= ~DNS_COMPRESS_PERMITTED;
}
+ dns_compress_setmultiuse(cctx, false);
}
bool
DNS_COMPRESS_LARGE = 0x00000004U,
/* can toggle while rendering a message */
DNS_COMPRESS_PERMITTED = 0x00000008U,
+ DNS_COMPRESS_MULTIUSE = 0x00000010U,
};
/*
dns_compress_flags_t flags;
uint16_t mask;
uint16_t count;
+ uint16_t coff;
isc_mem_t *mctx;
dns_compress_slot_t *set;
dns_compress_slot_t smallset[1 << DNS_COMPRESS_SMALLBITS];
*/
void
+dns_compress_setmultiuse(dns_compress_t *cctx, bool multi);
+/*%<
+ * Indicates this compression context is to be used for
+ * multiple calls to dns_name_towire(), for example when
+ * rendering the rdata in an rdataset. This causes the
+ * compression offset to be reusable across calls.
+ *
+ * Requires:
+ *\li 'cctx' is not NULL.
+ */
+
+bool
+dns_compress_getmultiuse(dns_compress_t *cctx);
+
+/*%<
+ * Find out whether multiuse is enabled.
+ *
+ * Requires:
+ *\li 'cctx' to be initialized.
+ *
+ * Returns:
+ *\li allowed compression bitmap.
+ */
+void
dns_compress_setpermitted(dns_compress_t *cctx, bool permitted);
/*%<
* Sets whether compression is allowed, according to RFC 3597.
- * This can vary depending on the rdata type.
+ * This can vary depending on the rdata type. This will also
+ * reset multiuse to false.
*
* Requires:
*\li 'cctx' to be initialized.
isc_result_t
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
- isc_buffer_t *target, uint16_t *comp_offsetp);
+ isc_buffer_t *target);
/*%<
* Convert 'name' into wire format, compressing it as specified by the
* compression context 'cctx', and storing the result in 'target'.
isc_result_t
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
- isc_buffer_t *target, uint16_t *name_coff) {
- bool compress;
+ isc_buffer_t *target) {
+ bool compress, multi;
unsigned int here;
unsigned int prefix_length;
unsigned int suffix_coff;
compress = !name->attributes.nocompress &&
dns_compress_getpermitted(cctx);
+ multi = compress && dns_compress_getmultiuse(cctx);
/*
* Write a compression pointer directly if the caller passed us
* a pointer to this name's offset that we saved previously.
*/
- if (compress && name_coff != NULL && *name_coff < 0x4000) {
+ if (multi && cctx->coff < 0x4000) {
if (isc_buffer_availablelength(target) < 2) {
return ISC_R_NOSPACE;
}
- isc_buffer_putuint16(target, *name_coff | 0xc000);
+ isc_buffer_putuint16(target, cctx->coff | 0xc000);
return ISC_R_SUCCESS;
}
* it isn't too short for compression to help (i.e. it's the root)
*/
here = isc_buffer_usedlength(target);
- if (name_coff != NULL && here < 0x4000 && prefix_length > 1) {
- *name_coff = (uint16_t)here;
+ if (multi && here < 0x4000 && prefix_length > 1) {
+ cctx->coff = (uint16_t)here;
}
if (prefix_length > 0) {
}
if (suffix_coff > 0) {
- if (name_coff != NULL && prefix_length == 0) {
- *name_coff = suffix_coff;
+ if (multi && prefix_length == 0) {
+ cctx->coff = suffix_coff;
}
if (isc_buffer_availablelength(target) < 2) {
return ISC_R_NOSPACE;
* Write the name.
*/
dns_compress_setpermitted(cctx, true);
- result = dns_name_towire(&name, cctx, target, NULL);
+ result = dns_name_towire(&name, cctx, target);
if (result != ISC_R_SUCCESS) {
goto rollback;
}
dns_rdata_toregion(rdata, &sr);
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
isc_region_consume(&sr, name_length(&name));
return mem_tobuffer(target, sr.base, sr.length);
}
dns_name_fromregion(&name, &sregion);
isc_region_consume(&sregion, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
isc_buffer_availableregion(target, &tregion);
if (tregion.length < 2) {
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_name_fromregion(&rmail, ®ion);
isc_region_consume(®ion, name_length(&rmail));
- RETERR(dns_name_towire(&rmail, cctx, target, NULL));
+ RETERR(dns_name_towire(&rmail, cctx, target));
dns_name_fromregion(&rmail, ®ion);
isc_region_consume(®ion, rmail.length);
- return dns_name_towire(&rmail, cctx, target, NULL);
+ return dns_name_towire(&rmail, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_name_init(&name);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
*/
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, &sr);
dns_name_fromregion(&name, &sr);
isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
return mem_tobuffer(target, sr.base, sr.length);
}
dns_rdata_toregion(rdata, &sr);
dns_name_fromregion(&name, &sr);
isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
return mem_tobuffer(target, sr.base, sr.length);
}
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_name_fromregion(&rmail, ®ion);
isc_region_consume(®ion, rmail.length);
- RETERR(dns_name_towire(&rmail, cctx, target, NULL));
+ RETERR(dns_name_towire(&rmail, cctx, target));
dns_name_fromregion(&rmail, ®ion);
isc_region_consume(®ion, rmail.length);
- return dns_name_towire(&rmail, cctx, target, NULL);
+ return dns_name_towire(&rmail, cctx, target);
}
static int
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
/*
* Signature.
dns_name_init(&name);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
/*
* Signature.
dns_name_fromregion(&mname, &sregion);
isc_region_consume(&sregion, name_length(&mname));
- RETERR(dns_name_towire(&mname, cctx, target, NULL));
+ RETERR(dns_name_towire(&mname, cctx, target));
dns_name_fromregion(&rname, &sregion);
isc_region_consume(&sregion, name_length(&rname));
- RETERR(dns_name_towire(&rname, cctx, target, NULL));
+ RETERR(dns_name_towire(&rname, cctx, target));
isc_buffer_availableregion(target, &tregion);
if (tregion.length < 20) {
dns_name_fromregion(&prev, &sregion);
isc_region_consume(&sregion, name_length(&prev));
- RETERR(dns_name_towire(&prev, cctx, target, NULL));
+ RETERR(dns_name_towire(&prev, cctx, target));
dns_name_fromregion(&next, &sregion);
isc_region_consume(&sregion, name_length(&next));
- return dns_name_towire(&next, cctx, target, NULL);
+ return dns_name_towire(&next, cctx, target);
}
static int
dns_rdata_toregion(rdata, &sr);
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
isc_region_consume(&sr, name_length(&name));
return mem_tobuffer(target, sr.base, sr.length);
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_name_init(&name);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
*/
dns_name_init(&name);
dns_name_fromregion(&name, ®ion);
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
isc_region_consume(®ion, name_length(&name));
/*
*/
dns_name_init(&name);
dns_name_fromregion(&name, ®ion);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
*/
dns_name_init(&name);
dns_name_fromregion(&name, &sr);
- return dns_name_towire(&name, cctx, target, NULL);
+ return dns_name_towire(&name, cctx, target);
}
static int
*/
dns_name_init(&name);
dns_name_fromregion(&name, ®ion);
- RETERR(dns_name_towire(&name, cctx, target, NULL));
+ RETERR(dns_name_towire(&name, cctx, target));
isc_region_consume(®ion, name_length(&name));
/*
struct towire_sort *out = out_fixed;
dns_fixedname_t fixed;
dns_name_t *name = NULL;
- uint16_t offset;
/*
* Convert 'rdataset' to wire format, compressing names as specified
name = dns_fixedname_initname(&fixed);
dns_name_copy(owner_name, name);
dns_rdataset_getownercase(rdataset, name);
- offset = 0xffff;
+ dns_compress_setmultiuse(cctx, true);
name->attributes.nocompress |= owner_name->attributes.nocompress;
rrbuffer = *target;
dns_compress_setpermitted(cctx, true);
- result = dns_name_towire(name, cctx, target, &offset);
+ result = dns_name_towire(name, cctx, target);
if (result != ISC_R_SUCCESS) {
goto rollback;
}
headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
if (!question) {
headlen += sizeof(dns_ttl_t) + 2;
- } /* XXX 2 for rdata len
- */
+ } /* XXX 2 for rdata len */
isc_buffer_availableregion(target, &r);
if (r.length < headlen) {
result = ISC_R_NOSPACE;
memset(&zr, 0, sizeof(zr));
isc_buffer_init(&zb, zone, sizeof(zone));
dns_compress_setpermitted(&cctx, false);
- result = dns_name_towire(fctx->domain, &cctx, &zb, NULL);
+ result = dns_name_towire(fctx->domain, &cctx, &zb);
if (result == ISC_R_SUCCESS) {
isc_buffer_usedregion(&zb, &zr);
}
dns_compress_init(&cctx, fctx->mctx, 0);
dns_compress_setpermitted(&cctx, false);
isc_buffer_init(&zb, zone, sizeof(zone));
- result = dns_name_towire(fctx->domain, &cctx, &zb, NULL);
+ result = dns_name_towire(fctx->domain, &cctx, &zb);
if (result == ISC_R_SUCCESS) {
isc_buffer_usedregion(&zb, &zr);
}
isc_buffer_init(&b, zone, sizeof(zone));
dns_compress_setpermitted(&cctx, false);
- eresult = dns_name_towire(zo, &cctx, &b, NULL);
+ eresult = dns_name_towire(zo, &cctx, &b);
if (eresult == ISC_R_SUCCESS) {
isc_buffer_usedregion(&b, &zr);
}
for (unsigned int i = 0; i < count; i++) {
dns_name_t *name = dns_fixedname_name(&fixedname[i]);
- result = dns_name_towire(name, &cctx, &buf, NULL);
+ result = dns_name_towire(name, &cctx, &buf);
if (result == ISC_R_NOSPACE) {
dns_compress_invalidate(&cctx);
dns_compress_init(&cctx, mctx, 0);
isc_buffer_init(&zb, zone, sizeof(zone));
dns_compress_init(&cctx, mctx, 0);
dns_compress_setpermitted(&cctx, false);
- result = dns_name_towire(zname, &cctx, &zb, NULL);
+ result = dns_name_towire(zname, &cctx, &zb);
assert_int_equal(result, ISC_R_SUCCESS);
dns_compress_invalidate(&cctx);
isc_buffer_usedregion(&zb, &zr);
if (rdata) {
/* RDATA compression */
- assert_int_equal(dns_name_towire(name1, cctx, &source, NULL),
+ assert_int_equal(dns_name_towire(name1, cctx, &source),
ISC_R_SUCCESS);
- assert_int_equal(dns_name_towire(name2, cctx, &source, NULL),
+ assert_int_equal(dns_name_towire(name2, cctx, &source),
ISC_R_SUCCESS);
- assert_int_equal(dns_name_towire(name2, cctx, &source, NULL),
+ assert_int_equal(dns_name_towire(name2, cctx, &source),
ISC_R_SUCCESS);
- assert_int_equal(dns_name_towire(name3, cctx, &source, NULL),
+ assert_int_equal(dns_name_towire(name3, cctx, &source),
ISC_R_SUCCESS);
} else {
/* Owner name compression */
- uint16_t offset = 0xffff;
- assert_int_equal(dns_name_towire(name1, cctx, &source, &offset),
+ dns_compress_setmultiuse(cctx, true);
+ assert_int_equal(dns_name_towire(name1, cctx, &source),
ISC_R_SUCCESS);
- offset = 0xffff;
- assert_int_equal(dns_name_towire(name2, cctx, &source, &offset),
+ dns_compress_setmultiuse(cctx, true);
+ assert_int_equal(dns_name_towire(name2, cctx, &source),
ISC_R_SUCCESS);
- assert_int_equal(dns_name_towire(name2, cctx, &source, &offset),
+ assert_int_equal(dns_name_towire(name2, cctx, &source),
ISC_R_SUCCESS);
- offset = 0xffff;
- assert_int_equal(dns_name_towire(name3, cctx, &source, &offset),
+ dns_compress_setmultiuse(cctx, true);
+ assert_int_equal(dns_name_towire(name3, cctx, &source),
ISC_R_SUCCESS);
}
assert_int_equal(source.used, compressed_length);
}
dns_compress_rollback(&cctx, coff);
- result = dns_name_towire(&name, &cctx, &message, NULL);
+ dns_compress_setmultiuse(&cctx, true);
+ result = dns_name_towire(&name, &cctx, &message);
assert_int_equal(result, ISC_R_SUCCESS);
/* we must be able to find the name we just added */