]> git.sur5r.net Git - openldap/commitdiff
Add a retry for failed connections
authorHoward Chu <hyc@openldap.org>
Fri, 1 Oct 2004 11:16:38 +0000 (11:16 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 1 Oct 2004 11:16:38 +0000 (11:16 +0000)
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/compare.c
servers/slapd/back-ldap/delete.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/modrdn.c
servers/slapd/back-ldap/search.c

index d508c20bad9dac9c4824ad4ef077b5f8dd625e6c..638acfa6b11a874f374214612dfc5bc6758aacbc 100644 (file)
@@ -46,10 +46,9 @@ ldap_back_add(
        ber_int_t msgid;
        dncookie dc;
        int isupdate;
+       int do_retry = 1;
        LDAPControl **ctrls = NULL;
-#ifdef LDAP_BACK_PROXY_AUTHZ 
        int rc = LDAP_SUCCESS;
-#endif /* LDAP_BACK_PROXY_AUTHZ */
 
        Debug(LDAP_DEBUG_ARGS, "==> ldap_back_add: %s\n", op->o_req_dn.bv_val, 0, 0);
        
@@ -128,13 +127,20 @@ ldap_back_add(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_add_ext(lc->ld, mdn.bv_val, attrs,
                        ctrls, NULL, &msgid);
-
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
        if ( ctrls && ctrls != op->o_ctrls ) {
@@ -142,7 +148,6 @@ cleanup:
                free( ctrls );
        } 
 #endif /* LDAP_BACK_PROXY_AUTHZ */
-
        for (--i; i>= 0; --i) {
                ch_free(attrs[i]->mod_vals.modv_bvals);
                ch_free(attrs[i]);
@@ -151,12 +156,6 @@ cleanup:
        if ( mdn.bv_val != op->o_req_dn.bv_val ) {
                free( mdn.bv_val );
        }
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-       return ldap_back_op_result( lc, op, rs, msgid, 1 ) != LDAP_SUCCESS;
+       return rc;
 }
 
index 44203222865cdaf0c3aea843134e6d2293dd0179..00fe4da2280fe1986e0de1f40255b4004cfb9eb4 100644 (file)
@@ -167,6 +167,7 @@ typedef struct dncookie {
 int ldap_back_freeconn( Operation *op, struct ldapconn *lc );
 struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs);
 int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs);
+int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs);
 int ldap_back_map_result(SlapReply *rs);
 int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
        ber_int_t msgid, int sendok);
index 3d8092d7842c06ebdaba328986e266d970878ec5..0bd908f5b01b25951d022c5a5ffb4432eccbcb30 100644 (file)
@@ -711,6 +711,39 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
        return( ERR_OK( rs->sr_err ) ? 0 : -1 );
 }
 
