]> git.sur5r.net Git - openldap/commitdiff
invalidate idle connection if a candidate target does not respond for the duration...
authorPierangelo Masarati <ando@openldap.org>
Sat, 26 Aug 2006 15:24:49 +0000 (15:24 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 26 Aug 2006 15:24:49 +0000 (15:24 +0000)
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/search.c

index 21259ca6378402ac4f09e5b66a6acb2bdb45ea1a..c752a7d8d69205197ddf6c02ef857c0fa8b49007 100644 (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;
index 9a3b8c8f33fc6d7340397790ce2c250862559522..b82ecd9ed5bcda10783ba0539caed929a52d4ebe 100644 (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;
index 7b9ab0243034f68a87dff31c36fbf5db2960077a..05ea183e0bac81fc3242eb3d2173007e713d1962 100644 (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;
index 58d727d44c55465942aec0f933b197d041d17bd4..99a03636eec2a0efa86ea328797a01fe8b97710f 100644 (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 ) {
index 0a2efbeb53d24e17f4445cb3bedc987fd9ddc0d0..463141d2b2edb6110dd4dd5cb3062356eaca4cc9 100644 (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;
+
+                       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 ) {