Commit 6b89d3f5b7 for bind
commit 6b89d3f5b730149cbb7ba8e8c66835027cbaeeb2
Author: Alessio Podda <alessio@isc.org>
Date: Thu Sep 24 15:15:50 2026 +0200
Fold rdclass choice into the switch
We fold the rdclass choice into the switch by creating a key off
rdclass and rdtype.
This also makes every non-IN rdclass be a pure copy, which is intended
behaviour.
diff --git a/lib/dns/rdata/towire.c b/lib/dns/rdata/towire.c
index e357ac4ed6..4a86571b61 100644
--- a/lib/dns/rdata/towire.c
+++ b/lib/dns/rdata/towire.c
@@ -289,11 +289,13 @@ towire_in_px(ARGS_TOWIRE) {
return dns_name_towire(&name, cctx, target);
}
+#define RDATA_KEY(rdclass, rdtype) \
+ (((uint32_t)(rdclass) << 16) | (uint32_t)(rdtype))
+
isc_result_t
dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
isc_buffer_t *target) {
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- bool use_default = false;
+ isc_result_t result;
isc_buffer_t st;
REQUIRE(rdata != NULL);
@@ -309,172 +311,113 @@ dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
st = *target;
- switch (rdata->type) {
- case dns_rdatatype_ns:
+ switch (RDATA_KEY(rdata->rdclass, rdata->type)) {
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_ns):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_md:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_md):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_mf:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_mf):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_cname:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_cname):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_soa:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_soa):
result = towire_soa(rdata, cctx, target);
break;
- case dns_rdatatype_mb:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_mb):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_mg:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_mg):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_mr:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_mr):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_ptr:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_ptr):
result = towire_name(rdata, cctx, target, true, 0, 0);
break;
- case dns_rdatatype_minfo:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_minfo):
result = towire_minfo(rdata, cctx, target);
break;
- case dns_rdatatype_mx:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_mx):
result = towire_name(rdata, cctx, target, true, 2, 0);
break;
- case dns_rdatatype_rp:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_rp):
result = towire_rp(rdata, cctx, target);
break;
- case dns_rdatatype_afsdb:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_afsdb):
result = towire_name(rdata, cctx, target, false, 2, 0);
break;
- case dns_rdatatype_rt:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_rt):
result = towire_name(rdata, cctx, target, false, 2, 0);
break;
- case dns_rdatatype_nsap_ptr:
- switch (rdata->rdclass) {
- case dns_rdataclass_in:
- result = towire_name(rdata, cctx, target, false, 0, 0);
- break;
- default:
- use_default = 1;
- break;
- }
- break;
- case dns_rdatatype_sig:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_nsap_ptr):
+ result = towire_name(rdata, cctx, target, false, 0, 0);
+ break;
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_sig):
result = towire_name(rdata, cctx, target, false, 18,
TOWIRE_NAME_REST);
break;
- case dns_rdatatype_px:
- switch (rdata->rdclass) {
- case dns_rdataclass_in:
- result = towire_in_px(rdata, cctx, target);
- break;
- default:
- use_default = 1;
- break;
- }
- break;
- case dns_rdatatype_nxt:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_px):
+ result = towire_in_px(rdata, cctx, target);
+ break;
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_nxt):
result = towire_name(rdata, cctx, target, false, 0,
TOWIRE_NAME_REST);
break;
- case dns_rdatatype_srv:
- switch (rdata->rdclass) {
- case dns_rdataclass_in:
- result = towire_name(rdata, cctx, target, false, 6, 0);
- break;
- default:
- use_default = 1;
- break;
- }
- break;
- case dns_rdatatype_naptr:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_srv):
+ result = towire_name(rdata, cctx, target, false, 6, 0);
+ break;
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_naptr):
result = towire_naptr(rdata, cctx, target);
break;
- case dns_rdatatype_kx:
- switch (rdata->rdclass) {
- case dns_rdataclass_in:
- result = towire_name(rdata, cctx, target, false, 2, 0);
- break;
- default:
- use_default = 1;
- break;
- }
- break;
- case dns_rdatatype_a6:
- switch (rdata->rdclass) {
- case dns_rdataclass_in:
- result = towire_in_a6(rdata, cctx, target);
- break;
- default:
- use_default = 1;
- break;
- }
- break;
- case dns_rdatatype_dname:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_kx):
+ result = towire_name(rdata, cctx, target, false, 2, 0);
+ break;
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_a6):
+ result = towire_in_a6(rdata, cctx, target);
+ break;
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_dname):
result = towire_name(rdata, cctx, target, false, 0, 0);
break;
- case dns_rdatatype_rrsig:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_rrsig):
result = towire_name(rdata, cctx, target, false, 18,
TOWIRE_NAME_REST);
break;
- case dns_rdatatype_nsec:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_nsec):
result = towire_name(rdata, cctx, target, false, 0,
TOWIRE_NAME_REST);
break;
- case dns_rdatatype_talink:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_talink):
result = towire_talink(rdata, cctx, target);
break;
- case dns_rdatatype_svcb:
- switch (rdata->rdclass) {
- case dns_rdataclass_in:
- result = towire_name(rdata, cctx, target, false, 2,
- TOWIRE_NAME_REST);
- break;
- default:
- use_default = 1;
- break;
- }
- break;
- case dns_rdatatype_https:
- switch (rdata->rdclass) {
- case dns_rdataclass_in:
- result = towire_name(rdata, cctx, target, false, 2,
- TOWIRE_NAME_REST);
- break;
- default:
- use_default = 1;
- break;
- }
- break;
- case dns_rdatatype_dsync:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_svcb):
+ result = towire_name(rdata, cctx, target, false, 2,
+ TOWIRE_NAME_REST);
+ break;
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_https):
+ result = towire_name(rdata, cctx, target, false, 2,
+ TOWIRE_NAME_REST);
+ break;
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_dsync):
result = towire_name(rdata, cctx, target, false, 5, 0);
break;
- case dns_rdatatype_tkey:
+ case RDATA_KEY(dns_rdataclass_in, dns_rdatatype_tkey):
result = towire_name(rdata, cctx, target, false, 0,
TOWIRE_NAME_REST);
break;
- case dns_rdatatype_tsig:
- switch (rdata->rdclass) {
- case dns_rdataclass_any:
- result = towire_name(rdata, cctx, target, false, 0,
- TOWIRE_NAME_REST);
- break;
- default:
- use_default = 1;
- break;
- }
+ case RDATA_KEY(dns_rdataclass_any, dns_rdatatype_tsig):
+ result = towire_name(rdata, cctx, target, false, 0,
+ TOWIRE_NAME_REST);
break;
default:
- use_default = 1;
+ result = mem_tobuffer(target, rdata->data, rdata->length);
break;
}
- if (use_default) {
- return mem_tobuffer(target, rdata->data, rdata->length);
- }
if (result != ISC_R_SUCCESS) {
*target = st;
dns_compress_rollback(cctx, target->used);
diff --git a/tests/dns/rdata_test.c b/tests/dns/rdata_test.c
index b3774236cc..3acb79e4c1 100644
--- a/tests/dns/rdata_test.c
+++ b/tests/dns/rdata_test.c
@@ -3934,6 +3934,42 @@ ISC_RUN_TEST_IMPL(secalg_format) {
assert_string_equal(small, "");
}
+/* Non-IN names must be copied without compression, even on repeated use. */
+ISC_RUN_TEST_IMPL(towire_other_classes) {
+ unsigned char wire[] = { 2, 'n', 's', 7, 'e', 'x',
+ 'a', 'm', 'p', 'l', 'e', 0 };
+ isc_region_t region = { .base = wire, .length = sizeof(wire) };
+ dns_rdataclass_t classes[] = { dns_rdataclass_ch, dns_rdataclass_hs,
+ 65535 };
+
+ for (size_t i = 0; i < sizeof(classes) / sizeof(classes[0]); i++) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_compress_t cctx;
+ unsigned char buf[2 * sizeof(wire)];
+ isc_buffer_t target;
+ isc_result_t result;
+
+ dns_rdata_fromregion(&rdata, classes[i], dns_rdatatype_ns,
+ ®ion);
+ dns_compress_init(&cctx, isc_g_mctx, 0);
+ isc_buffer_init(&target, buf, sizeof(buf));
+ for (size_t j = 0; j < 2; j++) {
+ result = dns_rdata_towire(&rdata, &cctx, &target);
+ assert_int_equal(result, ISC_R_SUCCESS);
+ assert_int_equal(isc_buffer_usedlength(&target),
+ (j + 1) * sizeof(wire));
+ assert_memory_equal(buf + j * sizeof(wire), wire,
+ sizeof(wire));
+ }
+ result = dns_rdata_towire(&rdata, &cctx, &target);
+ assert_int_equal(result, ISC_R_NOSPACE);
+ assert_int_equal(isc_buffer_usedlength(&target), sizeof(buf));
+ assert_memory_equal(buf, wire, sizeof(wire));
+ assert_memory_equal(buf + sizeof(wire), wire, sizeof(wire));
+ dns_compress_invalidate(&cctx);
+ }
+}
+
ISC_TEST_LIST_START
/* types */
@@ -3980,6 +4016,7 @@ ISC_TEST_ENTRY(atcname)
ISC_TEST_ENTRY(atparent)
ISC_TEST_ENTRY(iszonecutauth)
ISC_TEST_ENTRY(secalg_format)
+ISC_TEST_ENTRY(towire_other_classes)
ISC_TEST_LIST_END
ISC_TEST_MAIN