dnsbase
Copyright(c) Viktor Dukhovni 2026
LicenseBSD-3-Clause
Maintainerietf-dane@dukhovni.org
Stabilityunstable
Safe HaskellNone
LanguageGHC2024

Net.DNSBase.RData.SVCB

Description

The Service Binding RR (T_svcb) and its HTTPS-specific variant (T_https), defined by RFC 9460. Both share a wire format with three fields — priority, target name, and a list of typed (key, value) service parameters — represented internally by the X_svcb data type, indexed by a type-level natural that determines the specific RR type.

The service-parameter machinery is split across submodules:

New service-parameter value types can be installed at runtime via extendRRwithType on the SVCB or HTTPS RR type — see Net.DNSBase.Extensible for a worked example. The mandatory key (codepoint 0) is reserved and cannot be replaced by user code.

Synopsis

SVCB and HTTPS

data X_svcb (n :: Nat) Source #

Shared wire-format representation for the SVCB service binding record (RFC 9460 section 2) and its HTTPS-specific variant (RFC 9460 section 9).

                                1  1  1  1  1  1
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  SvcPriority                  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/                  TargetName                   /
/                                               /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/                   SvcParams                   /
/                                               /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

The type parameter n (either N_https or N_svcb) determines the RR type. Each has its own type synonym (T_https, T_svcb) and matching record pattern synonym (T_HTTPS, T_SVCB) with the corresponding field-name prefix (https, svcb). The wire format is shared, but the type role of n is nominal: a T_svcb value cannot be used where a T_https is expected. This is deliberate — the two RR types serve different transports, and future SvcParamKeys may apply to only one of them.

Note that T_https and T_svcb are just type aliases! The T_HTTPS and T_SVCB record pattern synonyms and their fields are bundled with the underlying X_svcb data type. In many cases it is sufficient to import just X_svcb(..), but if you also need the type aliases, they need to be imported separately:

import Net.DNSBase (X_svcb(..), T_https, T_svcb)

The target field is not subject to wire-form name compression (RFC 3597 section 4) and is not in the RFC 4034 section 6.2 list of types that lower-case their RDATA names — it is compared case-sensitively in canonical form. The Ord instance compares structurally on the parsed fields rather than on the wire form, so it is not canonical: callers that need RFC 4034 canonical ordering must serialise to wire form first.

The SvcParams field is a list of (key, length, value) triples — possibly empty — making up the rest of the RData:

                                1  1  1  1  1  1
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  SvcParamKey                  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  SvcParamLen                  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/                  SvcParamValue                /
/                                               /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

On the wire the list must be in strictly ascending key order; the presentation form may list keys in any order. Each value has the type associated with its key in the decoder state configured for the RR type — keys absent from the state decode as OpaqueSPV, preserving the raw bytes.

The record pattern synonyms T_SVCB and T_HTTPS build the corresponding T_svcb or T_https value directly, with their own field-name prefixes (svc and https):

let s = T_SVCB  { svcPriority      = 0
                , svcTarget        = RootDomain
                , svcParamValues   = [] }
    h = T_HTTPS { httpsPriority    = 0
                , httpsTarget      = RootDomain
                , httpsParamValues = [] }
 in RData s : RData h : []

Functions that work on either RR type can use the underscore-prefixed selectors on the shared X_svcb record:

aliasDomain :: forall n. X_svcb n -> Maybe Domain
aliasDomain r | x_svcPriority r == 0 = Just $ x_svcTarget r
              | otherwise           = Nothing

Constructors

X_SVCB 

Fields

Bundled Patterns

pattern T_SVCB

Record pattern synonym viewing the shared X_svcb record as a generic SVCB service-binding record (RFC 9460). Fields: svcPriority, svcTarget, svcParamValues. See X_svcb for why T_svcb and T_https are not coercible.

Fields

pattern T_HTTPS

Record pattern synonym viewing the shared X_svcb record as an HTTPS service-binding record (RFC 9460). Fields: httpsPriority, httpsTarget, httpsParamValues.

Fields

Instances

Instances details
Presentable (X_svcb n) Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB

(Nat16 n, KnownSymbol (XsvcbConName n)) => KnownRData (X_svcb n) Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB

Associated Types

type RDataExtensionVal (X_svcb n) 
Instance details

Defined in Net.DNSBase.RData.SVCB

Methods

rdataExtensionVal :: forall b -> b ~ X_svcb n => RDataExtensionVal (X_svcb n) Source #

