dnsbase-1.0.0.0: internal/Net/DNSBase/EDNS/Internal/Option/Opaque.hs
-- |
-- Module : Net.DNSBase.EDNS.Internal.Option.Opaque
-- Description : Internal: fallback wrapper for unrecognised EDNS options
-- Copyright : (c) Viktor Dukhovni, 2026
-- License : BSD-3-Clause
-- Maintainer : ietf-dane@dukhovni.org
-- Stability : unstable
module Net.DNSBase.EDNS.Internal.Option.Opaque
( OpaqueOption(..)
, opaqueEdnsOption
)
where
import Net.DNSBase.Decode.Internal.State
import Net.DNSBase.EDNS.Internal.OptNum
import Net.DNSBase.EDNS.Internal.Option
import Net.DNSBase.Encode.Internal.State
import Net.DNSBase.Internal.Bytes
import Net.DNSBase.Internal.Nat16
import Net.DNSBase.Internal.Present
import Net.DNSBase.Internal.Util
-- | Unrecognized EDNS Option whose contents are treated as an opaque octet-string
-- and are left unparsed. The OPTION-CODE is encoded as a type-level natural, so
-- opaque options with different option code values are of different types.
type OpaqueOption :: Nat -> Type
data OpaqueOption n = OpaqueOption ShortByteString
deriving instance Eq (OpaqueOption n)
instance Nat16 n => Show (OpaqueOption n) where
showsPrec p (OpaqueOption bs) = showsP p $
showString "OpaqueOption @" . shows (natToWord16 n) . showChar ' '
. shows @Bytes16 (coerce bs)
instance Presentable (OpaqueOption n) where
present = \ (OpaqueOption bs) -> present @Bytes16 (coerce bs)
instance Nat16 n => KnownEdnsOption (OpaqueOption n) where
optNum _ = OptNum $ natToWord16 n
{-# INLINE optNum #-}
optPres _ = present "OPT" . present (natToWord16 n)
optEncode (OpaqueOption bs) = putShortByteString $ coerce bs
optDecode _ _ = EdnsOption . OpaqueOption @n <.> getShortNByteString
-- | Create opaque option from its opcode and Bytes16 value
opaqueEdnsOption :: Word16 -> ShortByteString -> EdnsOption
opaqueEdnsOption w bs = withNat16 w go
where
go :: forall (n :: Nat) -> Nat16 n => EdnsOption
go n = EdnsOption $ OpaqueOption @n bs