svcb: update docs to ref RFC 9460

Since initial support for SVCB/HTTPS RRs landed in hickory-dns, RFC
9460[0] was published:

  Service Binding and Parameter Specification via the DNS (SVCB and HTTPS
  Resource Records)

This is the definitive reference for SVCB and HTTPS RRs and previous
references to `draft-ietf-dnsop-svcb-https-XX` need to be updated.

Thankfully, it seems as though the implementation did not change
meaningfully from draft-03 and so this commit can largely just update
documentation references and copied quotations to match RFC 9460.

One minor change is worth mentioning: the Encrypted Client Hello (ECH)
aspects of the draft were removed pre-publication and the RFC9460 IANA
registry includes a "reserved" allocation for the `"ech"` key, but no
details on its use. These details are now located in a separate draft,
draft-ietf-tls-svcb-ech-01[1].

Since the code in `svcb.rs` also concerned itself with ECH it now
references draft-ietf-tls-svcb-ech-01 where the ECH specific usage of
service parameter is under specification. Notably the new draft and RFC
9460 both use `"ech"` for the service parameter key for encrypted client
hello configs. Hickory-dns is currently using `"echconfig"`, but this
will be fixed in a follow-up commit to keep this one documentation only.

[0]: https://datatracker.ietf.org/doc/html/rfc9460
[1]: draft-ietf-tls-svcb-ech-01
This commit is contained in:
Daniel McCarney 2024-04-15 18:12:02 -04:00 committed by Dirkjan Ochtman
parent c01db51555
commit 190c814eb3
2 changed files with 202 additions and 185 deletions

View File

