> > Now the next question you might want to ask, "is it > allowed for > > exactly two threads to operate specifically the > SSL_read() and > > SSL_write() on the _SAME_ 'SSL *' instance at the same > time ?" My > > understanding would be that the answer is > NO. This is a limitation in > > the OpenSSL library, since some of the shared parts of > 'SSL *' have no > > protection and the SSL_read() and SSL_write() > code-paths have not been > > audited/reworked to minimize the contention/data-race > issues. > > This is how everything else works, it's odd to say it's > somehow a limitation > of OpenSSL that it works the same way everything else > works. Try to read to > a string in one thread while you write to it from another.
I think we've lost the point: if I write to a socket from more than one thread at a time, clearly I've messed up. Even if the operating system doesn't complain, my stream is nonsense (unless I only ever write a single byte at a time). However, it's clearly alright to read a socket from one thread while writing a socket from another: indeed, this is the purpose of a socket. That OpenSSL doesn't allow this usage seems like a limitation of the library. (Although maybe it's actually of the TLS protocol itself...?) > The other gotcha is that if you use separate read and write > threads, you > *must* remember that an SSL connection only has one state. > You cannot > independently maintain your own state in each thread, or > you can deadlock. > You see, in step 4, the write thread *must* know that the > read thread > changed the SSL connection's status. Otherwise you > deadlock. Your explanation here is excellent. If I understand it correctly it's not really the problem of multiple access to a shared buffer which would understandably cause corruption, it's that there's a single flag which indicates the 'direction' if you will of the SSL structure itself: #define SSL_ERROR_WANT_READ 2 #define SSL_ERROR_WANT_WRITE 3 And since these are defined in such a way that you can't have both READ|WRITE at the same time, if I don't somehow externally remember this information and share it between my threads I could run into trouble. Ok so to summarize you Dave and Darryl: Blocking sockets + OpenSSL will only work for a request-response model without redesigning the library itself, because external synchronization deadlocks (for obvious reasons) and no synchronization deadlocks because the library/application no longer know what needs to happen to make forward progress. Forgive me if I misunderstand either of you, but it sounds like if I use non-blocking sockets, I'll be able to use but a single thread to both push & pull independent streams of data, and I don't have to wait for an interrupted write to complete in order to begin a new read, or vice versa, so long as I remember the actual WANT_* state of each stream. I'd been warned away from non-blocking socket use in OpenSSL from the varies searches I did across this mailing list, but honestly I'd actually prefer to use them. To make sure I'm clear on this: if I myself don't have any data to read and an SSL_write returns WANT_READ, that doesn't mean I myself need to call SSL_read-- what it means is I need to wait until the socket is readable, and then call SSL_write again (with the same args of course). It'd be awesome if there was a 'canonical' example for this... I've read through several different applications using OpenSSL (stunnel, Ice, curl) but they're so heavily hacked up to overcome various system limitations / implementation needs that it's not entirely obvious what's going on. Guess I'll go make that example now. :) Thanks much, --jason ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org