From 55f12a7eee6e78edc94573923fa2eff13b79c987 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 1 Oct 2004 11:16:38 +0000 Subject: [PATCH] Add a retry for failed connections --- servers/slapd/back-ldap/add.c | 21 +++++++++--------- servers/slapd/back-ldap/back-ldap.h | 1 + servers/slapd/back-ldap/bind.c | 33 +++++++++++++++++++++++++++++ servers/slapd/back-ldap/compare.c | 20 ++++++++--------- servers/slapd/back-ldap/delete.c | 20 ++++++++--------- servers/slapd/back-ldap/extended.c | 14 ++++++++---- servers/slapd/back-ldap/modify.c | 18 +++++++++------- servers/slapd/back-ldap/modrdn.c | 20 ++++++++--------- servers/slapd/back-ldap/search.c | 10 +++++++++ 9 files changed, 104 insertions(+), 53 deletions(-) diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index d508c20bad..638acfa6b1 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -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; } diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 4420322286..00fe4da228 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -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); diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 3d8092d784..0bd908f5b0 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -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 diff --git a/servers/slapd/back-ldap/compare.c b/servers/slapd/back-ldap/compare.c index 6684c49846..635a2868d6 100644 --- a/servers/slapd/back-ldap/compare.c +++ b/servers/slapd/back-ldap/compare.c @@ -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; } diff --git a/servers/slapd/back-ldap/delete.c b/servers/slapd/back-ldap/delete.c index 9ae7dd45b5..9efc3fe932 100644 --- a/servers/slapd/back-ldap/delete.c +++ b/servers/slapd/back-ldap/delete.c @@ -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; } diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index 2661150224..5008de7acc 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -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; } diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index 71384ec924..891cc7038a 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -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; } diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c index 8c76a6bcb3..604325a542 100644 --- a/servers/slapd/back-ldap/modrdn.c +++ b/servers/slapd/back-ldap/modrdn.c @@ -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; } diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index e3dfa2e1df..b978982f25 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -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; -- 2.39.5