Hello,
I am trying to work a full SSL shutdown (close notify sent and received
before closing the socket).
The situation:
* Am currently in established / active SSL state, with a working
connection.
* No shutdown notify has been received and we are being to instigate
the shutdown notify.
The problem:
* I make the call to SSL_shutdown() for the first time and get the
expected return value of zero.
* To indicate that I have sent my notify.
* My code then calls SSL_shutdown() for the second time but there is no
data available just yet (expecting recv close notify) you can see the
EAGAIN for that, due to the non-blocking.
* Now here is the problem: The return value to the 2nd SSL_shutdown()
is zero, but I am expecting -1. Then I am expecting to interogate
SSL_get_errno(ssl, -1) for WANT_READ. This is what the man page
indicates should happen.
* I would think the zero return value should not be stick and only
happen for the first call to SSL_shutdown(), then it should go back to
-1, until it can return 1 (to indicate the recv notify arrived).
* If I want to know if I have set the notify I can use
SSL_get_shutdown() so there is no need to keep returning 0.
At the bottom is an STRACE output of the kernel calls to see the above
taking place. With some fprintf() debugging showing the SSL call and
its return. When I look at SSL_get_errno() I get the unusual
SSL_ERROR_SYSCALL the man page talks of, even when I expect to see -1
WANT_READ.
On a related query, I'd like to ask how to correctly handle the first
SSL_shutdown() return, how do I know if all the data relating to the
send notify has been queued into the kernel ?
Imagine this scenario:
* I'm doing non-blocking IO waiting for write to be free, when it
becomes free
* I am currently exhausting my kernel send buffer and OpenSSL is
getting EAGAIN returned for SSL_write() giving WANT_WRITE.
* I have a little more application data to send left to send
* As soon as I make my last SSL_write() of application data
* I immedialtely make my first call to SSL_shutdown(). Now what
happens if the kernel doesn't have enough room to allow OpenSSL to write
the entire send notify into the kernel ?
I would like to understand how the implementation work in this
situation, I am hoping for the elegant solution like:
* I get a regular -1 return to first SSL_shutdown() with WANT_WRITE,
and SSL_SENT_SHUTDOWN is not set.
* I can then restart my first SSL_shutdown() call when the fd is
available to write again. That OpenSSL will have remembered it is in
the process of writing out the send notify to the kernel and carry on.
* Thrn once the entire send notify is written to the kernel, it will
set SSL_SENT_SHUTDOWN and return 0. This tells me I can now start the
same process for the second call.
select(13, [5 6 7 8 9 10], [], [5 7 8], {0, 994811}) = 0 (Timeout)
write(10, "\25\3\1\0
\205\341\f\314\356\375\4\n\374\36\353SYQ\341n\r\301grb\200\33g\327;\225r\213\2739\260",
37) = 37
write(2, "SSL_shutdown()=0 (FIRST)\n", 25SSL_shutdown()=0 (FIRST)
) = 25
read(10, 0x557f80, 18437) = -1 EAGAIN (Resource temporarily
unavailable)
write(2, "SSL_shutdown()=0 (NEXT)\n", 24SSL_shutdown()=0 (NEXT)
) = 24
shutdown(10, 1 /* send */) = 0
select(13, [5 6 7 8 9 10], [], [5 7 8], {0, 3899}) = 1 (in [10], left {0, 3899})
read(10, "\25\3\1\0
\364\242\331\366M\277\24\224\370)\360u!\24\341B3\"E\300\246\30e\301H\332\210\341\6\360\302b",
18437) = 37
write(2, "SSL_shutdown()=1 (NEXT)\n", 24SSL_shutdown()=1 (NEXT)
) = 24
shutdown(10, 0 /* receive */) = -1 ENOTCONN (Transport endpoint is
not connected)
close(10) = 0
select(12, [5 6 7 8 9], [], [5 7 8], NULL
--
Darryl L. Miles
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager [EMAIL PROTECTED]