-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Asynchronous DNS Resolver -- -- This library provides an asynchronous DNS resolver on top of GNU ADNS -- http://www.chiark.greenend.org.uk/~ian/adns/. Not all options -- are supported, but A, MX, and PTR lookups work nicely. There is also -- support for retrieving generic RR types, CNAMEs, and for NSEC zone -- walking. The library can be expected to work with fine ADNS 1.4 or -- later. It might also work with version ADNS 1.3, but that hasn't been -- tested. -- -- The example program adns-reverse-lookup.hs demonstrates how the -- resolver is used. Given a list of host names on the command line, it -- performs an A/PTR double-lookup and checks whether the records are -- consistent. The output is printed in the order in which the DNS -- responses arrive: -- --
-- $ ./adns-reverse-lookup cryp.to localhost www.example.com -- OK: localhost <-> 127.0.0.1 -- FAIL: cryp.to -> 217.19.183.102 -> ["zuse.cryp.to"] -- OK: www.example.com <-> 192.0.32.10 --@package hsdns @version 1.7 -- | This module provides bindings to GNU ADNS, a domain name resolver -- library written in C. ADNS is available from -- http://www.gnu.org/software/adns/. -- -- You will most likely not need this module directly: ADNS -- provides a simpler API for the Haskell world; this module contains -- mostly marshaling code. module ADNS.Base data OpaqueState type AdnsState = Ptr OpaqueState data OpaqueQuery type Query = Ptr OpaqueQuery data InitFlag -- | do not look at environment NoEnv :: InitFlag -- | never print output to stderr (Debug overrides) NoErrPrint :: InitFlag -- | do not warn to stderr about duff nameservers etc NoServerWarn :: InitFlag -- | enable all output to stderr plus Debug msgs Debug :: InitFlag -- | include process id in diagnostic output LogPid :: InitFlag -- | do not make syscalls at every opportunity NoAutoSys :: InitFlag -- | allow adnsSynch to return eINTR Eintr :: InitFlag -- | application has SIGPIPE set to SIG_IGN, do not protect NoSigPipe :: InitFlag -- | do consistency checks on entry/exit to adns functions CheckC_EntEx :: InitFlag -- | do consistency checks very frequently (slow!) CheckC_Freq :: InitFlag data QueryFlag -- | use the searchlist Search :: QueryFlag -- | use a virtual circuit (TCP connection) UseVC :: QueryFlag -- | fill in the owner field in the answer Owner :: QueryFlag -- | allow special chars in query domain QuoteOk_Query :: QueryFlag -- | allow special chars in CNAME we go via (default) QuoteOk_CName :: QueryFlag -- | allow special chars in things supposed to be hostnames QuoteOk_AnsHost :: QueryFlag -- | refuse if quote-req chars in CNAME we go via QuoteFail_CName :: QueryFlag -- | allow refs to CNAMEs - without, get _s_cname CName_Loose :: QueryFlag -- | don't follow CNAMEs, instead give _s_cname CName_Forbid :: QueryFlag -- | The record types we support. data RRType A :: RRType CNAME :: RRType MX :: RRType NS :: RRType PTR :: RRType NSEC :: RRType SRV :: RRType RRType :: Int -> RRType -- | The status codes recognized by ADNS vary in different versions of the -- library. So instead of providing an Enum, the Status -- type contains the numeric value as returned by ADNS itself. For common -- status codes, helper functions like sOK or sNXDOMAIN are -- provided. The functions adnsErrTypeAbbrev, -- adnsErrAbbrev, and adnsStrerror can also be used to map -- these codes into human readable strings. newtype Status StatusCode :: Int -> Status sOK :: Status sNOMEMORY :: Status sUNKNOWNRRTYPE :: Status sSYSTEMFAIL :: Status sMAX_LOCALFAIL :: Status sTIMEOUT :: Status sALLSERVFAIL :: Status sNORECURSE :: Status sINVALIDRESPONSE :: Status sUNKNOWNFORMAT :: Status sMAX_REMOTEFAIL :: Status sRCODESERVFAIL :: Status sRCODEFORMATERROR :: Status sRCODENOTIMPLEMENTED :: Status sRCODEREFUSED :: Status sRCODEUNKNOWN :: Status -- | Original definition: -- --
-- typedef struct {
-- int len;
-- union {
-- struct sockaddr sa;
-- struct sockaddr_in inet;
-- } addr;
-- } adns_rr_addr;
--
--
-- Note: Anything but sockaddr_in will cause peek
-- to call fail, when marshaling this structure. poke is
-- not defined.
sMAX_TEMPFAIL :: Status
sINCONSISTENT :: Status
sPROHIBITEDCNAME :: Status
sANSWERDOMAININVALID :: Status
sANSWERDOMAINTOOLONG :: Status
sINVALIDDATA :: Status
sMAX_MISCONFIG :: Status
newtype RRAddr
RRAddr :: HostAddress -> RRAddr
sQUERYDOMAINWRONG :: Status
sQUERYDOMAININVALID :: Status
sQUERYDOMAINTOOLONG :: Status
sMAX_MISQUERY :: Status
sNXDOMAIN :: Status
sNODATA :: Status
sMAX_PERMFAIL :: Status
-- | Original definition:
--
--
-- typedef struct {
-- char *host;
-- adns_status astatus;
-- int naddrs; /* temp fail => -1, perm fail => 0, s_ok => >0
-- adns_rr_addr *addrs;
-- } adns_rr_hostaddr;
--
--
-- The naddrs field is not available in RRHostAddr
-- because I couldn't see how that information wouldn't be available in
-- the astatus field too. If I missed anything, please let me
-- know.
--
-- Note: The data type should probably contain HostAddress
-- rather than RRAddr. I'm using the former only because it has
-- nicer output with show. poke is not defined.
data RRHostAddr
RRHostAddr :: HostName -> Status -> [RRAddr] -> RRHostAddr
-- | Original definition:
--
--
-- typedef struct {
-- int i;
-- adns_rr_hostaddr ha;
-- } adns_rr_inthostaddr;
--
data RRIntHostAddr
RRIntHostAddr :: Int -> RRHostAddr -> RRIntHostAddr
-- | Original definition:
--
--
-- typedef struct {
-- int len;
-- unsigned char *data;
-- } adns_rr_byteblock;
--
data RRByteblock
RRByteblock :: Int -> (Ptr CChar) -> RRByteblock
-- | Original definition:
--
--
-- typedef struct {
-- int priority, weight, port;
-- char *host;
-- } adns_rr_srvraw;
--
data RRSrvRaw
RRSrvRaw :: Int -> Int -> Int -> (Ptr CChar) -> RRSrvRaw
data Answer
Answer :: Status -> Maybe String -> Maybe String -> CTime -> [Response] -> Answer
-- | Status code for this query.
[status] :: Answer -> Status
-- | Always Nothing for CNAME queries
[cname] :: Answer -> Maybe String
-- | Only set if Owner was requested for query.
[owner] :: Answer -> Maybe String
-- | Only defined if status is sOK, sNXDOMAIN, or
-- sNODATA.
[expires] :: Answer -> CTime
-- | The list will be empty if an error occured.
[rrs] :: Answer -> [Response]
data Response
RRA :: RRAddr -> Response
RRCNAME :: String -> Response
RRMX :: Int -> RRHostAddr -> Response
RRNS :: RRHostAddr -> Response
RRPTR :: String -> Response
RRNSEC :: String -> Response
RRUNKNOWN :: String -> Response
RRSRV :: Int -> Int -> Int -> String -> Response
-- | This function parses the Response union found in Answer.
-- It cannot be defined via Storable because it needs to know the
-- type of the record to expect. This is, by the way, the function to
-- look at, if you want to add support for additional RRType
-- records.
peekResp :: RRType -> Ptr b -> Int -> Int -> IO [Response]
-- | This function parses a FQDN in uncompressed wire format and advances
-- the pointer to the next byte after the parsed name.
peekFQDNAndAdvance :: Ptr a -> Int -> IO (String, Ptr a)
-- | Run the given IO computation with an initialized resolver. As
-- of now, the diagnose stream is always set to stderr. Initialize
-- the library with NoErrPrint if you don't wont to see any error
-- output. All resources are freed when adnsInit returns.
adnsInit :: [InitFlag] -> (AdnsState -> IO a) -> IO a
-- | Similar to adnsInit, but reads the resolver configuration from
-- a string rather than from /etc/resolv.conf. Supported are the
-- usual commands: nameserver, search, domain,
-- sortlist, and options.
--
-- Additionally, these non-standard commands may be used:
--
-- -- *ADNS> adnsStrerror sNXDOMAIN >>= print -- "No such domain" ---- -- Use this function with great care: It will crash the process when -- called with a status code that ADNS doesn't know about. So use it only -- to print values you got from the resolver! adnsStrerror :: Status -> IO String -- | Map a Status code to a short error name. Don't use this -- function to print a status code unless you've obtained it from the -- resolver! adnsErrAbbrev :: Status -> IO String -- | Map a Status code to a short description of the type of error. -- Don't use this function to print a status code unless you've obtained -- it from the resolver! adnsErrTypeAbbrev :: Status -> IO String adns_init :: Ptr AdnsState -> CInt -> Ptr CFile -> IO CInt adns_init_strcfg :: Ptr AdnsState -> CInt -> Ptr CFile -> CString -> IO CInt adns_finish :: AdnsState -> IO () adns_submit :: AdnsState -> CString -> CInt -> CInt -> Ptr a -> Ptr Query -> IO CInt adns_check :: AdnsState -> Ptr Query -> Ptr (Ptr Answer) -> Ptr (Ptr a) -> IO CInt adns_synchronous :: AdnsState -> CString -> CInt -> CInt -> Ptr (Ptr Answer) -> IO CInt adns_forallqueries_begin :: AdnsState -> IO () adns_forallqueries_next :: AdnsState -> Ptr (Ptr a) -> IO Query adns_strerror :: CInt -> IO CString adns_errabbrev :: CInt -> IO CString adns_errtypeabbrev :: CInt -> IO CString -- | Internel helper function to handle result passing from ADNS via -- Ptr (Ptr a), and to generate human-readable IO exceptions in -- case of an error. wrapAdns :: (Ptr (Ptr b) -> IO CInt) -> (Ptr (Ptr b) -> IO a) -> IO a -- | Map a list of flags (Enum types) into a CInt suitable -- for adns calls. mkFlags :: Enum a => [a] -> CInt instance GHC.Show.Show ADNS.Base.Answer instance GHC.Show.Show ADNS.Base.Response instance GHC.Show.Show ADNS.Base.RRIntHostAddr instance GHC.Show.Show ADNS.Base.RRHostAddr instance GHC.Classes.Eq ADNS.Base.RRAddr instance GHC.Show.Show ADNS.Base.Status instance GHC.Classes.Eq ADNS.Base.Status instance GHC.Read.Read ADNS.Base.RRType instance GHC.Show.Show ADNS.Base.QueryFlag instance GHC.Enum.Bounded ADNS.Base.QueryFlag instance GHC.Classes.Eq ADNS.Base.QueryFlag instance GHC.Show.Show ADNS.Base.InitFlag instance GHC.Enum.Bounded ADNS.Base.InitFlag instance GHC.Classes.Eq ADNS.Base.InitFlag instance GHC.Enum.Enum ADNS.Base.InitFlag instance GHC.Enum.Enum ADNS.Base.QueryFlag instance GHC.Classes.Eq ADNS.Base.RRType instance GHC.Show.Show ADNS.Base.RRType instance GHC.Enum.Enum ADNS.Base.RRType instance Foreign.Storable.Storable ADNS.Base.RRType instance GHC.Show.Show ADNS.Base.RRAddr instance Foreign.Storable.Storable ADNS.Base.RRAddr instance Foreign.Storable.Storable ADNS.Base.RRHostAddr instance Foreign.Storable.Storable ADNS.Base.RRIntHostAddr instance Foreign.Storable.Storable ADNS.Base.RRByteblock instance Foreign.Storable.Storable ADNS.Base.RRSrvRaw instance Foreign.Storable.Storable ADNS.Base.Answer -- | This module implements a Haskell DNS Resolver on top of the ADNS -- library. GHC users should compile their code using the -- -threaded runtime system. module ADNS.Resolver -- | A Resolver is an IO computation which -- given the name -- and type of the record to query -- returns an MVar that will -- eventually contain the Answer from the Domain Name System. type Resolver = String -> RRType -> [QueryFlag] -> IO (MVar Answer) -- | Run the given IO computation with an Initialized -- Resolver. Note that resolver functions can be shared, and -- should be shared between any number of IO threads. You -- may use multiple resolvers, of course, but doing so defeats the -- purpose of an asynchronous resolver. initResolver :: [InitFlag] -> (Resolver -> IO a) -> IO a -- | Print an IP host address as a string suitable for PTR lookups. toPTR :: HostAddress -> String -- | Resolve a hostname's A records. resolveA :: Resolver -> HostName -> IO (Either Status [HostAddress]) -- | Get the PTR records assigned to a host address. Note that -- although the API allows for a record to have more than one PTR -- entry, this will actually not happen because the GNU adns library -- can't handle this case and will return sINCONSISTENT. resolvePTR :: Resolver -> HostAddress -> IO (Either Status [HostName]) -- | Resolve the mail exchangers for a hostname. The returned list may -- contain more than one entry per hostname, in case the host has several -- A records. The records are returned in the order you should try -- to contact them as determined by the priority in the RRMX -- response. resolveMX :: Resolver -> HostName -> IO (Either Status [(HostName, HostAddress)]) -- | Resolve a hostname's SRV records. resolveSRV :: Resolver -> HostName -> IO (Either Status [(HostName, PortID)]) -- | Convenience wrapper that will modify any of the revolveXXX -- functions above to return Maybe rather than Either. The -- idea is that Nothing signifies any sort of failure: Just -- [] signifies sNXDOMAIN or sNODATA, and everything -- else signifies sOK. -- -- So if you aren't interested in getting accurate Status codes in -- case of failures. Wrap your DNS queries as follows: -- --
-- queryA :: Resolver -> HostName -> IO (Maybe [HostAddress]) -- queryA = query resolveA --query :: (Resolver -> a -> IO (Either Status [b])) -> Resolver -> a -> IO (Maybe [b]) -- | Use this function to disable DNS resolving. It will always return -- (Answer sSYSTEMFAIL Nothing (Just host) (-1) -- []). dummyDNS :: Resolver -- | An asynchronous DNS resolver based on GNU ADNS -- http://www.gnu.org/software/adns/. You should link your program -- with the threaded runtime-system when using this module. In -- GHC, this is accomplished by specifying -threaded on the -- command-line. module ADNS -- | Either a host name e.g., "haskell.org" or a numeric host -- address string consisting of a dotted decimal IPv4 address or an IPv6 -- address e.g., "192.168.0.1". type HostName = String -- | The raw network byte order number is read using host byte order. -- Therefore on little-endian architectures the byte order is swapped. -- For example 127.0.0.1 is represented as 0x0100007f -- on little-endian hosts and as 0x7f000001 on big-endian hosts. -- -- For direct manipulation prefer hostAddressToTuple and -- tupleToHostAddress. type HostAddress = Word32 -- | A Resolver is an IO computation which -- given the name -- and type of the record to query -- returns an MVar that will -- eventually contain the Answer from the Domain Name System. type Resolver = String -> RRType -> [QueryFlag] -> IO (MVar Answer) -- | Run the given IO computation with an Initialized -- Resolver. Note that resolver functions can be shared, and -- should be shared between any number of IO threads. You -- may use multiple resolvers, of course, but doing so defeats the -- purpose of an asynchronous resolver. initResolver :: [InitFlag] -> (Resolver -> IO a) -> IO a data InitFlag -- | do not look at environment NoEnv :: InitFlag -- | never print output to stderr (Debug overrides) NoErrPrint :: InitFlag -- | do not warn to stderr about duff nameservers etc NoServerWarn :: InitFlag -- | enable all output to stderr plus Debug msgs Debug :: InitFlag -- | include process id in diagnostic output LogPid :: InitFlag -- | do not make syscalls at every opportunity NoAutoSys :: InitFlag -- | allow adnsSynch to return eINTR Eintr :: InitFlag -- | application has SIGPIPE set to SIG_IGN, do not protect NoSigPipe :: InitFlag -- | do consistency checks on entry/exit to adns functions CheckC_EntEx :: InitFlag -- | do consistency checks very frequently (slow!) CheckC_Freq :: InitFlag queryA :: Resolver -> HostName -> IO (Maybe [HostAddress]) queryPTR :: Resolver -> HostAddress -> IO (Maybe [HostName]) queryMX :: Resolver -> HostName -> IO (Maybe [(HostName, HostAddress)]) -- | For quering SRV records. Result is the list of tuples (host, port). querySRV :: Resolver -> HostName -> IO (Maybe [(HostName, PortID)]) -- | Use this function to disable DNS resolving. It will always return -- (Answer sSYSTEMFAIL Nothing (Just host) (-1) -- []). dummyDNS :: Resolver