Issue 8980 - Async mode and TLS Non-Blocking Issue
Summary: Async mode and TLS Non-Blocking Issue
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: 2.4.47
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-02-19 05:57 UTC by vsmith@interlinknetworks.com
Modified: 2023-11-07 16:57 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description vsmith@interlinknetworks.com 2019-02-19 05:57:38 UTC
Full_Name: Vernon Smith
Version: 2.4.47
OS: Linux, Solaris
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (2601:40d:4300:679a:d18c:3060:e826:d35c)


I am using libldap library built with -DLDAP_USE_NON_BLOCKING_TLS and configured
for Async connection mode. I test making connections using the library to
servers that are hung to verify that my application will not hang in those
cases. I have found 3 issues. The first is that the ldap_pvt_connect() clears
non-blocking socket setup after the connection is made even when Async mode was
configured. So here is my patch for that.
diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c
index a823cc6..d7927e5 100644
--- a/libraries/libldap/os-ip.c
+++ b/libraries/libldap/os-ip.c
@@ -443,7 +443,7 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
 		if ( connect(s, sin, addrlen) != AC_SOCKET_ERROR ) {
 			osip_debug(ld, "connect success\n", 0, 0, 0);
 
-			if ( opt_tv && ldap_pvt_ndelay_off(ld, s) == -1 )
+			if ( !async && opt_tv && ldap_pvt_ndelay_off(ld, s) == -1 )
 				return ( -1 );
 			return ( 0 );
 		}

The second issue is that the tlso_session_connect() routine does not correctly
handle the return code from SSL_connect(), it just returns it to the caller. For
LDAP_USE_NON_BLOCKING_TLS, the return code must be checked and an appropriate
return used. Here is my patch.
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
index e95a448..7a31b5e 100644
--- a/libraries/libldap/tls_o.c
+++ b/libraries/libldap/tls_o.c
@@ -531,7 +531,23 @@ tlso_session_connect( LDAP *ld, tls_session *sess )
 	tlso_session *s = (tlso_session *)sess;
 
 	/* Caller expects 0 = success, OpenSSL returns 1 = success */
-	return SSL_connect( s ) - 1;
+	int rc = SSL_connect( s ) - 1;
+
+#ifdef LDAP_USE_NON_BLOCKING_TLS
+	int sslerr = SSL_get_error(s, rc+1);
+	int sockerr = sock_errno();
+
+	if ( rc < 0 ) {
+		if ( sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE ) {
+			rc = 0;
+		} else if (( sslerr == SSL_ERROR_SYSCALL ) &&
+			( sockerr == EAGAIN || sockerr == ENOTCONN )) {
+			rc = 0;
+		}
+	}
+#endif /* LDAP_USE_NON_BLOCKING_TLS */
+
+	return rc;
 }
 
 static int

The third issue is that ldap_int_tls_start() compiled with
-DLDAP_USE_NON_BLOCKING_TLS Plays with the socket non-blocking setting even if
Async mode is configured. Here is mt patch to only play with the socket setting
if not in Async mode.
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index d9b2d27..69b749c 100644
--- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c
@@ -1075,8 +1075,11 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn,
LDAPURLDesc *srv )
 	/*
 	 * Use non-blocking io during SSL Handshake when a timeout is configured
 	 */
+	int async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC );
 	if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
-		ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+		if ( ! async ) {
+			ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+		}
 		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
 		tv = ld->ld_options.ldo_tm_net;
 		tv0 = tv;
@@ -1110,8 +1113,10 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn,
LDAPURLDesc *srv )
 			ld->ld_errno = LDAP_TIMEOUT;
 			break;
 		} else {
-			/* ldap_int_poll called ldap_pvt_ndelay_off */
-			ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+			/* ldap_int_poll called ldap_pvt_ndelay_off if not in async mode */
+			if ( ! async ) {
+				ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+			}
 			ret = ldap_int_tls_connect( ld, conn, host );
 			if ( ret > 0 ) { /* need to call tls_connect once more */
 				struct timeval curr_time_tv, delta_tv;
@@ -1159,7 +1164,9 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc
*srv )
 		}
 	}
 	if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
-		ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, NULL );
+		if ( ! async ) {
+			ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, NULL );
+		}
 	}
 #endif /* LDAP_USE_NON_BLOCKING_TLS */
 
Thanks, Vern
Comment 1 Quanah Gibson-Mount 2019-02-19 06:34:39 UTC
--On Tuesday, February 19, 2019 5:57 AM +0000 vsmith@interlinknetworks.com 
wrote:

> Full_Name: Vernon Smith
> Version: 2.4.47
> OS: Linux, Solaris
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (2601:40d:4300:679a:d18c:3060:e826:d35c)
>
>
> I am using libldap library built with -DLDAP_USE_NON_BLOCKING_TLS and
> configured for Async connection mode. I test making connections using the
> library to servers that are hung to verify that my application will not
> hang in those cases. I have found 3 issues. The first is that the
> ldap_pvt_connect() clears non-blocking socket setup after the connection
> is made even when Async mode was configured. So here is my patch for that.

