Nanno Langstraat wrote:
So I can add one more voice to the choir: the current SSL_shutdown() API appears to give trouble to every non-blocking developer (I remember I lost serious time noticing + tracking down this 100% CPU bug), and afterwards things still don't really work right.

I can't immediately think of a reason why you'd get 100% CPU, except with a badly constructed event loop (even with non-blocking I/O in use) much as I'd like to see your support :).


The issue I am claiming is that the event loop has no way of knowing if the SSL_shutdown() managed to write and commit the entire "shutdown notify packet" into the BIO layer as the SSL_shutdown() return value will never indicate a -1/WANT_WRITE error condition, it always returns a value as-if everything has proceeded fine.

It also never returns -1/WANT_READ when it has successfully committed the "shutdown notify packet" to the BIO layer but it now waiting to receive and decode a "shutdown notify packet" from the remote end.

Knowing the exact state is important for non-blocking, the matters that concern a non-blocking user are:

1) Retrying the SSL_shutdown() when all the necessary data isn't yet been written as we need to get the send "shutdown notify packet" on the wire. 2) Knowing that all the necessary data has been written into the BIO layer so we can now take action to shutdown the sending side of the socket (at socket level, like with shutdown()) and cleanup that half, whilst leaving open the receiving half since we still wish to see the recvd "shutdown notify packet". 3) Allowing an application driven timeout to start from the moment we know we committed the send "shutdown notify packet" to the BIO layer, so we can enforce a timeout based on when we wrote the data to the wire as opposed to when we wanted to start shutdown proceedings.


Maybe you got 100% CPU because you were using SSL_shutdown() to look for a return value of 1, meaning its all over. My application uses SSL_read() even after the SSL_shutdown() has been called once. There are 2 reasons for this:

1) It is necessary to read (and discard/sink it if you don't want it) all the encrypted application data that appears before the shutdown. If you stopped calling SSL_read() then I guess 100% CPU results because FD_ISSET(fd, &fdread) always signals there is data and calling SSL_shutdown() alone may not clear it because there is application data waiting to be read that is stalling the inbound stream processing.

2) SSL_read() already has a return value -1/ZERO_RETURN which indicates end-of-stream. You may then call SSL_shutdown() to look to see if 1 is returned or not. Or even SSL_get_shutdown() and take whatever security action your application needs to take in the event of an improperly shutdown stream.

So as you can see my guess would be that your application has an incorrect event loop in relation to handling SSL_shutdown().


Darryl
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to