Parse and print HTTPS and SVCB records

This commit is contained in:
Mark Andrews 2020-11-05 17:22:52 +11:00
parent 42c22670b3
commit 36f34a3e79
17 changed files with 1913 additions and 27 deletions

View file

@ -0,0 +1,15 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 600
@ SOA ns hostmaster 2011012708 3600 1200 604800 1200
NS ns
ns A 192.0.2.1
svcb SVCB 0 . mandatory=alpn

View file

@ -0,0 +1,15 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 600
@ SOA ns hostmaster 2011012708 3600 1200 604800 1200
NS ns
ns A 192.0.2.1
svcb SVCB 0 . unknown=wha

View file

@ -0,0 +1,23 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 600
@ SOA ns hostmaster 2011012708 3600 1200 604800 1200
NS ns
ns A 192.0.2.1
svcb0 SVCB 0 example.net.
svcb1 SVCB 1 . port=60 alpn=h3 ech="ZWFzdGVyIGVnZyE="
svcb2 SVCB 2 . no-default-alpn alpn=alpn
svcb3 SVCB 3 . ipv4hint="10.10.10.10"
svcb4 SVCB 4 . ipv6hint="feed:a::bee"
svcb5 SVCB 5 . key9999="something"
svcb6 SVCB 6 . mandatory=port,alpn port=60 alpn=h3
svcb7 SVCB 7 . mandatory=port,alpn port=60 alpn=h1,h3
svcb8 SVCB 8 . mandatory=port,alpn port=60 alpn="h1\\,h2,h3"

View file

@ -2558,6 +2558,8 @@ hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4"
hinfo02.example. 3600 IN HINFO "PC" "NetBSD"
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip2.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
https0.example. 3600 IN HTTPS 0 example.net.
https1.example. 3600 IN HTTPS 1 . port=60
ipseckey01.example. 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey03.example. 3600 IN IPSECKEY 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
@ -2634,6 +2636,8 @@ srv01.example. 3600 IN SRV 0 0 0 .
srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.
sshfp01.example. 3600 IN SSHFP 4 2 C76D8329954DA2835751E371544E963EFDA099080D6C58DD2BFD9A31 6E162C83
sshfp02.example. 3600 IN SSHFP 1 2 BF29468C83AC58CCF8C85AB7B3BEB054ECF1E38512B8353AB36471FA 88961DCC
svcb0.example. 3600 IN SVCB 0 example.net.
svcb1.example. 3600 IN SVCB 1 . port=60
ta.example. 3600 IN TA 30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
talink0.example. 3600 IN TALINK . talink1.example.
talink1.example. 3600 IN TALINK talink0.example. talink2.example.

View file

