resolv 0.1.1.3 → 0.1.2.0
raw patch · 3 files changed
+87/−12 lines, 3 filesdep ~basedep ~base16-bytestringdep ~binary
Dependency ranges changed: base, base16-bytestring, binary, bytestring, containers, directory, filepath, tasty, tasty-hunit
Files
- ChangeLog.md +5/−0
- resolv.cabal +22/−10
- src/Network/DNS.hs +60/−2
ChangeLog.md view
@@ -2,6 +2,11 @@ # Revision history for `resolv` +## 0.1.2.0++* Add new high-level API functions `queryPTR`, `arpaIPv4`, and+ `arpaIPv6` for performing reverse address lookups.+ ## 0.1.1.3 * GHC 8.8 / base-4.13 only compat hotfix release; the next release will support
resolv.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: resolv-version: 0.1.1.3+version: 0.1.2.0 synopsis: Domain Name Service (DNS) lookup via the libresolv standard library routines description: {@@ -54,7 +54,18 @@ resolv.buildinfo cbits/hs_resolv_config.h -tested-with: GHC==8.6.2, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.10.1, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2+tested-with:+ GHC ==8.10.1+ || ==8.8.3+ || ==8.6.5+ || ==8.4.4+ || ==8.2.2+ || ==8.0.2+ || ==7.10.3+ || ==7.10.1+ || ==7.8.4+ || ==7.6.3+ || ==7.4.2 source-repository head type: git@@ -80,11 +91,12 @@ Network.DNS.FFI Compat - build-depends: base ^>= 4.13+ -- we need binary-0.7.3 for isolate+ build-depends: base >= 4.5 && <4.15 , base16-bytestring ^>= 0.1- , binary ^>= 0.8- , bytestring ^>= 0.10- , containers ^>= 0.5 || ^>= 0.6+ , binary ^>=0.7.3 || ^>= 0.8+ , bytestring ^>=0.9.2 || ^>= 0.10+ , containers ^>=0.4.2.1 || ^>= 0.5 || ^>= 0.6 ghc-options: -Wall include-dirs: cbits@@ -101,7 +113,7 @@ , bytestring -- additional dependencies not inherited- build-depends: tasty >= 1.1 && < 1.2- , tasty-hunit >= 0.10 && < 0.11- , directory >= 1.1.0.2 && < 1.4- , filepath >= 1.3.0 && < 1.5+ build-depends: tasty ^>= 1.2.3+ , tasty-hunit ^>= 0.10.0+ , directory ^>= 1.1.0 || ^>= 1.2.0 || ^>= 1.3.0+ , filepath ^>= 1.3.0 || ^>= 1.4.0
src/Network/DNS.hs view
@@ -18,6 +18,7 @@ queryA , queryAAAA , queryCNAME+ , queryPTR , querySRV , queryTXT @@ -50,8 +51,8 @@ , CharStr(..) -- *** IP addresses- , IPv4(..)- , IPv6(..)+ , IPv4(..), arpaIPv4+ , IPv6(..), arpaIPv6 -- *** RR TTL & Class , TTL(..)@@ -82,12 +83,15 @@ where import Control.Exception+import Data.Bits (unsafeShiftR, (.&.)) import Data.Typeable (Typeable) import Foreign.C import Foreign.Marshal.Alloc+import Numeric (showInt) import Prelude import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as BSC import Compat @@ -347,6 +351,21 @@ where n' = caseFoldName n +-- | Query @PTR@ records (see [RFC 1035, section 3.3.12](https://tools.ietf.org/html/rfc1035#section-3.3.12)).+--+-- >>> queryPTR (Name "4.4.8.8.in-addr.arpa.")+-- [(TTL 14390,Name "dns.google.")]+--+-- See also 'arpaIPv6' and 'arpaIPv4' for converting 'IPv6' and 'IPv4' values to the respective @.arpa."@ domain name for reverse lookups.+--+-- @since 0.1.2.0+queryPTR :: Name -> IO [(TTL,Name)]+queryPTR n = do+ res <- query classIN n' TypePTR+ pure [ (ttl,ptrs) | MsgRR { rrData = RDataPTR ptrs, rrTTL = ttl, rrName = n1, rrClass = Class 1 } <- msgAN res, caseFoldName n1 == n' ]+ where+ n' = caseFoldName n+ -- | 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")@@ -371,3 +390,42 @@ pure [ (ttl,srv) | MsgRR { rrData = RDataSRV srv, rrTTL = ttl, rrName = n1, rrClass = Class 1 } <- msgAN res, caseFoldName n1 == n' ] where n' = caseFoldName n+++-- | Convert 'IPv4' address to @in-addr.arpa.@ 'Name' (see [RFC 1035, section 3.5](https://tools.ietf.org/html/rfc1035#section-3.5)).+--+-- >>> arpaIPv4 (IPv4 0x8080404)+-- Name "4.4.8.8.in-addr.arpa."+--+-- @since 0.1.2.0+arpaIPv4 :: IPv4 -> Name+arpaIPv4 (IPv4 w) = Name (BSC.pack s)+ where+ s = showInt o0 ('.' : showInt o1 ('.' : showInt o2 ('.' : showInt o3 ".in-addr.arpa.")))++ o0, o1, o2, o3 :: Word8+ o0 = fromIntegral $ w+ o1 = fromIntegral $ w `unsafeShiftR` 8+ o2 = fromIntegral $ w `unsafeShiftR` 16+ o3 = fromIntegral $ w `unsafeShiftR` 24++-- | Convert 'IPv6' address to @ip6.arpa.@ 'Name' (see [RFC 3596, section 2.5](https://tools.ietf.org/html/rfc3596#section-2.5)).+--+-- >>> arpaIPv6 (IPv6 0x2001486048600000 0x8844)+-- Name "4.4.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa."+--+-- @since 0.1.2.0+arpaIPv6 :: IPv6 -> Name+arpaIPv6 (IPv6 hi lo) = Name (BSC.pack s)+ where+ s = go 16 lo (go 16 hi "ip6.arpa.")++ go :: Int -> Word64 -> ShowS+ go 0 _ cont = cont+ go n w cont = nib : '.' : go (n-1) w' cont+ where+ nib :: Char+ nib | x < 10 = toEnum (fromIntegral (0x30 + x))+ | otherwise = toEnum (fromIntegral (0x57 + x))+ x = w .&. 0xf+ w' = w `unsafeShiftR` 4