Darryl Miles wrote: > But this flag (while documented to the contrary) does nothing inside > libssl. So yes the documentation says you should set it, prove to me > that OpenSSL behaves in a different way because you set it.
One of the biggest downsides of open source software is that encourages people to code to what something happens to do rather than what it's guaranteed to do. > A hint to DS: grep the source tree of OpenSSL and follow all the > code-paths determined by this flag to their conclusion. Software development doesn't work that way. That's how you produce code that suddenly fails mysteriously when you upgrade an unrelated component. The first rule of software development is "thou shall not assume that something that happens a particular way is guaranteed to do so, especially when the documentation specifically warns that it is not". > 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. The general rule of thread synchronization is that it is your responsibility to serialize access to the same object from concurrent threads and the library's job to synchronize accesses to distinct objects. OpenSSL follows this general rule. Kernel objects are the exception, only because we cannot allow a program (broken or valid) to screw up kernel objects. So the kernel has no choice but to "overserialize". > Your application then also has to evaluate its intent to send data, you > don't always have something more to send. If you do then you need to > indicate to the OS to wake me up if I can push more data down into the > kernel buffer. No, that is not how OpenSSL works. When you want to send data, you simply call SSL_write. You only check if I/O is possible if OpenSSL specifically tells you to. (OpenSSL may need to do something other than write to send the data, for example, it may need to read renegotiation data.) 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. This is a major cause of SSL deadlocks in "two thread" applications that run their threads independently. Here's the nightmare scenario: 1) You are in a point in the protocol where the other side will not send anything unless we send something first. However, we try to read just in case it sends something. 2) You call SSL_write from your write thread trying to send the data that will keep the application protocol going, but a renegotiation is in progress and no data has been received yet. You get WANT_READ. (At this point, the SSL connection's one and only status is "want read to send".) 2) The renegotiation data is received, but no application data is received. 3) You call SSL_read from your read thread (either just to try it, or because you get a 'select' hit from the renegotiation data being received, it doesn't matter. The OpenSSL library reads the renegotiation data, but no application data is available. You get WANT_READ, since application data needs to be received to make forward progress. (At this point, the SSL connection's one and only status is "want read to receive". Note that the read thread's actions *invalidate* the state the write thread thinks it's in.) 4) Your write thread, having no idea that the read thread received a different status, stupidly thinks it cannot make forward progress based on the state it got from step 1 (since that's the last thing *it* did). However, it *can* make forward progress (because another thread changed the SSL state). 5) Now the other end is waiting for you to send data, and you are waiting to receive the renegotiation data you already received. You see, in step 4, the write thread *must* know that the read thread changed the SSL connection's status. Otherwise you deadlock. DS ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org