+/* return true if bound, false if failed */
+int
+ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs )
+{
+       struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+       int vers = op->o_protocol;
+       LDAP *ld;
+
+       ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
+       ldap_unbind( lc->ld );
+       lc->bound = 0;
+       rs->sr_err = ldap_initialize(&ld, li->url);
+               
+       if (rs->sr_err != LDAP_SUCCESS) {
+               rs->sr_err = slap_map_api2result( rs );
+               if (rs->sr_text == NULL) {
+                       rs->sr_text = "ldap_initialize() failed";
+               }
+               if (op->o_conn) send_ldap_result( op, rs );
+               rs->sr_text = NULL;
+               return 0;
+       }
+       /* Set LDAP version. This will always succeed: If the client
+        * bound with a particular version, then so can we.
+        */
+       ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers);
+       /* FIXME: configurable? */
+       ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON);
+       lc->ld = ld;
+       ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
+       return ldap_back_dobind( lc, op, rs );
+}
+
 #ifdef LDAP_BACK_PROXY_AUTHZ
 /*
  * ldap_back_proxy_authz_ctrl() prepends a proxyAuthz control
index 6684c4984653e01d9c0221cd509442492d8996f8..635a2868d661f538d5f3be89d56a4ecc30fcd1b2 100644 (file)
@@ -42,11 +42,10 @@ ldap_back_compare(
        struct berval mdn = BER_BVNULL;
        ber_int_t msgid;
        int freeval = 0;
+       int do_retry = 1;
        dncookie dc;
        LDAPControl **ctrls = NULL;
-#ifdef LDAP_BACK_PROXY_AUTHZ 
        int rc = LDAP_SUCCESS;
-#endif /* LDAP_BACK_PROXY_AUTHZ */
 
        lc = ldap_back_getconn(op, rs);
        if (!lc || !ldap_back_dobind( lc, op, rs ) ) {
@@ -104,13 +103,21 @@ ldap_back_compare(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_compare_ext( lc->ld, mdn.bv_val,
                        mapped_at.bv_val, &mapped_val, 
                        ctrls, NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
@@ -126,12 +133,5 @@ cleanup:
        if ( freeval ) {
                free( mapped_val.bv_val );
        }
-
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-       return( ldap_back_op_result( lc, op, rs, msgid, 1 ) );
+       return rc;
 }
index 9ae7dd45b5d58fbc8ecfe4e3d55d6765d2ee0ab6..9efc3fe9322ea2fd1953fa284f4a0048550586f2 100644 (file)
@@ -41,9 +41,8 @@ ldap_back_delete(
        ber_int_t msgid;
        dncookie dc;
        LDAPControl **ctrls = NULL;
-#ifdef LDAP_BACK_PROXY_AUTHZ 
+       int do_retry = 1;
        int rc = LDAP_SUCCESS;
-#endif /* LDAP_BACK_PROXY_AUTHZ */
 
        struct berval mdn = BER_BVNULL;
 
@@ -74,12 +73,20 @@ ldap_back_delete(
        ctrls = op->o_ctrls;
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_delete_ext( lc->ld, mdn.bv_val,
                        ctrls, NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
@@ -93,12 +100,5 @@ cleanup:
                free( mdn.bv_val );
        }
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-       return( ldap_back_op_result( lc, op, rs, msgid, 1 ) );
+       return rc;
 }
index 2661150224394265ef18a81f4fccd36423ae27ea..5008de7acc2e33ec2fb7bdcb848227ca41cf0090 100644 (file)
@@ -100,6 +100,7 @@ ldap_back_exop_passwd(
        LDAPMessage *res;
        ber_int_t msgid;
        int rc, isproxy;
+       int do_retry = 1;
        dncookie dc;
 
        lc = ldap_back_getconn(op, rs);
@@ -128,15 +129,12 @@ ldap_back_exop_passwd(
                }
        }
 
+retry:
        rc = ldap_passwd(lc->ld, isproxy ? &mdn : NULL,
                qpw->rs_old.bv_val ? &qpw->rs_old : NULL,
                qpw->rs_new.bv_val ? &qpw->rs_new : NULL,
                op->o_ctrls, NULL, &msgid);
 
-       if (mdn.bv_val != op->o_req_dn.bv_val) {
-               free(mdn.bv_val);
-       }
-
        if (rc == LDAP_SUCCESS) {
                if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
                        ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc);
@@ -166,6 +164,10 @@ ldap_back_exop_passwd(
        }
        if (rc != LDAP_SUCCESS) {
                rs->sr_err = slap_map_api2result( rs );
+               if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+                       do_retry = 0;
+                       if ( ldap_back_retry (lc, op, rs )) goto retry;
+               }
                send_ldap_result(op, rs);
                if (rs->sr_matched) free((char *)rs->sr_matched);
                if (rs->sr_text) free((char *)rs->sr_text);
@@ -173,5 +175,9 @@ ldap_back_exop_passwd(
                rs->sr_text = NULL;
                rc = -1;
        }
+       if (mdn.bv_val != op->o_req_dn.bv_val) {
+               free(mdn.bv_val);
+       }
+
        return rc;
 }
index 71384ec9242bda59008a5f0f6161dde315609194..891cc7038ace2de3d6159d4ef42cf13bed2237a2 100644 (file)
@@ -47,6 +47,7 @@ ldap_back_modify(
        ber_int_t msgid;
        dncookie dc;
        int isupdate;
+       int do_retry = 1;
        LDAPControl **ctrls = NULL;
 
        lc = ldap_back_getconn(op, rs);
@@ -161,12 +162,20 @@ ldap_back_modify(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_modify_ext( lc->ld, mdn.bv_val, modv,
                        ctrls, NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 cleanup:;
 #ifdef LDAP_BACK_PROXY_AUTHZ
@@ -185,13 +194,6 @@ cleanup:;
        ch_free( mods );
        ch_free( modv );
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-       return ldap_back_op_result( lc, op, rs, msgid, 1 );
+       return rc;
 }
 
index 8c76a6bcb3f3680add54952bee0588db1cb93995..604325a54212244f3bd6bc98723ce6810cc17084 100644 (file)
@@ -41,9 +41,8 @@ ldap_back_modrdn(
        ber_int_t msgid;
        dncookie dc;
        LDAPControl **ctrls = NULL;
-#ifdef LDAP_BACK_PROXY_AUTHZ 
+       int do_retry = 1;
        int rc = LDAP_SUCCESS;
-#endif /* LDAP_BACK_PROXY_AUTHZ */
 
        struct berval mdn = BER_BVNULL, mnewSuperior = BER_BVNULL;
 
@@ -92,15 +91,23 @@ ldap_back_modrdn(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_rename( lc->ld, mdn.bv_val,
                        op->orr_newrdn.bv_val, mnewSuperior.bv_val,
                        op->orr_deleteoldrdn,
                        ctrls,
                        NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
@@ -118,13 +125,6 @@ cleanup:
                free( mnewSuperior.bv_val );
        }
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-       return( ldap_back_op_result( lc, op, rs, msgid, 1 ) );
+       return rc;
 }
 
index e3dfa2e1dfd054b0b3d9aa748207effdfe6d41c9..b978982f2540a22b14355560c6b0b5c6e4e4a670 100644 (file)
@@ -57,6 +57,7 @@ ldap_back_search(
        struct berval mfilter = BER_BVNULL;
        int dontfreetext = 0;
        int freeconn = 0;
+       int do_retry = 1;
        dncookie dc;
        LDAPControl **ctrls = NULL;
 
@@ -141,6 +142,7 @@ ldap_back_search(
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
        
+retry:
        rs->sr_err = ldap_search_ext( lc->ld, mbase.bv_val,
                        op->ors_scope, mfilter.bv_val,
                        mapped_attrs, op->ors_attrsonly,
@@ -181,6 +183,8 @@ fail:;
                        Entry ent = {0};
                        struct berval bdn;
                        int abort = 0;
+                       do_retry = 0;
+
                        e = ldap_first_entry( lc->ld, res );
                        rc = ldap_build_entry( op, e, &ent, &bdn,
                                        LDAP_BUILD_ENTRY_PRIVATE );
@@ -222,6 +226,7 @@ fail:;
                        char            **references = NULL;
                        int             cnt;
 
+                       do_retry = 0;
                        rc = ldap_parse_reference( lc->ld, res,
                                        &references, &rs->sr_ctrls, 1 );
 
@@ -271,6 +276,11 @@ fail:;
        }
 
        if ( rc == -1 ) {
+               if ( do_retry ) {
+                       do_retry = 0;
+                       if ( ldap_back_retry( lc, op, rs ))
+                               goto retry;
+               }
                /* FIXME: invalidate the connection? */
                rs->sr_err = LDAP_SERVER_DOWN;
                freeconn = 1;