https://bugs.openldap.org/show_bug.cgi?id=9244
Bug ID: 9244 Summary: API calls blocking after async connect Product: OpenLDAP Version: 2.4.49 Hardware: All OS: All Status: UNCONFIRMED Severity: normal Priority: --- Component: libraries Assignee: bugs@openldap.org Reporter: ryan@openldap.org Target Milestone: ---
Created attachment 721 --> https://bugs.openldap.org/attachment.cgi?id=721&action=edit async connect test without TLS
My understanding of LDAP_OPT_CONNECT_ASYNC is that the attached program should not block. If the connection does not establish fast enough, the bind call is supposed to return LDAP_X_CONNECTING.
(At least that's how I understand it, based on the original behaviour (circa 2.4.23 up to 2.4.40) as well as the bind loop in back-meta. On the other hand, the man page does "Subsequent calls to library routines will poll for completion of the connect before performing further operations" which might be interpreted as meaning they would block...)
In current releases it does block, as demonstrated by strace on Linux (latency added using 'tc qdisc'):
[...] connect(3, {sa_family=AF_INET, sin_port=htons(389), sin_addr=inet_addr("192.168.1.204")}, 16) = -1 EINPROGRESS (Operation now in progress) write(3, "0\f\2\1\1`\7\2\1\3\4\0\200\0", 14) = -1 EAGAIN (Resource temporarily unavailable) poll([{fd=3, events=POLLOUT|POLLERR|POLLHUP}], 1, -1) = 1 ([{fd=3, revents=POLLOUT}]) write(3, "0\f\2\1\1`\7\2\1\3\4\0\200\0", 14) = 14 poll([{fd=3, events=POLLIN|POLLPRI}], 1, -1) = 1 ([{fd=3, revents=POLLIN}]) read(3, "0\f\2\1\1a\7\n", 8) = 8 read(3, "\1\0\4\0\4\0", 6) = 6 write(2, "OK: ldap_simple_bind_returned 0 "..., 42OK: ldap_simple_bind_returned 0 (Success) ) = 42 [...]
As discussed in IRC, I believe I bisected this down to commit ae6347bac, from bug 8022. The reasoning is sound, but ldap_int_open_connection does not actually return -2, only -1 or 0.
The patch is simple enough, but I'm also looking at some later commits that were probably done to work around this, and might not be needed now (bug 8957, bug 8968, bug 8980). Also need to test all setups thoroughly (ldap, ldaps, STARTTLS, not to mention back-meta/asyncmeta).
I also notice that LDAP_OPT_CONNECT_ASYNC is not effective unless LDAP_OPT_NETWORK_TIMEOUT is also set. It might be intentional, but the man page doesn't mention this specifically, and I don't see why it would be necessary...