]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9502 Implement LDAP_OPT_TCP_USER_TIMEOUT
authorNadezhda Ivanova <nivanova@symas.com>
Mon, 15 Mar 2021 13:02:19 +0000 (15:02 +0200)
committerQuanah Gibson-Mount <quanah@openldap.org>
Thu, 22 Apr 2021 21:52:12 +0000 (21:52 +0000)
doc/man/man3/ldap_get_option.3
include/ldap.h
libraries/libldap/init.c
libraries/libldap/ldap-int.h
libraries/libldap/options.c
libraries/libldap/os-ip.c

index 9675520ab46370273138b5852e2e75ebc4e74167..25027ac7f290f72187e9b0c92ec4d1b64916e63b 100644 (file)
@@ -451,6 +451,11 @@ Instructs
 .BR ldap_result (3)
 to keep the connection open on read error or if Notice of Disconnection is received. In these cases, the connection should be closed by the caller.
 This option is OpenLDAP specific.
+.TP
+.B LDAP_OPT_TCP_USER_TIMEOUT
+Allows to configure TCP_USER_TIMEOUT in milliseconds on the connection, overriding the operating system setting.
+This option is OpenLDAP specific and supported only on Linux 2.6.37 or higher.
+
 .SH SASL OPTIONS
 The SASL options are OpenLDAP specific.
 .TP
index fcea81d9f3437a6622cb09c16cf3ad24d4f4ba2c..6877d9fd11d64a0394b8cb9a5c70dd0cbb530c8e 100644 (file)
@@ -133,6 +133,7 @@ LDAP_BEGIN_DECL
 #define        LDAP_OPT_SESSION_REFCNT         0x5012  /* session reference count */
 #define        LDAP_OPT_KEEPCONN               0x5013  /* keep the connection on read error or NoD */
 #define        LDAP_OPT_SOCKET_BIND_ADDRESSES  0x5014  /* user configured bind IPs */
+#define        LDAP_OPT_TCP_USER_TIMEOUT       0x5015  /* set TCP_USER_TIMEOUT if the OS supports it, ignored otherwise */
 
 /* OpenLDAP TLS options */
 #define LDAP_OPT_X_TLS                         0x6000
index b247327d5792d30491e5c56c01096f1f523eac60..341a44483f654708ea58bfb5edad09238122bc49 100644 (file)
@@ -620,6 +620,8 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
        gopts->ldo_keepalive_interval = 0;
        gopts->ldo_keepalive_idle = 0;
 
+       gopts->ldo_tcp_user_timeout = 0;
+
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_init( &gopts->ldo_mutex );
 #endif
index 4dacecbfedd8231bc3e6088e5edf442963b9d1d3..2dae6effdcc7288e266612dc3a1655e6b17e38af 100644 (file)
@@ -248,6 +248,12 @@ struct ldapoptions {
        ber_int_t ldo_keepalive_probes;
        ber_int_t ldo_keepalive_interval;
 
+       /*
+        * Per connection tcp user timeout (Linux >= 2.6.37 only,
+        * ignored where unsupported)
+        */
+       ber_uint_t ldo_tcp_user_timeout;
+
        int             ldo_refhoplimit;        /* limit on referral nesting */
 
        /* LDAPv3 server and client controls */
@@ -267,7 +273,7 @@ struct ldapoptions {
 
        LDAP_BOOLEANS ldo_booleans;     /* boolean options */
 
-#define LDAP_LDO_NULLARG       ,0,0,0,0 ,{0},{0} ,0,0,0,0, 0,0,0,0, 0,0, 0,0,0,0,0,0, 0, 0
+#define LDAP_LDO_NULLARG       ,0,0,0,0 ,{0},{0} ,0,0,0,0, 0,0,0,0,0, 0,0, 0,0,0,0,0,0, 0, 0
 
        /* LDAP user configured bind IPs */
        struct ldapsourceip ldo_local_ip_addrs;
index e07a4ce60b4a083d63fe39080a516243ebc1b3d2..b51220c57fd6774d48bbc15315ff4a3d40de2d74 100644 (file)
@@ -418,6 +418,11 @@ ldap_get_option(
                rc = LDAP_OPT_SUCCESS;
                break;
 
+       case LDAP_OPT_TCP_USER_TIMEOUT:
+               * (unsigned int *) outvalue = lo->ldo_tcp_user_timeout;
+               rc = LDAP_OPT_SUCCESS;
+               break;
+
        default:
 #ifdef HAVE_TLS
                if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) {
@@ -842,6 +847,7 @@ ldap_set_option(
        case LDAP_OPT_X_KEEPALIVE_IDLE:
        case LDAP_OPT_X_KEEPALIVE_PROBES :
        case LDAP_OPT_X_KEEPALIVE_INTERVAL :
+       case LDAP_OPT_TCP_USER_TIMEOUT:
                if(invalue == NULL) {
                        /* no place to set from */
                        LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
@@ -962,6 +968,10 @@ ldap_set_option(
                lo->ldo_keepalive_interval = * (const int *) invalue;
                rc = LDAP_OPT_SUCCESS;
                break;
+       case LDAP_OPT_TCP_USER_TIMEOUT:
+               lo->ldo_tcp_user_timeout = * (const unsigned int *) invalue;
+               rc = LDAP_OPT_SUCCESS;
+               break;
        
        }
        LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
index 14899cc00791191f03c3ef69dec18ab64e834bec..3e8d86718ec0093f42fc22ec4b658cff746fb8ee 100644 (file)
@@ -118,7 +118,7 @@ ldap_int_prepare_socket(LDAP *ld, int s, int proto )
 {
        Debug1(LDAP_DEBUG_TRACE, "ldap_prepare_socket: %d\n", s );
 
-#if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY )
+#if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY ) || defined( TCP_USER_TIMEOUT )
        if ( proto == LDAP_PROTO_TCP ) {
                int dummy = 1;
 #ifdef SO_KEEPALIVE
@@ -190,8 +190,25 @@ ldap_int_prepare_socket(LDAP *ld, int s, int proto )
                                s );
                }
 #endif /* TCP_NODELAY */
+               if ( ld->ld_options.ldo_tcp_user_timeout > 0 )
+               {
+#ifdef TCP_USER_TIMEOUT
+                       if ( setsockopt( s, IPPROTO_TCP, TCP_USER_TIMEOUT,
+                                       (void*) &ld->ld_options.ldo_tcp_user_timeout,
+                                       sizeof(ld->ld_options.ldo_tcp_user_timeout) ) == AC_SOCKET_ERROR )
+                       {
+                               Debug1(LDAP_DEBUG_TRACE,
+                                       "ldap_prepare_socket: "
+                                       "setsockopt(%d, TCP_USER_TIMEOUT) failed (ignored).\n",
+                                       s );
+                       }
+#else
+                       Debug0(LDAP_DEBUG_TRACE, "ldap_prepare_socket: "
+                              "sockopt TCP_USER_TIMEOUT not supported on this system.\n" );
+#endif /* TCP_USER_TIMEOUT */
+               }
        }
-#endif /* SO_KEEPALIVE || TCP_NODELAY */
+#endif /* SO_KEEPALIVE || TCP_NODELAY || TCP_USER_TIMEOUT */
 
        return 0;
 }