Did you pick up the fix for ITS#8957 from RE24?

Did you pick up the fix for ITS#8968 from RE24?

Did you pick up the fix for ITS#8963 from RE24?

Those are all post 2.4.47 fixes.

--Quanah



--

Quanah Gibson-Mount
Product Architect
Symas Corporation
Packaged, certified, and supported LDAP solutions powered by OpenLDAP:
<http://www.symas.com>


Comment 2 Quanah Gibson-Mount 2019-02-19 14:40:52 UTC
--On Tuesday, February 19, 2019 2:12 AM -0500 Vern Smith 
<vsmith@interlinknetworks.com> wrote:

> ITS#8957 and ITS#8968 are my submits and I was using those changes.
> ITS#8963 is for OpenLDAP servers and I only an using the libraries so it
> does not apply to my updates.

Please keep replies to the ITS system.

When filing an ITS, please note specifically which commits past a release 
you've applied, so the ITS is a clear representation of the issue you're 
reporting (and thus avoiding questions such as those I posited).  Thanks!

--Quanah


--

Quanah Gibson-Mount
Product Architect
Symas Corporation
Packaged, certified, and supported LDAP solutions powered by OpenLDAP:
<http://www.symas.com>


Comment 3 Quanah Gibson-Mount 2019-02-20 14:42:20 UTC
--On Tuesday, February 19, 2019 2:41 PM +0000 quanah@symas.com wrote:

> --On Tuesday, February 19, 2019 2:12 AM -0500 Vern Smith
> <vsmith@interlinknetworks.com> wrote:
>
>> ITS#8957 and ITS#8968 are my submits and I was using those changes.
>> ITS#8963 is for OpenLDAP servers and I only an using the libraries so it
>> does not apply to my updates.
>
> Please keep replies to the ITS system.

Hi,

Although each change is individually tiny, the sum of changes is not.  Can 
you please add an IPR to this ITS, as documented at 
<https://www.openldap.org/devel/contributing.html#notice>

Thanks!

Regards,
Quanah


--

Quanah Gibson-Mount
Product Architect
Symas Corporation
Packaged, certified, and supported LDAP solutions powered by OpenLDAP:
<http://www.symas.com>


Comment 4 vsmith@interlinknetworks.com 2019-02-20 19:30:53 UTC
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p><font face="Arial,Verdana,Helvetica">The attached files are
        derived from OpenLDAP Software.
        All of the modifications to OpenLDAP Software represented in the
        following patch(es) were developed by Interlink Networks LLC. </font><font
        face="Arial,Verdana,Helvetica"><font
          face="Arial,Verdana,Helvetica">Interlink Networks LLC</font>
        has not assigned rights and/or interest in
        this work to any party. I, Vernon Smith am authorized by </font><font
        face="Arial,Verdana,Helvetica"><font
          face="Arial,Verdana,Helvetica">Interlink Networks LLC</font>,
        my employer, to release this work under
        the following terms.</font></p>
    <p><font face="Arial,Verdana,Helvetica"><font
          face="Arial,Verdana,Helvetica">Interlink Networks LLC </font></font><font
        face="Arial,Verdana,Helvetica">hereby place the following
        modifications to
        OpenLDAP Software (and only these modifications) into the public
        domain. Hence, these modifications may be freely used and/or
        redistributed for any purpose with or without attribution and/or
        other notice.</font></p>
    <p><font face="Arial,Verdana,Helvetica">Thanks, Vern<br>
      </font></p>
    <div class="moz-cite-prefix">On 2/20/2019 9:42 AM, Quanah
      Gibson-Mount wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:8A8B819A395EEAE290F20248@[192.168.1.39]">--On Tuesday,
      February 19, 2019 2:41 PM +0000 <a class="moz-txt-link-abbreviated" href="mailto:quanah@symas.com">quanah@symas.com</a> wrote:
      <br>
      <br>
      <blockquote type="cite">--On Tuesday, February 19, 2019 2:12 AM
        -0500 Vern Smith
        <br>
        <a class="moz-txt-link-rfc2396E" href="mailto:vsmith@interlinknetworks.com">&lt;vsmith@interlinknetworks.com&gt;</a> wrote:
        <br>
        <br>
        <blockquote type="cite">ITS#8957 and ITS#8968 are my submits and
          I was using those changes.
          <br>
          ITS#8963 is for OpenLDAP servers and I only an using the
          libraries so it
          <br>
          does not apply to my updates.
          <br>
        </blockquote>
        <br>
        Please keep replies to the ITS system.
        <br>
      </blockquote>
      <br>
      Hi,
      <br>
      <br>
      Although each change is individually tiny, the sum of changes is
      not.  Can you please add an IPR to this ITS, as documented at
      <a class="moz-txt-link-rfc2396E" href="https://www.openldap.org/devel/contributing.html#notice">&lt;https://www.openldap.org/devel/contributing.html#notice&gt;</a>
      <br>
      <br>
      Thanks!
      <br>
      <br>
      Regards,
      <br>
      Quanah
      <br>
      <br>
      <br>
      --
      <br>
      <br>
      Quanah Gibson-Mount
      <br>
      Product Architect
      <br>
      Symas Corporation
      <br>
      Packaged, certified, and supported LDAP solutions powered by
      OpenLDAP:
      <br>
      <a class="moz-txt-link-rfc2396E" href="http://www.symas.com">&lt;http://www.symas.com&gt;</a>
      <br>
      <br>
      <br>
    </blockquote>
  </body>
