Skip to content

Commit

Permalink
DSYNC RR type
Browse files Browse the repository at this point in the history
  • Loading branch information
wtoorop committed Dec 30, 2024
1 parent 5187e38 commit 90ec6fa
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 4 deletions.
2 changes: 2 additions & 0 deletions include/zone.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ extern "C" {
/** Service binding @rfc{9460} */
#define ZONE_TYPE_HTTPS (65u)
/** Sender Policy Framework @rfc{7208} */
#define ZONE_TYPE_DSYNC (66u)
/** Endpoint discovery for delegation synchronization @draft{ietf, dnsop-generalized-notify} */
#define ZONE_TYPE_SPF (99u)
/** Node Identifier @rfc{6742} */
#define ZONE_TYPE_NID (104u)
Expand Down
1 change: 1 addition & 0 deletions scripts/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ static const tuple_t types_and_classes[] = {
{ "ZONEMD", 63, true },
{ "SVCB", 64, true },
{ "HTTPS", 65, true },
{ "DSYNC", 66, true },
{ "SPF", 99, true },
{ "NID", 104, true },
{ "L32", 105, true },
Expand Down
2 changes: 1 addition & 1 deletion src/generic/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static const struct {
V(0), T(16), V(0), V(0), T(56), T(14), T(22), V(0),
V(0), T(13), V(0), T(47), T(21), V(0), T(65), T(27),
V(0), V(0), V(0), V(0), V(0), T(1), T(62), V(0),
V(0), C(1), V(0), T(44), V(0), V(0), T(33), V(0),
V(0), C(1), V(0), T(44), T(66), V(0), T(33), V(0),
V(0), V(0), V(0), V(0), T(63), V(0), T(266), V(0),
C(3), T(99), T(37), V(0), V(0), V(0), C(2), T(43),
V(0), T(50), C(4), T(51), V(0), V(0), V(0), T(2),
Expand Down
76 changes: 74 additions & 2 deletions src/generic/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2189,6 +2189,71 @@ static int32_t parse_https_rdata(
return accept_rr(parser, type, rdata);
}

nonnull_all
static int32_t check_dsync_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
{
int32_t r;
size_t c = 0;
const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets;
const uint8_t *o = parser->rdata->octets;
const rdata_info_t *f = type->rdata.fields;

if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) ||
(r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) ||
(r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) ||
(r = check(&c, check_name(parser, type, &f[3], o+c, n-c))))
return r;

const uint8_t dsync_scheme = o[2];
uint16_t dsync_type;
memcpy(&dsync_type, o, sizeof(dsync_type));
dsync_type = be16toh(dsync_type);
if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS
&& dsync_type != ZONE_TYPE_CDNSKEY)
SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type));

if (c > n)
SYNTAX_ERROR(parser, "Invalid %s", NAME(type));
return accept_rr(parser, type, rdata);
}

nonnull_all
static int32_t parse_dsync_rdata(
parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token)
{
int32_t code;
const rdata_info_t *fields = type->rdata.fields;

if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
return code;
if ((code = parse_type(parser, type, &fields[0], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
return code;
if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
return code;
if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0)
return code;
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
return code;
if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
return code;
take(parser, token);

const uint8_t dsync_scheme = parser->rdata->octets[2];
uint16_t dsync_type;
memcpy(&dsync_type, parser->rdata->octets, sizeof(dsync_type));
dsync_type = be16toh(dsync_type);
if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS
&& dsync_type != ZONE_TYPE_CDNSKEY)
SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type));

return accept_rr(parser, type, rdata);
}

nonnull_all
static int32_t check_nid_rr(
parser_t *parser, const type_info_t *type, const rdata_t *rdata)
Expand Down Expand Up @@ -2847,6 +2912,13 @@ static const rdata_info_t https_rdata_fields[] = {
FIELD("params")
};

static const rdata_info_t dsync_rdata_fields[] = {
FIELD("rrtype"),
FIELD("scheme"),
FIELD("port"),
FIELD("target")
};

static const rdata_info_t spf_rdata_fields[] = {
FIELD("text")
};
Expand Down Expand Up @@ -3066,8 +3138,8 @@ static const type_info_t types[] = {
check_svcb_rr, parse_svcb_rdata),
TYPE("HTTPS", ZONE_TYPE_HTTPS, ZONE_CLASS_IN, FIELDS(https_rdata_fields),
check_https_rr, parse_https_rdata),

UNKNOWN_TYPE(66),
TYPE("DSYNC", ZONE_TYPE_DSYNC, ZONE_CLASS_ANY, FIELDS(dsync_rdata_fields),
check_dsync_rr, parse_dsync_rdata),
UNKNOWN_TYPE(67),
UNKNOWN_TYPE(68),
UNKNOWN_TYPE(69),
Expand Down
2 changes: 1 addition & 1 deletion src/westmere/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static const struct {
V(0), T(16), V(0), V(0), T(56), T(14), T(22), V(0),
V(0), T(13), V(0), T(47), T(21), V(0), T(65), T(27),
V(0), V(0), V(0), V(0), V(0), T(1), T(62), V(0),
V(0), C(1), V(0), T(44), V(0), V(0), T(33), V(0),
V(0), C(1), V(0), T(44), T(66), V(0), T(33), V(0),
V(0), V(0), V(0), V(0), T(63), V(0), T(266), V(0),
C(3), T(99), T(37), V(0), V(0), V(0), C(2), T(43),
V(0), T(50), C(4), T(51), V(0), V(0), V(0), T(2),
Expand Down
59 changes: 59 additions & 0 deletions tests/semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,62 @@ void zonemd_digest_lengths(void **state)
assert_int_equal(code, tests[i].code);
}
}