@ -493,6 +493,12 @@ dlv DLV 30795 1 1 (
; type 65280-65534 (private use)
https0 HTTPS 0 example.net.
https1 HTTPS 1 . port=60
svcb0 SVCB 0 example.net.
svcb1 SVCB 1 . port=60
; keydata (internal type used for managed keys)
keydata TYPE65533 \# 0
keydata TYPE65533 \# 6 010203040506

View file

@ -59,6 +59,8 @@ CDNSKEY
OPENPGPKEY
CSYNC
ZONEMD
SVCB
HTTPS
SPF
UINFO
UID

View file

@ -59,6 +59,8 @@ hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4"
hinfo02.example. 3600 IN HINFO "PC" "NetBSD"
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip2.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
https0.example. 3600 IN HTTPS 0 example.net.
https1.example. 3600 IN HTTPS 1 . port=60
ipseckey01.example. 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey03.example. 3600 IN IPSECKEY 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
@ -137,6 +139,8 @@ sink02.example. 3600 IN SINK 8 0 2 l4ik
smimea.example. 3600 IN SMIMEA 1 1 2 92003BA34942DC74152E2F2C408D29ECA5A520E7F2E06BB944F4DCA3 46BAF63C1B177615D466F6C4B71C216A50292BD58C9EBDD2F74E38FE 51FFD48C43326CBC
srv01.example. 3600 IN SRV 0 0 0 .
srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.
svcb0.example. 3600 IN SVCB 0 example.net.
svcb1.example. 3600 IN SVCB 1 . port=60
ta.example. 3600 IN TA 30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
talink0.example. 3600 IN TALINK . talink1.example.
talink1.example. 3600 IN TALINK talink0.example. talink2.example.

View file

@ -69,6 +69,8 @@ isdn04.example. 3600 IN ISDN "isdn-address" "subaddress"
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip2.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
dnskey01.example. 3600 IN DNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
https0.example. 3600 IN HTTPS 0 example.net.
https1.example. 3600 IN HTTPS 1 . port=60
keydata.example. 3600 IN TYPE65533 \# 0
keydata.example. 3600 IN TYPE65533 \# 6 010203040506
keydata.example. 3600 IN TYPE65533 \# 18 010203040506010203040506010203040506
@ -137,6 +139,8 @@ srv01.example. 3600 IN SRV 0 0 0 .
srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.
sshfp01.example. 3600 IN SSHFP 4 2 C76D8329954DA2835751E371544E963EFDA099080D6C58DD2BFD9A31 6E162C83
sshfp02.example. 3600 IN SSHFP 1 2 BF29468C83AC58CCF8C85AB7B3BEB054ECF1E38512B8353AB36471FA 88961DCC
svcb0.example. 3600 IN SVCB 0 example.net.
svcb1.example. 3600 IN SVCB 1 . port=60
ta.example. 3600 IN TA 30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
talink0.example. 3600 IN TALINK . talink1.example.
talink1.example. 3600 IN TALINK talink0.example. talink2.example.

View file

@ -162,8 +162,9 @@
#define DNS_R_NSEC3SALTRANGE (ISC_RESULTCLASS_DNS + 124)
#define DNS_R_NSEC3BADALG (ISC_RESULTCLASS_DNS + 125)
#define DNS_R_NSEC3RESALT (ISC_RESULTCLASS_DNS + 126)
#define DNS_R_INCONSISTENTRR (ISC_RESULTCLASS_DNS + 127)
#define DNS_R_NRESULTS 127 /*%< Number of results */
#define DNS_R_NRESULTS 128 /*%< Number of results */
/*
* DNS wire format rcodes.

View file

@ -159,6 +159,13 @@ txt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
static isc_result_t
txt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
static isc_result_t
commatxt_fromtext(isc_textregion_t *source, bool comma, isc_buffer_t *target);
static isc_result_t
commatxt_totext(isc_region_t *source, bool quote, bool comma,
isc_buffer_t *target);
static isc_result_t
multitxt_totext(isc_region_t *source, isc_buffer_t *target);
@ -302,6 +309,22 @@ static isc_result_t generic_tostruct_tlsa(ARGS_TOSTRUCT);
static void generic_freestruct_tlsa(ARGS_FREESTRUCT);
static isc_result_t generic_fromtext_in_svcb(ARGS_FROMTEXT);
static isc_result_t generic_totext_in_svcb(ARGS_TOTEXT);
static isc_result_t generic_fromwire_in_svcb(ARGS_FROMWIRE);
static isc_result_t generic_towire_in_svcb(ARGS_TOWIRE);
static isc_result_t generic_fromstruct_in_svcb(ARGS_FROMSTRUCT);
static isc_result_t generic_tostruct_in_svcb(ARGS_TOSTRUCT);
static void generic_freestruct_in_svcb(ARGS_FREESTRUCT);
static isc_result_t generic_additionaldata_in_svcb(ARGS_ADDLDATA);
static bool generic_checknames_in_svcb(ARGS_CHECKNAMES);
static isc_result_t
generic_rdata_in_svcb_first(dns_rdata_in_svcb_t *);
static isc_result_t
generic_rdata_in_svcb_next(dns_rdata_in_svcb_t *);
static void
generic_rdata_in_svcb_current(dns_rdata_in_svcb_t *, isc_region_t *);
/*% INT16 Size */
#define NS_INT16SZ 2
/*% IPv6 Address Size */
@ -1415,7 +1438,8 @@ name_length(const dns_name_t *name) {
}
static isc_result_t
txt_totext(isc_region_t *source, bool quote, isc_buffer_t *target) {
commatxt_totext(isc_region_t *source, bool quote, bool comma,
isc_buffer_t *target) {
unsigned int tl;
unsigned int n;
unsigned char *sp;
@ -1445,30 +1469,48 @@ txt_totext(isc_region_t *source, bool quote, isc_buffer_t *target) {
/*
* \DDD space (0x20) if not quoting.
*/
if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) {
if (*sp < (quote ? ' ' : '!') || *sp >= 0x7f) {
if (tl < 4) {
return (ISC_R_NOSPACE);
}
*tp++ = 0x5c;
*tp++ = 0x30 + ((*sp / 100) % 10);
*tp++ = 0x30 + ((*sp / 10) % 10);
*tp++ = 0x30 + (*sp % 10);
*tp++ = '\\';
*tp++ = '0' + ((*sp / 100) % 10);
*tp++ = '0' + ((*sp / 10) % 10);
*tp++ = '0' + (*sp % 10);
sp++;
tl -= 4;
continue;
}
/*
* Escape double quote and backslash. If we are not
* enclosing the string in double quotes also escape
* at sign and semicolon.
* enclosing the string in double quotes, also escape
* at sign (@) and semicolon (;) unless comma is set.
* If comma is set, then only escape commas (,).
*/
if (*sp == 0x22 || *sp == 0x5c ||
(!quote && (*sp == 0x40 || *sp == 0x3b))) {
if (*sp == '"' || *sp == '\\' || (comma && *sp == ',') ||
(!comma && !quote && (*sp == '@' || *sp == ';')))
{
if (tl < 2) {
return (ISC_R_NOSPACE);
}
*tp++ = '\\';
tl--;
/*
* Perform comma escape processing.
* ',' => '\\,'
* '\' => '\\\\'
*/
if (comma && (*sp == ',' || *sp == '\\')) {
if (tl < ((*sp == '\\') ? 3 : 2)) {
return (ISC_R_NOSPACE);
}
*tp++ = '\\';
tl--;
if (*sp == '\\') {
*tp++ = '\\';
tl--;
}
}
}
if (tl < 1) {
return (ISC_R_NOSPACE);
@ -1490,9 +1532,14 @@ txt_totext(isc_region_t *source, bool quote, isc_buffer_t *target) {
}
static isc_result_t
txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
txt_totext(isc_region_t *source, bool quote, isc_buffer_t *target) {
return (commatxt_totext(source, quote, false, target));
}
static isc_result_t
commatxt_fromtext(isc_textregion_t *source, bool comma, isc_buffer_t *target) {
isc_region_t tregion;
bool escape;
bool escape = false, comma_escape = false, seen_comma = false;
unsigned int n, nrem;
char *s;
unsigned char *t;
@ -1504,7 +1551,6 @@ txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
n = source->length;
t = tregion.base;
nrem = tregion.length;
escape = false;
if (nrem < 1) {
return (ISC_R_NOSPACE);
}
@ -1549,6 +1595,25 @@ txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
continue;
}
escape = false;
/*
* Level 1 escape processing complete.
* If comma is set perform comma escape processing.
*
* Level 1 Level 2 ALPN's
* h1\,h2 => h1,h2 => h1 and h2
* h1\\,h2 => h1\,h2 => h1,h2
* h1\\h2 => h1\h2 => h1h2
* h1\\\\h2 => h1\\h2 => h1\h2
*/
if (comma && !comma_escape && c == ',') {
seen_comma = true;
break;
}
if (comma && !comma_escape && c == '\\') {
comma_escape = true;
continue;
}
comma_escape = false;
if (nrem == 0) {
return ((tregion.length <= 256U) ? ISC_R_NOSPACE
: DNS_R_SYNTAX);
@ -1556,14 +1621,41 @@ txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
*t++ = c;
nrem--;
}
if (escape) {
/*
* Incomplete escape processing?
*/
if (escape || (comma && comma_escape)) {
return (DNS_R_SYNTAX);
}
if (comma) {
/*
* Disallow empty ALPN at start (",h1") or in the
* middle ("h1,,h2").
*/
if (s == source->base || (seen_comma && s == source->base + 1))
{
return (DNS_R_SYNTAX);
}
isc_textregion_consume(source, s - source->base);
/*
* Disallow empty ALPN at end ("h1,").
*/
if (seen_comma && source->length == 0) {
return (DNS_R_SYNTAX);
}
}
*tregion.base = (unsigned char)(t - tregion.base - 1);
isc_buffer_add(target, *tregion.base + 1);
return (ISC_R_SUCCESS);
}
static isc_result_t
txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
return (commatxt_fromtext(source, false, target));
}
static isc_result_t
txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
unsigned int n;
@ -1618,20 +1710,20 @@ multitxt_totext(isc_region_t *source, isc_buffer_t *target) {
n0 = source->length - 1;
while (n--) {
if (*sp < 0x20 || *sp >= 0x7f) {
if (*sp < ' ' || *sp >= 0x7f) {
if (tl < 4) {
return (ISC_R_NOSPACE);
}
*tp++ = 0x5c;
*tp++ = 0x30 + ((*sp / 100) % 10);
*tp++ = 0x30 + ((*sp / 10) % 10);
*tp++ = 0x30 + (*sp % 10);
*tp++ = '\\';
*tp++ = '0' + ((*sp / 100) % 10);
*tp++ = '0' + ((*sp / 10) % 10);
*tp++ = '0' + (*sp % 10);
sp++;
tl -= 4;
continue;
}
/* double quote, backslash */
if (*sp == 0x22 || *sp == 0x5c) {
if (*sp == '"' || *sp == '\\') {
if (tl < 2) {
return (ISC_R_NOSPACE);
}

View file

@ -0,0 +1,184 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/* draft-ietf-dnsop-svcb-https-02 */
#ifndef RDATA_IN_1_HTTPS_65_C
#define RDATA_IN_1_HTTPS_65_C
#define RRTYPE_HTTPS_ATTRIBUTES 0
/*
* Most of these functions refer to equivalent functions for SVCB,
* since wire and presentation formats are identical.
*/
static inline isc_result_t
fromtext_in_https(ARGS_FROMTEXT) {
REQUIRE(type == dns_rdatatype_https);
REQUIRE(rdclass == dns_rdataclass_in);
return (generic_fromtext_in_svcb(CALL_FROMTEXT));
}
static inline isc_result_t
totext_in_https(ARGS_TOTEXT) {
REQUIRE(rdata->type == dns_rdatatype_https);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
REQUIRE(rdata->length != 0);
return (generic_totext_in_svcb(CALL_TOTEXT));
}
static inline isc_result_t
fromwire_in_https(ARGS_FROMWIRE) {
REQUIRE(type == dns_rdatatype_https);
REQUIRE(rdclass == dns_rdataclass_in);
return (generic_fromwire_in_svcb(CALL_FROMWIRE));
}
static inline isc_result_t
towire_in_https(ARGS_TOWIRE) {
REQUIRE(rdata->type == dns_rdatatype_https);
REQUIRE(rdata->length != 0);
return (generic_towire_in_svcb(CALL_TOWIRE));
}
static inline int
compare_in_https(ARGS_COMPARE) {
isc_region_t region1;
isc_region_t region2;
REQUIRE(rdata1->type == rdata2->type);
REQUIRE(rdata1->rdclass == rdata2->rdclass);
REQUIRE(rdata1->type == dns_rdatatype_https);
REQUIRE(rdata1->rdclass == dns_rdataclass_in);
REQUIRE(rdata1->length != 0);
REQUIRE(rdata2->length != 0);
dns_rdata_toregion(rdata1, &region1);
dns_rdata_toregion(rdata2, &region2);
return (isc_region_compare(&region1, &region2));
}
static inline isc_result_t
fromstruct_in_https(ARGS_FROMSTRUCT) {
dns_rdata_in_https_t *https = source;
REQUIRE(type == dns_rdatatype_https);
REQUIRE(rdclass == dns_rdataclass_in);
REQUIRE(https != NULL);
REQUIRE(https->common.rdtype == type);
REQUIRE(https->common.rdclass == rdclass);
return (generic_fromstruct_in_svcb(CALL_FROMSTRUCT));
}
static inline isc_result_t
tostruct_in_https(ARGS_TOSTRUCT) {
dns_rdata_in_https_t *https = target;
REQUIRE(rdata->rdclass == dns_rdataclass_in);
REQUIRE(rdata->type == dns_rdatatype_https);
REQUIRE(https != NULL);
REQUIRE(rdata->length != 0);
return (generic_tostruct_in_svcb(CALL_TOSTRUCT));
}
static inline void
freestruct_in_https(ARGS_FREESTRUCT) {
dns_rdata_in_https_t *https = source;
REQUIRE(https != NULL);
REQUIRE(https->common.rdclass == dns_rdataclass_in);
REQUIRE(https->common.rdtype == dns_rdatatype_https);
generic_freestruct_in_svcb(CALL_FREESTRUCT);
}
static inline isc_result_t
additionaldata_in_https(ARGS_ADDLDATA) {
REQUIRE(rdata->type == dns_rdatatype_https);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
return (generic_additionaldata_in_svcb(CALL_ADDLDATA));
}
static inline isc_result_t
digest_in_https(ARGS_DIGEST) {
isc_region_t region1;
REQUIRE(rdata->type == dns_rdatatype_https);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
dns_rdata_toregion(rdata, &region1);
return ((digest)(arg, &region1));
}
static inline bool
checkowner_in_https(ARGS_CHECKOWNER) {
REQUIRE(type == dns_rdatatype_https);
REQUIRE(rdclass == dns_rdataclass_in);
UNUSED(name);
UNUSED(type);
UNUSED(rdclass);
UNUSED(wildcard);
return (true);
}
static inline bool
checknames_in_https(ARGS_CHECKNAMES) {
REQUIRE(rdata->type == dns_rdatatype_https);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
return (generic_checknames_in_svcb(CALL_CHECKNAMES));
}
static inline int
casecompare_in_https(ARGS_COMPARE) {
return (compare_in_https(rdata1, rdata2));
}
isc_result_t
dns_rdata_in_https_first(dns_rdata_in_https_t *https) {
REQUIRE(https != NULL);
REQUIRE(https->common.rdtype == dns_rdatatype_https);
REQUIRE(https->common.rdclass == dns_rdataclass_in);
return (generic_rdata_in_svcb_first(https));
}
isc_result_t
dns_rdata_in_https_next(dns_rdata_in_https_t *https) {
REQUIRE(https != NULL);
REQUIRE(https->common.rdtype == dns_rdatatype_https);
REQUIRE(https->common.rdclass == dns_rdataclass_in);
return (generic_rdata_in_svcb_next(https));
}
void
dns_rdata_in_https_current(dns_rdata_in_https_t *https, isc_region_t *region) {
REQUIRE(https != NULL);
REQUIRE(https->common.rdtype == dns_rdatatype_https);
REQUIRE(https->common.rdclass == dns_rdataclass_in);
REQUIRE(region != NULL);
generic_rdata_in_svcb_current(https, region);
}
#endif /* RDATA_IN_1_HTTPS_65_C */

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#ifndef IN_1_HTTPS_65_H
#define IN_1_HTTPS_65_H 1
/*!
* \brief Per draft-ietf-dnsop-svcb-https-02
*/
/*
* Wire and presentation formats for HTTPS are identical to SVCB.
*/
typedef struct dns_rdata_in_svcb dns_rdata_in_https_t;
isc_result_t
dns_rdata_in_https_first(dns_rdata_in_https_t *);
isc_result_t
dns_rdata_in_https_next(dns_rdata_in_https_t *);
void
dns_rdata_in_https_current(dns_rdata_in_https_t *, isc_region_t *);
#endif /* IN_1_HTTPS_65_H */

1217
lib/dns/rdata/in_1/svcb_64.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#ifndef IN_1_SVCB_64_H
#define IN_1_SVCB_64_H 1
/*!
* \brief Per draft-ietf-dnsop-svcb-https-02
*/
typedef struct dns_rdata_in_svcb {
dns_rdatacommon_t common;
isc_mem_t *mctx;
uint16_t priority;
dns_name_t svcdomain;
unsigned char *svc;
uint16_t svclen;
uint16_t offset;
} dns_rdata_in_svcb_t;
isc_result_t
dns_rdata_in_svcb_first(dns_rdata_in_svcb_t *);
isc_result_t
dns_rdata_in_svcb_next(dns_rdata_in_svcb_t *);
void
dns_rdata_in_svcb_current(dns_rdata_in_svcb_t *, isc_region_t *);
#endif /* IN_1_SVCB_64_H */

View file

@ -174,6 +174,7 @@ static const char *text[DNS_R_NRESULTS] = {
"cannot use NSEC3 with key algorithm", /*%< 125 DNS_R_NSEC3BADALG */
"NSEC3 resalt", /*%< 126 DNS_R_NSEC3RESALT */
"inconsistent resource record", /*%< 127 DNS_R_INCONSISTENTRR */
};
static const char *ids[DNS_R_NRESULTS] = {
@ -308,6 +309,7 @@ static const char *ids[DNS_R_NRESULTS] = {
"DNS_R_NSEC3SALTRANGE",
"DNS_R_NSEC3BADALG",
"DNS_R_NSEC3RESALT",
"DNS_R_INCONSISTENTRR",
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {

View file

@ -299,7 +299,8 @@ check_struct_conversions(dns_rdata_t *rdata, size_t structsize,
assert_memory_equal(buf, rdata->data, rdata->length);
/*
* Check that one can walk hip rendezvous servers.
* Check that one can walk hip rendezvous servers and
* https/svcb parameters.
*/
switch (type) {
case dns_rdatatype_hip: {
@ -319,6 +320,38 @@ check_struct_conversions(dns_rdata_t *rdata, size_t structsize,
assert_int_equal(count, loop);
break;
}
case dns_rdatatype_https: {
dns_rdata_in_https_t *https = rdata_struct;
for (result = dns_rdata_in_https_first(https);
result == ISC_R_SUCCESS;
result = dns_rdata_in_https_next(https))
{
isc_region_t region;
dns_rdata_in_https_current(https, &region);
assert_true(region.length >= 4);
count++;
}
assert_int_equal(result, ISC_R_NOMORE);
assert_int_equal(count, loop);
break;
}
case dns_rdatatype_svcb: {
dns_rdata_in_svcb_t *svcb = rdata_struct;
for (result = dns_rdata_in_svcb_first(svcb);
result == ISC_R_SUCCESS;
result = dns_rdata_in_svcb_next(svcb))
{
isc_region_t region;
dns_rdata_in_svcb_current(svcb, &region);
assert_true(region.length >= 4);
count++;
}
assert_int_equal(result, ISC_R_NOMORE);
assert_int_equal(count, loop);
break;
}
}
isc_mem_free(dt_mctx, rdata_struct);
@ -339,6 +372,10 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
isc_result_t result;
size_t length = 0;
if (debug) {
fprintf(stdout, "#check_text_ok_single(%s)\n",
text_ok->text_in);
}
/*
* Try converting text form RDATA into uncompressed wire form.
*/
@ -350,7 +387,9 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
*/
if (text_ok->text_out != NULL) {
if (debug && result != ISC_R_SUCCESS) {
fprintf(stdout, "#'%s'\n", text_ok->text_in);
fprintf(stdout, "# '%s'\n", text_ok->text_in);
fprintf(stdout, "# result=%s\n",
dns_result_totext(result));
}
assert_int_equal(result, ISC_R_SUCCESS);
} else {
@ -374,6 +413,18 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
*/
isc_buffer_init(&target, buf_totext, sizeof(buf_totext));
result = dns_rdata_totext(&rdata, NULL, &target);
if (result != ISC_R_SUCCESS && debug) {
size_t i;
fprintf(stdout, "# dns_rdata_totext -> %s",
dns_result_totext(result));
for (i = 0; i < rdata.length; i++) {
if ((i % 16) == 0) {
fprintf(stdout, "\n#");
}
fprintf(stdout, " %02x", rdata.data[i]);
}
fprintf(stdout, "\n");
}
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Ensure buf_totext is properly NUL terminated as dns_rdata_totext()
@ -387,6 +438,10 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
}
assert_string_equal(buf_totext, text_ok->text_out);
if (debug) {
fprintf(stdout, "#dns_rdata_totext -> '%s'\n", buf_totext);
}
/*
* Ensure that fromtext_*() output is valid input for fromwire_*().
*/
@ -463,6 +518,10 @@ check_text_conversions(dns_rdata_t *rdata) {
result = dns_test_rdatafromstring(&rdata2, rdata->rdclass, rdata->type,
buf_fromtext, sizeof(buf_fromtext),
buf_totext, false);
if (debug && result != ISC_R_SUCCESS) {
fprintf(stdout, "# result = %s\n", dns_result_totext(result));
fprintf(stdout, "# '%s'\n", buf_fromtext);
}
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(rdata2.length, rdata->length);
assert_memory_equal(buf_fromtext, rdata->data, rdata->length);
@ -2412,6 +2471,186 @@ wks(void **state) {
dns_rdatatype_wks, sizeof(dns_rdata_in_wks_t));
}
static void
https_svcb(void **state) {
/*
* Known keys: mandatory, apln, no-default-alpn, port,
* ipv4hint, port, ipv6hint.
*/
text_ok_t text_ok[] = {
/* unknown key invalid */
TEXT_INVALID("1 . unknown="),
/* no domain */
TEXT_INVALID("0"),
/* minimal record */
TEXT_VALID_LOOP(0, "0 ."),
/* Alias form requires SvcFieldValue to be empty */
TEXT_INVALID("0 . alpn=\"h2\""),
/* no "key" prefix */
TEXT_INVALID("2 svc.example.net. 0=\"2222\""),
/* no key value */
TEXT_INVALID("2 svc.example.net. key"),
/* no key value */
TEXT_INVALID("2 svc.example.net. key=\"2222\""),
/* zero pad invalid */
TEXT_INVALID("2 svc.example.net. key07=\"2222\""),
TEXT_VALID_LOOP(1, "2 svc.example.net. key7=\"2222\""),
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. key7=2222",
"2 svc.example.net. key7=\"2222\""),
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. alpn=h2",
"2 svc.example.net. alpn=\"h2\""),
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. alpn=h3",
"2 svc.example.net. alpn=\"h3\""),
/* alpn has 2 sub field "h2" and "h3" */
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. alpn=h2,h3",
"2 svc.example.net. alpn=\"h2,h3\""),
/* apln has 2 sub fields "h1,h2" and "h3" (comma escaped) */
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. alpn=h1\\\\,h2,h3",
"2 svc.example.net. alpn=\"h1\\\\,h2,h3\""),
TEXT_VALID_LOOP(1, "2 svc.example.net. port=50"),
/* no-default-alpn, alpn is required */
TEXT_INVALID("2 svc.example.net. no-default-alpn"),
/* no-default-alpn with alpn present */
TEXT_VALID_LOOPCHG(
2, "2 svc.example.net. no-default-alpn alpn=h2",
"2 svc.example.net. alpn=\"h2\" no-default-alpn"),
/* empty hint */
TEXT_INVALID("2 svc.example.net. ipv4hint="),
TEXT_VALID_LOOP(1, "2 svc.example.net. "
"ipv4hint=10.50.0.1,10.50.0.2"),
/* empty hint */
TEXT_INVALID("2 svc.example.net. ipv6hint="),
TEXT_VALID_LOOP(1, "2 svc.example.net. ipv6hint=::1,2002::1"),
TEXT_VALID_LOOP(1, "2 svc.example.net. ech=abcdefghijkl"),
/* bad base64 */
TEXT_INVALID("2 svc.example.net. ech=abcdefghijklm"),
TEXT_VALID_LOOP(1, "2 svc.example.net. key7=\"2222\""),
/* Out of key order on input (alpn == key1). */
TEXT_VALID_LOOPCHG(2,
"2 svc.example.net. key7=\"2222\" alpn=h2",
"2 svc.example.net. alpn=\"h2\" "
"key7=\"2222\""),
TEXT_VALID_LOOP(1, "2 svc.example.net. key65535=\"2222\""),
TEXT_INVALID("2 svc.example.net. key65536=\"2222\""),
TEXT_VALID_LOOP(1, "2 svc.example.net. key10"),
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. key11=",
"2 svc.example.net. key11"),
TEXT_VALID_LOOPCHG(1, "2 svc.example.net. key12=\"\"",
"2 svc.example.net. key12"),
/* empty alpn-id sub fields */
TEXT_INVALID("2 svc.example.net. alpn"),
TEXT_INVALID("2 svc.example.net. alpn="),
TEXT_INVALID("2 svc.example.net. alpn=,h1"),
TEXT_INVALID("2 svc.example.net. alpn=h1,"),
TEXT_INVALID("2 svc.example.net. alpn=h1,,h2"),
/* mandatory */
TEXT_VALID_LOOP(2, "2 svc.example.net. mandatory=alpn "
"alpn=\"h2\""),
TEXT_VALID_LOOP(3, "2 svc.example.net. mandatory=alpn,port "
"alpn=\"h2\" port=443"),
TEXT_VALID_LOOPCHG(3,
"2 svc.example.net. mandatory=port,alpn "
"alpn=\"h2\" port=443",
"2 svc.example.net. mandatory=alpn,port "
"alpn=\"h2\" port=443"),
TEXT_INVALID("2 svc.example.net. mandatory=mandatory"),
TEXT_INVALID("2 svc.example.net. mandatory=port"),
TEXT_INVALID("2 svc.example.net. mandatory=,port port=433"),
TEXT_INVALID("2 svc.example.net. mandatory=port, port=433"),
TEXT_INVALID("2 svc.example.net. "
"mandatory=alpn,,port alpn=h2 port=433"),
/* mandatory w/ unknown key values */
TEXT_VALID_LOOP(2, "2 svc.example.net. mandatory=key7 key7"),
TEXT_VALID_LOOP(3, "2 svc.example.net. mandatory=key7,key8 "
"key7 key8"),
TEXT_VALID_LOOPCHG(
3, "2 svc.example.net. mandatory=key8,key7 key7 key8",
"2 svc.example.net. mandatory=key7,key8 key7 key8"),
TEXT_INVALID("2 svc.example.net. "
"mandatory=key7,key7"),
TEXT_INVALID("2 svc.example.net. mandatory=,key7"),
TEXT_INVALID("2 svc.example.net. mandatory=key7,"),
TEXT_INVALID("2 svc.example.net. "
"mandatory=key7,,key7"),
TEXT_SENTINEL()
};
wire_ok_t wire_ok[] = {
/*
* Too short
*/
WIRE_INVALID(0x00, 0x00),
/*
* Minimal length record.
*/
WIRE_VALID(0x00, 0x00, 0x00),
/*
* Alias with non-empty SvcFieldValue (key7="").
*/
WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00),
/*
* Bad key7= length (longer than rdata).
*/
WIRE_INVALID(0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x01),
/*
* Port (0x03) too small (zero and one octets).
*/
WIRE_INVALID(0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00),
WIRE_INVALID(0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00),
/* Valid port */
WIRE_VALID_LOOP(1, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x02,
0x00, 0x00),
/*
* Port (0x03) too big (three octets).
*/
WIRE_INVALID(0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
0x00, 0x00),
/*
* Duplicate keys.
*/
WIRE_INVALID(0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00),
/*
* Out of order keys.
*/
WIRE_INVALID(0x01, 0x01, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00),
/*
* Empty of mandatory key list.
*/
WIRE_INVALID(0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00),
/*
* "mandatory=mandatory" is invalid
*/
WIRE_INVALID(0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
0x00),
/*
* Out of order mandatory key list.
*/
WIRE_INVALID(0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x80, 0x00, 0x71, 0x00, 0x71, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00),
/*
* Alpn(0x00 0x01) (length 0x00 0x09) "h1,h2" + "h3"
*/
WIRE_VALID_LOOP(0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x09,
5, 'h', '1', ',', 'h', '2', 2, 'h', '3'),
/*
* Alpn(0x00 0x01) (length 0x00 0x09) "h1\h2" + "h3"
*/
WIRE_VALID_LOOP(0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x09,
5, 'h', '1', '\\', 'h', '2', 2, 'h', '3'),
WIRE_SENTINEL()
};
UNUSED(state);
check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
dns_rdatatype_svcb, sizeof(dns_rdata_in_svcb_t));
check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
dns_rdatatype_https, sizeof(dns_rdata_in_https_t));
}
/*
* ZONEMD tests.
*
@ -2755,18 +2994,18 @@ iszonecutauth(void **state) {
int
main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
/* types */
cmocka_unit_test_setup_teardown(amtrelay, _setup, _teardown),
cmocka_unit_test_setup_teardown(apl, _setup, _teardown),
cmocka_unit_test_setup_teardown(atma, _setup, _teardown),
cmocka_unit_test_setup_teardown(cdnskey, _setup, _teardown),
cmocka_unit_test_setup_teardown(csync, _setup, _teardown),
cmocka_unit_test_setup_teardown(doa, _setup, _teardown),
cmocka_unit_test_setup_teardown(dnskey, _setup, _teardown),
cmocka_unit_test_setup_teardown(doa, _setup, _teardown),
cmocka_unit_test_setup_teardown(ds, _setup, _teardown),
cmocka_unit_test_setup_teardown(eid, _setup, _teardown),
cmocka_unit_test_setup_teardown(edns_client_subnet, _setup,
_teardown),
cmocka_unit_test_setup_teardown(hip, _setup, _teardown),
cmocka_unit_test_setup_teardown(https_svcb, _setup, _teardown),
cmocka_unit_test_setup_teardown(isdn, _setup, _teardown),
cmocka_unit_test_setup_teardown(key, _setup, _teardown),
cmocka_unit_test_setup_teardown(loc, _setup, _teardown),
@ -2774,10 +3013,13 @@ main(int argc, char **argv) {
cmocka_unit_test_setup_teardown(nsec, _setup, _teardown),
cmocka_unit_test_setup_teardown(nsec3, _setup, _teardown),
cmocka_unit_test_setup_teardown(nxt, _setup, _teardown),
cmocka_unit_test_setup_teardown(rkey, _setup, _teardown),
cmocka_unit_test_setup_teardown(sshfp, _setup, _teardown),
cmocka_unit_test_setup_teardown(wks, _setup, _teardown),
cmocka_unit_test_setup_teardown(rkey, _setup, _teardown),
cmocka_unit_test_setup_teardown(zonemd, _setup, _teardown),
/* other tests */
cmocka_unit_test_setup_teardown(edns_client_subnet, _setup,
_teardown),
cmocka_unit_test_setup_teardown(atcname, NULL, NULL),
cmocka_unit_test_setup_teardown(atparent, NULL, NULL),
cmocka_unit_test_setup_teardown(iszonecutauth, NULL, NULL),

View file

@ -1497,6 +1497,8 @@
./lib/dns/rdata/in_1/dhcid_49.h C 2006,2007,2016,2018,2019,2020,2021
./lib/dns/rdata/in_1/eid_31.c C 2018,2019,2020,2021
./lib/dns/rdata/in_1/eid_31.h C 2018,2019,2020,2021
./lib/dns/rdata/in_1/https_65.c C 2019,2020,2021
./lib/dns/rdata/in_1/https_65.h C 2019,2020,2021
./lib/dns/rdata/in_1/kx_36.c C 1999,2000,2001,2003,2004,2005,2007,2009,2015,2016,2017,2018,2019,2020,2021
./lib/dns/rdata/in_1/kx_36.h C 1999,2000,2001,2004,2005,2007,2016,2018,2019,2020,2021
./lib/dns/rdata/in_1/nimloc_32.c C 2018,2019,2020,2021
@ -1509,6 +1511,8 @@
./lib/dns/rdata/in_1/px_26.h C 1999,2000,2001,2004,2005,2007,2016,2018,2019,2020,2021
./lib/dns/rdata/in_1/srv_33.c C 1999,2000,2001,2003,2004,2005,2007,2009,2015,2016,2018,2019,2020,2021
./lib/dns/rdata/in_1/srv_33.h C 1999,2000,2001,2004,2005,2007,2016,2018,2019,2020,2021
./lib/dns/rdata/in_1/svcb_64.c C 2019,2020,2021
./lib/dns/rdata/in_1/svcb_64.h C 2019,2020,2021
./lib/dns/rdata/in_1/wks_11.c C 1999,2000,2001,2002,2004,2007,2009,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
./lib/dns/rdata/in_1/wks_11.h C 1999,2000,2001,2004,2007,2016,2018,2019,2020,2021
./lib/dns/rdata/rdatastructpre.h C 1999,2000,2001,2004,2007,2016,2018,2019,2020,2021