Style
This commit is contained in:
parent
e598e3e8d2
commit
499f872d1a
1 changed files with 35 additions and 33 deletions
68
src/Lib.hs
68
src/Lib.hs
|
@ -27,6 +27,7 @@ import qualified Network.Socket.ByteString as N
|
||||||
import qualified Network.WebSockets as WS
|
import qualified Network.WebSockets as WS
|
||||||
import qualified Network.WebSockets.Stream as WS
|
import qualified Network.WebSockets.Stream as WS
|
||||||
|
|
||||||
|
import Data.Maybe
|
||||||
import Network.Connection (Connection, ConnectionParams (..),
|
import Network.Connection (Connection, ConnectionParams (..),
|
||||||
TLSSettings (..), connectTo,
|
TLSSettings (..), connectTo,
|
||||||
connectionGetChunk, connectionPut,
|
connectionGetChunk, connectionPut,
|
||||||
|
@ -71,16 +72,13 @@ runTCPClient (host, port) app = do
|
||||||
runUDPClient :: (HostName, PortNumber) -> (UdpAppData -> IO ()) -> IO ()
|
runUDPClient :: (HostName, PortNumber) -> (UdpAppData -> IO ()) -> IO ()
|
||||||
runUDPClient (host, port) app = do
|
runUDPClient (host, port) app = do
|
||||||
putStrLn $ "CONNECTING to " <> tshow host <> ":" <> tshow port
|
putStrLn $ "CONNECTING to " <> tshow host <> ":" <> tshow port
|
||||||
bracket
|
bracket (N.getSocketUDP host (fromIntegral port)) (N.close . fst) $ \(socket, addrInfo) -> do
|
||||||
(N.getSocketUDP host (fromIntegral port))
|
sem <- newEmptyMVar
|
||||||
(N.close . fst)
|
app UdpAppData { appAddr = N.addrAddress addrInfo
|
||||||
(\(socket, addrInfo) -> do
|
, appSem = sem
|
||||||
sem <- newEmptyMVar
|
, appRead = fst <$> N.recvFrom socket 4096
|
||||||
app UdpAppData { appAddr = N.addrAddress addrInfo
|
, appWrite = \payload -> void $ N.sendTo socket payload (N.addrAddress addrInfo)
|
||||||
, appSem = sem
|
}
|
||||||
, appRead = fst <$> N.recvFrom socket 4096
|
|
||||||
, appWrite = \payload -> void $ N.sendTo socket payload (N.addrAddress addrInfo)
|
|
||||||
})
|
|
||||||
|
|
||||||
putStrLn $ "CLOSE connection to " <> tshow host <> ":" <> tshow port
|
putStrLn $ "CLOSE connection to " <> tshow host <> ":" <> tshow port
|
||||||
|
|
||||||
|
@ -88,33 +86,35 @@ runUDPServer :: (HostName, PortNumber) -> (UdpAppData -> IO ()) -> IO ()
|
||||||
runUDPServer (host, port) app = do
|
runUDPServer (host, port) app = do
|
||||||
putStrLn $ "WAIT for datagrames on " <> tshow host <> ":" <> tshow port
|
putStrLn $ "WAIT for datagrames on " <> tshow host <> ":" <> tshow port
|
||||||
notebook <- newMVar mempty
|
notebook <- newMVar mempty
|
||||||
bracket (N.bindPortUDP (fromIntegral port) (fromString host)) N.close (runEventLoop notebook)
|
bracket (N.bindPortUDP (fromIntegral port) (fromString host))
|
||||||
|
N.close
|
||||||
|
(runEventLoop notebook)
|
||||||
putStrLn "CLOSE tunnel"
|
putStrLn "CLOSE tunnel"
|
||||||
|
|
||||||
where
|
where
|
||||||
runEventLoop :: MVar (H.HashMap N.SockAddr UdpAppData) -> N.Socket -> IO ()
|
runEventLoop :: MVar (H.HashMap N.SockAddr UdpAppData) -> N.Socket -> IO ()
|
||||||
runEventLoop clientMapM socket = do
|
runEventLoop clientMapM socket = forever $ do
|
||||||
(payload, addr) <- N.recvFrom socket 4096
|
(payload, addr) <- N.recvFrom socket 4096
|
||||||
clientMap <- readMVar clientMapM
|
clientCtx <- H.lookup addr <$> readMVar clientMapM
|
||||||
case H.lookup addr clientMap of
|
|
||||||
Just appData -> putMVar (appSem appData) payload
|
|
||||||
Nothing -> do
|
|
||||||
let action = bracket (do sem <- newMVar payload
|
|
||||||
let appData = UdpAppData addr sem (takeMVar sem) (\payload' -> void $ N.sendTo socket payload' addr)
|
|
||||||
void $ swapMVar clientMapM (H.insert addr appData clientMap)
|
|
||||||
return appData
|
|
||||||
)
|
|
||||||
(\appData' -> do
|
|
||||||
m <- takeMVar clientMapM
|
|
||||||
putMVar clientMapM (H.delete (appAddr appData') m)
|
|
||||||
putStrLn "TIMEOUT connection"
|
|
||||||
)
|
|
||||||
(timeout (30 * 10^(6 :: Int)) . app)
|
|
||||||
|
|
||||||
void $ async action
|
|
||||||
|
|
||||||
runEventLoop clientMapM socket
|
|
||||||
|
|
||||||
|
if isJust clientCtx
|
||||||
|
then putMVar (appSem $ fromJust clientCtx) payload
|
||||||
|
else
|
||||||
|
void $ async $ bracket
|
||||||
|
(do sem <- newMVar payload
|
||||||
|
let appData = UdpAppData { appAddr = addr
|
||||||
|
, appSem = sem
|
||||||
|
, appRead = takeMVar sem
|
||||||
|
, appWrite = \payload' -> void $ N.sendTo socket payload' addr
|
||||||
|
}
|
||||||
|
void $ withMVar clientMapM (return . H.insert addr appData)
|
||||||
|
return appData
|
||||||
|
)
|
||||||
|
(\appData' -> do
|
||||||
|
void $ withMVar clientMapM (return . H.delete (appAddr appData'))
|
||||||
|
putStrLn "TIMEOUT connection"
|
||||||
|
)
|
||||||
|
(timeout (30 * 10^(6 :: Int)) . app)
|
||||||
|
|
||||||
runTunnelingClient :: Proto -> (HostName, PortNumber) -> (HostName, PortNumber) -> (WS.Connection -> IO ()) -> IO ()
|
runTunnelingClient :: Proto -> (HostName, PortNumber) -> (HostName, PortNumber) -> (WS.Connection -> IO ()) -> IO ()
|
||||||
runTunnelingClient proto (wsHost, wsPort) (remoteHost, remotePort) app = do
|
runTunnelingClient proto (wsHost, wsPort) (remoteHost, remotePort) app = do
|
||||||
|
@ -177,10 +177,12 @@ runServer = runTunnelingServer
|
||||||
|
|
||||||
runTlsTunnelingClient :: Proto -> (HostName, PortNumber) -> (HostName, PortNumber) -> (WS.Connection -> IO ()) -> IO ()
|
runTlsTunnelingClient :: Proto -> (HostName, PortNumber) -> (HostName, PortNumber) -> (WS.Connection -> IO ()) -> IO ()
|
||||||
runTlsTunnelingClient proto (wsHost, wsPort) (remoteHost, remotePort) app = do
|
runTlsTunnelingClient proto (wsHost, wsPort) (remoteHost, remotePort) app = do
|
||||||
context <- initConnectionContext
|
putStrLn $ "OPEN tls connection to " <> tshow remoteHost <> ":" <> tshow remotePort
|
||||||
|
context <- initConnectionContext
|
||||||
connection <- connectTo context (connectionParams wsHost (fromIntegral wsPort))
|
connection <- connectTo context (connectionParams wsHost (fromIntegral wsPort))
|
||||||
stream <- WS.makeStream (reader connection) (writer connection)
|
stream <- WS.makeStream (reader connection) (writer connection)
|
||||||
WS.runClientWithStream stream wsHost (toPath proto remoteHost remotePort) WS.defaultConnectionOptions [] app
|
WS.runClientWithStream stream wsHost (toPath proto remoteHost remotePort) WS.defaultConnectionOptions [] app
|
||||||
|
putStrLn $ "CLOSE tls connection to " <> tshow remoteHost <> ":" <> tshow remotePort
|
||||||
|
|
||||||
|
|
||||||
connectionParams :: HostName -> PortNumber -> ConnectionParams
|
connectionParams :: HostName -> PortNumber -> ConnectionParams
|
||||||
|
|
Loading…
Reference in a new issue