/*!cmocka */
void dsync_scheme_types(void **state)
{
static const char fmt[] =
"example.com. 86400 IN DSYNC %s %d 5359 ( type-scanner.example.net. )";
static const char hex_fmt[] =
"example.com. 86400 CLASS1 TYPE66 \\# 31 %.4x %.2x 14ef "
"( 0c747970652d7363616e6e6572076578616d706c65036e657400 )";

static const struct {
const char* dsync_type_str;
uint16_t dsync_type;
uint8_t dsync_scheme;
int32_t code;
} tests[] = {
// Schema 0: Reserved
{ "CDS" , ZONE_TYPE_CDS , 0, ZONE_SUCCESS },
{ "TYPE59" , 59 /* CDS */ , 0, ZONE_SUCCESS },
{ "CDNSKEY", ZONE_TYPE_CDNSKEY, 0, ZONE_SUCCESS },
{ "TYPE60" , 60 /* CDNSKEY */ , 0, ZONE_SUCCESS },
{ "TXT" , ZONE_TYPE_TXT , 0, ZONE_SUCCESS },
{ "TYPE16" , 16 /* TXT */ , 0, ZONE_SUCCESS },
// Scheme 1: only CDS and CDNSKEY
{ "CDS" , ZONE_TYPE_CDS , 1, ZONE_SUCCESS },
{ "TYPE59" , 59 /* CDS */ , 1, ZONE_SUCCESS },
{ "CDNSKEY", ZONE_TYPE_CDNSKEY, 1, ZONE_SUCCESS },
{ "TYPE60" , 60 /* CDNSKEY */ , 1, ZONE_SUCCESS },
{ "TXT" , ZONE_TYPE_TXT , 1, ZONE_SEMANTIC_ERROR },
{ "TYPE16" , 16 /* TXT */ , 1, ZONE_SEMANTIC_ERROR },
// Other schemes, anything goes
{ "CDS" , ZONE_TYPE_CDS , 2, ZONE_SUCCESS },
{ "TYPE59" , 59 /* CDS */ , 2, ZONE_SUCCESS },
{ "CDNSKEY", ZONE_TYPE_CDNSKEY, 2, ZONE_SUCCESS },
{ "TYPE60" , 60 /* CDNSKEY */ , 2, ZONE_SUCCESS },
{ "TXT" , ZONE_TYPE_TXT , 2, ZONE_SUCCESS },
{ "TYPE16" , 16 /* TXT */ , 2, ZONE_SUCCESS }
};

(void)state;

int32_t code;

for (size_t i=0, n = sizeof(tests)/sizeof(tests[0]); i < n; i++) {
char buf[512];
const char *dsync_type_str = tests[i].dsync_type_str;
const uint16_t dsync_type = tests[i].dsync_type;
const uint8_t dsync_scheme = tests[i].dsync_scheme;

snprintf(buf, sizeof(buf), fmt, dsync_type_str, (int)dsync_scheme);
code = parse_digest(buf);
assert_int_equal(code, tests[i].code);

/* No need to htobe16(dsync_type), since %.4x is "written" big endian */
snprintf(buf, sizeof(buf), hex_fmt, (int)dsync_type, (int)dsync_scheme);
code = parse_digest(buf);
assert_int_equal(code, tests[i].code);
}
}
27 changes: 27 additions & 0 deletions tests/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,31 @@ static const rdata_t svcb_rdata =
3, 'f', 'o', 'o', 0,
0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00);

static const char dsync_text[] =
PAD("foo. DSYNC CDS 1 5359 cds-scanner.example.net.");
static const char dsync_generic_text[] =
PAD("foo. DSYNC \\# 30 "
/* type */
"003b"
/* scheme */
"01"
/* port */
"14ef"
/* target */
"0b6364732d7363616e6e6572 076578616d706c65 036e6574 00");
static const rdata_t dsync_rdata =
RDATA(/* type */
0x00, 0x3b,
/* scheme */
0x01,
/* port */
0x14, 0xef,
/* target */
11, 'c', 'd', 's', '-', 's', 'c', 'a', 'n', 'n', 'e', 'r',
7, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
3, 'n', 'e', 't',
0);

static const char spf_text[] =
PAD("foo. SPF \"v=spf1 +all\"");
static const char spf_generic_text[] =
Expand Down Expand Up @@ -977,6 +1002,8 @@ static const test_t tests[] = {
{ ZONE_TYPE_ZONEMD, zonemd_text, &zonemd_rdata },
{ ZONE_TYPE_ZONEMD, zonemd_generic_text, &zonemd_rdata },
{ ZONE_TYPE_SVCB, svcb_text, &svcb_rdata },
{ ZONE_TYPE_DSYNC, dsync_text, &dsync_rdata },
{ ZONE_TYPE_DSYNC, dsync_generic_text, &dsync_rdata },
{ ZONE_TYPE_SPF, spf_text, &spf_rdata },
{ ZONE_TYPE_SPF, spf_generic_text, &spf_rdata },
{ ZONE_TYPE_NID, nid_text, &nid_rdata },
Expand Down

0 comments on commit 90ec6fa

Please sign in to comment.