packages feed

courier-0.1.0.15: tests/TestUtils.hs

module TestUtils
    ( newTCPAddress
    , newUDPAddress
    , newTCPAddress6
    , newUDPAddress6)
    where

import Control.Exception
import qualified Network.Socket as NS

newTCPAddress :: IO String
newTCPAddress = do
  NS.SockAddrInet (NS.PortNum p) _ <- availablePort NS.AF_INET NS.Stream
  return $ "localhost:" ++ show p

newUDPAddress :: IO String
newUDPAddress = do
  NS.SockAddrInet (NS.PortNum p) _ <- availablePort NS.AF_INET NS.Datagram
  return $ "localhost:" ++ show p

newTCPAddress6 :: IO String
newTCPAddress6 = do
  NS.SockAddrInet6 (NS.PortNum p) _ _ _ <- availablePort NS.AF_INET6 NS.Stream
  return $ "localhost:" ++ show p

newUDPAddress6 :: IO String
newUDPAddress6 = do
  NS.SockAddrInet6 (NS.PortNum p) _ _ _ <- availablePort NS.AF_INET6 NS.Datagram
  return $ "localhost:" ++ show p

availablePort     :: NS.Family -> NS.SocketType -> IO NS.SockAddr
availablePort f t = do
  let hints = NS.defaultHints { NS.addrFamily = f
                              , NS.addrSocketType = t
                              , NS.addrFlags = [ NS.AI_PASSIVE ]
                              , NS.addrProtocol = NS.defaultProtocol }
  addrs <- NS.getAddrInfo (Just hints) Nothing (Just "0")
  let a = head addrs
  bracket
    (NS.socket (NS.addrFamily a) (NS.addrSocketType a) (NS.addrProtocol a))
    NS.close
    (\s -> do
       NS.bindSocket s (NS.addrAddress a)
       addr <- NS.getSocketName s
       if isPrivileged addr
         then availablePort f t
         else return addr
    )

isPrivileged :: NS.SockAddr -> Bool
isPrivileged (NS.SockAddrInet (NS.PortNum p) _) = p < 1025
isPrivileged (NS.SockAddrInet6 (NS.PortNum p) _ _ _) = p < 1025
isPrivileged (NS.SockAddrUnix _) = False