guenther+ldapdev@sendmail.com wrote:
Full_Name: Philip Guenther Version: 2.3.27 OS: Linux and Solaris URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (64.58.1.252)
[I vaguely recall seeing a report of this issue in the archives of one of the mailing lists, but I can no longer find the original.]
If you trace the packets sent when you use, for example, ldapsearch against a server on a different host, using either the -Z option to do TLS or using an ldaps URI, you'll discover that the TCP connection is actually reset instead of being closed cleanly: the client sends TCP RSTs in response to the server's final packets.
This is because libldap uses the following sequence when unbind a TLS or SSL connection:
- send the unbind request (over the TLS or SSL layer)
- call SSL_shutdown(), sending the TLS close_notify alert
- call close()
After receiving the close_notify alert from step (2), the server sends back its own close_notify alert and then calls close(). However, because the client didn't wait for the server's response before calling close() on its end, the client's TCP stack considers the TCP connection to already be gone and responds with the RST packets. This occurs with Linux and Solaris clients and probably most other unices: the response to packets after a close() doesn't vary in my experience.
There are a number of ways this can be handled:
- change the client to wait until it sees the server's close_notify alert by replacing "SSL_shutdown( p->ssl );" in tls.c with the two lines: if (SSL_shutdown( p->ssl ) == 0) SSL_shutdown( p->ssl ); (I have confirmed that this works. As documented, the first call will return
1 if the server's close_notify has already been received, if not, the second call will block until it is received.)
So if the server doesn't send one, the client will be stuck waiting forever?
- change the client to not bother to send a close_notify alert when it's just going to close() the connection; change the server to not send a
close_notify if it didn't get one. This probably violates the TLS spec, but the fact that TLS/1.1 permits resumption of sessions without close_notify having been sent indicates that the violation is not a major issue, particularly given that LDAP's unbind request prevents truncation attacks. Close_notifies are, of course, required if the client just wants to terminate the TLS layer and resume unprotected LDAP operations.
Sounds like a change in the SSL library, not something for us to worry about.
- ignore the issue: it only causes one or two extra packets to be sent. While
it also eliminates the TIME_WAIT state, LDAP's application-level close (the unbind request) means it doesn't need reliable full-duplex closure, so the only concern would be random connection issues from reincarnations of the TCP tuple, which is unlikely for an LDAP connection.
Personally, I like the simplicity and cleanliness of solution (1).
(1) has the possibility of an indefinite hang. As such, I think it best to leave it with the current behavior.