]> git.sur5r.net Git - openldap/commitdiff
Introduce options to configure tcp-keepalive settings per connection. These
authorRalf Haferkamp <ralf@openldap.org>
Wed, 6 May 2009 13:14:36 +0000 (13:14 +0000)
committerRalf Haferkamp <ralf@openldap.org>
Wed, 6 May 2009 13:14:36 +0000 (13:14 +0000)
settings only work on Linux and are ignore when not supported (see
discussion on -devel)

include/ldap.h
libraries/libldap/init.c
libraries/libldap/ldap-int.h
libraries/libldap/options.c
libraries/libldap/os-ip.c

index 695996c1a88f58b8e2474d3ab6deab2902dbbb11..16b62dc0a8801f77c909620bd870af9904fe2e40 100644 (file)
@@ -191,6 +191,13 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT      0x6200
 #define LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL   0x6201
 
+/*
+ * OpenLDAP per connection tcp-keepalive settings
+ * (Linux only, ignored where unsupported)
+ */
+#define LDAP_OPT_X_KEEPALIVE_IDLE              0x6300
+#define LDAP_OPT_X_KEEPALIVE_PROBES            0x6301
+#define LDAP_OPT_X_KEEPALIVE_INTERVAL  0x6302
 
 /* Private API Extensions -- reserved for application use */
 #define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x7000  /* Private API inclusive */
index 4f88dc672a8a22f6bac852b9908d3c83d2699ae6..7349e113aea22021793c89b6c69cb3c75bed4e16 100644 (file)
@@ -545,6 +545,9 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
        gopts->ldo_tls_connect_arg = NULL;
        gopts->ldo_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
 #endif
+       gopts->ldo_keepalive_probes = 0;
+       gopts->ldo_keepalive_interval = 0;
+       gopts->ldo_keepalive_idle = 0;
 
        gopts->ldo_valid = LDAP_INITIALIZED;
        return;
index 48b6ccd298802634cad9c4696e8f186165bcc32d..6708503069bd7b7a4fee8a412ecce5a193d781d3 100644 (file)
@@ -244,6 +244,14 @@ struct ldapoptions {
        unsigned ldo_gssapi_options;
 #endif
 
+       /*
+        * Per connection tcp-keepalive settings (Linux only,
+        * ignored where unsupported)
+        */
+       ber_int_t ldo_keepalive_idle;
+       ber_int_t ldo_keepalive_probes;
+       ber_int_t ldo_keepalive_interval;
+
        int             ldo_refhoplimit;        /* limit on referral nesting */
 
        /* LDAPv3 server and client controls */
index 0b25aa69460dcc0fcef4f5b326540449286280e4..e9ae6d4da240b24569c0b87da999433cb946cdb2 100644 (file)
@@ -342,6 +342,18 @@ ldap_get_option(
        case LDAP_OPT_DEBUG_LEVEL:
                * (int *) outvalue = lo->ldo_debug;
                return LDAP_OPT_SUCCESS;
+       
+       case LDAP_OPT_X_KEEPALIVE_IDLE:
+               * (int *) outvalue = lo->ldo_keepalive_idle;
+               return LDAP_OPT_SUCCESS;
+
+       case LDAP_OPT_X_KEEPALIVE_PROBES:
+               * (int *) outvalue = lo->ldo_keepalive_probes;
+               return LDAP_OPT_SUCCESS;
+
+       case LDAP_OPT_X_KEEPALIVE_INTERVAL:
+               * (int *) outvalue = lo->ldo_keepalive_interval;
+               return LDAP_OPT_SUCCESS;
 
        default:
 #ifdef HAVE_TLS
@@ -681,6 +693,9 @@ ldap_set_option(
        case LDAP_OPT_TIMEOUT:
        case LDAP_OPT_NETWORK_TIMEOUT:
        case LDAP_OPT_CONNECT_CB:
+       case LDAP_OPT_X_KEEPALIVE_IDLE:
+       case LDAP_OPT_X_KEEPALIVE_PROBES :
+       case LDAP_OPT_X_KEEPALIVE_INTERVAL :
                if(invalue == NULL) {
                        /* no place to set from */
                        return LDAP_OPT_ERROR;
@@ -770,6 +785,16 @@ ldap_set_option(
                        lo->ldo_conn_cbs = ll;
                }
                return LDAP_OPT_SUCCESS;
+       case LDAP_OPT_X_KEEPALIVE_IDLE:
+               lo->ldo_keepalive_idle = * (const int *) invalue;
+               return LDAP_OPT_SUCCESS;
+       case LDAP_OPT_X_KEEPALIVE_PROBES :
+               lo->ldo_keepalive_probes = * (const int *) invalue;
+               return LDAP_OPT_SUCCESS;
+       case LDAP_OPT_X_KEEPALIVE_INTERVAL :
+               lo->ldo_keepalive_interval = * (const int *) invalue;
+               return LDAP_OPT_SUCCESS;
+       
        }
        return LDAP_OPT_ERROR;
 }
index a3a3306f93144293f3d91adc0ea8fd45e323ee18..d2d0fac434ebca374f86a3b72efd23bcf7ad4bb2 100644 (file)
@@ -142,6 +142,57 @@ ldap_int_prepare_socket(LDAP *ld, int s, int proto )
                                "setsockopt(%d, SO_KEEPALIVE) failed (ignored).\n",
                                s, 0, 0 );
                }
+               if ( ld->ld_options.ldo_keepalive_idle > 0 )
+               {
+#ifdef TCP_KEEPIDLE
+                       if ( setsockopt( s, SOL_TCP, TCP_KEEPIDLE,
+                                       (void*) &ld->ld_options.ldo_keepalive_idle,
+                                       sizeof(ld->ld_options.ldo_keepalive_idle) ) == AC_SOCKET_ERROR )
+                       {
+                               osip_debug( ld, "ldap_prepare_socket: "
+                                       "setsockopt(%d, TCP_KEEPIDLE) failed (ignored).\n",
+                                       s, 0, 0 );
+                       }
+#else
+                       osip_debug( ld, "ldap_prepare_socket: "
+                                       "sockopt TCP_KEEPIDLE not supported on this system.\n", 
+                                       0, 0, 0 );
+#endif /* TCP_KEEPIDLE */
+               }
+               if ( ld->ld_options.ldo_keepalive_probes > 0 )
+               {
+#ifdef TCP_KEEPCNT
+                       if ( setsockopt( s, SOL_TCP, TCP_KEEPCNT,
+                                       (void*) &ld->ld_options.ldo_keepalive_probes,
+                                       sizeof(ld->ld_options.ldo_keepalive_probes) ) == AC_SOCKET_ERROR )
+                       {
+                               osip_debug( ld, "ldap_prepare_socket: "
+                                       "setsockopt(%d, TCP_KEEPCNT) failed (ignored).\n",
+                                       s, 0, 0 );
+                       }
+#else
+                       osip_debug( ld, "ldap_prepare_socket: "
+                                       "sockopt TCP_KEEPCNT not supported on this system.\n", 
+                                       0, 0, 0 );
+#endif /* TCP_KEEPCNT */
+               }
+               if ( ld->ld_options.ldo_keepalive_interval > 0 )
+               {
+#ifdef TCP_KEEPINTVL
+                       if ( setsockopt( s, SOL_TCP, TCP_KEEPINTVL,
+                                       (void*) &ld->ld_options.ldo_keepalive_interval,
+                                       sizeof(ld->ld_options.ldo_keepalive_interval) ) == AC_SOCKET_ERROR )
+                       {
+                               osip_debug( ld, "ldap_prepare_socket: "
+                                       "setsockopt(%d, TCP_KEEPINTVL) failed (ignored).\n",
+                                       s, 0, 0 );
+                       } 
+#else
+                       osip_debug( ld, "ldap_prepare_socket: "
+                                       "sockopt TCP_KEEPINTVL not supported on this system.\n", 
+                                       0, 0, 0 );
+#endif /* TCP_KEEPINTVL */
+               }
 #endif /* SO_KEEPALIVE */
 #ifdef TCP_NODELAY
                if ( setsockopt( s, IPPROTO_TCP, TCP_NODELAY,