The issue is down to the OpenSSL API thread-safety rules (which are
dictated to by the internal design of OpenSSL).
I covered those thread-safety rules in a previous posting.
Yes the common application design pattern for full-duplex SSL streams is
to only ever have one thread doing the work on a specific instance of
'SSL *' at any one time.
Given your application design requirements you indicated in your
original posting then in order to achieve all your goals you must use
the kernel socket in non-blocking mode.
The reasons why were explained in a previous reply of mine.
There is no reason why you should be warned away from using OpenSSL with
non-blocking sockets. But you have to understand multi-threaded
programming is hard and therefore more programmers will have difficulty
previously in simply not understanding the concepts correctly.
Jason Pettiss wrote:
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).
Okay this is a new question. Yes if you call SSL_write() and get back
-1/WANT_READ then yes you do need to call SSL_read() to unstall that
situation. In-fact SSL_peek() might be better to use if you have no
where to put the application data right now but you want to attempt to
see if the condition can be resolved by the next SSL protocol packet to
be processed. Obviously if application data exists and is in the way
calling SSL_peek() won't clear the SSL_write() stall. You must
SSL_read() that data so the OpenSSL library can get to the final part of
the renegotiation handshake packet.
I do not believe the SSL_write() call is allowed to access the
underlying BIO/kernel-socket to read in more data. I think SSL_write()
is allowed to process any data already read into buffer (from kernel to
OpenSSL library internal buffer) in an attempt to unstall the situation
itself. But it can't invoke read() on the kernel for it.
Due to this you have to call SSL_read()|SSL_peek() at least once, since
these calls are allowed to access the underlying BIO/kernel-socket to
attempt to read() in more data.
So once you observe an SSL_write() returning -1/WANT_READ you should
immediately attempt to SSL_read()|SSL_peek() and if that also returns
-1/WANT_READ then you can go to sleep and wait for more data to come in
(wait until the socket is readable).
When that data comes in you call SSL_read()|SSL_peek() and if that
doesn't return -1/WANT_READ then should give your SSL_write() another
try. From memory I think SSL_read()|SSL_peek() return 0 (i.e. no new
application data) at least once to eat up the final part of the
renegotiation handshake process.
But it doesn't hurt to always call SSL_write() after every
SSL_read()|SSL_peek() if you know that you are under this special
condition (that SSL_write() previously returned -1/WANT_READ). Once
your SSL_write() returns something other than -1/WANT_READ you can clear
this special condition.
Now the same is true in reverse. The special condition that is
SSL_read() returning -1/WANT_WRITE. I'm sure you can work out the
details on this.
Darryl
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org