Davide Libenzi wrote:
Can this be worked around? Sure. With some woodoo/ugly magic code in the async status code handling. You *cannot* always wait for read&write, since you'll be exiting the event selection loop immediately, every time. You need to bolt-in the shutdown logic *outside* the shutdown API, and lever over the fact that it is internally composed by a write, followed by a read. And setup the waited I/O flags accordingly. If that's an example of "working API" for someone, it's no surprise websphere blows.

Yes, I'm not sure I follow your workarounds/jargon completely, the possible workarounds I can suggest would go something like this:


Suggestion One)

After the call to SSL_shutdown() that returns 0 starts a periodic timer, which calls SSL_shutdown() again without fail everytime that timer expires. This is because it is not possible to tell if the first SSL_shutdown() that returned 0 actually committed the "send shutdown notify" packet to the BIO layer.

The point of the periodic timer is that your suggestion of monitoring fd writability does not work and can result in 100% CPU usage for the normal case that the 1st write to the BIO from the first call to SSL_shutdown() did commit the packet, because its impossible to tell if the "send shutdown packet" was written to the BIO from the return code from SSL_shutdown().

So the periodic time effectively is a form of rate limiting for the call that may restart/flush the data to the BIO. Instead of the normal event loop testing FD_ISSET(fd, &fdwrite) you rate limit to save your CPU.

You would also put in place a timeout to ensure your application just gave up eventually.

The cons of this workaround is the delay created by the periodic timer when the first attempt to write out the "send shutdown notify" packet failed.



Suggestion Two)

Implement your own BIO layer, so that you can see what libssl commits to the BIO layer. Then just before you call SSL_shutdown() signal to your BIO layer to be on the look out for a "send shutdown notify" packet.

Then your BIO layer perform its own SSL packet decode (or guess the contents base on packet length), or nick/hijack/hack the crypto key and manually decode the packet somehow, probably a futile task with a CBC stream.

Then after your SSL_shutdown() returns 0, you ask your custom BIO layer if it saw the "send shutdown notify" packet yet, if it did then you know for sure it got committed and can therefore from this point forward close down the send side shutdown(fd, SHUT_WR) and/or permanently ignore the writability indicator for that fd/BIO.




I do not advocate any of these workarounds I'm simply making it clear how ugly a workaround is compared to the fix.

I've just re-interpreted the SSL_shutdown() man page and it already documents the behavior my patch is providing (thats my interpretation), so if there is any bug its in someone not following the documentation but following their observation of the implementation (due to the implementation not following the documentation).

The documentation as I interpret is good and would work for non-blocking; but the implementation is as this moment is bad.

Its easy to audit the SSL_shutdown() code and see that it looses/drops the -1 error return in cases where the man page clearly says it will indicate them back to the application.


If I'm misunderstanding the man page and/or the source code please speak up.


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

Reply via email to