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

Net.DNSBase.Encode.State

Description

The SPut encoder monad for serialising DNS wire-form data, plus primitive writers (put8, put16, ...), DNS-style helpers (putDomain, putWireForm), length-prefixed byte-string writers, and the high-level driver functions encodeCompressed / encodeVerbatim. Used by authors of KnownRData and KnownEdnsOption instances to implement value-side encoding; most applications will not use this module directly.

putDomain applies DNS name compression (RFC 1035 section 4.1.4) when the surrounding driver permits it; putWireForm is the compression-free counterpart for RR types whose target domains forbid compression on encode.

Synopsis

Low level DNS data encoding primitives

data EncodeErr r where Source #

Encoding error, polymorphic over the context type

Constructors

EncodeTooLong :: forall r. (Typeable r, Show r, Eq r) => r -> EncodeErr r

message or field too long

CantEncode :: forall r. (Typeable r, Show r, Eq r) => r -> EncodeErr r

Invalid input

ReservedType :: forall r. (Typeable r, Show r, Eq r) => RRTYPE -> r -> EncodeErr r

Unencodable reserved type

EDNSRequired :: forall r. EncodeErr r

RCODE or flags require EDNS

Instances

Instances details
Show r => Show (EncodeErr r) Source # 
Instance details

Defined in Net.DNSBase.Internal.Error

Eq r => Eq (EncodeErr r) Source # 
Instance details

Defined in Net.DNSBase.Internal.Error

Methods

(==) :: EncodeErr r -> EncodeErr r -> Bool #

(/=) :: EncodeErr r -> EncodeErr r -> Bool #

type ErrorContext r = (Typeable r, Show r, Eq r) Source #

type SPut s r = SPutM s r () Source #

Encode an output packet in the ST monad, with r as an optional error context (typically the RData being encoded, when applicable).

data SPutM s r a Source #

The underlying SPut monad

Instances

Instances details
Applicative (SPutM s r) Source # 
Instance details

Defined in Net.DNSBase.Encode.Internal.State

Methods

pure :: a -> SPutM s r a #

(<*>) :: SPutM s r (a -> b) -> SPutM s r a -> SPutM s r b #

liftA2 :: (a -> b -> c) -> SPutM s r a -> SPutM s r b -> SPutM s r c #

(*>) :: SPutM s r a -> SPutM s r b -> SPutM s r b #

(<*) :: SPutM s r a -> SPutM s r b -> SPutM s r a #

Functor (SPutM s r) Source # 
Instance details

Defined in Net.DNSBase.Encode.Internal.State

Methods

fmap :: (a -> b) -> SPutM s r a -> SPutM s r b #

(<$) :: a -> SPutM s r b -> SPutM s r a #

Monad (SPutM s r) Source # 
Instance details

Defined in Net.DNSBase.Encode.Internal.State

Methods

(>>=) :: SPutM s r a -> (a -> SPutM s r b) -> SPutM s r b #

(>>) :: SPutM s r a -> SPutM s r b -> SPutM s r b #

return :: a -> SPutM s r a #

localSPut :: forall s r a. (Maybe r -> Maybe r) -> SPutM s r a -> SPutM s r a Source #

Run the encoder with a modified context

buildCompressed :: ErrorContext r => (forall s. SPut s r) -> Either (EncodeErr (Maybe r)) Builder Source #

Perform a stateful encoding with DNS name compression. The initial error context is Nothing. Specific values can be provided during the computation by using localSPut.

encodeCompressed :: ErrorContext r => (forall s. SPut s r) -> Either (EncodeErr (Maybe r)) ByteString Source #

Perform a stateful encoding with DNS name compression. The initial error context is Nothing. Specific values can be provided during the computation by using localSPut.

buildVerbatim :: ErrorContext r => (forall s. SPut s r) -> Either (EncodeErr (Maybe r)) Builder Source #

Perform a stateful encoding without DNS name compression. The initial error context is Nothing. Specific values can be provided during the computation by using localSPut.

