diff --git a/include/zone.h b/include/zone.h index b7e27a8..d384a1a 100644 --- a/include/zone.h +++ b/include/zone.h @@ -255,6 +255,8 @@ extern "C" { #define ZONE_SVC_PARAM_KEY_OHTTP (8u) /** Supported groups in TLS @draft{ietf, tls-key-share-prediction} */ #define ZONE_SVC_PARAM_KEY_TLS_SUPPORTED_GROUPS (9u) +/** DNS over CoAP resource path @rfc{9953} */ +#define ZONE_SVC_PARAM_KEY_DOCPATH (10u) /** Reserved ("invalid key") @rfc{9460} */ #define ZONE_SVC_PARAM_KEY_INVALID_KEY (65535u) /** @} */ diff --git a/src/generic/svcb.h b/src/generic/svcb.h index ffc932a..d26a752 100644 --- a/src/generic/svcb.h +++ b/src/generic/svcb.h @@ -419,6 +419,19 @@ static int32_t parse_tls_supported_groups( return 0; } +nonnull_all +static int32_t parse_docpath( + parser_t *parser, + const type_info_t *type, + const rdata_info_t *field, + uint16_t key, + const svc_param_info_t *param, + rdata_t *rdata, + const token_t *token) +{ + return parse_alpn(parser, type, field, key, param, rdata, token); +} + nonnull_all static int32_t parse_mandatory_lax( parser_t *parser, @@ -481,6 +494,8 @@ static const svc_param_info_t svc_params[] = { // draft-ietf-tls-key-share-prediction-01 section 3.1 SVC_PARAM("tls-supported-groups", 9u, MANDATORY_VALUE, parse_tls_supported_groups, parse_tls_supported_groups), + // RFC 9953 section 5: + SVC_PARAM("docpath", 10u, OPTIONAL_VALUE, parse_docpath, parse_docpath), }; static const svc_param_info_t unknown_svc_param = @@ -542,6 +557,8 @@ static really_inline size_t scan_svc_param( return (void)(*param = &svc_params[(*key = ZONE_SVC_PARAM_KEY_IPV6HINT)]), 8; else if (memcmp(data, "dohpath", 7) == 0) return (void)(*param = &svc_params[(*key = ZONE_SVC_PARAM_KEY_DOHPATH)]), 7; + else if (memcmp(data, "docpath", 7) == 0) + return (void)(*param = &svc_params[(*key = ZONE_SVC_PARAM_KEY_DOCPATH)]), 7; else if (memcmp(data, "ohttp", 5) == 0) return (void)(*param = &svc_params[(*key = ZONE_SVC_PARAM_KEY_OHTTP)]), 5; else if (memcmp(data, "tls-supported-groups", 20) == 0) diff --git a/tests/svcb.c b/tests/svcb.c index 21b7dcd..d82b272 100644 --- a/tests/svcb.c +++ b/tests/svcb.c @@ -764,6 +764,52 @@ static const char tsg_f2_text[] = PAD("tsg-f2 7200 IN SVCB 3 server.example.net. (\n" "port=\"8004\" tls-supported-groups=29,23,29 )"); +// From RFC 9953 Section 3.2.1. Examples: +static const char docpath_s1_text[] = + PAD("docpath-s1 1576 IN SVCB 1 dns.example.org. (\n" + " alpn=co docpath )"); +static const rdata_t docpath_s1_rdata = + RDATA( + 0x00, 0x01, // priority + 3, 'd', 'n', 's', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'o', 'r', 'g', 0, // target + 0x00, 0x01, 0x00, 0x03, 0x02, 'c', 'o', // alpn=co + 0x00, 0x0a, 0x00, 0x00 // docpath + ); + +static const char docpath_s2_text[] = + PAD("docpath-s2 85 IN SVCB 1 dns.example.org. (\n" + " alpn=co docpath=dns )"); +static const rdata_t docpath_s2_rdata = + RDATA( + 0x00, 0x01, // priority + 3, 'd', 'n', 's', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'o', 'r', 'g', 0, // target + 0x00, 0x01, 0x00, 0x03, 0x02, 'c', 'o', // alpn=co + 0x00, 0x0a, 0x00, 0x04, 0x03, 'd', 'n', 's' // docpath=dns + ); + +static const char docpath_s3_text[] = + PAD("docpath-s3 1643 IN SVCB 1 dns.example.org. (\n" + " alpn=co docpath=n,s )"); +static const rdata_t docpath_s3_rdata = + RDATA( + 0x00, 0x01, // priority + 3, 'd', 'n', 's', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'o', 'r', 'g', 0, // target + 0x00, 0x01, 0x00, 0x03, 0x02, 'c', 'o', // alpn=co + 0x00, 0x0a, 0x00, 0x04, 0x01, 'n', 0x01, 's' // docpath=n,s + ); + +static const char docpath_s4_text[] = + PAD("docpath-s4 429 IN SVCB 1 dns.example.org. (\n" + " alpn=h3,co dohpath=/{?dns} docpath )"); +static const rdata_t docpath_s4_rdata = + RDATA( + 0x00, 0x01, // priority + 3, 'd', 'n', 's', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'o', 'r', 'g', 0, // target + 0x00, 0x01, 0x00, 0x06, 0x02, 'h', '3', 0x02, 'c', 'o', // alpn=h3,co + 0x00, 0x07, 0x00, 0x07, '/', '{', '?', 'd', 'n', 's', '}', + 0x00, 0x0a, 0x00, 0x00 // docpath + ); + // FIXME: make a test that verifies correct behavior for no-default-alpn="some value" typedef struct test test_t; @@ -858,7 +904,11 @@ static const test_t tests[] = { { false, ZONE_TYPE_HTTPS, ZONE_SEMANTIC_ERROR, ohttp_f1_text, NULL }, { false, ZONE_TYPE_SVCB, 0, tsg_s1_text, &tsg_s1_rdata }, { false, ZONE_TYPE_SVCB, ZONE_SEMANTIC_ERROR, tsg_f1_text, NULL }, - { false, ZONE_TYPE_SVCB, ZONE_SEMANTIC_ERROR, tsg_f2_text, NULL } + { false, ZONE_TYPE_SVCB, ZONE_SEMANTIC_ERROR, tsg_f2_text, NULL }, + { false, ZONE_TYPE_SVCB, 0, docpath_s1_text, &docpath_s1_rdata }, + { false, ZONE_TYPE_SVCB, 0, docpath_s2_text, &docpath_s2_rdata }, + { false, ZONE_TYPE_SVCB, 0, docpath_s3_text, &docpath_s3_rdata }, + { false, ZONE_TYPE_SVCB, 0, docpath_s4_text, &docpath_s4_rdata } }; static int32_t add_rr(