{-# LANGUAGE Trustworthy #-} -- | -- Copyright: © 2017 Herbert Valerio Riedel -- License: GPLv3 -- -- This module implements an API for accessing -- the [Domain Name Service (DNS)](https://tools.ietf.org/html/rfc1035) -- resolver service via the standard [/dnsapi.dll](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682100\(v=vs.85\).aspx) -- system library on Win32 systems. -- module Network.DNS ( -- ** High level API queryA , queryAAAA , queryCNAME , querySRV , queryTXT -- * Types , Name(..) , CharStr(..) , IPv4(..) , IPv6(..) , TTL(..) , SRV(..) ) where import Network.DNS.FFI -- | Query @TXT@ records (see [RFC 1035, section 3.3.14](https://tools.ietf.org/html/rfc1035#section-3.3.14)). -- -- >>> queryTXT (Name "_mirrors.hackage.haskell.org") -- [(TTL 299,["0.urlbase=http://hackage.fpcomplete.com/", -- "1.urlbase=http://objects-us-west-1.dream.io/hackage-mirror/"])] -- queryTXT :: Name -> IO [(TTL, [CharStr])] queryTXT n = do recs <- dnsQuery True n DnsTypeTXT case recs of Left err -> fail ("DnsQuery_A failed with " ++ show err) Right recs' -> return [ (ttl,ts) | DnsRecord { drTTL = ttl, drData = DnsDataTXT ts } <- recs' ] -- | Query @A@ record (see [RFC 1035, section 3.4.1](https://tools.ietf.org/html/rfc1035#section-3.4.1)). -- -- This query returns only exact matches (modulo 'foldCaseName'). -- E.g. in case of @CNAME@ responses even if the -- answer section would contain @A@ records for the hostnames pointed -- to by the @CNAME@. -- -- >>> queryA (Name "www.google.com") -- [(TTL 72,IPv4 0xd83acde4)] -- queryA :: Name -> IO [(TTL,IPv4)] queryA n = do recs <- dnsQuery True n DnsTypeA case recs of Left err -> fail ("DnsQuery_A failed with " ++ show err) Right recs' -> return [ (ttl,ip4) | DnsRecord { drTTL = ttl, drData = DnsDataA ip4 } <- recs' ] -- | Query @AAAA@ records (see [RFC 3596](https://tools.ietf.org/html/rfc3596)). -- -- This query returns only exact matches (modulo 'foldCaseName'). -- E.g. in case of @CNAME@ responses even if the answer section would -- contain @A@ records for the hostnames pointed to by the -- @CNAME@. -- -- >>> queryAAAA (Name "www.google.com") -- [(TTL 299,IPv6 0x2a0014504001081e 0x2004)] -- queryAAAA :: Name -> IO [(TTL,IPv6)] queryAAAA n = do recs <- dnsQuery True n DnsTypeAAAA case recs of Left err -> fail ("DnsQuery_A failed with " ++ show err) Right recs' -> return [ (ttl,ip6) | DnsRecord { drTTL = ttl, drData = DnsDataAAAA ip6 } <- recs' ] -- | Query @CNAME@ records (see [RFC 1035, section 3.3.1](https://tools.ietf.org/html/rfc1035#section-3.3.1)). -- -- >>> queryCNAME (Name "hackage.haskell.org") -- [(TTL 299,Name "j.global-ssl.fastly.net.")] -- queryCNAME :: Name -> IO [(TTL,Name)] queryCNAME n = do recs <- dnsQuery True n DnsTypeCNAME case recs of Left err -> fail ("DnsQuery_A failed with " ++ show err) Right recs' -> return [ (ttl,cname) | DnsRecord { drTTL = ttl, drData = DnsDataCNAME cname } <- recs' ] -- | Query @SRV@ records (see [RFC 2782](https://tools.ietf.org/html/rfc2782)). -- -- >>> querySRV (Name "_imap._tcp.gmail.com") -- [(TTL 21599,SRV {srvPriority = 0, srvWeight = 0, srvPort = 0, srvTarget = Name "."})] -- querySRV :: Name -> IO [(TTL,SRV Name)] querySRV n = do recs <- dnsQuery True n DnsTypeSRV case recs of Left err -> fail ("DnsQuery_A failed with " ++ show err) Right recs' -> return [ (ttl,srv) | DnsRecord { drTTL = ttl, drData = DnsDataSRV srv } <- recs' ]