encodeVerbatim :: ErrorContext r => (forall s. SPut s r) -> Either (EncodeErr (Maybe r)) ByteString Source #

Perform a stateful encoding without DNS name compression. The initial error context is Nothing. Specific values can be provided during the computation by using localSPut.

putDomain :: ErrorContext r => Domain -> SPut s r Source #

Encode a domain with possible name compression if the entire name fits in the first 16K of the output.

putWireForm :: ErrorContext r => Domain -> SPut s r Source #

Encode a domain name verbatim, without name compression.

put8 :: ErrorContext r => Word8 -> SPut s r Source #

Write a single octet.

put16 :: ErrorContext r => Word16 -> SPut s r Source #

Write a big-endian 16-bit word.

put32 :: ErrorContext r => Word32 -> SPut s r Source #

Write a big-endian 32-bit word.

put64 :: ErrorContext r => Word64 -> SPut s r Source #

Write a big-endian 64-bit word.

putIPv4 :: ErrorContext r => IPv4 -> SPut s r Source #

Write the four octets of an IPv4 address in network order.

putIPv6 :: ErrorContext r => IPv6 -> SPut s r Source #

Write the sixteen octets of an IPv6 address in network order.

putByteString :: ErrorContext r => ByteString -> SPut s r Source #

Write the bytes of a ByteString verbatim, with no length prefix.

putByteStringLen8 :: ErrorContext r => ByteString -> SPut s r Source #

Write a DNS character-string: an 8-bit length prefix followed by the bytes. Fails with EncodeTooLong if the input exceeds 255 bytes.

putByteStringLen16 :: ErrorContext r => ByteString -> SPut s r Source #

Write a 16-bit-length-prefixed ByteString. Fails with EncodeTooLong if the input exceeds 65535 bytes.

putShortByteString :: ErrorContext r => ShortByteString -> SPut s r Source #

Write the bytes of a ShortByteString verbatim, with no length prefix.

putUtf8Text :: ErrorContext r => Text -> SPut s r Source #

Write the UTF-8 encoding of a Text verbatim, with no length prefix.

putUtf8TextLen8 :: ErrorContext r => Text -> SPut s r Source #

Write a UTF-8-encoded Text with an 8-bit length prefix (length in bytes, not codepoints). Fails with EncodeTooLong if the UTF-8 encoding exceeds 255 bytes.

putUtf8TextLen16 :: ErrorContext r => Text -> SPut s r Source #

Write a UTF-8-encoded Text with a 16-bit length prefix (length in bytes). Fails with EncodeTooLong if the UTF-8 encoding exceeds 65535 bytes.

putSizedBuilder :: ErrorContext r => SizedBuilder -> SPut s r Source #

Write a length-tracked SizedBuilder verbatim, advancing the encoder offset by the builder's recorded length. Fails with EncodeTooLong when the builder itself carries the overflow sentinel.

putReplicate :: ErrorContext r => Word8 -> Word8 -> SPut s r Source #

Write n copies of the byte w (used for fixed-width zero-padded fields).

Encoder state mutation

passLen :: ErrorContext r => SPutM s r a -> SPutM s r a Source #

Wrap a writer with an outer 16-bit length prefix that is computed automatically from the writer's output. Used for RDLENGTH and the various length-prefixed sub-fields of RR data (SVCB option values, EDNS option values, and so on).

failWith :: ErrorContext r => (forall a. ErrorContext a => a -> EncodeErr a) -> SPut s r Source #

Abort the encoder with the given error, attaching the current ErrorContext from the reader environment. Used by individual writers when an out-of-range or otherwise invalid value cannot be serialised.

setContext :: ErrorContext r => r -> SPutM s r a -> SPutM s r a Source #

Run a sub-encoder with the given context value installed, so that any failWith inside reports its error against that context. Used to label sections of the encode (RR header, RR data, EDNS option, ...) so that error messages identify which field went wrong.