module Network.DNS.Lookup (
lookupA, lookupAAAA
, lookupMX, lookupAviaMX, lookupAAAAviaMX
, lookupNS
, lookupNSAuth
, lookupTXT
, lookupSOA
, lookupPTR
, lookupRDNS
, lookupSRV
) where
import qualified Data.ByteString.Char8 as BS
import Data.IP (IPv4, IPv6)
import Network.DNS.Imports
import Network.DNS.LookupRaw as DNS
import Network.DNS.Resolver as DNS
import Network.DNS.Types
lookupA :: Resolver -> Domain -> IO (Either DNSError [IPv4])
lookupA :: Resolver -> Domain -> IO (Either DNSError [IPv4])
lookupA Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup Resolver
rlv Domain
dom TYPE
A
case Either DNSError [RData]
erds of
Left DNSError
err -> Either DNSError [IPv4] -> IO (Either DNSError [IPv4])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [IPv4]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either DNSError [IPv4] -> IO (Either DNSError [IPv4])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [IPv4] -> IO (Either DNSError [IPv4]))
-> Either DNSError [IPv4] -> IO (Either DNSError [IPv4])
forall a b. (a -> b) -> a -> b
$ (RData -> Either DNSError IPv4)
-> [RData] -> Either DNSError [IPv4]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData -> Either DNSError IPv4
unTag [RData]
rds
where
unTag :: RData -> Either DNSError IPv4
unTag :: RData -> Either DNSError IPv4
unTag (RD_A IPv4
x) = IPv4 -> Either DNSError IPv4
forall a b. b -> Either a b
Right IPv4
x
unTag RData
_ = DNSError -> Either DNSError IPv4
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA
lookupAAAA :: Resolver -> Domain -> IO (Either DNSError [IPv6])
lookupAAAA :: Resolver -> Domain -> IO (Either DNSError [IPv6])
lookupAAAA Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup Resolver
rlv Domain
dom TYPE
AAAA
case Either DNSError [RData]
erds of
Left DNSError
err -> Either DNSError [IPv6] -> IO (Either DNSError [IPv6])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [IPv6]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either DNSError [IPv6] -> IO (Either DNSError [IPv6])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [IPv6] -> IO (Either DNSError [IPv6]))
-> Either DNSError [IPv6] -> IO (Either DNSError [IPv6])
forall a b. (a -> b) -> a -> b
$ (RData -> Either DNSError IPv6)
-> [RData] -> Either DNSError [IPv6]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData -> Either DNSError IPv6
unTag [RData]
rds
where
unTag :: RData -> Either DNSError IPv6
unTag :: RData -> Either DNSError IPv6
unTag (RD_AAAA IPv6
x) = IPv6 -> Either DNSError IPv6
forall a b. b -> Either a b
Right IPv6
x
unTag RData
_ = DNSError -> Either DNSError IPv6
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA
lookupMX :: Resolver -> Domain -> IO (Either DNSError [(Domain,Int)])
lookupMX :: Resolver -> Domain -> IO (Either DNSError [(Domain, Int)])
lookupMX Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup Resolver
rlv Domain
dom TYPE
MX
case Either DNSError [RData]
erds of
Left DNSError
err -> Either DNSError [(Domain, Int)]
-> IO (Either DNSError [(Domain, Int)])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [(Domain, Int)]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either DNSError [(Domain, Int)]
-> IO (Either DNSError [(Domain, Int)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [(Domain, Int)]
-> IO (Either DNSError [(Domain, Int)]))
-> Either DNSError [(Domain, Int)]
-> IO (Either DNSError [(Domain, Int)])
forall a b. (a -> b) -> a -> b
$ (RData -> Either DNSError (Domain, Int))
-> [RData] -> Either DNSError [(Domain, Int)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData -> Either DNSError (Domain, Int)
unTag [RData]
rds
where
unTag :: RData -> Either DNSError (Domain,Int)
unTag :: RData -> Either DNSError (Domain, Int)
unTag (RD_MX Word16
pr Domain
dm) = (Domain, Int) -> Either DNSError (Domain, Int)
forall a b. b -> Either a b
Right (Domain
dm, Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
pr)
unTag RData
_ = DNSError -> Either DNSError (Domain, Int)
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA
lookupAviaMX :: Resolver -> Domain -> IO (Either DNSError [IPv4])
lookupAviaMX :: Resolver -> Domain -> IO (Either DNSError [IPv4])
lookupAviaMX Resolver
rlv Domain
dom = Resolver
-> Domain
-> (Domain -> IO (Either DNSError [IPv4]))
-> IO (Either DNSError [IPv4])
forall a.
Resolver
-> Domain
-> (Domain -> IO (Either DNSError [a]))
-> IO (Either DNSError [a])
lookupXviaMX Resolver
rlv Domain
dom (Resolver -> Domain -> IO (Either DNSError [IPv4])
lookupA Resolver
rlv)
lookupAAAAviaMX :: Resolver -> Domain -> IO (Either DNSError [IPv6])
lookupAAAAviaMX :: Resolver -> Domain -> IO (Either DNSError [IPv6])
lookupAAAAviaMX Resolver
rlv Domain
dom = Resolver
-> Domain
-> (Domain -> IO (Either DNSError [IPv6]))
-> IO (Either DNSError [IPv6])
forall a.
Resolver
-> Domain
-> (Domain -> IO (Either DNSError [a]))
-> IO (Either DNSError [a])
lookupXviaMX Resolver
rlv Domain
dom (Resolver -> Domain -> IO (Either DNSError [IPv6])
lookupAAAA Resolver
rlv)
lookupXviaMX :: Resolver
-> Domain
-> (Domain -> IO (Either DNSError [a]))
-> IO (Either DNSError [a])
lookupXviaMX :: Resolver
-> Domain
-> (Domain -> IO (Either DNSError [a]))
-> IO (Either DNSError [a])
lookupXviaMX Resolver
rlv Domain
dom Domain -> IO (Either DNSError [a])
func = do
Either DNSError [(Domain, Int)]
edps <- Resolver -> Domain -> IO (Either DNSError [(Domain, Int)])
lookupMX Resolver
rlv Domain
dom
case Either DNSError [(Domain, Int)]
edps of
Left DNSError
err -> Either DNSError [a] -> IO (Either DNSError [a])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [a]
forall a b. a -> Either a b
Left DNSError
err)
Right [(Domain, Int)]
dps -> do
[Either DNSError [a]]
responses <- ((Domain, Int) -> IO (Either DNSError [a]))
-> [(Domain, Int)] -> IO [Either DNSError [a]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Domain -> IO (Either DNSError [a])
func (Domain -> IO (Either DNSError [a]))
-> ((Domain, Int) -> Domain)
-> (Domain, Int)
-> IO (Either DNSError [a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Domain, Int) -> Domain
forall a b. (a, b) -> a
fst) [(Domain, Int)]
dps
let overall :: Either DNSError [[a]]
overall = [Either DNSError [a]] -> Either DNSError [[a]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Either DNSError [a]]
responses
Either DNSError [a] -> IO (Either DNSError [a])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [a] -> IO (Either DNSError [a]))
-> Either DNSError [a] -> IO (Either DNSError [a])
forall a b. (a -> b) -> a -> b
$ ([[a]] -> [a]) -> Either DNSError [[a]] -> Either DNSError [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat Either DNSError [[a]]
overall
lookupNSImpl :: (Resolver -> Domain -> TYPE -> IO (Either DNSError [RData]))
-> Resolver
-> Domain
-> IO (Either DNSError [Domain])
lookupNSImpl :: (Resolver -> Domain -> TYPE -> IO (Either DNSError [RData]))
-> Resolver -> Domain -> IO (Either DNSError [Domain])
lookupNSImpl Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
lookup_function Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
lookup_function Resolver
rlv Domain
dom TYPE
NS
case Either DNSError [RData]
erds of
Left DNSError
err -> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [Domain]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [Domain] -> IO (Either DNSError [Domain]))
-> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall a b. (a -> b) -> a -> b
$ (RData -> Either DNSError Domain)
-> [RData] -> Either DNSError [Domain]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData -> Either DNSError Domain
unTag [RData]
rds
where
unTag :: RData -> Either DNSError Domain
unTag :: RData -> Either DNSError Domain
unTag (RD_NS Domain
dm) = Domain -> Either DNSError Domain
forall a b. b -> Either a b
Right Domain
dm
unTag RData
_ = DNSError -> Either DNSError Domain
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA
lookupNS :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupNS :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupNS = (Resolver -> Domain -> TYPE -> IO (Either DNSError [RData]))
-> Resolver -> Domain -> IO (Either DNSError [Domain])
lookupNSImpl Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup
lookupNSAuth :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupNSAuth :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupNSAuth = (Resolver -> Domain -> TYPE -> IO (Either DNSError [RData]))
-> Resolver -> Domain -> IO (Either DNSError [Domain])
lookupNSImpl Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookupAuth
lookupTXT :: Resolver -> Domain -> IO (Either DNSError [ByteString])
lookupTXT :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupTXT Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup Resolver
rlv Domain
dom TYPE
TXT
case Either DNSError [RData]
erds of
Left DNSError
err -> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [Domain]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [Domain] -> IO (Either DNSError [Domain]))
-> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall a b. (a -> b) -> a -> b
$ (RData -> Either DNSError Domain)
-> [RData] -> Either DNSError [Domain]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData -> Either DNSError Domain
unTag [RData]
rds
where
unTag :: RData -> Either DNSError ByteString
unTag :: RData -> Either DNSError Domain
unTag (RD_TXT Domain
x) = Domain -> Either DNSError Domain
forall a b. b -> Either a b
Right Domain
x
unTag RData
_ = DNSError -> Either DNSError Domain
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA
lookupSOA :: Resolver -> Domain -> IO (Either DNSError [(Domain,Mailbox,Word32,Word32,Word32,Word32,Word32)])
lookupSOA :: Resolver
-> Domain
-> IO
(Either
DNSError
[(Domain, Domain, Word32, Word32, Word32, Word32, Word32)])
lookupSOA Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup Resolver
rlv Domain
dom TYPE
SOA
case Either DNSError [RData]
erds of
Left DNSError
err -> Either
DNSError [(Domain, Domain, Word32, Word32, Word32, Word32, Word32)]
-> IO
(Either
DNSError
[(Domain, Domain, Word32, Word32, Word32, Word32, Word32)])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError
-> Either
DNSError [(Domain, Domain, Word32, Word32, Word32, Word32, Word32)]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either
DNSError [(Domain, Domain, Word32, Word32, Word32, Word32, Word32)]
-> IO
(Either
DNSError
[(Domain, Domain, Word32, Word32, Word32, Word32, Word32)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
DNSError [(Domain, Domain, Word32, Word32, Word32, Word32, Word32)]
-> IO
(Either
DNSError
[(Domain, Domain, Word32, Word32, Word32, Word32, Word32)]))
-> Either
DNSError [(Domain, Domain, Word32, Word32, Word32, Word32, Word32)]
-> IO
(Either
DNSError
[(Domain, Domain, Word32, Word32, Word32, Word32, Word32)])
forall a b. (a -> b) -> a -> b
$ (RData
-> Either
DNSError (Domain, Domain, Word32, Word32, Word32, Word32, Word32))
-> [RData]
-> Either
DNSError [(Domain, Domain, Word32, Word32, Word32, Word32, Word32)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData
-> Either
DNSError (Domain, Domain, Word32, Word32, Word32, Word32, Word32)
unTag [RData]
rds
where
unTag :: RData -> Either DNSError (Domain,Mailbox,Word32,Word32,Word32,Word32,Word32)
unTag :: RData
-> Either
DNSError (Domain, Domain, Word32, Word32, Word32, Word32, Word32)
unTag (RD_SOA Domain
mn Domain
mr Word32
serial Word32
refresh Word32
retry Word32
expire Word32
mini) = (Domain, Domain, Word32, Word32, Word32, Word32, Word32)
-> Either
DNSError (Domain, Domain, Word32, Word32, Word32, Word32, Word32)
forall a b. b -> Either a b
Right (Domain
mn, Domain
mr, Word32
serial, Word32
refresh, Word32
retry, Word32
expire, Word32
mini)
unTag RData
_ = DNSError
-> Either
DNSError (Domain, Domain, Word32, Word32, Word32, Word32, Word32)
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA
lookupPTR :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupPTR :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupPTR Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup Resolver
rlv Domain
dom TYPE
PTR
case Either DNSError [RData]
erds of
Left DNSError
err -> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [Domain]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [Domain] -> IO (Either DNSError [Domain]))
-> Either DNSError [Domain] -> IO (Either DNSError [Domain])
forall a b. (a -> b) -> a -> b
$ (RData -> Either DNSError Domain)
-> [RData] -> Either DNSError [Domain]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData -> Either DNSError Domain
unTag [RData]
rds
where
unTag :: RData -> Either DNSError Domain
unTag :: RData -> Either DNSError Domain
unTag (RD_PTR Domain
dm) = Domain -> Either DNSError Domain
forall a b. b -> Either a b
Right Domain
dm
unTag RData
_ = DNSError -> Either DNSError Domain
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA
lookupRDNS :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupRDNS :: Resolver -> Domain -> IO (Either DNSError [Domain])
lookupRDNS Resolver
rlv Domain
ip = Resolver -> Domain -> IO (Either DNSError [Domain])
lookupPTR Resolver
rlv Domain
dom
where
dot :: Domain
dot = String -> Domain
BS.pack String
"."
suffix :: Domain
suffix = String -> Domain
BS.pack String
".in-addr.arpa"
octets :: [Domain]
octets = Char -> Domain -> [Domain]
BS.split Char
'.' Domain
ip
reverse_ip :: Domain
reverse_ip = Domain -> [Domain] -> Domain
BS.intercalate Domain
dot ([Domain] -> [Domain]
forall a. [a] -> [a]
reverse [Domain]
octets)
dom :: Domain
dom = Domain
reverse_ip Domain -> Domain -> Domain
`BS.append` Domain
suffix
lookupSRV :: Resolver -> Domain -> IO (Either DNSError [(Word16, Word16, Word16, Domain)])
lookupSRV :: Resolver
-> Domain
-> IO (Either DNSError [(Word16, Word16, Word16, Domain)])
lookupSRV Resolver
rlv Domain
dom = do
Either DNSError [RData]
erds <- Resolver -> Domain -> TYPE -> IO (Either DNSError [RData])
DNS.lookup Resolver
rlv Domain
dom TYPE
SRV
case Either DNSError [RData]
erds of
Left DNSError
err -> Either DNSError [(Word16, Word16, Word16, Domain)]
-> IO (Either DNSError [(Word16, Word16, Word16, Domain)])
forall (m :: * -> *) a. Monad m => a -> m a
return (DNSError -> Either DNSError [(Word16, Word16, Word16, Domain)]
forall a b. a -> Either a b
Left DNSError
err)
Right [RData]
rds -> Either DNSError [(Word16, Word16, Word16, Domain)]
-> IO (Either DNSError [(Word16, Word16, Word16, Domain)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either DNSError [(Word16, Word16, Word16, Domain)]
-> IO (Either DNSError [(Word16, Word16, Word16, Domain)]))
-> Either DNSError [(Word16, Word16, Word16, Domain)]
-> IO (Either DNSError [(Word16, Word16, Word16, Domain)])
forall a b. (a -> b) -> a -> b
$ (RData -> Either DNSError (Word16, Word16, Word16, Domain))
-> [RData] -> Either DNSError [(Word16, Word16, Word16, Domain)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM RData -> Either DNSError (Word16, Word16, Word16, Domain)
unTag [RData]
rds
where
unTag :: RData -> Either DNSError (Word16, Word16, Word16, Domain)
unTag :: RData -> Either DNSError (Word16, Word16, Word16, Domain)
unTag (RD_SRV Word16
pri Word16
wei Word16
prt Domain
dm) = (Word16, Word16, Word16, Domain)
-> Either DNSError (Word16, Word16, Word16, Domain)
forall a b. b -> Either a b
Right (Word16
pri,Word16
wei,Word16
prt,Domain
dm)
unTag RData
_ = DNSError -> Either DNSError (Word16, Word16, Word16, Domain)
forall a b. a -> Either a b
Left DNSError
UnexpectedRDATA