1 -- | Helpers to perform DNS queries.
8 import Control.Concurrent.ParallelIO.Global ( parallel )
9 import qualified Data.ByteString.Char8 as BS (
24 -- The return type of lookupPTR.
25 type PTRResult = Either DNSError [Domain]
28 -- | Convert the given IP address (as a ByteString) to the format
29 -- required for a PTR lookup. For example, "192.168.0.0" should be
30 -- converted to "0.0.168.192.in-addr.arpa".
31 ip_to_in_addr_arpa :: Domain -> Domain
32 ip_to_in_addr_arpa ip =
33 rev_ip `BS.append` suffix
36 suffix = BS.pack ".in-addr.arpa"
37 rev_ip = BS.intercalate dot (reverse (BS.split '.' ip))
39 -- | Take the default ResolvConf and increase the timeout to 15
41 our_resolv_conf :: ResolvConf
43 defaultResolvConf { resolvTimeout = 15*1000*1000 } -- 15s
46 -- | Takes a list of IP addresses (as ByteStrings) and performs
47 -- reverse (PTR) lookups on each of them.
48 lookup_ptrs :: [Domain] -> IO [PTRResult]
50 rs <- makeResolvSeed our_resolv_conf
51 let lookup' addr = withResolver rs $ \resolver ->
52 lookupPTR resolver addr
54 parallel $ map lookup' in_addrs
57 in_addrs = map ip_to_in_addr_arpa ips