I believe I have seen the OS return 0 on a 2nd read even when not at EOF.
I'll try to come up with a test case to demonstrate it.
(See http://groups.google.com/groups?selm=3DB8738F.2000409%40kegel.com
for a related thread.)
- Dan


"Noel Burton-Krahn" [EMAIL PROTECTED] wrote:
Uh... Dan, read() always returns 0 on EOF, so SSL_read() will always return
0 too (also setting SSL_ERROR_ZERO_RETURN). That's true for the first read
on EOF and all reads afterwards. Do you think that read() will return 0 if
it's not EOF? If read() would block, it returns -1 and sets errno=EAGAIN.
read()==0 alwats means EOF.

----- Original Message -----
From: "Dan Kegel" <[EMAIL PROTECTED]>
With Unix nonblocking sockets, the only way to detect that the
connection has shut down is to check for a zero return from read
after poll or select says the socket is ready for reading.
(Read will cheerfully return zero at any time if you call it
again after a fully successful read(), so only the first read()
after poll() should be checked.  If you don't believe me, try it.)

Given that, let's look at how OpenSSL detects EOF:

int SSL_get_error(SSL *s,int i)
{
...
     if (i == 0) {
         if (s->version == SSL2_VERSION) {
             /* assume it is the socket being closed */
             return(SSL_ERROR_ZERO_RETURN);
         } else {
             if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
                 (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY))
                 return(SSL_ERROR_ZERO_RETURN);
          }
      }
      return(SSL_ERROR_SYSCALL);
}

Hrmf.  Looks like SSL_get_error will return SSL_ERROR_ZERO_RETURN
or SSL_ERROR_SYSCALL on any zero read.  When using SSLV3 or TLS,
OpenSSL seems to have a case where it won't tell you about
zero returns from read(), which is confusing.
And since the user has no idea when OpenSSL is calling read(),
and there's no way to tell OpenSSL what poll() said,
*there is no way to properly detect EOF with nonblocking
sockets in OpenSSL when using SSL_set_fd() / bss_sock.c *.

I'm starting to think that you *must* do the read() yourself
into a buffer, and use a memory BIO of some sort.  Otherwise
you have too little control over hard EOF detection.

Somebody tell me how I'm wrong, please... I almost certainly haven't
looked into this enough to know what I'm talking about.

Thanks,
Dan

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to