</html>

Comment 5 Quanah Gibson-Mount 2019-02-28 17:31:08 UTC
--On Wednesday, February 20, 2019 2:30 PM -0500 Vern Smith 
<vsmith@interlinknetworks.com> wrote:

>
> The attached files are derived from OpenLDAP Software. All of the
> modifications to OpenLDAP Software represented in the following patch(es)
> were developed by Interlink Networks LLC. Interlink Networks LLC has not
> assigned rights and/or interest in this work to any party. I, Vernon
> Smith am authorized by Interlink Networks LLC, my employer, to release
> this work under the following terms.


Thanks!  This has been applied to git master.

Regards,
Quanah


--

Quanah Gibson-Mount
Product Architect
Symas Corporation
Packaged, certified, and supported LDAP solutions powered by OpenLDAP:
<http://www.symas.com>


Comment 6 Quanah Gibson-Mount 2019-02-28 17:41:31 UTC
changed notes
changed state Open to Release
moved from Incoming to Software Bugs
Comment 7 OpenLDAP project 2019-07-24 19:04:46 UTC
Fixed in master
Fixed in RE24 (2.4.48)
Comment 8 Quanah Gibson-Mount 2019-07-24 19:04:46 UTC
changed notes
changed state Release to Closed
Comment 9 Sun, Wei 2019-12-05 21:27:39 UTC
Hi,
I have two questions about enabling LDAP_USE_NON_BLOCKING_TLS.

I am hitting a problem when I run a test that does a ldapsearch to a stopped sldapd server to simulate a communication error, and the command hung because LDAP_USE_NON_BLOCKING_TLS is not enabled.

It seems to be that on the 2.4.48 release, in file tls2.c, LDAP_USE_NON_BLOCKING_TLS is tied to LDAP_DEVEL, however, on the main branch, it is enabled by default?

// Release 2.4.48
#ifdef LDAP_DEVEL
#define LDAP_USE_NON_BLOCKING_TLS
#endif /* LDAP_DEVEL */

// Master
#ifndef HAVE_MOZNSS
#define LDAP_USE_NON_BLOCKING_TLS
#endif

Is this because we are missing the commit “1a712bf1 – Enable features that were hidden behind LDAP_DEVEL”? Was the intention to enable LDAP_USE_NON_BLOCKING_TLS  by default?

The second question, when I tried to enable LDAP_USE_NON_BLOCKING_TLS through CFLAGS, I am hitting this other issue mentioned in the ITS#8980, in the second fix.

-       return SSL_connect( s ) - 1;
+       int rc = SSL_connect( s ) - 1;
+
+#ifdef LDAP_USE_NON_BLOCKING_TLS
+       int sslerr = SSL_get_error(s, rc+1);
+       int sockerr = sock_errno();
+
+       if ( rc < 0 ) {
+              if ( sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE ) {
+                      rc = 0;
+              } else if (( sslerr == SSL_ERROR_SYSCALL ) &&
+                      ( sockerr == EAGAIN || sockerr == ENOTCONN )) {
+                      rc = 0;
+              }
+       }
+#endif /* LDAP_USE_NON_BLOCKING_TLS */

When I stopped the sldapd, I got SSL_ERROR_WANT_READ,(resource temporarily unavailable) which is expected. However I expect the connection to fail, and return back to the caller, and stopped search. However, due to above code, It instead got a RC=0, which is a success. So the code kept going and sent the initial request. This leads to about a 2 minutes delay in returning back to the caller, that causes my application to fail.  I am not an expert on openldap, but should above code be changed to return some error instead of success?

I don’t have the problem in the master branch, since this part of the code is not enabled in tls_o.c.

Thanks for your attention!

Wei

Comment 10 Quanah Gibson-Mount 2019-12-05 23:46:17 UTC

--On Thursday, December 5, 2019 9:27 PM +0000 "Sun, Wei" 
<Wei.Sun@netapp.com> wrote:

> It seems to be that on the 2.4.48 release, in file tls2.c,
> LDAP_USE_NON_BLOCKING_TLS is tied to LDAP_DEVEL, however, on the main
> branch, it is enabled by default?

Because it is a 2.5 feature.

Regards,
Quanah

--

Quanah Gibson-Mount
Product Architect
Symas Corporation
Packaged, certified, and supported LDAP solutions powered by OpenLDAP:
<http://www.symas.com>