From 6995603a3d780bfd03e6e644dd216e1d0aebeb5f Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 9 Jan 2006 14:20:37 +0000 Subject: [PATCH] refine fix to ITS#4315; apply it to back-meta as well --- servers/slapd/back-ldap/bind.c | 14 ++++---- servers/slapd/back-meta/bind.c | 2 +- servers/slapd/back-meta/conn.c | 60 +++++++++++++++++++++++----------- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 8fb0a7ad08..e8dc09a830 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -468,7 +468,7 @@ ldapconn_t * ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - ldapconn_t *lc, + ldapconn_t *lc = NULL, lc_curr = { 0 }; int refcnt = 1; @@ -490,9 +490,7 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) } /* Explicit Bind requests always get their own conn */ - if ( sendok & LDAP_BACK_BINDING ) { - lc = NULL; - } else { + if ( !( sendok & LDAP_BACK_BINDING ) ) { /* Searches for a ldapconn in the avl tree */ retry_lock: ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); @@ -500,13 +498,13 @@ retry_lock: lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ); if ( lc != NULL ) { - refcnt = ++lc->lc_refcnt; /* Don't reuse connections while they're still binding */ - if ( LDAP_BACK_CONN_BINDING( lc )) { + if ( LDAP_BACK_CONN_BINDING( lc ) ) { ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); ldap_pvt_thread_yield(); goto retry_lock; } + refcnt = ++lc->lc_refcnt; } ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); } @@ -516,9 +514,9 @@ retry_lock: if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) { return NULL; } - if ( sendok & LDAP_BACK_BINDING ) + if ( sendok & LDAP_BACK_BINDING ) { LDAP_BACK_CONN_BINDING_SET( lc ); - + } lc->lc_conn = lc_curr.lc_conn; ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn ); diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 54c669e7fc..cc2b5bcb99 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -91,7 +91,7 @@ meta_back_bind( Operation *op, SlapReply *rs ) /* we need meta_back_getconn() not send result even on error, * because we want to intercept the error and make it * invalidCredentials */ - mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_DONTSEND ); + mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_SERR ); if ( !mc ) { char buf[ SLAP_TEXT_BUFLEN ]; diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index b92b285f28..08fcbea92c 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -755,21 +755,31 @@ meta_back_getconn( } } - /* Searches for a metaconn in the avl tree */ - ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); - mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, - (caddr_t)&mc_curr, meta_back_conn_cmp ); - if ( mc ) { - if ( mc->mc_tainted ) { - rs->sr_err = LDAP_UNAVAILABLE; - rs->sr_text = "remote server unavailable"; - ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); - return NULL; - } + /* Explicit Bind requests always get their own conn */ + if ( !( sendok & LDAP_BACK_BINDING ) ) { + /* Searches for a metaconn in the avl tree */ +retry_lock: + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, + (caddr_t)&mc_curr, meta_back_conn_cmp ); + if ( mc ) { + if ( mc->mc_tainted ) { + rs->sr_err = LDAP_UNAVAILABLE; + rs->sr_text = "remote server unavailable"; + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); + return NULL; + } - mc->mc_refcnt++; + /* Don't reuse connections while they're still binding */ + if ( LDAP_BACK_CONN_BINDING( mc ) ) { + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); + ldap_pvt_thread_yield(); + goto retry_lock; + } + mc->mc_refcnt++; + } + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); } - ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); switch ( op->o_tag ) { case LDAP_REQ_ADD: @@ -822,6 +832,9 @@ meta_back_getconn( mc->mc_conn = mc_curr.mc_conn; ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn ); new_conn = 1; + if ( sendok & LDAP_BACK_BINDING ) { + LDAP_BACK_CONN_BINDING_SET( mc ); + } } for ( i = 0; i < mi->mi_ntargets; i++ ) { @@ -947,13 +960,15 @@ meta_back_getconn( /* Retries searching for a metaconn in the avl tree * the reason is that the connection might have been * created by meta_back_get_candidate() */ - ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); - mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, - (caddr_t)&mc_curr, meta_back_conn_cmp ); - if ( mc != NULL ) { - mc->mc_refcnt++; + if ( !( sendok & LDAP_BACK_BINDING ) ) { + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, + (caddr_t)&mc_curr, meta_back_conn_cmp ); + if ( mc != NULL ) { + mc->mc_refcnt++; + } + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); } - ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); /* Looks like we didn't get a bind. Open a new session... */ if ( mc == NULL ) { @@ -961,6 +976,9 @@ meta_back_getconn( mc->mc_conn = mc_curr.mc_conn; ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn ); new_conn = 1; + if ( sendok & LDAP_BACK_BINDING ) { + LDAP_BACK_CONN_BINDING_SET( mc ); + } } } @@ -1015,6 +1033,9 @@ meta_back_getconn( mc->mc_conn = mc_curr.mc_conn; ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn ); new_conn = 1; + if ( sendok & LDAP_BACK_BINDING ) { + LDAP_BACK_CONN_BINDING_SET( mc ); + } } for ( i = 0; i < mi->mi_ntargets; i++ ) { @@ -1165,6 +1186,7 @@ meta_back_release_conn( ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); assert( mc->mc_refcnt > 0 ); mc->mc_refcnt--; + LDAP_BACK_CONN_BINDING_CLEAR( mc ); if ( mc->mc_refcnt == 0 && mc->mc_tainted ) { (void)avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc, meta_back_conn_cmp ); -- 2.39.5