{-# LANGUAGE RecordWildCards #-}
module Net.DNSBase.Decode.Internal.RData
( getRData
, getRR
, fromOpaqueRData
) where
import qualified Data.IntMap as IM
import qualified Data.ByteString as B
import qualified Data.ByteString.Short as SB
import Net.DNSBase.Decode.Internal.Domain
import Net.DNSBase.Decode.Internal.Option
import Net.DNSBase.Decode.Internal.State
import Net.DNSBase.Internal.Domain
import Net.DNSBase.Internal.Error
import Net.DNSBase.Internal.Nat16
import Net.DNSBase.Internal.RData
import Net.DNSBase.Internal.RR
import Net.DNSBase.Internal.RRCLASS
import Net.DNSBase.Internal.RRTYPE
import Net.DNSBase.Internal.Util
import Net.DNSBase.RData.Internal.XNAME
import Net.DNSBase.Resolver.Internal.Types
getRData :: RDataMap
-> Maybe OptionMap
-> Word16
-> Int
-> SGet RData
getRData :: RDataMap -> Maybe OptionMap -> Word16 -> Key -> SGet RData
getRData RDataMap
_ (Just OptionMap
om) (Word16 -> RRTYPE
RRTYPE -> RRTYPE
OPT) = OptionMap -> Key -> SGet RData
getOPTWith OptionMap
om
getRData RDataMap
_ Maybe OptionMap
Nothing t :: Word16
t@(Word16 -> RRTYPE
RRTYPE -> RRTYPE
OPT) = Word16 -> Key -> SGet RData
opaqueDecoder Word16
t
getRData RDataMap
dm Maybe OptionMap
_ (RDataMap -> Word16 -> Maybe RDataCodec
dmLookup RDataMap
dm -> Just RDataCodec
dc) = RDataCodec -> Key -> SGet RData
decodeWith RDataCodec
dc
getRData RDataMap
_ Maybe OptionMap
_ Word16
t = Word16 -> Key -> SGet RData
opaqueDecoder Word16
t
decodeWith :: RDataCodec -> Int -> SGet RData
decodeWith :: RDataCodec -> Key -> SGet RData
decodeWith (RDataCodec (Proxy a
_ :: proxy a) (RDataExtensionVal a
opts :: RDataExtensionVal a)) =
(a ~ a) => RDataExtensionVal a -> Key -> SGet RData
RDataExtensionVal a -> Key -> SGet RData
forall b -> (b ~ a) => RDataExtensionVal a -> Key -> SGet RData
forall a.
KnownRData a =>
forall b -> (b ~ a) => RDataExtensionVal a -> Key -> SGet RData
rdDecode a RDataExtensionVal a
opts
opaqueDecoder :: Word16 -> Int -> SGet RData
opaqueDecoder :: Word16 -> Key -> SGet RData
opaqueDecoder Word16
rrtype = Word16 -> ShortByteString -> RData
opaqueRData Word16
rrtype (ShortByteString -> RData)
-> (ShortByteString -> ShortByteString) -> ShortByteString -> RData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> ShortByteString
forall a b. Coercible a b => a -> b
coerce (ShortByteString -> RData)
-> (Key -> SGet ShortByteString) -> Key -> SGet RData
forall (m :: * -> *) b c a.
Functor m =>
(b -> c) -> (a -> m b) -> a -> m c
<.> Key -> SGet ShortByteString
getShortNByteString
fromOpaqueRData :: ResolvSeed -> RData -> Either DNSError RData
fromOpaqueRData :: ResolvSeed -> RData -> Either DNSError RData
fromOpaqueRData ResolvSeed{NonEmpty Nameserver
RDataMap
OptionMap
ResolverConf
seedConfig :: ResolverConf
seedRDataMap :: RDataMap
seedOptionMap :: OptionMap
seedServers :: NonEmpty Nameserver
seedServers :: ResolvSeed -> NonEmpty Nameserver
seedOptionMap :: ResolvSeed -> OptionMap
seedRDataMap :: ResolvSeed -> RDataMap
seedConfig :: ResolvSeed -> ResolverConf
..} rd :: RData
rd@(RData -> RRTYPE
rdataType -> RRTYPE
t) = Word16
-> (forall (n :: Nat) -> Nat16 n => Either DNSError RData)
-> Either DNSError RData
forall r. Word16 -> (forall (n :: Nat) -> Nat16 n => r) -> r
withNat16 (RRTYPE -> Word16
forall a b. Coercible a b => a -> b
coerce RRTYPE
t) forall (n :: Nat) -> Nat16 n => Either DNSError RData
go
where
go :: forall (n :: Nat) -> Nat16 n => Either DNSError RData
go :: forall (n :: Nat) -> Nat16 n => Either DNSError RData
go n | Just RDataCodec
dc <- RDataMap -> Word16 -> Maybe RDataCodec
dmLookup RDataMap
seedRDataMap (Word16 -> Maybe RDataCodec) -> Word16 -> Maybe RDataCodec
forall a b. (a -> b) -> a -> b
$ RRTYPE -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral RRTYPE
t
, Just (OpaqueRData ShortByteString
d :: OpaqueRData n) <- RData -> Maybe (OpaqueRData n)
forall a. KnownRData a => RData -> Maybe a
fromRData RData
rd
, ByteString
bs <- ShortByteString -> ByteString
SB.fromShort (ShortByteString -> ShortByteString
forall a b. Coercible a b => a -> b
coerce ShortByteString
d)
, Key
len <- ByteString -> Key
B.length ByteString
bs
= Int64 -> Bool -> SGet RData -> ByteString -> Either DNSError RData
forall a.
Int64 -> Bool -> SGet a -> ByteString -> Either DNSError a
decodeAtWith Int64
0 Bool
False (RDataCodec -> Key -> SGet RData
decodeWith RDataCodec
dc Key
len) ByteString
bs
| Bool
otherwise
= RData -> Either DNSError RData
forall a b. b -> Either a b
Right RData
rd
dmLookup :: RDataMap -> Word16 -> Maybe RDataCodec
dmLookup :: RDataMap -> Word16 -> Maybe RDataCodec
dmLookup RDataMap
dm Word16
typ = Key -> RDataMap -> Maybe RDataCodec
forall a. Key -> IntMap a -> Maybe a
IM.lookup (Word16 -> Key
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
typ) RDataMap
dm
getRR :: RDataMap -> Maybe OptionMap -> SGet RR
getRR :: RDataMap -> Maybe OptionMap -> SGet RR
getRR RDataMap
dm Maybe OptionMap
om = do
owner <- SGet Domain
getLastOwner
cname <- getLastCname
rrOwner <- setLastOwner =<< dedup owner cname <$> getDomain
typ <- get16
rrClass <- getRRCLASS
local (setDecodeTriple (DnsTriple rrOwner (coerce typ) rrClass)) do
rrTTL <- get32
len <- getInt16
rrData <- fitSGet len $
if | typ == coerce CNAME ->
RData . T_CNAME <$> (setLastCname =<< getDomain)
| otherwise -> getRData dm om typ len
return RR{..}
where
getRRCLASS :: SGet RRCLASS
getRRCLASS = Word16 -> RRCLASS
RRCLASS (Word16 -> RRCLASS) -> SGet Word16 -> SGet RRCLASS
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SGet Word16
get16
dedup :: a -> a -> a -> a
dedup a
n1 a
n2 a
name | a
name a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
n1 = a
n1
| a
name a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
n2 = a
n2
| Bool
otherwise = a
name