[Date Prev][Date Next] [Chronological] [Thread] [Top]

socket I/O and EOF



There appears to be a problem with OpenSSL when used with non-blocking I/O
on Linux. (Running SuSE 6.0, Linux kernel 2.2.5.) A similar situation seems
to be happening on NT as well.

The code doesn't seem to detect that a socket has been closed by the remote
end. Read loops tend to execute a huge number of times in this case, always
returning 0 bytes of data. I haven't figured out how/why the loop ever
terminates, but in normal situations, it eventually does. In one case in
particular in the OpenLDAP slapd (developer snapshot) if a session is just
being started, and SSL_accept fails, slapd will loop forever, retrying the
SSL_accept. (This assumes the slapd is configured to require a user
certificate. The error can be reproduced by using a client without a user
certificate to connect to the slapd.)

In slapd the I/O loop is structured around a select(). As you know, select
will return "readable" for a socket that was closed, and a read on this
socket will return 0 bytes to indicate EOF. Unfortunately, it appears that
the SSL library doesn't do anything special when a read returns 0 bytes. In
particular, the SSL session handle's rwstate variable remains set to
SSL_READING in this case, and the upper levels treat this as "a read was
incomplete and should be retried." Of course, none of the retries will ever
succeed, and so you have a fine infinite loop.

This message is going to both the OpenSSL and the OpenLDAP crew because I
haven't figured out yet who's doing the wrong thing. This infinite loop may
be caused by the ldap_pvt_tls_accept that we wrap around SSL_accept. The
large number of loops even in the successful case seems to be a more general
problem.

  -- Howard Chu
  Chief Architect, Symas Corp.       Director, Highland Sun
  http://www.symas.com               http://highlandsun.com/hyc