meta_back_conndn_cmp );
assert( tmpmc == mc );
+ /* delete all cached connections with the current connection */
+ if ( LDAP_BACK_SINGLECONN( mi ) ) {
+ while ( ( tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp ) ) != NULL )
+ {
+ Debug( LDAP_DEBUG_TRACE,
+ "=>meta_back_bind: destroying conn %ld (refcnt=%u)\n",
+ LDAP_BACK_PCONN_ID( mc->mc_conn ), mc->mc_refcnt, 0 );
+
+ if ( mc->mc_refcnt != 0 ) {
+ /* taint it */
+ LDAP_BACK_CONN_TAINTED_SET( tmpmc );
+
+ } else {
+ /*
+ * Needs a test because the handler may be corrupted,
+ * and calling ldap_unbind on a corrupted header results
+ * in a segmentation fault
+ */
+ meta_back_conn_free( tmpmc );
+ }
+ }
+ }
+
ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
meta_back_conndn_cmp, meta_back_conndn_dup );
return 1;
}
+ /* single-conn? */
+ } else if ( strcasecmp( argv[ 0 ], "single-conn" ) == 0 ) {
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"single-conn {FALSE|true}\" takes 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( mi->mi_ntargets > 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"single-conn\" must appear before target definitions\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ switch ( check_true_false( argv[ 1 ] ) ) {
+ case 0:
+ mi->mi_flags &= ~LDAP_BACK_F_SINGLECONN;
+ break;
+
+ case 1:
+ mi->mi_flags |= LDAP_BACK_F_SINGLECONN;
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"single-conn {FALSE|true}\": invalid arg \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+
} else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
char *sep;
time_t *tv = mi->mi_ntargets ?
/*
* Set PRINT_CONNTREE larger than 0 to dump the connection tree (debug only)
*/
+#ifndef PRINT_CONNTREE
#define PRINT_CONNTREE 0
+#endif /* !PRINT_CONNTREE */
/*
* meta_back_conndn_cmp
ravl_print( Avlnode *root, int depth )
{
int i;
- metaconn_t *mc = (metaconn_t *)root->avl_data;
+ metaconn_t *mc;
if ( root == 0 ) {
return;
ravl_print( root->avl_right, depth + 1 );
for ( i = 0; i < depth; i++ ) {
- printf( " " );
+ fprintf( stderr, "-" );
}
- printf( "c(%d%s%s) %d\n",
- LDAP_BACK_PCONN_ID( mc->mc_conn ),
- BER_BVISNULL( &mc->mc_local_ndn ) ? "" : ": ",
- BER_BVISNULL( &mc->mc_local_ndn ) ? "" : mc->mc_local_ndn.bv_val,
- root->avl_bf );
+ mc = (metaconn_t *)root->avl_data;
+ fprintf( stderr, "mc=%p local=\"%s\" conn=%p %s refcnt=%d\n",
+ (void *)mc,
+ mc->mc_local_ndn.bv_val ? mc->mc_local_ndn.bv_val : "",
+ (void *)mc->mc_conn,
+ avl_bf2str( root->avl_bf ), mc->mc_refcnt );
ravl_print( root->avl_left, depth + 1 );
}
static void
-myprint( Avlnode *root )
+myprint( Avlnode *root, char *msg )
{
- printf( "********\n" );
+ fprintf( stderr, "========> %s\n", msg );
if ( root == 0 ) {
- printf( "\tNULL\n" );
+ fprintf( stderr, "\tNULL\n" );
+
} else {
ravl_print( root, 0 );
}
- printf( "********\n" );
+ fprintf( stderr, "<======== %s\n", msg );
}
#endif /* PRINT_CONNTREE */
/*
meta_back_conndn_cmp, meta_back_conndn_dup );
#if PRINT_CONNTREE > 0
- myprint( mi->mi_conninfo.lai_tree );
+ myprint( mi->mi_conninfo.lai_tree, "meta_back_getconn" );
#endif /* PRINT_CONNTREE */
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );