Я пытаюсь выяснить, как правильно использовать OpenSSL.Session API в параллельном контексте
например. предположим, что я хочу реализовать stunnel-style ssl-wrapper, я ожидал бы иметь следующую основную структуру скелета, которая реализует наивный full-duplex tcp-port-forwarder:
runProxy :: PortID -> AddrInfo -> IO ()
runProxy [email protected](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? Где опасности W.R.T для параллельного/параллельного выполнения (в контексте вышеупомянутого варианта использования) вызовов функций, предоставляемых API HsOpenSSL?
PS: Я все еще пытаюсь полностью понять, как сделать код надежным w.r.t. к исключениям и утечкам ресурсов. Поэтому, хотя и не являясь основной задачей этого вопроса, если вы заметили что-то плохое в коде выше, оставьте комментарий.
