Saya mencoba mencari cara untuk menggunakan API OpenSSL.Session dengan benar dalam konteks bersamaan
Misalkan saya ingin mengimplementasikan stunnel-style ssl-wrapper
, saya berharap memiliki struktur kerangka dasar berikut, yang mengimplementasikan naiffull-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
Bagaimana cara mengubah kerangka di atas menjadi full-duplex ssl-wrapping tcp-forwarding proxy
? Di mana bahaya WRT untuk eksekusi bersamaan / paralel (dalam konteks kasus penggunaan di atas) dari pemanggilan fungsi yang disediakan oleh API HsOpenSSL?
PS: Saya masih berjuang untuk sepenuhnya memahami bagaimana membuat kode yang kuat untuk pengecualian dan kebocoran sumber daya. Jadi, meskipun tidak menjadi fokus utama dari pertanyaan ini, jika Anda melihat sesuatu yang buruk dalam kode di atas, silakan tinggalkan komentar.
full-duplex ssl-rewrapping tcp-forwarding
), tetapi yang digunakanNetwork.TLS
(pakettls
) sebagai gantinya. Dan itu jelek. Anda dapat menemukannya di sini , jika tertarik.Jawaban:
Untuk melakukan ini, Anda perlu mengganti
copySocket
dengan dua fungsi berbeda, satu untuk menangani data dari soket biasa ke SSL dan yang lainnya dari SSL ke soket biasa:Maka Anda perlu memodifikasi
connectToServer
sehingga membangun koneksi SSLdan ubah
finalize
untuk mematikan sesi SSLAkhirnya, jangan lupa untuk menjalankan hal-hal utama Anda
withOpenSSL
seperti di dalamsumber
stunnels
mode-klien, dapatkah Anda juga memberikan contoh cara mendengarkan soket ssl lokal (misalnya untuk menyediakan local-ssl-ke-remote-non-ssl) ssl proxy)?