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 :: SockAddr -> IO Socket natRebinding SockAddr sa = IO Socket -> (Socket -> IO ()) -> (Socket -> IO Socket) -> IO Socket forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c E.bracketOnError IO Socket open Socket -> IO () close Socket -> IO Socket forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a return where family :: Family family = SockAddr -> Family sockAddrFamily SockAddr sa open :: IO Socket open = Family -> SocketType -> ProtocolNumber -> IO Socket socket Family family SocketType Datagram ProtocolNumber defaultProtocol sockAddrFamily :: SockAddr -> Family sockAddrFamily :: SockAddr -> Family sockAddrFamily SockAddrInet{} = Family AF_INET sockAddrFamily SockAddrInet6{} = Family AF_INET6 sockAddrFamily SockAddr _ = [Char] -> Family forall a. HasCallStack => [Char] -> a error [Char] "sockAddrFamily" clientSocket :: HostName -> ServiceName -> IO (Socket, SockAddr) clientSocket :: [Char] -> [Char] -> IO (Socket, SockAddr) clientSocket [Char] host [Char] port = do AddrInfo addr <- NonEmpty AddrInfo -> AddrInfo forall a. NonEmpty a -> a NE.head (NonEmpty AddrInfo -> AddrInfo) -> IO (NonEmpty AddrInfo) -> IO AddrInfo forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Maybe AddrInfo -> Maybe [Char] -> Maybe [Char] -> IO (NonEmpty AddrInfo) forall (t :: * -> *). GetAddrInfo t => Maybe AddrInfo -> Maybe [Char] -> Maybe [Char] -> IO (t AddrInfo) getAddrInfo (AddrInfo -> Maybe AddrInfo forall a. a -> Maybe a Just AddrInfo hints) ([Char] -> Maybe [Char] forall a. a -> Maybe a Just [Char] host) ([Char] -> Maybe [Char] forall a. a -> Maybe a Just [Char] port) IO Socket -> (Socket -> IO ()) -> (Socket -> IO (Socket, SockAddr)) -> IO (Socket, SockAddr) forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c E.bracketOnError (AddrInfo -> IO Socket openSocket AddrInfo addr) Socket -> IO () close ((Socket -> IO (Socket, SockAddr)) -> IO (Socket, SockAddr)) -> (Socket -> IO (Socket, SockAddr)) -> IO (Socket, SockAddr) forall a b. (a -> b) -> a -> b $ \Socket s -> (Socket, SockAddr) -> IO (Socket, SockAddr) forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a return (Socket s, AddrInfo -> SockAddr addrAddress AddrInfo addr) where hints :: AddrInfo hints = AddrInfo defaultHints{addrSocketType = Datagram, addrFlags = [AI_ADDRCONFIG]} serverSocket :: (IP, PortNumber) -> IO Socket serverSocket :: (IP, PortNumber) -> IO Socket serverSocket (IP, PortNumber) ip = IO Socket -> (Socket -> IO ()) -> (Socket -> IO Socket) -> IO Socket forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c E.bracketOnError IO Socket open Socket -> IO () close ((Socket -> IO Socket) -> IO Socket) -> (Socket -> IO Socket) -> IO Socket forall a b. (a -> b) -> a -> b $ \Socket s -> do Socket -> SocketOption -> Int -> IO () setSocketOption Socket s SocketOption ReuseAddr Int 1 Socket -> (ProtocolNumber -> IO ()) -> IO () forall r. Socket -> (ProtocolNumber -> IO r) -> IO r withFdSocket Socket s ProtocolNumber -> IO () setCloseOnExecIfNeeded Socket -> SockAddr -> IO () bind Socket s SockAddr sa Socket -> IO Socket forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a return Socket s where sa :: SockAddr sa = (IP, PortNumber) -> SockAddr toSockAddr (IP, PortNumber) ip family :: Family family = SockAddr -> Family sockAddrFamily SockAddr sa open :: IO Socket open = Family -> SocketType -> ProtocolNumber -> IO Socket socket Family family SocketType Datagram ProtocolNumber defaultProtocol