On Tue, Sep 18, 2018 at 10:55:50PM -0700, Ryan Tandy wrote:
There is some EAGAIN handling conditional on LDAP_USE_NON_BLOCKING_TLS which itself is behind LDAP_DEVEL. However this code is meant for non-blocking sockets, and in my case it ends up stuck in poll() waiting for a notification that never arrives.
This turned out to be because the fd and timeout fields are only initialized when timeout is configured and the non-blocking behaviour was triggered because of it. Otherwise the code simply doesn't anticipate EAGAIN could be returned and the behaviour is more or less undefined; it ends up calling poll() with fd = -1 and a garbage timeout.
It's possible that what I actually want here is a (ret > 0) case in ldap_int_tls_start for when LDAP_USE_NON_BLOCKING_TLS is absent and ldap_int_tls_connect returns 1. (I'd also need to adapt the non-blocking path to be able to handle a blocking socket as well.)
More precisely, what I actually want is a (ret > 0) case that is used unless both USE_NON_BLOCKING_TLS is true and a timeout is configured.
If we added to ber_sockbuf_ctrl() the ability to query whether the socket is non-blocking, for GnuTLS at least we could bypass poll() and go straight back into ldap_int_tls_connect(). However I don't see a lot of benefit to this as long as calling poll() on a blocking socket has no downside.