This directive causes a cached connection to be dropped an recreated
after it has been idle for the specified time.
+.TP
+.B conn-ttl <time>
+This directive causes a cached connection to be dropped an recreated
+after a given ttl, regardless of being idle or not.
+
.SH BACKWARD COMPATIBILITY
The LDAP backend has been heavily reworked between releases 2.2 and 2.3;
as a side-effect, some of the traditional directives have been
.B idle-timeout
directive.
+.TP
+.B conn-ttl <time>
+This directive causes a cached connection to be dropped an recreated
+after a given ttl, regardless of being idle or not.
+
.TP
.B onerr {CONTINUE|stop}
This directive allows to select the behavior in case an error is returned
unsigned lc_refcnt;
unsigned lc_flags;
+ time_t lc_create_time;
time_t lc_time;
} ldapconn_t;
ldap_avl_info_t li_conninfo;
time_t li_network_timeout;
+ time_t li_conn_ttl;
time_t li_idle_timeout;
time_t li_timeout[ LDAP_BACK_OP_LAST ];
} ldapinfo_t;
send_ldap_result( op, rs );
rs->sr_text = NULL;
}
+
+ } else {
+ if ( li->li_conn_ttl > 0 ) {
+ (*lcp)->lc_create_time = op->o_time;
+ }
}
return rs->sr_err;
}
} else {
- if ( li->li_idle_timeout != 0 && op->o_time > lc->lc_time + li->li_idle_timeout ) {
+ if ( ( li->li_idle_timeout != 0 && op->o_time > lc->lc_time + li->li_idle_timeout )
+ || ( li->li_conn_ttl != 0 && op->o_time > lc->lc_create_time + li->li_conn_ttl ) )
+ {
/* in case of failure, it frees/taints lc and sets it to NULL */
- if ( ldap_back_retry( &lc, op, rs, sendok ) ) {
+ if ( !ldap_back_retry( &lc, op, rs, sendok ) ) {
lc = NULL;
}
}
LDAP_BACK_CFG_WHOAMI,
LDAP_BACK_CFG_TIMEOUT,
LDAP_BACK_CFG_IDLE_TIMEOUT,
+ LDAP_BACK_CFG_CONN_TTL,
LDAP_BACK_CFG_REWRITE,
LDAP_BACK_CFG_LAST
"SYNTAX OMsDirectoryString "
"SINGLE-VALUE )",
NULL, NULL },
+ { "conn-ttl", "ttl", 2, 0, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL,
+ ldap_back_cf_gen, "( OLcfgDbAt:3.16 "
+ "NAME 'olcDbConnTtl' "
+ "DESC 'connection ttl' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
{ "suffixmassage", "[virtual]> <real", 2, 3, 0,
ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
ldap_back_cf_gen, NULL, NULL, NULL },
value_add_one( &c->rvalue_vals, &bv );
} break;
+ case LDAP_BACK_CFG_CONN_TTL: {
+ char buf[ SLAP_TEXT_BUFLEN ];
+
+ if ( li->li_conn_ttl == 0 ) {
+ return 1;
+ }
+
+ lutil_unparse_time( buf, sizeof( buf ), li->li_conn_ttl );
+ ber_str2bv( buf, 0, 0, &bv );
+ value_add_one( &c->rvalue_vals, &bv );
+ } break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
li->li_idle_timeout = 0;
break;
+ case LDAP_BACK_CFG_CONN_TTL:
+ li->li_conn_ttl = 0;
+ break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
li->li_idle_timeout = (time_t)t;
} break;
+ case LDAP_BACK_CFG_CONN_TTL: {
+ unsigned long t;
+
+ if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
+ snprintf( c->msg, sizeof( c->msg),
+ "unable to parse conn ttl\"%s\"",
+ c->argv[ 1 ] );
+ Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+ return 1;
+ }
+ li->li_conn_ttl = (time_t)t;
+ } break;
+
case LDAP_BACK_CFG_REWRITE:
snprintf( c->msg, sizeof( c->msg ),
"rewrite/remap capabilities have been moved "
#define META_ANONYMOUS 2
#endif
+ time_t msc_create_time;
time_t msc_time;
struct metainfo_t *msc_info;
unsigned mt_flags;
int mt_version;
time_t mt_network_timeout;
+ time_t mt_conn_ttl;
time_t mt_idle_timeout;
struct timeval mt_bind_timeout;
#define META_BIND_TIMEOUT LDAP_BACK_RESULT_UTIMEOUT
int mi_version;
time_t mi_network_timeout;
+ time_t mi_conn_ttl;
time_t mi_idle_timeout;
struct timeval mi_bind_timeout;
time_t mi_timeout[ LDAP_BACK_OP_LAST ];
mi->mi_targets[ i ].mt_flags = mi->mi_flags;
mi->mi_targets[ i ].mt_version = mi->mi_version;
mi->mi_targets[ i ].mt_network_timeout = mi->mi_network_timeout;
+ mi->mi_targets[ i ].mt_conn_ttl = mi->mi_conn_ttl;
mi->mi_targets[ i ].mt_idle_timeout = mi->mi_idle_timeout;
mi->mi_targets[ i ].mt_bind_timeout = mi->mi_bind_timeout;
for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
*tp = (time_t)t;
+ /* conn ttl */
+ } else if ( strcasecmp( argv[ 0 ], "conn-ttl" ) == 0 ) {
+ unsigned long t;
+ time_t *tp = mi->mi_ntargets ?
+ &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_conn_ttl
+ : &mi->mi_conn_ttl;
+
+ switch ( argc ) {
+ case 1:
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing ttl value in \"conn-ttl <seconds>\" line\n",
+ fname, lineno, 0 );
+ return 1;
+ case 2:
+ break;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: extra cruft after ttl value in \"conn-ttl <seconds>\" line\n",
+ fname, lineno, 0 );
+ return 1;
+ }
+
+ if ( lutil_parse_time( argv[ 1 ], &t ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse ttl \"%s\" in \"conn-ttl <seconds>\" line\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+
+ }
+
+ *tp = (time_t)t;
+
/* bind timeout when connecting to ldap servers */
} else if ( strcasecmp( argv[ 0 ], "bind-timeout" ) == 0 ) {
unsigned long t;
* Already init'ed
*/
if ( msc->msc_ld != NULL ) {
- if ( mt->mt_idle_timeout == 0 ) {
- return rs->sr_err = LDAP_SUCCESS;
- }
+ int doreturn = 1;
- if ( op->o_time > msc->msc_time + mt->mt_idle_timeout ) {
+ if ( ( mt->mt_idle_timeout != 0 && op->o_time > msc->msc_time + mt->mt_idle_timeout )
+ || ( mt->mt_conn_ttl != 0 && op->o_time > msc->msc_create_time + mt->mt_conn_ttl ) )
+ {
Debug( LDAP_DEBUG_TRACE,
- "%s meta_back_init_one_conn[%d]: idle timeout.\n",
+ "%s meta_back_init_one_conn[%d]: idle timeout/ttl.\n",
op->o_log_prefix, candidate, 0 );
if ( meta_back_retry( op, rs, mc, candidate, sendok ) ) {
return rs->sr_err;
}
+
+ doreturn = 0;
}
- msc->msc_time = op->o_time;
+ if ( mt->mt_idle_timeout != 0 ) {
+ msc->msc_time = op->o_time;
+ }
+
+ if ( doreturn ) {
+ return rs->sr_err = LDAP_SUCCESS;
+ }
}
/*
msc->msc_time = op->o_time;
}
+ if ( mt->mt_conn_ttl ) {
+ msc->msc_create_time = op->o_time;
+ }
+
} else {
rs->sr_err = slap_map_api2result( rs );
if ( sendok & LDAP_BACK_SENDERR ) {