rdType :: forall b -> b ~ X_svcb n => RRTYPE Source #

rdTypePres :: forall b -> b ~ X_svcb n => Builder -> Builder Source #

rdDecode :: forall b -> b ~ X_svcb n => RDataExtensionVal (X_svcb n) -> Int -> SGet RData Source #

rdEncode :: X_svcb n -> SPut s RData Source #

cnEncode :: X_svcb n -> SPut s RData Source #

KnownSymbol (XsvcbConName n) => Show (X_svcb n) Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB

Methods

showsPrec :: Int -> X_svcb n -> ShowS #

show :: X_svcb n -> String #

showList :: [X_svcb n] -> ShowS #

Eq (X_svcb n) Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB

Methods

(==) :: X_svcb n -> X_svcb n -> Bool #

(/=) :: X_svcb n -> X_svcb n -> Bool #

Ord (X_svcb n) Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB

Methods

compare :: X_svcb n -> X_svcb n -> Ordering #

(<) :: X_svcb n -> X_svcb n -> Bool #

(<=) :: X_svcb n -> X_svcb n -> Bool #

(>) :: X_svcb n -> X_svcb n -> Bool #

(>=) :: X_svcb n -> X_svcb n -> Bool #

max :: X_svcb n -> X_svcb n -> X_svcb n #

min :: X_svcb n -> X_svcb n -> X_svcb n #

type RDataExtensionVal (X_svcb n) Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB

type TypeExtensionArg (X_svcb n) b Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB

type family XsvcbConName (n :: Nat) :: Symbol where ... Source #

Equations

XsvcbConName N_svcb = "T_SVCB" 
XsvcbConName N_https = "T_HTTPS" 
XsvcbConName n = TypeError ('ShowType n ':<>: 'Text " is not a SVCB-based RRTYPE") :: Symbol 

T_HTTPS pattern record synonym fields

type T_https = X_svcb N_https Source #

X_svcb specialised to HTTPS records.

Note that T_https is just a type alias! The T_HTTPS record pattern synonym and its fields are bundled with the underlying X_svcb data type. In many cases it is sufficient to import just X_svcb(..), but if you also need the type alias, it needs to be imported separately:

import Net.DNSBase (X_svcb(..), T_https)

T_SVCB pattern record synonym fields

type T_svcb = X_svcb N_svcb Source #

X_svcb specialised to SVCB records.

Note that T_svcb is just a type alias! The T_SCVB record pattern synonym and its fields are bundled with the underlying X_svcb data type. In many cases it is sufficient to import just X_svcb(..), but if you also need the type alias, it needs to be imported separately:

import Net.DNSBase (X_svcb(..), T_svcb)

Service parameter values

class (Typeable a, Eq a, Ord a, Show a, Presentable a) => KnownSVCParamValue a where Source #

The class of types representing the value side of a service parameter inside an SVCB or HTTPS record. Each instance corresponds to a specific SVCParamKey; the encodeSPV and decodeSPV methods handle only the value bytes.

The Presentable instance builds the RFC 9460 zone-file presentation form: the key name followed (where the value is non-empty) by = and the value. The Show instance is typically derived and aims to produce syntactically valid Haskell.

Minimal complete definition

spvKey, encodeSPV, decodeSPV

Methods

spvKey :: forall b -> b ~ a => SVCParamKey Source #

The associated key number

spvKeyPres :: forall b -> b ~ a => Builder -> Builder Source #

CPS presentation form builder for the key

encodeSPV :: ErrorContext r => a -> SPut s r Source #

Encode value to wire form. The surrounding (key, length) frame is owned by the SVCB-record encoder: encodeSPV writes just the payload, and the framework wraps the result in the 2-byte length prefix. For valueless parameters this means encodeSPV is just pure ().

decodeSPV :: forall b -> b ~ a => Int -> SGet SVCParamValue Source #

Decode value from wire form. The overall SVCB RData decoder gives each parameter decoder a view into a buffer of exactly the indicated length, and makes sure exactly that many bytes are consumed. The length argument is only needed in decoders that read variable-length fields that run to the end of the record.

Instances

Instances details
KnownSVCParamValue SPV_alpn Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Methods

spvKey :: forall b -> b ~ SPV_alpn => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ SPV_alpn => Builder -> Builder Source #

encodeSPV :: ErrorContext r => SPV_alpn -> SPut s r Source #

decodeSPV :: forall b -> b ~ SPV_alpn => Int -> SGet SVCParamValue Source #

KnownSVCParamValue SPV_docpath Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Methods

spvKey :: forall b -> b ~ SPV_docpath => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ SPV_docpath => Builder -> Builder Source #

encodeSPV :: ErrorContext r => SPV_docpath -> SPut s r Source #

decodeSPV :: forall b -> b ~ SPV_docpath => Int -> SGet SVCParamValue Source #

KnownSVCParamValue SPV_dohpath Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Methods

spvKey :: forall b -> b ~ SPV_dohpath => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ SPV_dohpath => Builder -> Builder Source #

encodeSPV :: ErrorContext r => SPV_dohpath -> SPut s r Source #

decodeSPV :: forall b -> b ~ SPV_dohpath => Int -> SGet SVCParamValue Source #

KnownSVCParamValue SPV_ech Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Methods

spvKey :: forall b -> b ~ SPV_ech => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ SPV_ech => Builder -> Builder Source #

encodeSPV :: ErrorContext r => SPV_ech -> SPut s r Source #

decodeSPV :: forall b -> b ~ SPV_ech => Int -> SGet SVCParamValue Source #

KnownSVCParamValue SPV_ipv4hint Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

KnownSVCParamValue SPV_ipv6hint Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

KnownSVCParamValue SPV_mandatory Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

KnownSVCParamValue SPV_ndalpn Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Methods

spvKey :: forall b -> b ~ SPV_ndalpn => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ SPV_ndalpn => Builder -> Builder Source #

encodeSPV :: ErrorContext r => SPV_ndalpn -> SPut s r Source #

decodeSPV :: forall b -> b ~ SPV_ndalpn => Int -> SGet SVCParamValue Source #

KnownSVCParamValue SPV_port Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Methods

spvKey :: forall b -> b ~ SPV_port => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ SPV_port => Builder -> Builder Source #

encodeSPV :: ErrorContext r => SPV_port -> SPut s r Source #

decodeSPV :: forall b -> b ~ SPV_port => Int -> SGet SVCParamValue Source #

KnownSVCParamValue SPV_pvd Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Methods

spvKey :: forall b -> b ~ SPV_pvd => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ SPV_pvd => Builder -> Builder Source #

encodeSPV :: ErrorContext r => SPV_pvd -> SPut s r Source #

decodeSPV :: forall b -> b ~ SPV_pvd => Int -> SGet SVCParamValue Source #

KnownSVCParamValue SPV_tlsgroups Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPV

Nat16 n => KnownSVCParamValue (OpaqueSPV n) Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SVCParamValue

Methods

spvKey :: forall b -> b ~ OpaqueSPV n => SVCParamKey Source #

spvKeyPres :: forall b -> b ~ OpaqueSPV n => Builder -> Builder Source #

encodeSPV :: ErrorContext r => OpaqueSPV n -> SPut s r Source #

decodeSPV :: forall b -> b ~ OpaqueSPV n => Int -> SGet SVCParamValue Source #

data SPVSet where Source #

The set of service parameters in an SVCB or HTTPS record, with at most one value per SVCParamKey. The Monoid instance provides the empty set; the Semigroup instance is left-biased on key collisions.

Bundled Patterns

pattern SPVMap

One-sided pattern that exposes the underlying IntMap for traversal or low-level inspection. The values are kept in the existential SVCParamValue wrapper, so any concrete parameter may be either typed (a KnownSVCParamValue instance) or OpaqueSPV. For typed lookups by parameter type use spvLookup instead.

Fields

Instances

Instances details
Presentable SPVSet Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

Monoid SPVSet Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

Semigroup SPVSet Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

IsList SPVSet Source #

Construction is via fromList, and enumeration is via toList.

Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

Associated Types

type Item SPVSet 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

Show SPVSet Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

Eq SPVSet Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

Methods

(==) :: SPVSet -> SPVSet -> Bool #

(/=) :: SPVSet -> SPVSet -> Bool #

type Item SPVSet Source # 
Instance details

Defined in Net.DNSBase.RData.SVCB.SPVSet

spvLookup :: KnownSVCParamValue a => SPVSet -> Maybe a Source #

Look up the parameter at the key associated with type a, returning a Just only when the stored value really is of type a. A value of the same key code but held as OpaqueSPV (because the typed instance was not registered when the record was decoded) does not match — opaque values must be retrieved through SPVMap.