{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE OverloadedStrings #-}
module System.IO.Streams.Network.Internal.Address
( getSockAddr
, getSockAddrImpl
, AddressNotSupportedException(..)
) where
import Control.Exception (Exception, throwIO)
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as S
import Data.Typeable (Typeable)
import Network.Socket (AddrInfo (addrAddress, addrFamily, addrFlags), AddrInfoFlag (AI_NUMERICSERV), Family, SockAddr, defaultHints, getAddrInfo)
data AddressNotSupportedException = AddressNotSupportedException String
deriving (Typeable)
instance Show AddressNotSupportedException where
show (AddressNotSupportedException x) = "Address not supported: " ++ x
instance Exception AddressNotSupportedException
getSockAddr :: Int
-> ByteString
-> IO (Family, SockAddr)
getSockAddr = getSockAddrImpl getAddrInfo
getSockAddrImpl
:: (Maybe AddrInfo -> Maybe String -> Maybe String -> IO [AddrInfo])
-> Int -> ByteString -> IO (Family, SockAddr)
getSockAddrImpl !_getAddrInfo p s = do
ais <- _getAddrInfo (Just hints) (Just $ S.unpack s)
(Just $ show p)
if null ais
then throwIO $ AddressNotSupportedException $ show s
else do
let !ai = head ais
let !fm = addrFamily ai
let !sa = addrAddress ai
return (fm, sa)
where
hints = defaultHints { addrFlags = [AI_NUMERICSERV] }