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

Re: (ITS#8650) EAGAIN from gnutls_handshake not respected



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.