invalidate idle connection if a candidate target does not respond for the duration of time limit...

This commit is contained in:
Pierangelo Masarati 2006-08-26 15:24:49 +00:00
parent b7873dbb94
commit 828d55be4d
5 changed files with 70 additions and 12 deletions

View File

@ -174,6 +174,7 @@ typedef struct metasingleconn_t {
#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;

View File

@ -353,6 +353,11 @@ retry:;
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 );
@ -882,6 +887,11 @@ retry:;
* 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;

View File

@ -198,11 +198,12 @@ meta_back_compare( Operation *op, SlapReply *rs )
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,
@ -212,7 +213,17 @@ meta_back_compare( Operation *op, SlapReply *rs )
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;

View File

@ -347,10 +347,12 @@ meta_back_init_one_conn(
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--;
@ -359,12 +361,22 @@ retry:;
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;
@ -385,6 +397,7 @@ retry:;
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";
}
@ -1260,8 +1273,10 @@ retry_lock2:;
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 ) {

View File

@ -727,13 +727,14 @@ get_result:;
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 ) {
@ -785,8 +786,17 @@ really_bad:;
candidates[ i ].sr_msgid = META_MSGID_IGNORE;
--ncandidates;
rs->sr_err = candidates[ i ].sr_err;
continue;
} else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
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_SEARCH_ENTRY ) {
if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
/* don't retry any more... */
candidates[ i ].sr_type = REP_RESULT;
@ -1311,6 +1321,17 @@ finish:;
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 ) {