【发布时间】:2012-01-04 17:21:35
【问题描述】:
我正在尝试弄清楚如何在并发上下文中正确使用 OpenSSL.Session API
例如假设我想实现一个stunnel-style ssl-wrapper,我希望有以下基本骨架结构,它实现了一个幼稚的full-duplex tcp-port-forwarder:
runProxy :: PortID -> AddrInfo -> IO ()
runProxy localPort@(PortNumber lpn) serverAddrInfo = do
listener <- listenOn localPort
forever $ do
(sClient, clientAddr) <- accept listener
let finalize sServer = do
sClose sServer
sClose sClient
forkIO $ do
tidToServer <- myThreadId
bracket (connectToServer serverAddrInfo) finalize $ \sServer -> do
-- execute one 'copySocket' thread for each data direction
-- and make sure that if one direction dies, the other gets
-- pulled down as well
bracket (forkIO (copySocket sServer sClient
`finally` killThread tidToServer))
(killThread) $ \_ -> do
copySocket sClient sServer -- "controlling" thread
where
-- |Copy data from source to dest until EOF occurs on source
-- Copying may also be aborted due to exceptions
copySocket :: Socket -> Socket -> IO ()
copySocket src dst = go
where
go = do
buf <- B.recv src 4096
unless (B.null buf) $ do
B.sendAll dst buf
go
-- |Create connection to given AddrInfo target and return socket
connectToServer saddr = do
sServer <- socket (addrFamily saddr) Stream defaultProtocol
connect sServer (addrAddress saddr)
return sServer
如何将上述骨架转换为full-duplex ssl-wrapping tcp-forwarding proxy? HsOpenSSL API 提供的函数调用的并发/并行执行(在上述用例的上下文中)的危险在哪里?
PS:我仍在努力完全理解如何使代码变得健壮 w.r.t。异常和资源泄漏。所以,虽然不是这个问题的主要焦点,如果你发现上面的代码有什么不好的地方,请发表评论。
【问题讨论】:
-
我认为这对 SO 来说可能是一个过于宽泛的问题。
-
我会尽快回复你 :-)
-
文档的链接已损坏,这是正在工作的人:hackage.haskell.org/packages/archive/HsOpenSSL/0.10.2/doc/html/…
-
我做了类似的东西(
full-duplex ssl-rewrapping tcp-forwarding),但它使用了Network.TLS(包tls)。它很丑陋。如果有兴趣,你可以找到它here。