From 828d55be4def7649155943ceec8a0c32d47cf76b Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 26 Aug 2006 15:24:49 +0000 Subject: [PATCH] invalidate idle connection if a candidate target does not respond for the duration of time limit... --- servers/slapd/back-meta/back-meta.h | 1 + servers/slapd/back-meta/bind.c | 10 ++++++++++ servers/slapd/back-meta/compare.c | 17 ++++++++++++++--- servers/slapd/back-meta/conn.c | 27 +++++++++++++++++++++------ servers/slapd/back-meta/search.c | 27 ++++++++++++++++++++++++--- 5 files changed, 70 insertions(+), 12 deletions(-) diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 21259ca637..c752a7d8d6 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -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; diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 9a3b8c8f33..b82ecd9ed5 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -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; diff --git a/servers/slapd/back-meta/compare.c b/servers/slapd/back-meta/compare.c index 7b9ab02430..05ea183e0b 100644 --- a/servers/slapd/back-meta/compare.c +++ b/servers/slapd/back-meta/compare.c @@ -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; diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 58d727d44c..99a03636ee 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -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 ) { diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 0a2efbeb53..463141d2b2 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -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; + + 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; @@ -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 ) { -- 2.39.5