Commit 7d7f0e1d authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

Connection code refactoring

parent 15828a87
......@@ -61,11 +61,11 @@ enum {
LDAP_BACK_PCONN_LAST
};
typedef struct ldapconn_t {
Connection *lc_conn;
typedef struct ldapconn_base_t {
Connection *lcb_conn;
#define LDAP_BACK_CONN2PRIV(lc) ((unsigned long)(lc)->lc_conn)
#define LDAP_BACK_PCONN_ISPRIV(lc) ((void *)(lc)->lc_conn >= (void *)LDAP_BACK_PCONN_FIRST \
&& (void *)(lc)->lc_conn < (void *)LDAP_BACK_PCONN_LAST)
#define LDAP_BACK_PCONN_ISPRIV(lc) (((void *)(lc)->lc_conn) >= ((void *)LDAP_BACK_PCONN_FIRST) \
&& ((void *)(lc)->lc_conn) < ((void *)LDAP_BACK_PCONN_LAST))
#define LDAP_BACK_PCONN_ISROOTDN(lc) (LDAP_BACK_PCONN_ISPRIV((lc)) \
&& (LDAP_BACK_CONN2PRIV((lc)) < LDAP_BACK_PCONN_ANON))
#define LDAP_BACK_PCONN_ISANON(lc) (LDAP_BACK_PCONN_ISPRIV((lc)) \
......@@ -75,8 +75,6 @@ typedef struct ldapconn_t {
&& (LDAP_BACK_CONN2PRIV((lc)) >= LDAP_BACK_PCONN_BIND))
#define LDAP_BACK_PCONN_ISTLS(lc) (LDAP_BACK_PCONN_ISPRIV((lc)) \
&& (LDAP_BACK_CONN2PRIV((lc)) & LDAP_BACK_PCONN_TLS))
#define LDAP_BACK_PCONN_ID(lc) (LDAP_BACK_PCONN_ISPRIV((lc)) ? \
( -1 - (long)(lc)->lc_conn ) : (lc)->lc_conn->c_connid )
#ifdef HAVE_TLS
#define LDAP_BACK_PCONN_ROOTDN_SET(lc, op) \
((lc)->lc_conn = (void *)((op)->o_conn->c_is_tls ? (void *) LDAP_BACK_PCONN_ROOTDN_TLS : (void *) LDAP_BACK_PCONN_ROOTDN))
......@@ -96,10 +94,22 @@ typedef struct ldapconn_t {
(BER_BVISEMPTY(&(op)->o_ndn) ? \
LDAP_BACK_PCONN_ANON_SET((lc), (op)) : LDAP_BACK_PCONN_ROOTDN_SET((lc), (op)))
LDAP *lc_ld;
struct berval lc_cred;
struct berval lc_bound_ndn;
struct berval lc_local_ndn;
struct berval lcb_local_ndn;
unsigned lcb_refcnt;
time_t lcb_create_time;
time_t lcb_time;
} ldapconn_base_t;
typedef struct ldapconn_t {
ldapconn_base_t lc_base;
#define lc_conn lc_base.lcb_conn
#define lc_local_ndn lc_base.lcb_local_ndn
#define lc_refcnt lc_base.lcb_refcnt
#define lc_create_time lc_base.lcb_create_time
#define lc_time lc_base.lcb_time
LDAP_TAILQ_ENTRY(ldapconn_t) lc_q;
unsigned lc_lcflags;
#define LDAP_BACK_CONN_ISSET_F(fp,f) (*(fp) & (f))
#define LDAP_BACK_CONN_SET_F(fp,f) (*(fp) |= (f))
......@@ -164,12 +174,10 @@ typedef struct ldapconn_t {
#define LDAP_BACK_CONN_CACHED_SET(lc) LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_CACHED)
#define LDAP_BACK_CONN_CACHED_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_CACHED)
unsigned lc_refcnt;
LDAP *lc_ld;
struct berval lc_cred;
struct berval lc_bound_ndn;
unsigned lc_flags;
time_t lc_create_time;
time_t lc_time;
LDAP_TAILQ_ENTRY(ldapconn_t) lc_q;
} ldapconn_t;
typedef struct ldap_avl_info_t {
......@@ -444,6 +452,7 @@ typedef struct ldap_extra_t {
void (*retry_info_destroy)( slap_retry_info_t *ri );
int (*retry_info_parse)( char *in, slap_retry_info_t *ri, char *buf, ber_len_t buflen );
int (*retry_info_unparse)( slap_retry_info_t *ri, struct berval *bvout );
int (*connid2str)( const ldapconn_base_t *lc, char *buf, ber_len_t buflen );
} ldap_extra_t;
LDAP_END_DECL
......
......@@ -40,6 +40,45 @@
#define LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ "2.16.840.1.113730.3.4.12"
#if LDAP_BACK_PRINT_CONNTREE > 0
static const struct {
slap_mask_t f;
char c;
} flagsmap[] = {
{ LDAP_BACK_FCONN_ISBOUND, 'B' },
{ LDAP_BACK_FCONN_ISANON, 'A' },
{ LDAP_BACK_FCONN_ISPRIV, 'P' },
{ LDAP_BACK_FCONN_ISTLS, 'T' },
{ LDAP_BACK_FCONN_BINDING, 'X' },
{ LDAP_BACK_FCONN_TAINTED, 'E' },
{ LDAP_BACK_FCONN_ABANDON, 'N' },
{ LDAP_BACK_FCONN_ISIDASR, 'S' },
{ LDAP_BACK_FCONN_CACHED, 'C' },
{ 0, '\0' }
};
static void
ldap_back_conn_print( ldapconn_t *lc, const char *avlstr )
{
char buf[ SLAP_TEXT_BUFLEN ];
char fbuf[ sizeof("BAPTIENSC") ];
int i;
ldap_back_conn2str( &lc->lc_base, buf, sizeof( buf ) );
for ( i = 0; flagsmap[ i ].c != '\0'; i++ ) {
if ( lc->lc_lcflags & flagsmap[i].f ) {
fbuf[i] = flagsmap[i].c;
} else {
fbuf[i] = '.';
}
}
fbuf[i] = '\0';
fprintf( stderr, "lc=%p %s %s flags=0x%08x (%s)\n",
(void *)lc, buf, avlstr, lc->lc_lcflags, fbuf );
}
static void
ldap_back_ravl_print( Avlnode *root, int depth )
{
......@@ -57,13 +96,9 @@ ldap_back_ravl_print( Avlnode *root, int depth )
}
lc = root->avl_data;
fprintf( stderr, "lc=%p local=\"%s\" conn=%p %s refcnt=%d flags=0x%08x\n",
(void *)lc,
lc->lc_local_ndn.bv_val ? lc->lc_local_ndn.bv_val : "",
(void *)lc->lc_conn,
avl_bf2str( root->avl_bf ), lc->lc_refcnt, lc->lc_lcflags );
ldap_back_ravl_print( root->avl_left, depth+1 );
ldap_back_conn_print( lc, avl_bf2str( root->avl_bf ) );
ldap_back_ravl_print( root->avl_left, depth + 1 );
}
static char* priv2str[] = {
......@@ -91,11 +126,8 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg )
LDAP_TAILQ_FOREACH( lc, &li->li_conn_priv[ c ].lic_priv, lc_q )
{
fprintf( stderr, " [%d] lc=%p local=\"%s\" conn=%p refcnt=%d flags=0x%08x\n",
i,
(void *)lc,
lc->lc_local_ndn.bv_val ? lc->lc_local_ndn.bv_val : "",
(void *)lc->lc_conn, lc->lc_refcnt, lc->lc_lcflags );
fprintf( stderr, " [%d] ", i );
ldap_back_conn_print( lc, "" );
i++;
}
}
......@@ -303,9 +335,10 @@ retry_lock:;
if ( LDAP_BACK_SINGLECONN( li ) ) {
while ( ( tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ) ) != NULL )
{
assert( !LDAP_BACK_PCONN_ISPRIV( lc ) );
Debug( LDAP_DEBUG_TRACE,
"=>ldap_back_bind: destroying conn %ld (refcnt=%u)\n",
LDAP_BACK_PCONN_ID( lc ), lc->lc_refcnt, 0 );
"=>ldap_back_bind: destroying conn %lu (refcnt=%u)\n",
lc->lc_conn->c_connid, lc->lc_refcnt, 0 );
if ( tmplc->lc_refcnt != 0 ) {
/* taint it */
......@@ -631,7 +664,7 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_
LDAP *ld = NULL;
#ifdef HAVE_TLS
int is_tls = op->o_conn->c_is_tls;
time_t lc_time = (time_t)(-1);
time_t lctime = (time_t)(-1);
slap_bindconf *sb;
#endif /* HAVE_TLS */
......@@ -704,7 +737,7 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_
} else if ( li->li_idle_timeout ) {
/* only touch when activity actually took place... */
lc_time = op->o_time;
lctime = op->o_time;
}
#endif /* HAVE_TLS */
......@@ -716,8 +749,8 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_
} else {
LDAP_BACK_CONN_ISTLS_CLEAR( lc );
}
if ( lc_time != (time_t)(-1) ) {
lc->lc_time = lc_time;
if ( lctime != (time_t)(-1) ) {
lc->lc_time = lctime;
}
#endif /* HAVE_TLS */
......@@ -750,7 +783,7 @@ ldap_back_getconn(
{
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
ldapconn_t *lc = NULL,
lc_curr = { 0 };
lc_curr = {{ 0 }};
int refcnt = 1,
lookupconn = !( sendok & LDAP_BACK_BINDING );
......@@ -2714,3 +2747,84 @@ ldap_back_controls_free( Operation *op, SlapReply *rs, LDAPControl ***pctrls )
return 0;
}
int
ldap_back_conn2str( const ldapconn_base_t *lc, char *buf, ber_len_t buflen )
{
char tbuf[ SLAP_TEXT_BUFLEN ];
char *ptr = buf, *end = buf + buflen;
int len;
if ( ptr + sizeof("conn=") > end ) return -1;
ptr = lutil_strcopy( ptr, "conn=" );
len = ldap_back_connid2str( lc, ptr, (ber_len_t)(end - ptr) );
ptr += len;
if ( ptr >= end ) return -1;
if ( !BER_BVISNULL( &lc->lcb_local_ndn ) ) {
if ( ptr + sizeof(" DN=\"\"") + lc->lcb_local_ndn.bv_len > end ) return -1;
ptr = lutil_strcopy( ptr, " DN=\"" );
ptr = lutil_strncopy( ptr, lc->lcb_local_ndn.bv_val, lc->lcb_local_ndn.bv_len );
*ptr++ = '"';
}
if ( lc->lcb_create_time != 0 ) {
len = snprintf( tbuf, sizeof(tbuf), "%ld", lc->lcb_create_time );
if ( ptr + sizeof(" created=") + len >= end ) return -1;
ptr = lutil_strcopy( ptr, " created=" );
ptr = lutil_strcopy( ptr, tbuf );
}
if ( lc->lcb_time != 0 ) {
len = snprintf( tbuf, sizeof(tbuf), "%ld", lc->lcb_time );
if ( ptr + sizeof(" modified=") + len >= end ) return -1;
ptr = lutil_strcopy( ptr, " modified=" );
ptr = lutil_strcopy( ptr, tbuf );
}
len = snprintf( tbuf, sizeof(tbuf), "%u", lc->lcb_refcnt );
if ( ptr + sizeof(" refcnt=") + len >= end ) return -1;
ptr = lutil_strcopy( ptr, " refcnt=" );
ptr = lutil_strcopy( ptr, tbuf );
return ptr - buf;
}
int
ldap_back_connid2str( const ldapconn_base_t *lc, char *buf, ber_len_t buflen )
{
static struct berval conns[] = {
BER_BVC("ROOTDN"),
BER_BVC("ROOTDN-TLS"),
BER_BVC("ANON"),
BER_BVC("ANON-TLS"),
BER_BVC("BIND"),
BER_BVC("BIND-TLS"),
BER_BVNULL
};
int len = 0;
if ( LDAP_BACK_PCONN_ISPRIV( (const ldapconn_t *)lc ) ) {
long cid;
struct berval *bv;
cid = (long)lc->lcb_conn;
assert( cid >= LDAP_BACK_PCONN_FIRST && cid < LDAP_BACK_PCONN_LAST );
bv = &conns[ cid ];
if ( bv->bv_len >= buflen ) {
return bv->bv_len + 1;
}
len = bv->bv_len;
lutil_strncopy( buf, bv->bv_val, bv->bv_len + 1 );
} else {
len = snprintf( buf, buflen, "%lu", lc->lcb_conn->c_connid );
}
return len;
}
......@@ -2063,7 +2063,6 @@ int
chain_initialize( void )
{
int rc;
const char *text;
/* Make sure we don't exceed the bits reserved for userland */
config_check_userland( CH_LAST );
......
......@@ -39,7 +39,8 @@ static const ldap_extra_t ldap_extra = {
slap_idassert_parse_cf,
slap_retry_info_destroy,
slap_retry_info_parse,
slap_retry_info_unparse
slap_retry_info_unparse,
ldap_back_connid2str
};
int
......
......@@ -63,6 +63,9 @@ extern void ldap_back_conn_free( void *c );
extern ldapconn_t * ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc );
extern int ldap_back_conn2str( const ldapconn_base_t *lc, char *buf, ber_len_t buflen );
extern int ldap_back_connid2str( const ldapconn_base_t *lc, char *buf, ber_len_t buflen );
extern int
ldap_back_proxy_authz_ctrl(
Operation *op,
......
......@@ -53,11 +53,11 @@ ldap_back_conn_destroy(
#endif /* LDAP_BACK_PRINT_CONNTREE */
while ( ( lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ) ) != NULL )
{
assert( !LDAP_BACK_PCONN_ISPRIV( lc ) );
Debug( LDAP_DEBUG_TRACE,
"=>ldap_back_conn_destroy: destroying conn %ld "
"=>ldap_back_conn_destroy: destroying conn %lu "
"refcnt=%d flags=0x%08x\n",
LDAP_BACK_PCONN_ID( lc ),
lc->lc_refcnt, lc->lc_lcflags );
lc->lc_conn->c_connid, lc->lc_refcnt, lc->lc_lcflags );
if ( lc->lc_refcnt > 0 ) {
/* someone else might be accessing the connection;
......
......@@ -221,14 +221,16 @@ typedef struct metasingleconn_t {
} metasingleconn_t;
typedef struct metaconn_t {
Connection *mc_conn;
#define lc_conn mc_conn
unsigned mc_refcnt;
time_t mc_create_time;
time_t mc_time;
ldapconn_base_t lc_base;
#define mc_base lc_base
#define mc_conn mc_base.lcb_conn
#define mc_local_ndn mc_base.lcb_local_ndn
#define mc_refcnt mc_base.lcb_refcnt
#define mc_create_time mc_base.lcb_create_time
#define mc_time mc_base.lcb_time
struct berval mc_local_ndn;
LDAP_TAILQ_ENTRY(metaconn_t) mc_q;
/* NOTE: msc_mscflags is used to recycle the #define
* in metasingleconn_t */
unsigned msc_mscflags;
......@@ -243,8 +245,6 @@ typedef struct metaconn_t {
struct metainfo_t *mc_info;
LDAP_TAILQ_ENTRY(metaconn_t) mc_q;
/* supersedes the connection stuff */
metasingleconn_t mc_conns[ 1 ];
/* NOTE: mc_conns must be last, because
......
......@@ -223,9 +223,10 @@ meta_back_bind( Operation *op, SlapReply *rs )
while ( ( tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp ) ) != NULL )
{
assert( !LDAP_BACK_PCONN_ISPRIV( mc ) );
Debug( LDAP_DEBUG_TRACE,
"=>meta_back_bind: destroying conn %ld (refcnt=%u)\n",
LDAP_BACK_PCONN_ID( mc ), mc->mc_refcnt, 0 );
"=>meta_back_bind: destroying conn %lu (refcnt=%u)\n",
mc->mc_conn->c_connid, mc->mc_refcnt, 0 );
if ( tmpmc->mc_refcnt != 0 ) {
/* taint it */
......@@ -660,11 +661,15 @@ meta_back_dobind(
isroot = 1;
}
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_dobind: conn=%ld%s\n",
op->o_log_prefix,
LDAP_BACK_PCONN_ID( mc ),
isroot ? " (isroot)" : "" );
if ( LogTest( LDAP_DEBUG_TRACE ) ) {
char buf[STRLENOF("4294967295U") + 1] = { 0 };
mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) );
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_dobind: conn=%s%s\n",
op->o_log_prefix, buf,
isroot ? " (isroot)" : "" );
}
/*
* all the targets are bound as pseudoroot
......@@ -796,9 +801,14 @@ retry_ok:;
}
done:;
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_dobind: conn=%ld bound=%d\n",
op->o_log_prefix, LDAP_BACK_PCONN_ID( mc ), bound );
if ( LogTest( LDAP_DEBUG_TRACE ) ) {
char buf[STRLENOF("4294967295U") + 1] = { 0 };
mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) );
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_dobind: conn=%s bound=%d\n",
op->o_log_prefix, buf, bound );
}
if ( bound == 0 ) {
meta_back_release_conn( mi, mc );
......
......@@ -1024,7 +1024,7 @@ meta_back_getconn(
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc = NULL,
mc_curr = { 0 };
mc_curr = {{ 0 }};
int cached = META_TARGET_NONE,
i = META_TARGET_NONE,
err = LDAP_SUCCESS,
......@@ -1168,8 +1168,14 @@ retry_lock:;
LDAP_BACK_CONN_TAINTED_SET( mc );
LDAP_BACK_CONN_CACHED_CLEAR( mc );
Debug( LDAP_DEBUG_TRACE, "%s meta_back_getconn: mc=%p conn=%ld expired (tainted).\n",
op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc ) );
if ( LogTest( LDAP_DEBUG_TRACE ) ) {
char buf[STRLENOF("4294967295U") + 1] = { 0 };
mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) );
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_getconn: mc=%p conn=%s expired (tainted).\n",
op->o_log_prefix, (void *)mc, buf );
}
}
mc->mc_refcnt++;
......@@ -1654,10 +1660,14 @@ done:;
default:
LDAP_BACK_CONN_CACHED_CLEAR( mc );
Debug( LDAP_DEBUG_ANY,
"%s meta_back_getconn: candidates=%d conn=%ld insert failed\n",
op->o_log_prefix, ncandidates,
LDAP_BACK_PCONN_ID( mc ) );
if ( LogTest( LDAP_DEBUG_ANY ) ) {
char buf[STRLENOF("4294967295U") + 1] = { 0 };
mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) );
Debug( LDAP_DEBUG_ANY,
"%s meta_back_getconn: candidates=%d conn=%s insert failed\n",
op->o_log_prefix, ncandidates, buf );
}
mc->mc_refcnt = 0;
meta_back_conn_free( mc );
......@@ -1671,16 +1681,24 @@ done:;
}
}
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_getconn: candidates=%d conn=%ld inserted\n",
op->o_log_prefix, ncandidates,
LDAP_BACK_PCONN_ID( mc ) );
if ( LogTest( LDAP_DEBUG_TRACE ) ) {
char buf[STRLENOF("4294967295U") + 1] = { 0 };
mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) );
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_getconn: candidates=%d conn=%s inserted\n",
op->o_log_prefix, ncandidates, buf );
}
} else {
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_getconn: candidates=%d conn=%ld fetched\n",
op->o_log_prefix, ncandidates,
LDAP_BACK_PCONN_ID( mc ) );
if ( LogTest( LDAP_DEBUG_TRACE ) ) {
char buf[STRLENOF("4294967295U") + 1] = { 0 };
mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) );
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_getconn: candidates=%d conn=%s fetched\n",
op->o_log_prefix, ncandidates, buf );
}
}
return mc;
......
......@@ -39,7 +39,7 @@ meta_back_conn_destroy(
{
metainfo_t *mi = ( metainfo_t * )be->be_private;
metaconn_t *mc,
mc_curr = { 0 };
mc_curr = {{ 0 }};
int i;
......@@ -56,11 +56,11 @@ meta_back_conn_destroy(
#endif /* META_BACK_PRINT_CONNTREE */
while ( ( mc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr, meta_back_conn_cmp ) ) != NULL )
{
assert( !LDAP_BACK_PCONN_ISPRIV( mc ) );
Debug( LDAP_DEBUG_TRACE,
"=>meta_back_conn_destroy: destroying conn %ld "
"=>meta_back_conn_destroy: destroying conn %lu "
"refcnt=%d flags=0x%08x\n",
LDAP_BACK_PCONN_ID( mc ),
mc->mc_refcnt, mc->msc_mscflags );
mc->mc_conn->c_connid, mc->mc_refcnt, mc->msc_mscflags );
if ( mc->mc_refcnt > 0 ) {
/* someone else might be accessing the connection;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment