diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c index 8cf2530b399144872389dcbe80c40dd139c76421..d21f44bb795cac84edff8368d70897e7dc74ac67 100644 --- a/libraries/libldap/init.c +++ b/libraries/libldap/init.c @@ -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; diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 883566f4295bde7a0bd0d3e02f624aa91e2c5a58..6c5b22e1d8c7c7585a18b5b00a474cd2d544b9c8 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -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 */ diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index 0b25aa69460dcc0fcef4f5b326540449286280e4..e9ae6d4da240b24569c0b87da999433cb946cdb2 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -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; } diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c index a3a3306f93144293f3d91adc0ea8fd45e323ee18..d2d0fac434ebca374f86a3b72efd23bcf7ad4bb2 100644 --- a/libraries/libldap/os-ip.c +++ b/libraries/libldap/os-ip.c @@ -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,