@ -5,7 +5,7 @@
// https://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! SVCB records, see [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03)
//! SVCB records, see [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460)
#![allow(clippy::use_self)]
use std::{
@ -30,7 +30,7 @@ use crate::{
},
};
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-2.2)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-2.2)
///
/// ```text
/// 2.2. RDATA wire format
@ -51,10 +51,9 @@ use crate::{
/// * a 2 octet field containing the SvcParamKey as an integer in
/// network byte order. (See Section 14.3.2 for the defined values.)
/// * a 2 octet field containing the length of the SvcParamValue as an
/// integer between 0 and 65535 in network byte order (but constrained
/// by the RDATA and DNS message sizes).
/// * an octet string of this length whose contents are in a format
/// determined by the SvcParamKey.
/// integer between 0 and 65535 in network byte order
/// * an octet string of this length whose contents are the SvcParamValue
/// in a format determined by the SvcParamKey
///
/// SvcParamKeys SHALL appear in increasing numeric order.
///
@ -95,7 +94,7 @@ impl SVCB {
}
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-2.4.1)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-2.4.1)
/// ```text
/// 2.4.1. SvcPriority
///
@ -107,9 +106,9 @@ impl SVCB {
/// ServiceMode records in the set.
///
/// RRSets are explicitly unordered collections, so the SvcPriority field
/// is used to impose an ordering on SVCB RRs. SVCB RRs with a smaller
/// SvcPriority value SHOULD be given preference over RRs with a larger
/// SvcPriority value.
/// is used to impose an ordering on SVCB RRs. A smaller SvcPriority indicates
/// that the domain owner recommends the use of this record over ServiceMode
/// RRs with a larger SvcPriority value.
///
/// When receiving an RRSet containing multiple SVCB records with the
/// same SvcPriority value, clients SHOULD apply a random shuffle within
@ -120,7 +119,7 @@ impl SVCB {
self.svc_priority
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-2.5)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-2.5)
/// ```text
/// 2.5. Special handling of "." in TargetName
///
@ -138,13 +137,14 @@ impl SVCB {
///
/// For ServiceMode SVCB RRs, if TargetName has the value ".", then the
/// owner name of this record MUST be used as the effective TargetName.
/// If the record has a wildcard owner name in the zone file, the recipient
/// SHALL use the response's synthesized owner name as the effective TargetName.
///
/// For example, in the following example "svc2.example.net" is the
/// effective TargetName:
/// Here, for example, "svc2.example.net" is the effective TargetName:
///
/// example.com. 7200 IN HTTPS 0 svc.example.net.
/// svc.example.net. 7200 IN CNAME svc2.example.net.
/// svc2.example.net. 7200 IN HTTPS 1 . port=8002 echconfig="..."
/// svc2.example.net. 7200 IN HTTPS 1 . port=8002
/// svc2.example.net. 300 IN A 192.0.2.2
/// svc2.example.net. 300 IN AAAA 2001:db8::2
/// ```
@ -158,6 +158,8 @@ impl SVCB {
}
}
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-14.3.2)
///
/// ```text
/// 14.3.2. Initial contents
///
@ -182,16 +184,16 @@ impl SVCB {
/// | 4 | ipv4hint | IPv4 address hints | (This |
/// | | | | document) |
/// +-------------+-----------------+----------------------+-----------+
/// | 5 | echconfig | Encrypted | (This |
/// | | | ClientHello info | document) |
/// | 5 | ech | RESERVED (held for | N/A |
/// | | | ECH) | |
/// +-------------+-----------------+----------------------+-----------+
/// | 6 | ipv6hint | IPv6 address hints | (This |
/// | | | | document) |
/// +-------------+-----------------+----------------------+-----------+
/// | 65280-65534 | keyNNNNN | Private Use | (This |
/// | 65280-65534 | N/A | Private Use | (This |
/// | | | | document) |
/// +-------------+-----------------+----------------------+-----------+
/// | 65535 | key65535 | Reserved ("Invalid | (This |
/// | 65535 | N/A | Reserved ("Invalid | (This |
/// | | | key") | document) |
/// +-------------+-----------------+----------------------+-----------+
///
@ -360,24 +362,30 @@ pub enum SvcParamValue {
///
/// see `Mandatory`
Mandatory(Mandatory),
/// The "alpn" and "no-default-alpn" SvcParamKeys together indicate the
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.1)
///
/// ```text
/// The "alpn" and "no-default-alpn" SvcParamKeys together indicate the
/// set of Application Layer Protocol Negotiation (ALPN) protocol
/// identifiers [Alpn] and associated transport protocols supported by
/// this service endpoint.
/// this service endpoint (the "SVCB ALPN set").
/// ```
Alpn(Alpn),
/// For "no-default-alpn", the presentation and wire format values MUST
/// be empty.
/// See also `Alpn`
NoDefaultAlpn,
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.2)
///
/// ```text
/// 6.2. "port"
/// 7.2. "port"
///
/// The "port" SvcParamKey defines the TCP or UDP port that should be
/// used to reach this alternative endpoint. If this key is not present,
/// clients SHALL use the authority endpoint's port number.
///
/// The presentation "value" of the SvcParamValue is a single decimal
/// integer between 0 and 65535 in ASCII. Any other "value" (e.g. an
/// The presentation value of the SvcParamValue is a single decimal
/// integer between 0 and 65535 in ASCII. Any other value (e.g. an
/// empty value) is a syntax error. To enable simpler parsing, this
/// SvcParam MUST NOT contain escape sequences.
///
@ -390,6 +398,8 @@ pub enum SvcParamValue {
/// caution when using this SvcParamKey to specify a non-default port.
/// ```
Port(u16),
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.2)
///
/// The "ipv4hint" and "ipv6hint" keys convey IP addresses that clients
/// MAY use to reach the service. If A and AAAA records for TargetName
/// are locally available, the client SHOULD ignore these hints.
@ -403,25 +413,15 @@ pub enum SvcParamValue {
///
/// see `IpHint`
Ipv4Hint(IpHint<A>),
/// [draft-ietf-tls-svcb-ech-01 Bootstrapping TLS Encrypted ClientHello with DNS Service Bindings, Sep 2024](https://datatracker.ietf.org/doc/html/draft-ietf-tls-svcb-ech-01)
///
/// ```text
/// 6.3. "echconfig"
/// 2. "SvcParam for ECH configuration"
///
/// The SvcParamKey to enable Encrypted ClientHello (ECH) is "echconfig".
/// Its value is defined in Section 9. It is applicable to most TLS-
/// based protocols.
///
/// When publishing a record containing an "echconfig" parameter, the
/// publisher MUST ensure that all IP addresses of TargetName correspond
/// to servers that have access to the corresponding private key or are
/// authoritative for the public name. (See Section 7.2.2 of [ECH] for
/// more details about the public name.) This yields an anonymity set of
/// cardinality equal to the number of ECH-enabled server domains
/// supported by a given client-facing server. Thus, even with an
/// encrypted ClientHello, an attacker who can enumerate the set of ECH-
/// enabled domains supported by a client-facing server can guess the
/// correct SNI with probability at least 1/K, where K is the size of
/// this ECH-enabled server anonymity set. This probability may be
/// increased via traffic analysis or other mechanisms.
/// The "ech" SvcParamKey is defined for conveying the ECH configuration
/// of an alternative endpoint. It is applicable to all TLS-based protocols
/// (including DTLS [RFC9147] and QUIC version 1 [RFC9001]) unless otherwise
/// specified.
/// ```
EchConfig(EchConfig),
/// See `IpHint`
@ -527,8 +527,10 @@ impl fmt::Display for SvcParamValue {
}
}
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-8)
///
/// ```text
/// 7. ServiceMode RR compatibility and mandatory keys
/// 8. ServiceMode RR compatibility and mandatory keys
///
/// In a ServiceMode RR, a SvcParamKey is considered "mandatory" if the
/// RR will not function correctly for clients that ignore this
@ -540,11 +542,10 @@ impl fmt::Display for SvcParamValue {
///
/// A ServiceMode RR is considered "compatible" with a client if the
/// client recognizes all the mandatory keys, and their values indicate
/// that successful connection establishment is possible. If the SVCB
/// RRSet contains no compatible RRs, the client will generally act as if
/// the RRSet is empty.
/// that successful connection establishment is possible. Incompatible RRs
/// are ignored (see step 5 of the procedure defined in Section 3)
///
/// The presentation "value" SHALL be a comma-separated list
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more valid SvcParamKeys, either by their
/// registered name or in the unknown-key format (Section 2.1). Keys MAY
/// appear in any order, but MUST NOT appear more than once. For self-
@ -556,10 +557,10 @@ impl fmt::Display for SvcParamValue {
///
/// For example, the following is a valid list of SvcParams:
///
/// echconfig=... key65333=ex1 key65444=ex2 mandatory=key65444,echconfig
/// ipv6hint=... key65333=ex1 key65444=ex2 mandatory=key65444,ipv6hint
///
/// In wire format, the keys are represented by their numeric values in
/// network byte order, concatenated in ascending order.
/// network byte order, concatenated in strictly increasing numeric order.
///
/// This SvcParamKey is always automatically mandatory, and MUST NOT
/// appear in its own value-list. Other automatically mandatory keys
@ -577,7 +578,7 @@ impl<'r> BinDecodable<'r> for Mandatory {
///
/// ```text
/// In wire format, the keys are represented by their numeric values in
/// network byte order, concatenated in ascending order.
/// network byte order, concatenated in strictly increasing numeric order.
/// ```
fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
let mut keys = Vec::with_capacity(1);
@ -600,7 +601,7 @@ impl BinEncodable for Mandatory {
///
/// ```text
/// In wire format, the keys are represented by their numeric values in
/// network byte order, concatenated in ascending order.
/// network byte order, concatenated in strictly increasing numeric order.
/// ```
fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
if self.0.is_empty() {
@ -617,7 +618,9 @@ impl BinEncodable for Mandatory {
}
impl fmt::Display for Mandatory {
/// The presentation "value" SHALL be a comma-separated list
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-8)
///
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more valid SvcParamKeys, either by their
/// registered name or in the unknown-key format (Section 2.1). Keys MAY
/// appear in any order, but MUST NOT appear more than once. For self-
@ -629,7 +632,7 @@ impl fmt::Display for Mandatory {
///
/// For example, the following is a valid list of SvcParams:
///
/// echconfig=... key65333=ex1 key65444=ex2 mandatory=key65444,echconfig
/// ipv6hint=... key65333=ex1 key65444=ex2 mandatory=key65444,ipv6hint
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
for key in self.0.iter() {
// TODO: confirm in the RFC that trailing commas are ok
@ -640,7 +643,7 @@ impl fmt::Display for Mandatory {
}
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-6.1)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.1)
///
/// ```text
/// 6.1. "alpn" and "no-default-alpn"
@ -652,18 +655,29 @@ impl fmt::Display for Mandatory {
///
/// As with Alt-Svc [AltSvc], the ALPN protocol identifier is used to
/// identify the application protocol and associated suite of protocols
/// supported by the endpoint (the "protocol suite"). Clients filter the
/// set of ALPN identifiers to match the protocol suites they support,
/// and this informs the underlying transport protocol used (such as
/// QUIC-over-UDP or TLS-over-TCP).
/// supported by the endpoint (the "protocol suite"). The presence of an
/// ALPN protocol identifier in the SVCB ALPN set indicates that this
/// service endpoint, described by TargetName and the other parameters
/// (e.g., "port"), offers service with the protocol suite associated
/// with this ALPN identifier.
///
/// Clients filter the set of ALPN identifiers to match the protocol suites
/// they support, and this informs the underlying transport protocol used
/// (such as QUIC over UDP or TLS over TCP). ALPN protocol identifiers that do
/// not uniquely identify a protocol suite (e.g., an Identification Sequence
/// that can be used with both TLS and DTLS) are not compatible with this
/// SvcParamKey and MUST NOT be included in the SVCB ALPN set.
///
/// ALPNs are identified by their registered "Identification Sequence"
/// ("alpn-id"), which is a sequence of 1-255 octets.
///
/// alpn-id = 1*255OCTET
///
/// The presentation "value" SHALL be a comma-separated list
/// (Appendix A.1) of one or more "alpn-id"s.
/// For "alpn", the presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more alpn-ids. Zone-file implementations MAY
/// disallow the "," and "\" characters in ALPN IDs instead of implementing
/// the value-list escaping procedure, relying on the opaque key format
/// (e.g., key1=\002h2) in the event that these characters are needed.
///
/// The wire format value for "alpn" consists of at least one "alpn-id"
/// prefixed by its length as a single octet, and these length-value
@ -676,19 +690,11 @@ impl fmt::Display for Mandatory {
/// also be specified in order for the RR to be "self-consistent"
/// (Section 2.4.3).
///
/// Each scheme that uses this SvcParamKey defines a "default set" of
/// supported ALPNs, which SHOULD NOT be empty. To determine the set of
/// protocol suites supported by an endpoint (the "SVCB ALPN set"), the
/// client adds the default set to the list of "alpn-id"s unless the "no-
/// default-alpn" SvcParamKey is present. The presence of an ALPN
/// protocol in the SVCB ALPN set indicates that this service endpoint,
/// described by TargetName and the other parameters (e.g. "port") offers
/// service with the protocol suite associated with this ALPN protocol.
///
/// ALPN protocol names that do not uniquely identify a protocol suite
/// (e.g. an Identification Sequence that can be used with both TLS and
/// DTLS) are not compatible with this SvcParamKey and MUST NOT be
/// included in the SVCB ALPN set.
/// Each scheme that uses this SvcParamKey defines a "default set" of ALPN
/// IDs that are supported by nearly all clients and servers; this set MAY
/// be empty. To determine the SVCB ALPN set, the client starts with the
/// list of alpn-ids from the "alpn" SvcParamKey, and it adds the default
/// set unless the "no-default-alpn" SvcParamKey is present.
///
/// To establish a connection to the endpoint, clients MUST
///
@ -713,6 +719,12 @@ impl fmt::Display for Mandatory {
/// in that handshake proceeds as specified in [ALPN], without regard to
/// the SVCB ALPN set.
///
/// Clients MAY implement a fallback procedure, using a less-preferred
/// transport if more-preferred transports fail to connect. This fallback
/// behavior is vulnerable to manipulation by a network attacker who blocks
/// the more-preferred transports, but it may be necessary for compatibility
/// with existing networks.
///
/// With this procedure in place, an attacker who can modify DNS and
/// network traffic can prevent a successful transport connection, but
/// cannot otherwise interfere with ALPN protocol selection. This
@ -720,15 +732,16 @@ impl fmt::Display for Mandatory {
/// one protocol from the SVCB ALPN set.
///
/// Clients SHOULD NOT attempt connection to a service endpoint whose
/// SVCB ALPN set does not contain any supported protocols. To ensure
/// consistency of behavior, clients MAY reject the entire SVCB RRSet and
/// fall back to basic connection establishment if all of the RRs
/// SVCB ALPN set does not contain any supported protocols.
///
/// To ensure consistency of behavior, clients MAY reject the entire SVCB RRSet
/// and fall back to basic connection establishment if all of the RRs
/// indicate "no-default-alpn", even if connection could have succeeded
/// using a non-default alpn.
///
/// For compatibility with clients that require default transports, zone
/// operators SHOULD ensure that at least one RR in each RRSet supports
/// the default transports.
/// Zone operators SHOULD ensure that at least one RR in each RRset supports
/// the default transports. This enables compatibility with the greatest
/// number of clients.
/// ```
#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
@ -783,7 +796,7 @@ impl BinEncodable for Alpn {
}
impl fmt::Display for Alpn {
/// The presentation "value" SHALL be a comma-separated list
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more "alpn-id"s.
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
for alpn in self.0.iter() {
@ -795,26 +808,15 @@ impl fmt::Display for Alpn {
}
}
/// [draft-ietf-tls-svcb-ech-01 Bootstrapping TLS Encrypted ClientHello with DNS Service Bindings, Sep 2024](https://datatracker.ietf.org/doc/html/draft-ietf-tls-svcb-ech-01)
///
/// ```text
/// 9. SVCB/HTTPS RR parameter for ECH configuration
/// 2. "SvcParam for ECH configuration"
///
/// The SVCB "echconfig" parameter is defined for conveying the ECH
/// configuration of an alternative endpoint. In wire format, the value
/// of the parameter is an ECHConfigs vector [ECH], including the
/// redundant length prefix. In presentation format, the value is a
/// single ECHConfigs encoded in Base64 [base64]. Base64 is used here to
/// simplify integration with TLS server software. To enable simpler
/// parsing, this SvcParam MUST NOT contain escape sequences.
///
/// When ECH is in use, the TLS ClientHello is divided into an
/// unencrypted "outer" and an encrypted "inner" ClientHello. The outer
/// ClientHello is an implementation detail of ECH, and its contents are
/// controlled by the ECHConfig in accordance with [ECH]. The inner
/// ClientHello is used for establishing a connection to the service, so
/// its contents may be influenced by other SVCB parameters. For
/// example, the requirements on the ProtocolNameList in Section 6.1
/// apply only to the inner ClientHello. Similarly, it is the inner
/// ClientHello whose Server Name Indication identifies the desired
/// The "ech" SvcParamKey is defined for conveying the ECH configuration
/// of an alternative endpoint. It is applicable to all TLS-based protocols
/// (including DTLS [RFC9147] and QUIC version 1 [RFC9001]) unless
/// otherwise specified.
/// ```
#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
#[derive(PartialEq, Eq, Hash, Clone)]
@ -822,10 +824,11 @@ impl fmt::Display for Alpn {
pub struct EchConfig(pub Vec<u8>);
impl<'r> BinDecodable<'r> for EchConfig {
/// In wire format, the value
/// of the parameter is an ECHConfigs vector (ECH), including the
/// redundant length prefix (a 2 octet field containing the length of the SvcParamValue
/// as an integer between 0 and 65535 in network byte order).
/// In wire format, the value of the parameter is an ECHConfigList (Section 4 of draft-ietf-tls-esni-18),
/// including the redundant length prefix. In presentation format, the value is the
/// ECHConfigList in Base 64 Encoding (Section 4 of RFC4648).
/// Base 64 is used here to simplify integration with TLS server software.
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
let redundant_len = decoder
.read_u16()?
@ -841,10 +844,11 @@ impl<'r> BinDecodable<'r> for EchConfig {
}
impl BinEncodable for EchConfig {
/// In wire format, the value
/// of the parameter is an ECHConfigs vector (ECH), including the
/// redundant length prefix (a 2 octet field containing the length of the SvcParamValue
/// as an integer between 0 and 65535 in network byte order).
/// In wire format, the value of the parameter is an ECHConfigList (Section 4 of draft-ietf-tls-esni-18),
/// including the redundant length prefix. In presentation format, the value is the
/// ECHConfigList in Base 64 Encoding (Section 4 of RFC4648).
/// Base 64 is used here to simplify integration with TLS server software.
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
let len = u16::try_from(self.0.len())
.map_err(|_| ProtoError::from("ECH value length exceeds max size of u16::MAX"))?;
@ -861,12 +865,12 @@ impl fmt::Display for EchConfig {
/// As the documentation states, the presentation format (what this function outputs) must be a BASE64 encoded string.
/// hickory-dns will encode to BASE64 during formatting of the internal data, and output the BASE64 value.
///
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-9)
/// [draft-ietf-tls-svcb-ech-01 Bootstrapping TLS Encrypted ClientHello with DNS Service Bindings, Sep 2024](https://datatracker.ietf.org/doc/html/draft-ietf-tls-svcb-ech-01)
/// ```text
/// In presentation format, the value is a
/// single ECHConfigs encoded in Base64 [base64]. Base64 is used here to
/// simplify integration with TLS server software. To enable simpler
/// parsing, this SvcParam MUST NOT contain escape sequences.
/// In presentation format, the value is the ECHConfigList in Base 64 Encoding
/// (Section 4 of [RFC4648]). Base 64 is used here to simplify integration with
/// TLS server software. To enable simpler parsing, this SvcParam MUST NOT
/// contain escape sequences.
/// ```
///
/// *note* while the on the wire the EchConfig has a redundant length,
@ -888,8 +892,10 @@ impl fmt::Debug for EchConfig {
}
}
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.3)
///
/// ```text
/// 6.4. "ipv4hint" and "ipv6hint"
/// 7.3. "ipv4hint" and "ipv6hint"
///
/// The "ipv4hint" and "ipv6hint" keys convey IP addresses that clients
/// MAY use to reach the service. If A and AAAA records for TargetName
@ -902,24 +908,24 @@ impl fmt::Debug for EchConfig {
/// and/or AAAA response addresses could negatively impact load balancing
/// or other geo-aware features and thereby degrade client performance.
///
/// The presentation "value" SHALL be a comma-separated list
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more IP addresses of the appropriate family
/// in standard textual format [RFC5952]. To enable simpler parsing,
/// this SvcParamValue MUST NOT contain escape sequences.
///
/// The wire format for each parameter is a sequence of IP addresses in
/// network byte order. Like an A or AAAA RRSet, the list of addresses
/// represents an unordered collection, and clients SHOULD pick addresses
/// to use in a random order. An empty list of addresses is invalid.
/// network byte order (for the respective address family). Like an A or
/// AAAA RRSet, the list of addresses represents an unordered collection,
/// and clients SHOULD pick addresses to use in a random order. An empty
/// list of addresses is invalid.
///
/// When selecting between IPv4 and IPv6 addresses to use, clients may
/// use an approach such as Happy Eyeballs [HappyEyeballsV2]. When only
/// "ipv4hint" is present, IPv6-only clients may synthesize IPv6
/// addresses as specified in [RFC7050] or ignore the "ipv4hint" key and
/// wait for AAAA resolution (Section 3). Recursive resolvers MUST NOT
/// perform DNS64 ([RFC6147]) on parameters within a SVCB record. For
/// best performance, server operators SHOULD include an "ipv6hint"
/// parameter whenever they include an "ipv4hint" parameter.
/// "ipv4hint" is present, NAT64 clients may synthesize IPv6 addresses
/// as specified in [RFC7050] or ignore the "ipv4hint" key and
/// wait for AAAA resolution (Section 3). For best performance, server
/// operators SHOULD include an "ipv6hint" parameter whenever they
/// include an "ipv4hint" parameter.
///
/// These parameters are intended to minimize additional connection
/// latency when a recursive resolver is not compliant with the
@ -939,9 +945,10 @@ where
T: BinDecodable<'r>,
{
/// The wire format for each parameter is a sequence of IP addresses in
/// network byte order. Like an A or AAAA RRSet, the list of addresses
/// represents an unordered collection, and clients SHOULD pick addresses
/// to use in a random order. An empty list of addresses is invalid.
/// network byte order (for the respective address family). Like an A or
/// AAAA RRSet, the list of addresses represents an unordered collection,
/// and clients SHOULD pick addresses to use in a random order. An empty
/// list of addresses is invalid.
fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
let mut ips = Vec::new();
@ -958,9 +965,10 @@ where
T: BinEncodable,
{
/// The wire format for each parameter is a sequence of IP addresses in
/// network byte order. Like an A or AAAA RRSet, the list of addresses
/// represents an unordered collection, and clients SHOULD pick addresses
/// to use in a random order. An empty list of addresses is invalid.
/// network byte order (for the respective address family). Like an A or
/// AAAA RRSet, the list of addresses represents an unordered collection,
/// and clients SHOULD pick addresses to use in a random order. An empty
/// list of addresses is invalid.
fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
for ip in self.0.iter() {
ip.emit(encoder)?;
@ -974,7 +982,7 @@ impl<T> fmt::Display for IpHint<T>
where
T: fmt::Display,
{
/// The presentation "value" SHALL be a comma-separated list
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more IP addresses of the appropriate family
/// in standard textual format [RFC 5952](https://tools.ietf.org/html/rfc5952). To enable simpler parsing,
/// this SvcParamValue MUST NOT contain escape sequences.
@ -987,15 +995,15 @@ where
}
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-2.1)
/// ```text
/// Unrecognized keys are represented in presentation format as
/// "keyNNNNN" where NNNNN is the numeric value of the key type without
/// leading zeros. A SvcParam in this form SHALL be parsed as specified
/// above, and the decoded "value" SHALL be used as its wire format
/// encoding.
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-2.1)
///
/// For some SvcParamKeys, the "value" corresponds to a list or set of
/// ```text
/// Arbitrary keys can be represented using the unknown-key presentation
/// format "keyNNNNN" where NNNNN is the numeric value of the key type
/// without leading zeros. A SvcParam in this form SHALL be parsed as specified
/// above, and the decoded value SHALL be used as its wire-format encoding.
///
/// For some SvcParamKeys, the value corresponds to a list or set of
/// items. Presentation formats for such keys SHOULD use a comma-
/// separated list (Appendix A.1).
///
@ -1066,6 +1074,8 @@ impl BinEncodable for SVCB {
impl<'r> RecordDataDecodable<'r> for SVCB {
/// Reads the SVCB record from the decoder.
///
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-2.2)
///
/// ```text
/// Clients MUST consider an RR malformed if:
///
@ -1150,7 +1160,7 @@ impl RecordData for SVCB {
}
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-10.3)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-10.4)
///
/// ```text
/// simple.example. 7200 IN HTTPS 1 . alpn=h3

View File

@ -20,49 +20,50 @@ use crate::{
},
};
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-2.2)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-2.1)
///
/// ```text
/// 2.1. Zone file presentation format
///
/// The presentation format of the record is:
/// The presentation format <RDATA> of the record ([RFC1035]) has the form:
///
/// Name TTL IN SVCB SvcPriority TargetName SvcParams
/// SvcPriority TargetName SvcParams
///
/// The SVCB record is defined specifically within the Internet ("IN")
/// Class ([RFC1035]).
///
/// SvcPriority is a number in the range 0-65535, TargetName is a domain
/// name, and the SvcParams are a whitespace-separated list, with each
/// SvcParam consisting of a SvcParamKey=SvcParamValue pair or a
/// standalone SvcParamKey. SvcParamKeys are subject to IANA control
/// (Section 14.3).
/// SvcPriority is a number in the range 0-65535, TargetName is a
/// <domain-name> ([RFC1035], Section 5.1), and the SvcParams are
/// a whitespace-separated list, with each SvcParam consisting of a
/// SvcParamKey=SvcParamValue pair or a standalone SvcParamKey.
/// SvcParamKeys are registered by IANA (Section 14.3).
///
/// Each SvcParamKey SHALL appear at most once in the SvcParams. In
/// presentation format, SvcParamKeys are lower-case alphanumeric
/// presentation format, SvcParamKeys are lowercase alphanumeric
/// strings. Key names should contain 1-63 characters from the ranges
/// "a"-"z", "0"-"9", and "-". In ABNF [RFC5234],
///
/// alpha-lc = %x61-7A ; a-z
/// SvcParamKey = 1*63(alpha-lc / DIGIT / "-")
/// SvcParam = SvcParamKey ["=" SvcParamValue]
/// SvcParamValue = char-string
/// value = *OCTET
/// SvcParamValue = char-string ; See Appendix A.
/// value = *OCTET ; Value before key-specific parsing
///
/// The SvcParamValue is parsed using the character-string decoding
/// algorithm (Appendix A), producing a "value". The "value" is then
/// algorithm (Appendix A), producing a value. The value is then
/// validated and converted into wire-format in a manner specific to each
/// key.
///
/// When the "=" is omitted, the "value" is interpreted as empty.
/// When the optional "=" and SvcParamValue are omitted, the value is
/// interpreted as empty.
///
/// Unrecognized keys are represented in presentation format as
/// "keyNNNNN" where NNNNN is the numeric value of the key type without
/// leading zeros. A SvcParam in this form SHALL be parsed as specified
/// above, and the decoded "value" SHALL be used as its wire format
/// Arbitrary keys can be represented using the unknown-key presentation
/// format "keyNNNNN" where NNNNN is the numeric value of the key type
/// without leading zeros. A SvcParam in this form SHALL be parsed as
/// specified above, and the decoded value SHALL be used as its wire-format
/// encoding.
///
/// For some SvcParamKeys, the "value" corresponds to a list or set of
/// For some SvcParamKeys, the value corresponds to a list or set of
/// items. Presentation formats for such keys SHOULD use a comma-
/// separated list (Appendix A.1).
///
@ -144,9 +145,10 @@ fn parse_char_data(value: &str) -> Result<String, ParseError> {
}
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-7)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-8)
///
/// ```text
/// The presentation "value" SHALL be a comma-separated list
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more valid SvcParamKeys, either by their
/// registered name or in the unknown-key format (Section 2.1). Keys MAY
/// appear in any order, but MUST NOT appear more than once. For self-
@ -158,7 +160,7 @@ fn parse_char_data(value: &str) -> Result<String, ParseError> {
///
/// For example, the following is a valid list of SvcParams:
///
/// echconfig=... key65333=ex1 key65444=ex2 mandatory=key65444,echconfig
/// ipv6hint=... key65333=ex1 key65444=ex2 mandatory=key65444,ipv6hint
/// ```
///
/// Currently this does not validate that the mandatory section matches the other keys
@ -173,15 +175,16 @@ fn parse_mandatory(value: Option<&str>) -> Result<SvcParamValue, ParseError> {
Ok(SvcParamValue::Mandatory(Mandatory(mandatories)))
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-6.1)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.1.1)
///
/// ```text
/// ALPNs are identified by their registered "Identification Sequence"
/// ALPNs are identified by their registered "Identification Sequence"
/// ("alpn-id"), which is a sequence of 1-255 octets.
///
/// alpn-id = 1*255OCTET
///
/// The presentation "value" SHALL be a comma-separated list
/// (Appendix A.1) of one or more "alpn-id"s.
/// For "alpn", the presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more alpn-ids.
/// ```
///
/// This does not currently check to see if the ALPN code is legitimate
@ -194,9 +197,10 @@ fn parse_alpn(value: Option<&str>) -> Result<SvcParamValue, ParseError> {
Ok(SvcParamValue::Alpn(Alpn(alpns)))
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-6.1)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.1.1)
///
/// ```text
/// For "no-default-alpn", the presentation and wire format values MUST
/// For "no-default-alpn", the presentation and wire format values MUST
/// be empty. When "no-default-alpn" is specified in an RR, "alpn" must
/// also be specified in order for the RR to be "self-consistent"
/// (Section 2.4.3).
@ -209,10 +213,11 @@ fn parse_no_default_alpn(value: Option<&str>) -> Result<SvcParamValue, ParseErro
Ok(SvcParamValue::NoDefaultAlpn)
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-6.2)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.2)
///
/// ```text
/// The presentation "value" of the SvcParamValue is a single decimal
/// integer between 0 and 65535 in ASCII. Any other "value" (e.g. an
/// The presentation value of the SvcParamValue is a single decimal
/// integer between 0 and 65535 in ASCII. Any other value (e.g. an
/// empty value) is a syntax error. To enable simpler parsing, this
/// SvcParam MUST NOT contain escape sequences.
/// ```
@ -226,9 +231,10 @@ fn parse_port(value: Option<&str>) -> Result<SvcParamValue, ParseError> {
Ok(SvcParamValue::Port(port))
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-6.4)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.3)
///
/// ```text
/// The presentation "value" SHALL be a comma-separated list
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more IP addresses of the appropriate family
/// in standard textual format [RFC5952]. To enable simpler parsing,
/// this SvcParamValue MUST NOT contain escape sequences.
@ -242,15 +248,15 @@ fn parse_ipv4_hint(value: Option<&str>) -> Result<SvcParamValue, ParseError> {
Ok(SvcParamValue::Ipv4Hint(IpHint(hints)))
}
/// As the documentation states, the presentation format (what this function reads) must be a BASE64 encoded string.
/// hickory-dns will decode the BASE64 during parsing and stores the internal data as the raw bytes.
/// As the documentation states, the presentation format (what this function outputs) must be a BASE64 encoded string.
/// hickory-dns will encode to BASE64 during formatting of the internal data, and output the BASE64 value.
///
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-9)
/// [draft-ietf-tls-svcb-ech-01 Bootstrapping TLS Encrypted ClientHello with DNS Service Bindings, Sep 2024](https://datatracker.ietf.org/doc/html/draft-ietf-tls-svcb-ech-01)
/// ```text
/// In presentation format, the value is a
/// single ECHConfigs encoded in Base64 [base64]. Base64 is used here to
/// simplify integration with TLS server software. To enable simpler
/// parsing, this SvcParam MUST NOT contain escape sequences.
/// In presentation format, the value is the ECHConfigList in Base 64 Encoding
/// (Section 4 of [RFC4648]). Base 64 is used here to simplify integration with
/// TLS server software. To enable simpler parsing, this SvcParam MUST NOT
/// contain escape sequences.
/// ```
fn parse_ech_config(value: Option<&str>) -> Result<SvcParamValue, ParseError> {
let value = value.ok_or_else(|| {
@ -264,9 +270,10 @@ fn parse_ech_config(value: Option<&str>) -> Result<SvcParamValue, ParseError> {
Ok(SvcParamValue::EchConfig(EchConfig(ech_config_bytes)))
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-6.4)
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-7.3)
///
/// ```text
/// The presentation "value" SHALL be a comma-separated list
/// The presentation value SHALL be a comma-separated list
/// (Appendix A.1) of one or more IP addresses of the appropriate family
/// in standard textual format [RFC5952]. To enable simpler parsing,
/// this SvcParamValue MUST NOT contain escape sequences.
@ -280,15 +287,15 @@ fn parse_ipv6_hint(value: Option<&str>) -> Result<SvcParamValue, ParseError> {
Ok(SvcParamValue::Ipv6Hint(IpHint(hints)))
}
/// [draft-ietf-dnsop-svcb-https-03 SVCB and HTTPS RRs for DNS, February 2021](https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-03#section-2.1)
/// ```text
/// Unrecognized keys are represented in presentation format as
/// "keyNNNNN" where NNNNN is the numeric value of the key type without
/// leading zeros. A SvcParam in this form SHALL be parsed as specified
/// above, and the decoded "value" SHALL be used as its wire format
/// encoding.
/// [RFC 9460 SVCB and HTTPS Resource Records, Nov 2023](https://datatracker.ietf.org/doc/html/rfc9460#section-2.1)
///
/// For some SvcParamKeys, the "value" corresponds to a list or set of
/// ```text
/// Arbitrary keys can be represented using the unknown-key presentation
/// format "keyNNNNN" where NNNNN is the numeric value of the key type
/// without leading zeros. A SvcParam in this form SHALL be parsed as specified
/// above, and the decoded value SHALL be used as its wire-format encoding.
///
/// For some SvcParamKeys, the value corresponds to a list or set of
/// items. Presentation formats for such keys SHOULD use a comma-
/// separated list (Appendix A.1).
///