module Network.QUIC.Socket ( serverSocket, clientSocket, natRebinding, ) where import qualified Control.Exception as E import Data.IP (IP, toSockAddr) import qualified Data.List.NonEmpty as NE import Network.Socket natRebinding :: SockAddr -> IO Socket natRebinding sa = E.bracketOnError open close return where family = sockAddrFamily sa open = socket family Datagram defaultProtocol sockAddrFamily :: SockAddr -> Family sockAddrFamily SockAddrInet{} = AF_INET sockAddrFamily SockAddrInet6{} = AF_INET6 sockAddrFamily _ = error "sockAddrFamily" clientSocket :: HostName -> ServiceName -> IO (Socket, SockAddr) clientSocket host port = do addr <- NE.head <$> getAddrInfo (Just hints) (Just host) (Just port) E.bracketOnError (openSocket addr) close $ \s -> return (s, addrAddress addr) where hints = defaultHints{addrSocketType = Datagram, addrFlags = [AI_ADDRCONFIG]} serverSocket :: (IP, PortNumber) -> IO Socket serverSocket ip = E.bracketOnError open close $ \s -> do setSocketOption s ReuseAddr 1 withFdSocket s setCloseOnExecIfNeeded bind s sa return s where sa = toSockAddr ip family = sockAddrFamily sa open = socket family Datagram defaultProtocol