#define META_BINDING_CLEAR(rs) META_CND_CLEAR( (rs), META_BINDING )
LDAP *msc_ld;
+ time_t msc_time;
struct berval msc_bound_ndn;
struct berval msc_cred;
unsigned msc_mscflags;
break;
default:
+ /* only touch when activity actually took place... */
+ if ( mi->mi_idle_timeout != 0 && msc->msc_time < op->o_time ) {
+ msc->msc_time = op->o_time;
+ }
+
/* FIXME: matched? referrals? response controls? */
rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err,
NULL, NULL, NULL, NULL, 1 );
* structure (this includes
* LDAP_COMPARE_{TRUE|FALSE}) */
default:
+ /* only touch when activity actually took place... */
+ if ( mi->mi_idle_timeout != 0 && msc->msc_time < op->o_time ) {
+ msc->msc_time = op->o_time;
+ }
+
rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err,
&matched, &text, &refs, &ctrls, 1 );
res = NULL;
lrc = ldap_result( msc->msc_ld, msgid[ i ],
LDAP_MSG_ALL, &tv, &res );
- if ( lrc == 0 ) {
+ switch ( lrc ) {
+ case 0:
assert( res == NULL );
continue;
- } else if ( lrc == -1 ) {
+ case -1:
/* we do not retry in this case;
* only for unique operations... */
ldap_get_option( msc->msc_ld,
rc = -1;
goto finish;
- } else if ( lrc == LDAP_RES_COMPARE ) {
+ default:
+ /* only touch when activity actually took place... */
+ /* NOTE: no mutex because there's only a loose requirement
+ * to bump it up... */
+ if ( mi->mi_idle_timeout != 0 && msc->msc_time < op->o_time ) {
+ msc->msc_time = op->o_time;
+ }
+ break;
+ }
+
+ if ( lrc == LDAP_RES_COMPARE ) {
if ( count > 0 ) {
rres = LDAP_OTHER;
rc = -1;
retry:;
rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
- if ( rc < 0 ) {
+ switch ( rc ) {
+ case -1:
rs->sr_err = LDAP_OTHER;
+ break;
- } else if ( rc == 0 ) {
+ case 0:
if ( nretries != 0 ) {
if ( nretries > 0 ) {
nretries--;
goto retry;
}
rs->sr_err = LDAP_OTHER;
+ break;
- } else if ( rc == LDAP_RES_EXTENDED ) {
+ default:
+ /* only touch when activity actually took place... */
+ if ( mi->mi_idle_timeout != 0 && msc->msc_time < op->o_time ) {
+ msc->msc_time = op->o_time;
+ }
+ break;
+ }
+
+ if ( rc == LDAP_RES_EXTENDED ) {
struct berval *data = NULL;
+ /* NOTE: right now, data is unused, so don't get it */
rs->sr_err = ldap_parse_extended_result( msc->msc_ld, res,
- NULL, &data, 0 );
+ NULL, NULL /* &data */ , 0 );
if ( rs->sr_err == LDAP_SUCCESS ) {
int err;
ldap_install_tls( msc->msc_ld );
} else if ( rs->sr_err == LDAP_REFERRAL ) {
+ /* FIXME: LDAP_OPERATIONS_ERROR? */
rs->sr_err = LDAP_OTHER;
rs->sr_text = "unwilling to chase referral returned by Start TLS exop";
}
meta_back_release_conn( op, mc );
}
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
- rs->sr_text = "Unable to select valid candidates";
+ if ( rs->sr_err == LDAP_SUCCESS ) {
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_text = "Unable to select valid candidates";
+ }
if ( sendok & LDAP_BACK_SENDERR ) {
if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
rc = ldap_result( msc->msc_ld, candidates[ i ].sr_msgid,
LDAP_MSG_ONE, &tv, &res );
- if ( rc == 0 ) {
+ switch ( rc ) {
+ case 0:
/* FIXME: res should not need to be freed */
assert( res == NULL );
continue;
- } else if ( rc == -1 ) {
+ case -1:
really_bad:;
/* something REALLY bad happened! */
if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
candidates[ i ].sr_msgid = META_MSGID_IGNORE;
--ncandidates;
rs->sr_err = candidates[ i ].sr_err;
+ continue;
+
+ default:
+ /* only touch when activity actually took place... */
+ if ( mi->mi_idle_timeout != 0 && msc->msc_time < op->o_time ) {
+ msc->msc_time = op->o_time;
+ }
+ break;
+ }
- } else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
+ if ( rc == LDAP_RES_SEARCH_ENTRY ) {
if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
/* don't retry any more... */
candidates[ i ].sr_type = REP_RESULT;
if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) {
meta_back_quarantine( op, &candidates[ i ], i );
}
+
+ /* only in case of timelimit exceeded, if the timelimit exceeded because
+ * one contacted target never responded, invalidate the connection
+ * NOTE: should we quarantine the target as well? right now, the connection
+ * is invalidated; the next time it will be recreated and the target
+ * will be quarantined if it cannot be contacted */
+ if ( mi->mi_idle_timeout != 0 && rs->sr_err == LDAP_TIMELIMIT_EXCEEDED && op->o_time > mc->mc_conns[ i ].msc_time )
+ {
+ /* don't let anyone else use this expired connection */
+ LDAP_BACK_CONN_TAINTED_SET( mc );
+ }
}
if ( mc ) {