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]