mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-03 05:30:07 -05:00
PROTOTYPE: New connection management infrastructure designed to
remove race conditions on connection close. BROKEN: various counters for dn=monitor. Initial testing on FreeBSD (with and without pthreads) was successfull. Have not yet tested preemptive threading environments. Have not built against backends other than LDBM.
This commit is contained in:
parent
61f6d5d8ca
commit
8f02beada9
20 changed files with 1185 additions and 611 deletions
|
|
@ -49,19 +49,28 @@ do_abandon(
|
|||
* flag and abort the operation at a convenient time.
|
||||
*/
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
for ( o = conn->c_ops; o != NULL; o = o->o_next ) {
|
||||
if ( o->o_msgid == id )
|
||||
goto found_op;
|
||||
}
|
||||
for ( o = conn->c_pending_ops; o != NULL; o = o->o_next ) {
|
||||
if ( o->o_msgid == id )
|
||||
break;
|
||||
}
|
||||
|
||||
found_op:
|
||||
|
||||
if ( o != NULL ) {
|
||||
ldap_pvt_thread_mutex_lock( &o->o_abandonmutex );
|
||||
o->o_abandon = 1;
|
||||
ldap_pvt_thread_mutex_unlock( &o->o_abandonmutex );
|
||||
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE, "do_abandon: op not found\n", 0, 0,
|
||||
0 );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,7 +287,9 @@ acl_access_allowed(
|
|||
}
|
||||
}
|
||||
if ( b->a_addrpat != NULL ) {
|
||||
if ( regex_matches( b->a_addrpat, conn->c_addr, edn, matches ) ) {
|
||||
if ( regex_matches( b->a_addrpat, conn->c_client_addr,
|
||||
edn, matches ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"<= acl_access_allowed: matched by clause #%d access %s\n",
|
||||
i, (b->a_access & ~ACL_SELF) >= access ?
|
||||
|
|
@ -299,7 +301,8 @@ acl_access_allowed(
|
|||
if ( b->a_domainpat != NULL ) {
|
||||
Debug( LDAP_DEBUG_ARGS, "<= check a_domainpath: %s\n",
|
||||
b->a_domainpat, 0, 0 );
|
||||
if ( regex_matches( b->a_domainpat, conn->c_domain, edn, matches ) )
|
||||
if ( regex_matches( b->a_domainpat, conn->c_client_name,
|
||||
edn, matches ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"<= acl_access_allowed: matched by clause #%d access %s\n",
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ add_created_attrs( Operation *op, Entry *e )
|
|||
Attribute **a, **next;
|
||||
Attribute *tmp;
|
||||
struct tm *ltm;
|
||||
time_t currenttime;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "add_created_attrs\n", 0, 0, 0 );
|
||||
|
||||
|
|
@ -181,7 +182,8 @@ add_created_attrs( Operation *op, Entry *e )
|
|||
}
|
||||
attr_merge( e, "creatorsname", bvals );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
currenttime = slap_get_time();
|
||||
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
|
||||
#ifndef LDAP_LOCALTIME
|
||||
ltm = gmtime( ¤ttime );
|
||||
strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
|
||||
|
|
@ -189,7 +191,7 @@ add_created_attrs( Operation *op, Entry *e )
|
|||
ltm = localtime( ¤ttime );
|
||||
strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
|
||||
#endif
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
|
||||
|
||||
bv.bv_val = buf;
|
||||
bv.bv_len = strlen( bv.bv_val );
|
||||
|
|
|
|||
|
|
@ -41,9 +41,7 @@ ldbm_cache_open(
|
|||
flags, li->li_mode );
|
||||
|
||||
lru = 0;
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
curtime = currenttime;
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
curtime = slap_get_time();
|
||||
oldtime = curtime;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ ldbm_back_search(
|
|||
rcur = strchr( rbuf, '\0' );
|
||||
for ( id = idl_firstid( candidates ); id != NOID;
|
||||
id = idl_nextid( candidates, id ) ) {
|
||||
|
||||
/* check for abandon */
|
||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
||||
if ( op->o_abandon ) {
|
||||
|
|
@ -153,10 +154,7 @@ ldbm_back_search(
|
|||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
||||
|
||||
/* check time limit */
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
time( ¤ttime );
|
||||
if ( tlimit != -1 && currenttime > stoptime ) {
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
if ( tlimit != -1 && slap_get_time() > stoptime ) {
|
||||
send_ldap_search_result( conn, op,
|
||||
LDAP_TIMELIMIT_EXCEEDED, NULL, nrefs > 0 ? rbuf :
|
||||
NULL, nentries );
|
||||
|
|
@ -167,7 +165,6 @@ ldbm_back_search(
|
|||
}
|
||||
return( 0 );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
|
||||
/* get the entry with reader lock */
|
||||
if ( (e = id2entry_r( be, id )) == NULL ) {
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ do_bind(
|
|||
free( cred.bv_val );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
conn->c_protocol = version;
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ do_bind(
|
|||
conn->c_dn = NULL;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
|
||||
return;
|
||||
|
|
@ -168,7 +168,7 @@ do_bind(
|
|||
free( cred.bv_val );
|
||||
}
|
||||
if ( cred.bv_len == 0 ) {
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
conn->c_protocol = version;
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ do_bind(
|
|||
conn->c_dn = NULL;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
||||
NULL, NULL );
|
||||
|
|
@ -203,7 +203,7 @@ do_bind(
|
|||
ndn = suffixAlias( ndn, op, be );
|
||||
|
||||
if ( (*be->be_bind)( be, conn, op, ndn, method, &cred, &edn ) == 0 ) {
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
conn->c_protocol = version;
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ do_bind(
|
|||
Debug( LDAP_DEBUG_TRACE, "do_bind: bound \"%s\" to \"%s\"\n",
|
||||
conn->c_cdn, conn->c_dn, method );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
/* send this here to avoid a race condition */
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
|
||||
|
|
|
|||
|
|
@ -10,6 +10,16 @@
|
|||
|
||||
#include "slap.h"
|
||||
|
||||
/* protected by connections_mutex */
|
||||
static ldap_pvt_thread_mutex_t connections_mutex;
|
||||
static Connection *connections = NULL;
|
||||
static int conn_index = -1;
|
||||
static long conn_nextid = 0;
|
||||
|
||||
static Connection* connection_get( int s );
|
||||
|
||||
static int connection_input( Connection *c );
|
||||
|
||||
static int connection_op_activate( Connection *conn, Operation *op );
|
||||
static int connection_resched( Connection *conn );
|
||||
|
||||
|
|
@ -18,6 +28,360 @@ struct co_arg {
|
|||
Operation *co_op;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize connection management infrastructure.
|
||||
*/
|
||||
int connections_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( connections == NULL );
|
||||
|
||||
if( connections != NULL) { /* probably should assert this */
|
||||
Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n",
|
||||
0, 0, 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* should check return of every call */
|
||||
ldap_pvt_thread_mutex_init( &connections_mutex );
|
||||
|
||||
connections = (Connection *) calloc( dtblsize, sizeof(Connection) );
|
||||
|
||||
if( connections == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"connections_init: allocation (%d*%ld) of connection array failed.\n",
|
||||
dtblsize, (long) sizeof(Connection), 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* per entry initialization of the Connection array initialization
|
||||
* will be done by connection_init()
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Connection* connection_get( int s )
|
||||
{
|
||||
Connection *c = NULL;
|
||||
|
||||
assert( connections != NULL );
|
||||
|
||||
if(s < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
assert( connections[s].c_struct_state == SLAP_C_USED );
|
||||
assert( connections[s].c_conn_state != SLAP_C_INVALID );
|
||||
assert( connections[s].c_sb.sb_sd != -1 );
|
||||
|
||||
c = &connections[s];
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<dtblsize; i++) {
|
||||
if( connections[i].c_struct_state == SLAP_C_STRUCT_UNINITIALIZED ) {
|
||||
assert( connections[i].c_conn_state == SLAP_C_INVALID );
|
||||
assert( connections[s].c_sb.sb_sd == 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
if( connections[i].c_struct_state == SLAP_C_STRUCT_UNUSED ) {
|
||||
assert( connections[i].c_conn_state == SLAP_C_INVALID );
|
||||
assert( connections[s].c_sb.sb_sd == -1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
assert( connections[i].c_struct_state == SLAP_C_STRUCT_USED );
|
||||
assert( connections[i].c_conn_state != SLAP_C_INVALID );
|
||||
assert( connections[s].c_sb.sb_sd != -1 );
|
||||
|
||||
if( connections[i].c_sb.sb_sd == s ) {
|
||||
c = &connections[s];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( c != NULL ) {
|
||||
ldap_pvt_thread_mutex_lock( &c->c_mutex );
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static void connection_return( Connection *c )
|
||||
{
|
||||
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
|
||||
}
|
||||
|
||||
long connection_init(
|
||||
int s,
|
||||
const char* name,
|
||||
const char* addr)
|
||||
{
|
||||
long id;
|
||||
Connection *c;
|
||||
assert( connections != NULL );
|
||||
|
||||
if( s < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert( s >= 0 );
|
||||
#ifndef HAVE_WINSOCK
|
||||
assert( s < dtblsize );
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &connections_mutex );
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
c = &connections[s];
|
||||
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; i < dtblsize; i++ {
|
||||
if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) {
|
||||
assert( connections[i].c_sb.sb_sd == 0 );
|
||||
c = &connections[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if( connections[i].c_struct_state == SLAP_C_UNUSED ) {
|
||||
assert( connections[i].c_sb.sb_sd == -1 );
|
||||
c = &connections[i];
|
||||
break;
|
||||
}
|
||||
|
||||
assert( connections[i].c_struct_state == SLAP_C_USED );
|
||||
assert( connections[i].c_conn_state != SLAP_C_INVALID );
|
||||
assert( connections[i].c_sb.sb_sd != -1 );
|
||||
}
|
||||
|
||||
if( c == NULL ) {
|
||||
ldap_pvt_thread_mutex_unlock( &connections_mutex );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
assert( c != NULL );
|
||||
assert( c->c_struct_state != SLAP_C_USED );
|
||||
assert( c->c_conn_state == SLAP_C_INVALID );
|
||||
|
||||
if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
|
||||
c->c_dn = NULL;
|
||||
c->c_cdn = NULL;
|
||||
c->c_client_name = NULL;
|
||||
c->c_client_addr = NULL;
|
||||
c->c_ops = NULL;
|
||||
c->c_pending_ops = NULL;
|
||||
|
||||
lber_pvt_sb_init( &c->c_sb );
|
||||
|
||||
/* should check status of thread calls */
|
||||
ldap_pvt_thread_mutex_init( &c->c_mutex );
|
||||
ldap_pvt_thread_mutex_init( &c->c_write_mutex );
|
||||
ldap_pvt_thread_cond_init( &c->c_write_cv );
|
||||
|
||||
c->c_struct_state = SLAP_C_UNUSED;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &c->c_mutex );
|
||||
|
||||
assert( c->c_struct_state == SLAP_C_UNUSED );
|
||||
assert( c->c_dn == NULL );
|
||||
assert( c->c_cdn == NULL );
|
||||
assert( c->c_client_name == NULL );
|
||||
assert( c->c_client_addr == NULL );
|
||||
assert( c->c_ops == NULL );
|
||||
assert( c->c_pending_ops == NULL );
|
||||
|
||||
c->c_client_name = ch_strdup( name == NULL ? "" : name );
|
||||
c->c_client_addr = ch_strdup( addr );
|
||||
|
||||
c->c_n_ops_received = 0;
|
||||
#ifdef LDAP_COUNTERS
|
||||
c->c_n_ops_executing = 0;
|
||||
c->c_n_ops_pending = 0;
|
||||
c->c_n_ops_completed = 0;
|
||||
#endif
|
||||
|
||||
c->c_starttime = slap_get_time();
|
||||
|
||||
lber_pvt_sb_set_desc( &c->c_sb, s );
|
||||
lber_pvt_sb_set_io( &c->c_sb, &lber_pvt_sb_io_tcp, NULL );
|
||||
|
||||
if( lber_pvt_sb_set_nonblock( &c->c_sb, 1 ) < 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"connection_init(%d, %s, %s): set nonblocking failed\n",
|
||||
s, c->c_client_name, c->c_client_addr);
|
||||
}
|
||||
|
||||
id = c->c_connid = conn_nextid++;
|
||||
|
||||
c->c_conn_state = SLAP_C_INACTIVE;
|
||||
c->c_struct_state = SLAP_C_USED;
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &connections_mutex );
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static void
|
||||
connection_destroy( Connection *c )
|
||||
{
|
||||
assert( connections != NULL );
|
||||
assert( c != NULL );
|
||||
assert( c->c_struct_state != SLAP_C_UNUSED );
|
||||
assert( c->c_conn_state != SLAP_C_INVALID );
|
||||
assert( c->c_ops == NULL );
|
||||
|
||||
c->c_struct_state = SLAP_C_UNUSED;
|
||||
c->c_conn_state = SLAP_C_INVALID;
|
||||
|
||||
c->c_version = 0;
|
||||
c->c_protocol = 0;
|
||||
|
||||
c->c_starttime = 0;
|
||||
|
||||
if(c->c_dn != NULL) {
|
||||
free(c->c_dn);
|
||||
c->c_dn = NULL;
|
||||
}
|
||||
if(c->c_cdn != NULL) {
|
||||
free(c->c_cdn);
|
||||
c->c_cdn = NULL;
|
||||
}
|
||||
if(c->c_client_name != NULL) {
|
||||
free(c->c_client_name);
|
||||
c->c_client_name = NULL;
|
||||
}
|
||||
if(c->c_client_addr != NULL) {
|
||||
free(c->c_client_addr);
|
||||
c->c_client_addr = NULL;
|
||||
}
|
||||
|
||||
if ( lber_pvt_sb_in_use(&c->c_sb) ) {
|
||||
int sd = lber_pvt_sb_get_desc(&c->c_sb);
|
||||
|
||||
slapd_remove( sd );
|
||||
lber_pvt_sb_close( &c->c_sb );
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS,
|
||||
"conn=%d fd=%d closed.\n",
|
||||
c->c_connid, sd, 0, 0, 0 );
|
||||
}
|
||||
|
||||
lber_pvt_sb_destroy( &c->c_sb );
|
||||
}
|
||||
|
||||
static void connection_close( Connection *c )
|
||||
{
|
||||
assert( connections != NULL );
|
||||
assert( c != NULL );
|
||||
assert( c->c_struct_state == SLAP_C_USED );
|
||||
assert( c->c_conn_state == SLAP_C_CLOSING );
|
||||
|
||||
if( c->c_ops != NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"connection_close: deferring conn=%ld sd=%d.\n",
|
||||
c->c_connid, c->c_sb.sb_sd, 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%ld sd=%d.\n",
|
||||
c->c_connid, c->c_sb.sb_sd, 0 );
|
||||
|
||||
connection_destroy( c );
|
||||
}
|
||||
|
||||
long connections_nextid(void)
|
||||
{
|
||||
long id;
|
||||
assert( connections != NULL );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &connections_mutex );
|
||||
|
||||
id = conn_nextid;
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &connections_mutex );
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
Connection* connection_first(void)
|
||||
{
|
||||
assert( connections != NULL );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &connections_mutex );
|
||||
|
||||
assert( conn_index == -1 );
|
||||
conn_index = 0;
|
||||
|
||||
return connection_next(NULL);
|
||||
}
|
||||
|
||||
Connection* connection_next(Connection *c)
|
||||
{
|
||||
assert( connections != NULL );
|
||||
assert( conn_index != -1 );
|
||||
assert( conn_index <= dtblsize );
|
||||
|
||||
if( c != NULL ) {
|
||||
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
|
||||
}
|
||||
|
||||
c = NULL;
|
||||
|
||||
for(; conn_index < dtblsize; conn_index++) {
|
||||
if( connections[conn_index].c_struct_state == SLAP_C_UNINITIALIZED ) {
|
||||
assert( connections[conn_index].c_conn_state == SLAP_C_INVALID );
|
||||
#ifndef HAVE_WINSOCK
|
||||
continue;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if( connections[conn_index].c_struct_state == SLAP_C_USED ) {
|
||||
assert( connections[conn_index].c_conn_state != SLAP_C_INVALID );
|
||||
c = &connections[conn_index++];
|
||||
break;
|
||||
}
|
||||
|
||||
assert( connections[conn_index].c_struct_state == SLAP_C_UNUSED );
|
||||
assert( connections[conn_index].c_conn_state == SLAP_C_INVALID );
|
||||
}
|
||||
|
||||
if( c != NULL ) {
|
||||
ldap_pvt_thread_mutex_lock( &c->c_mutex );
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void connection_done(Connection *c)
|
||||
{
|
||||
assert( connections != NULL );
|
||||
assert( conn_index != -1 );
|
||||
assert( conn_index <= dtblsize );
|
||||
|
||||
if( c != NULL ) {
|
||||
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
|
||||
}
|
||||
|
||||
conn_index = -1;
|
||||
ldap_pvt_thread_mutex_unlock( &connections_mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
* connection_activity - handle the request operation op on connection
|
||||
* conn. This routine figures out what kind of operation it is and
|
||||
|
|
@ -31,13 +395,11 @@ connection_operation( void *arg_v )
|
|||
int tag = arg->co_op->o_tag;
|
||||
Connection *conn = arg->co_conn;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
|
||||
conn->c_ops_received++;
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
|
||||
|
||||
#ifdef LDAP_COUNTERS
|
||||
ldap_pvt_thread_mutex_lock( &ops_mutex );
|
||||
ops_initiated++;
|
||||
ldap_pvt_thread_mutex_unlock( &ops_mutex );
|
||||
#endif
|
||||
|
||||
switch ( tag ) {
|
||||
case LDAP_REQ_BIND:
|
||||
|
|
@ -91,12 +453,17 @@ connection_operation( void *arg_v )
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef LDAP_COUNTERS
|
||||
ldap_pvt_thread_mutex_lock( &ops_mutex );
|
||||
ops_completed++;
|
||||
ldap_pvt_thread_mutex_unlock( &ops_mutex );
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
#ifdef LDAP_COUNTERS
|
||||
conn->c_ops_completed++;
|
||||
#endif
|
||||
|
||||
slap_op_remove( &conn->c_ops, arg->co_op );
|
||||
slap_op_free( arg->co_op );
|
||||
|
|
@ -105,11 +472,27 @@ connection_operation( void *arg_v )
|
|||
free( (char *) arg );
|
||||
arg = NULL;
|
||||
|
||||
if((tag == LDAP_REQ_BIND) && (conn->c_state == SLAP_C_BINDING)) {
|
||||
conn->c_state = SLAP_C_ACTIVE;
|
||||
switch( tag ) {
|
||||
#ifdef LDAP_COMPAT30
|
||||
case LDAP_REQ_UNBIND_30:
|
||||
#endif
|
||||
case LDAP_REQ_UNBIND:
|
||||
conn->c_conn_state = SLAP_C_CLOSING;
|
||||
break;
|
||||
|
||||
case LDAP_REQ_BIND:
|
||||
if( conn->c_conn_state == SLAP_C_BINDING) {
|
||||
conn->c_conn_state = SLAP_C_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
|
||||
if( conn->c_conn_state == SLAP_C_CLOSING ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"connection_operation: attempting closing conn=%ld sd=%d.\n",
|
||||
conn->c_connid, conn->c_sb.sb_sd, 0 );
|
||||
|
||||
connection_close( conn );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
active_threads--;
|
||||
|
|
@ -120,11 +503,58 @@ connection_operation( void *arg_v )
|
|||
|
||||
connection_resched( conn );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
connection_activity(
|
||||
int connection_read(int s)
|
||||
{
|
||||
int rc = 0;
|
||||
Connection *c;
|
||||
assert( connections != NULL );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &connections_mutex );
|
||||
|
||||
c = connection_get( s );
|
||||
if( c == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"connection_read(%d): no connection!\n",
|
||||
s, 0, 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"connection_read(%d): checking for input on id=%ld\n",
|
||||
s, c->c_connid, 0 );
|
||||
|
||||
#define CONNECTION_INPUT_LOOP 1
|
||||
|
||||
#ifdef DATA_READY_LOOP
|
||||
while(!rc && lber_pvt_sb_data_ready(&c->c_sb))
|
||||
#elif CONNECTION_INPUT_LOOP
|
||||
while(!rc)
|
||||
#endif
|
||||
{
|
||||
rc = connection_input( c );
|
||||
}
|
||||
|
||||
if( rc < 0 ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"connection_read(%d): input error id=%ld, closing.\n",
|
||||
s, c->c_connid, 0 );
|
||||
|
||||
c->c_conn_state = SLAP_C_CLOSING;
|
||||
connection_close( c );
|
||||
}
|
||||
|
||||
connection_return( c );
|
||||
ldap_pvt_thread_mutex_unlock( &connections_mutex );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
connection_input(
|
||||
Connection *conn
|
||||
)
|
||||
{
|
||||
|
|
@ -136,30 +566,32 @@ connection_activity(
|
|||
if ( conn->c_currentber == NULL && (conn->c_currentber = ber_alloc())
|
||||
== NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if ( (tag = ber_get_next( &conn->c_sb, &len, conn->c_currentber ))
|
||||
!= LDAP_TAG_MESSAGE ) {
|
||||
!= LDAP_TAG_MESSAGE )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"ber_get_next on fd %d failed errno %d (%s)\n",
|
||||
lber_pvt_sb_get_desc(&conn->c_sb), errno, errno > -1 && errno < sys_nerr ?
|
||||
sys_errlist[errno] : "unknown" );
|
||||
Debug( LDAP_DEBUG_TRACE, "*** got %ld of %lu so far\n",
|
||||
(long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
|
||||
conn->c_currentber->ber_len, 0 );
|
||||
"ber_get_next on fd %d failed errno %d (%s)\n",
|
||||
lber_pvt_sb_get_desc(&conn->c_sb), errno,
|
||||
errno > -1 && errno < sys_nerr ? sys_errlist[errno] : "unknown" );
|
||||
Debug( LDAP_DEBUG_TRACE, "\t*** got %ld of %lu so far\n",
|
||||
(long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
|
||||
conn->c_currentber->ber_len, 0 );
|
||||
|
||||
if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
|
||||
/* log, close and send error */
|
||||
ber_free( conn->c_currentber, 1 );
|
||||
conn->c_currentber = NULL;
|
||||
|
||||
close_connection( conn, conn->c_connid, -1 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ber = conn->c_currentber;
|
||||
conn->c_currentber = NULL;
|
||||
|
||||
|
|
@ -168,9 +600,7 @@ connection_activity(
|
|||
Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0,
|
||||
0 );
|
||||
ber_free( ber, 1 );
|
||||
|
||||
close_connection( conn, conn->c_connid, -1 );
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
|
||||
|
|
@ -179,8 +609,7 @@ connection_activity(
|
|||
0 );
|
||||
ber_free( ber, 1 );
|
||||
|
||||
close_connection( conn, conn->c_connid, -1 );
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef LDAP_COMPAT30
|
||||
|
|
@ -189,22 +618,27 @@ connection_activity(
|
|||
}
|
||||
#endif
|
||||
|
||||
op = slap_op_alloc( ber, msgid, tag,
|
||||
conn->c_ops_received, conn->c_connid );
|
||||
op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++ );
|
||||
|
||||
if ( conn->c_state == SLAP_C_BINDING ) {
|
||||
/* connection is binding to a dn, make 'em wait */
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
|
||||
if ( conn->c_conn_state == SLAP_C_BINDING
|
||||
|| conn->c_conn_state == SLAP_C_CLOSING )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY, "deferring operation\n", 0, 0, 0 );
|
||||
slap_op_add( &conn->c_pending_ops, op );
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "deferring operation\n", 0, 0, 0 );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
|
||||
|
||||
return;
|
||||
} else {
|
||||
connection_op_activate( conn, op );
|
||||
}
|
||||
|
||||
connection_op_activate( conn, op );
|
||||
#ifdef NO_THREADS
|
||||
if ( conn->c_struct_state != SLAP_C_USED ) {
|
||||
/* connection must have got closed underneath us */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
assert( conn->c_struct_state == SLAP_C_USED );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -212,29 +646,21 @@ connection_resched( Connection *conn )
|
|||
{
|
||||
Operation *op;
|
||||
|
||||
if( conn->c_state != SLAP_C_ACTIVE ) {
|
||||
if( conn->c_conn_state != SLAP_C_ACTIVE ) {
|
||||
/* other states need different handling */
|
||||
return;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
|
||||
|
||||
for( op = slap_op_pop( &conn->c_pending_ops );
|
||||
op != NULL;
|
||||
op = slap_op_pop( &conn->c_pending_ops ) )
|
||||
{
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
|
||||
|
||||
connection_op_activate( conn, op );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
|
||||
|
||||
if ( conn->c_state == SLAP_C_BINDING ) {
|
||||
if ( conn->c_conn_state == SLAP_C_BINDING ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
|
||||
}
|
||||
|
||||
static int connection_op_activate( Connection *conn, Operation *op )
|
||||
|
|
@ -244,13 +670,11 @@ static int connection_op_activate( Connection *conn, Operation *op )
|
|||
int status;
|
||||
unsigned long tag = op->o_tag;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
|
||||
if ( conn->c_dn != NULL ) {
|
||||
tmpdn = ch_strdup( conn->c_dn );
|
||||
} else {
|
||||
tmpdn = NULL;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
|
||||
|
||||
arg = (struct co_arg *) ch_malloc( sizeof(struct co_arg) );
|
||||
arg->co_conn = conn;
|
||||
|
|
@ -259,16 +683,12 @@ static int connection_op_activate( Connection *conn, Operation *op )
|
|||
arg->co_op->o_dn = ch_strdup( tmpdn != NULL ? tmpdn : "" );
|
||||
arg->co_op->o_ndn = dn_normalize_case( ch_strdup( arg->co_op->o_dn ) );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
|
||||
|
||||
slap_op_add( &conn->c_ops, arg->co_op );
|
||||
|
||||
if(tag == LDAP_REQ_BIND) {
|
||||
conn->c_state = SLAP_C_BINDING;
|
||||
conn->c_conn_state = SLAP_C_BINDING;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
|
||||
|
||||
if ( tmpdn != NULL ) {
|
||||
free( tmpdn );
|
||||
}
|
||||
|
|
@ -281,8 +701,37 @@ static int connection_op_activate( Connection *conn, Operation *op )
|
|||
connection_operation, (void *) arg );
|
||||
|
||||
if ( status != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
|
||||
|
||||
/* should move op to pending list */
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int connection_write(int s)
|
||||
{
|
||||
Connection *c;
|
||||
assert( connections != NULL );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &connections_mutex );
|
||||
|
||||
c = connection_get( s );
|
||||
if( c == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"connection_write(%d): no connection!\n",
|
||||
s, 0, 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"connection_write(%d): waking output for id=%ld\n",
|
||||
s, c->c_connid, 0 );
|
||||
|
||||
ldap_pvt_thread_cond_signal( &c->c_write_cv );
|
||||
|
||||
connection_return( c );
|
||||
ldap_pvt_thread_mutex_unlock( &connections_mutex );
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
|
||||
/* Revision history
|
||||
*
|
||||
* 5-Jun-96 hodges
|
||||
* Added locking of new_conn_mutex when traversing the c[] array.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -33,26 +26,113 @@ int allow_severity = LOG_INFO;
|
|||
int deny_severity = LOG_NOTICE;
|
||||
#endif /* TCP Wrappers */
|
||||
|
||||
int dtblsize;
|
||||
Connection *c;
|
||||
/* globals */
|
||||
int dtblsize;
|
||||
|
||||
static ldap_pvt_thread_t listener_tid;
|
||||
static volatile sig_atomic_t slapd_shutdown = 0;
|
||||
|
||||
/* a link to the slapd.conf configuration parameters */
|
||||
extern char *slapd_pid_file;
|
||||
extern char *slapd_args_file;
|
||||
struct slap_daemon {
|
||||
ldap_pvt_thread_mutex_t sd_mutex;
|
||||
|
||||
void *
|
||||
slapd_daemon(
|
||||
int sd_nactives;
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
/* In winsock, accept() returns values higher than dtblsize
|
||||
so don't bother with this optimization */
|
||||
int sd_nfds;
|
||||
#endif
|
||||
|
||||
fd_set sd_actives;
|
||||
fd_set sd_readers;
|
||||
fd_set sd_writers;
|
||||
} slap_daemon;
|
||||
|
||||
/*
|
||||
* Add a descriptor to daemon control
|
||||
*/
|
||||
static void slapd_add(int s) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( !FD_ISSET( s, &slap_daemon.sd_actives ));
|
||||
assert( !FD_ISSET( s, &slap_daemon.sd_readers ));
|
||||
assert( !FD_ISSET( s, &slap_daemon.sd_writers ));
|
||||
|
||||
if (s >= slap_daemon.sd_nfds) {
|
||||
slap_daemon.sd_nfds = s + 1;
|
||||
}
|
||||
|
||||
FD_SET( s, &slap_daemon.sd_actives );
|
||||
FD_SET( s, &slap_daemon.sd_readers );
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: added %d%s%s\n", s,
|
||||
FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
|
||||
FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the descriptor from daemon control
|
||||
*/
|
||||
void slapd_remove(int s) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( s < slap_daemon.sd_nfds );
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_actives ));
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: removing %d%s%s\n", s,
|
||||
FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
|
||||
FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" );
|
||||
|
||||
FD_CLR( s, &slap_daemon.sd_actives );
|
||||
FD_CLR( s, &slap_daemon.sd_readers );
|
||||
FD_CLR( s, &slap_daemon.sd_writers );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
}
|
||||
|
||||
void slapd_clr_write(int s, int wake) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( s < slap_daemon.sd_nfds );
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_actives) );
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_writers) );
|
||||
FD_SET( s, &slap_daemon.sd_writers );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
|
||||
if( wake ) {
|
||||
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
|
||||
}
|
||||
}
|
||||
|
||||
void slapd_set_write(int s, int wake) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
FD_SET( s, &slap_daemon.sd_writers );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
|
||||
if( wake ) {
|
||||
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
|
||||
}
|
||||
}
|
||||
|
||||
static void slapd_close(int s) {
|
||||
slapd_remove(s);
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: closing %d\n", s, 0, 0 );
|
||||
close(s);
|
||||
}
|
||||
|
||||
static void *
|
||||
slapd_daemon_task(
|
||||
void *ptr
|
||||
)
|
||||
{
|
||||
struct sockaddr_in *addr = ptr;
|
||||
int i;
|
||||
int tcps, ns;
|
||||
fd_set readfds;
|
||||
fd_set writefds;
|
||||
FILE *fp;
|
||||
int tcps = -1;
|
||||
|
||||
#ifdef HAVE_SYSCONF
|
||||
dtblsize = sysconf( _SC_OPEN_MAX );
|
||||
|
|
@ -68,179 +148,201 @@ slapd_daemon(
|
|||
}
|
||||
#endif /* !FD_SETSIZE */
|
||||
|
||||
c = (Connection *) ch_calloc( (size_t) dtblsize, sizeof(Connection) );
|
||||
connections_init();
|
||||
|
||||
for ( i = 0; i < dtblsize; i++ ) {
|
||||
c[i].c_dn = NULL;
|
||||
c[i].c_cdn = NULL;
|
||||
c[i].c_addr = NULL;
|
||||
c[i].c_domain = NULL;
|
||||
c[i].c_ops = NULL;
|
||||
lber_pvt_sb_init( &c[i].c_sb );
|
||||
ldap_pvt_thread_mutex_init( &c[i].c_dnmutex );
|
||||
ldap_pvt_thread_mutex_init( &c[i].c_opsmutex );
|
||||
ldap_pvt_thread_mutex_init( &c[i].c_pdumutex );
|
||||
ldap_pvt_thread_cond_init( &c[i].c_wcv );
|
||||
}
|
||||
ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
|
||||
FD_ZERO( &slap_daemon.sd_readers );
|
||||
FD_ZERO( &slap_daemon.sd_writers );
|
||||
|
||||
if ( (tcps = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "socket() failed errno %d (%s)", errno,
|
||||
errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
|
||||
"unknown", 0 );
|
||||
exit( 1 );
|
||||
}
|
||||
if( addr != NULL ) {
|
||||
int tmp;
|
||||
|
||||
i = 1;
|
||||
if ( setsockopt( tcps, SOL_SOCKET, SO_REUSEADDR, (char *) &i,
|
||||
sizeof(i) ) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "setsockopt() failed errno %d (%s)",
|
||||
errno, errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
|
||||
"unknown", 0 );
|
||||
}
|
||||
|
||||
if ( bind( tcps, (struct sockaddr *) addr, sizeof(*addr) ) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "bind() failed errno %d (%s)\n",
|
||||
errno, errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
|
||||
"unknown", 0 );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( listen( tcps, 5 ) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "listen() failed errno %d (%s)",
|
||||
errno, errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
|
||||
"unknown", 0 );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
|
||||
|
||||
if (( slapd_pid_file != NULL ) &&
|
||||
(( fp = fopen( slapd_pid_file, "w" )) != NULL )) {
|
||||
fprintf( fp, "%d\n", (int) getpid() );
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
if (( slapd_args_file != NULL ) &&
|
||||
(( fp = fopen( slapd_args_file, "w" )) != NULL )) {
|
||||
for ( i = 0; i < g_argc; i++ ) {
|
||||
fprintf( fp, "%s ", g_argv[i] );
|
||||
if ( (tcps = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"daemon: socket() failed errno %d (%s)", errno,
|
||||
errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
|
||||
"unknown", 0 );
|
||||
exit( 1 );
|
||||
}
|
||||
fprintf( fp, "\n" );
|
||||
fclose( fp );
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
if ( tcps >= dtblsize ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"daemon: listener descriptor %d is too great",
|
||||
tcps, dtblsize, 0 );
|
||||
exit( 1 );
|
||||
}
|
||||
#endif
|
||||
|
||||
tmp = 1;
|
||||
if ( setsockopt( tcps, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *) &tmp, sizeof(tmp) ) == -1 )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"slapd(%d): setsockopt() failed errno %d (%s)",
|
||||
tcps, errno,
|
||||
errno > -1 && errno < sys_nerr
|
||||
? sys_errlist[errno] : "unknown" );
|
||||
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
if ( bind( tcps, (struct sockaddr *) addr, sizeof(*addr) ) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "daemon: bind(%d) failed errno %d (%s)\n",
|
||||
tcps, errno,
|
||||
errno > -1 && errno < sys_nerr
|
||||
? sys_errlist[errno] : "unknown" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( listen( tcps, 5 ) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"daemon: listen(%d, 5) failed errno %d (%s)\n",
|
||||
tcps, errno,
|
||||
errno > -1 && errno < sys_nerr
|
||||
? sys_errlist[errno] : "unknown" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
slapd_add( tcps );
|
||||
|
||||
} else {
|
||||
if( connection_init( 0, NULL, NULL ) ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"connection_init(%d) failed.\n",
|
||||
0, 0, 0 );
|
||||
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
slapd_add( 0 );
|
||||
}
|
||||
|
||||
while ( !slapd_shutdown ) {
|
||||
int i, ns, nfds;
|
||||
|
||||
fd_set readfds;
|
||||
fd_set writefds;
|
||||
|
||||
struct sockaddr_in from;
|
||||
struct hostent *hp;
|
||||
struct timeval zero;
|
||||
struct timeval *tvp;
|
||||
int len;
|
||||
int data_ready;
|
||||
|
||||
char *client_name;
|
||||
char *client_addr;
|
||||
|
||||
FD_ZERO( &writefds );
|
||||
FD_ZERO( &readfds );
|
||||
FD_SET( tcps, &readfds );
|
||||
|
||||
zero.tv_sec = 0;
|
||||
zero.tv_usec = 0;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"listening for connections on %d, activity on:",
|
||||
tcps, 0, 0 );
|
||||
|
||||
data_ready = 0;
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
for ( i = 0; i < dtblsize; i++ ) {
|
||||
if ( (c[i].c_state != SLAP_C_INACTIVE)
|
||||
&& (c[i].c_state != SLAP_C_CLOSING) )
|
||||
{
|
||||
assert(lber_pvt_sb_in_use( &c[i].c_sb ));
|
||||
|
||||
FD_SET( lber_pvt_sb_get_desc(&c[i].c_sb),
|
||||
&readfds );
|
||||
if (lber_pvt_sb_data_ready(&c[i].c_sb))
|
||||
data_ready = 1;
|
||||
if ( c[i].c_writewaiter ) {
|
||||
FD_SET( lber_pvt_sb_get_desc(&c[i].c_sb),
|
||||
&writefds );
|
||||
}
|
||||
Debug( LDAP_DEBUG_CONNS, " %dr%s", i,
|
||||
c[i].c_writewaiter ? "w" : "", 0 );
|
||||
#ifdef FD_SET_MANUAL_COPY
|
||||
for( s = 0; s < nfds; s++ ) {
|
||||
if(FD_ISSET( &slap_sd_writers, s )) {
|
||||
FD_SET( &writefds, s );
|
||||
}
|
||||
if(FD_ISSET( &slap_sd_writers, s )) {
|
||||
FD_SET( &writefds, s );
|
||||
}
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "before select active_threads %d\n",
|
||||
active_threads, 0, 0 );
|
||||
#if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
|
||||
tvp = (data_ready) ? &zero : NULL;
|
||||
#else
|
||||
tvp = (active_threads || data_ready) ? &zero : NULL;
|
||||
memcpy( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) );
|
||||
memcpy( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) );
|
||||
#endif
|
||||
|
||||
FD_SET( tcps, &readfds );
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
nfds = slap_daemon.sd_nfds;
|
||||
#else
|
||||
nfds = dtblsize;
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
#if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
|
||||
tvp = NULL;
|
||||
#else
|
||||
tvp = active_threads ? &zero : NULL;
|
||||
#endif
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"daemon: select: tcps=%d active_threads=%d tvp=%s\n",
|
||||
tcps, active_threads,
|
||||
tvp == NULL ? "NULL" : "zero" );
|
||||
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
|
||||
|
||||
switch ( i = select( dtblsize, &readfds, &writefds, 0, tvp ) ) {
|
||||
switch(ns = select( nfds, &readfds, &writefds, 0, tvp )) {
|
||||
case -1: /* failure - try again */
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"select failed errno %d (%s)\n",
|
||||
errno, errno > -1 && errno < sys_nerr ?
|
||||
sys_errlist[errno] : "unknown", 0 );
|
||||
if( errno != EINTR ) {
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"daemon: select failed (%d): %s\n",
|
||||
errno,
|
||||
errno >= 0 && errno < sys_nerr
|
||||
? sys_errlist[errno] : "unknown",
|
||||
0 );
|
||||
|
||||
slapd_shutdown = -1;
|
||||
}
|
||||
errno = 0;
|
||||
continue;
|
||||
|
||||
case 0: /* timeout - let threads run */
|
||||
Debug( LDAP_DEBUG_CONNS, "select timeout - yielding\n",
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
|
||||
0, 0, 0 );
|
||||
if (!data_ready)
|
||||
ldap_pvt_thread_yield();
|
||||
ldap_pvt_thread_yield();
|
||||
continue;
|
||||
|
||||
default: /* something happened - deal with it */
|
||||
Debug( LDAP_DEBUG_CONNS, "select activity on %d descriptors\n", i, 0, 0 );
|
||||
; /* FALL */
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
|
||||
ns, 0, 0 );
|
||||
/* FALL THRU */
|
||||
}
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
time( ¤ttime );
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
|
||||
/* new connection */
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
slap_set_time();
|
||||
|
||||
if ( FD_ISSET( tcps, &readfds ) ) {
|
||||
len = sizeof(from);
|
||||
if ( (ns = accept( tcps, (struct sockaddr *) &from,
|
||||
&len )) == -1 ) {
|
||||
int s;
|
||||
int len = sizeof(from);
|
||||
long id;
|
||||
|
||||
if ( (s = accept( tcps,
|
||||
(struct sockaddr *) &from, &len )) == -1 )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"accept() failed errno %d (%s)", errno,
|
||||
errno > -1 && errno < sys_nerr ?
|
||||
sys_errlist[errno] : "unknown", 0 );
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
"daemon: accept(%d) failed errno %d (%s)", errno,
|
||||
tcps, errno >= 0 && errno < sys_nerr ?
|
||||
sys_errlist[errno] : "unknown");
|
||||
continue;
|
||||
}
|
||||
|
||||
assert( !FD_ISSET( 0, &slap_daemon.sd_actives) );
|
||||
assert( !FD_ISSET( 0, &slap_daemon.sd_readers) );
|
||||
assert( !FD_ISSET( 0, &slap_daemon.sd_writers) );
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
/* make sure descriptor number isn't too great */
|
||||
if ( ns >= dtblsize ) {
|
||||
if ( s >= dtblsize ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"new connection on %d beyond descriptor table size %d\n",
|
||||
ns, dtblsize, 0 );
|
||||
close(ns);
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
"daemon: %d beyond descriptor table size %d\n",
|
||||
s, dtblsize, 0 );
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "new connection on %d\n", ns,
|
||||
0, 0 );
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %d\n",
|
||||
s, 0, 0 );
|
||||
|
||||
len = sizeof(from);
|
||||
|
||||
if ( getpeername( ns, (struct sockaddr *) &from, &len )
|
||||
== 0 ) {
|
||||
char *s;
|
||||
if ( getpeername( s, (struct sockaddr *) &from, &len ) == 0 ) {
|
||||
client_addr = inet_ntoa( from.sin_addr );
|
||||
|
||||
#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
|
||||
|
|
@ -249,11 +351,12 @@ slapd_daemon(
|
|||
sizeof(from.sin_addr.s_addr), AF_INET );
|
||||
|
||||
if(hp) {
|
||||
char *p;
|
||||
client_name = hp->h_name;
|
||||
|
||||
/* normalize the domain */
|
||||
for ( s = client_name; *s; s++ ) {
|
||||
*s = TOLOWER( (unsigned char) *s );
|
||||
for ( p = client_name; *p; p++ ) {
|
||||
*p = TOLOWER( (unsigned char) *p );
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -277,72 +380,42 @@ slapd_daemon(
|
|||
/* DENY ACCESS */
|
||||
Statslog( LDAP_DEBUG_ANY,
|
||||
"fd=%d connection from %s (%s) denied.\n",
|
||||
ns,
|
||||
client_name == NULL ? "unknown" : client_name,
|
||||
client_addr == NULL ? "unknown" : client_addr,
|
||||
s,
|
||||
client_name == NULL ? "unknown" : client_name,
|
||||
client_addr == NULL ? "unknown" : client_addr,
|
||||
0, 0 );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
#endif /* HAVE_TCPD */
|
||||
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &ops_mutex );
|
||||
c[ns].c_connid = num_conns++;
|
||||
ldap_pvt_thread_mutex_unlock( &ops_mutex );
|
||||
if( (id = connection_init(s, client_name, client_addr)) < 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"daemon: connection_init(%d, %s, %s) failed.\n",
|
||||
s,
|
||||
client_name == NULL ? "unknown" : client_name,
|
||||
client_addr == NULL ? "unknown" : client_addr);
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS,
|
||||
"conn=%d fd=%d connection from %s (%s) accepted.\n",
|
||||
c[ns].c_connid, ns,
|
||||
client_name == NULL ? "unknown" : client_name,
|
||||
client_addr == NULL ? "unknown" : client_addr,
|
||||
0 );
|
||||
"daemon: conn=%d fd=%d connection from %s (%s) accepted.\n",
|
||||
id, s,
|
||||
client_name == NULL ? "unknown" : client_name,
|
||||
client_addr == NULL ? "unknown" : client_addr,
|
||||
0 );
|
||||
|
||||
if ( c[ns].c_addr != NULL ) {
|
||||
free( c[ns].c_addr );
|
||||
}
|
||||
c[ns].c_addr = ch_strdup( client_addr );
|
||||
|
||||
if ( c[ns].c_domain != NULL ) {
|
||||
free( c[ns].c_domain );
|
||||
}
|
||||
|
||||
c[ns].c_domain = ch_strdup( client_name == NULL
|
||||
? "" : client_name );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &c[ns].c_dnmutex );
|
||||
if ( c[ns].c_dn != NULL ) {
|
||||
free( c[ns].c_dn );
|
||||
c[ns].c_dn = NULL;
|
||||
}
|
||||
if ( c[ns].c_cdn != NULL ) {
|
||||
free( c[ns].c_cdn );
|
||||
c[ns].c_cdn = NULL;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &c[ns].c_dnmutex );
|
||||
|
||||
c[ns].c_starttime = currenttime;
|
||||
c[ns].c_ops_received = 0;
|
||||
c[ns].c_ops_executing = 0;
|
||||
c[ns].c_ops_pending = 0;
|
||||
c[ns].c_ops_completed = 0;
|
||||
|
||||
lber_pvt_sb_set_desc( &c[ns].c_sb, ns );
|
||||
lber_pvt_sb_set_io( &c[ns].c_sb, &lber_pvt_sb_io_tcp, NULL );
|
||||
|
||||
if (lber_pvt_sb_set_nonblock( &c[ns].c_sb, 1)<0) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"FIONBIO ioctl on %d failed\n", ns, 0, 0 );
|
||||
}
|
||||
|
||||
c[ns].c_state = SLAP_C_ACTIVE;
|
||||
slapd_add( s );
|
||||
continue;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "activity on:", 0, 0, 0 );
|
||||
for ( i = 0; i < dtblsize; i++ ) {
|
||||
int r, w;
|
||||
#ifdef LDAP_DEBUG
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
|
||||
|
||||
for ( i = 0; i < nfds; i++ ) {
|
||||
int a, r, w;
|
||||
|
||||
r = FD_ISSET( i, &readfds );
|
||||
w = FD_ISSET( i, &writefds );
|
||||
|
|
@ -351,42 +424,70 @@ slapd_daemon(
|
|||
r ? "r" : "", w ? "w" : "" );
|
||||
}
|
||||
}
|
||||
Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
|
||||
|
||||
for ( i = 0; i < dtblsize; i++ ) {
|
||||
if ( i == tcps || (! FD_ISSET( i, &readfds ) &&
|
||||
! FD_ISSET( i, &writefds )) ) {
|
||||
Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
|
||||
#endif
|
||||
|
||||
/* loop through the writers */
|
||||
for ( i = 0; i < nfds; i++ ) {
|
||||
if ( i == tcps ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( FD_ISSET( i, &writefds ) ) {
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"signaling write waiter on %d\n", i, 0, 0 );
|
||||
"daemon: signaling write waiter on %d\n", i, 0, 0 );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
active_threads++;
|
||||
c[i].c_writewaiter = 0;
|
||||
ldap_pvt_thread_cond_signal( &c[i].c_wcv );
|
||||
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
|
||||
assert( FD_ISSET( 0, &slap_daemon.sd_actives) );
|
||||
|
||||
/* clear the write flag */
|
||||
slapd_clr_write( i, 0 );
|
||||
|
||||
if( connection_write( i ) < 0 ) {
|
||||
FD_CLR( i, &readfds );
|
||||
slapd_close( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; i < nfds; i++ ) {
|
||||
if ( i == tcps ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( FD_ISSET( i, &readfds ) ||
|
||||
lber_pvt_sb_data_ready( &c[i].c_sb ) ) {
|
||||
if ( FD_ISSET( i, &readfds ) ) {
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"read activity on %d\n", i, 0, 0 );
|
||||
"daemon: read activity on %d\n", i, 0, 0 );
|
||||
|
||||
connection_activity( &c[i] );
|
||||
assert( FD_ISSET( i, &slap_daemon.sd_actives) );
|
||||
|
||||
if( connection_read( i ) < 0) {
|
||||
slapd_close( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ldap_pvt_thread_yield();
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"slapd shutdown: shutdown initiated.\n",
|
||||
0, 0, 0 );
|
||||
if( slapd_shutdown > 0 ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"daemon: shutdown requested and initiated.\n",
|
||||
0, 0, 0 );
|
||||
|
||||
close( tcps );
|
||||
} else if ( slapd_shutdown < 0 ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"daemon: abnormal condition, shutdown initiated.\n",
|
||||
0, 0, 0 );
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"daemon: no active streams, shutdown initiated.\n",
|
||||
0, 0, 0 );
|
||||
}
|
||||
|
||||
if( tcps >= 0 ) {
|
||||
close( tcps );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
|
|
@ -400,10 +501,28 @@ slapd_daemon(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int slapd_daemon( struct sockaddr_in *addr )
|
||||
{
|
||||
int status;
|
||||
|
||||
status = ldap_pvt_thread_create( &listener_tid, 0,
|
||||
slapd_daemon_task, addr );
|
||||
|
||||
if ( status != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"listener ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
|
||||
return -1;
|
||||
} else {
|
||||
/* wait for the listener thread to complete */
|
||||
ldap_pvt_thread_join( listener_tid, (void *) NULL );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
slap_set_shutdown( int sig )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY, "slapd got shutdown signal %d\n", sig, 0, 0 );
|
||||
slapd_shutdown = 1;
|
||||
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
|
||||
|
||||
|
|
@ -414,8 +533,6 @@ slap_set_shutdown( int sig )
|
|||
void
|
||||
slap_do_nothing( int sig )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "slapd got do_nothing signal %d\n", sig, 0, 0 );
|
||||
|
||||
/* reinstall self */
|
||||
(void) SIGNAL( sig, slap_do_nothing );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "slap.h"
|
||||
|
||||
/*
|
||||
|
|
@ -25,8 +24,6 @@ int ldap_syslog;
|
|||
|
||||
int ldap_syslog_level = LOG_DEBUG;
|
||||
char *default_referral;
|
||||
time_t starttime;
|
||||
ldap_pvt_thread_t listener_tid;
|
||||
int g_argc;
|
||||
char **g_argv;
|
||||
|
||||
|
|
@ -37,11 +34,7 @@ int active_threads;
|
|||
ldap_pvt_thread_mutex_t active_threads_mutex;
|
||||
ldap_pvt_thread_cond_t active_threads_cond;
|
||||
|
||||
time_t currenttime;
|
||||
ldap_pvt_thread_mutex_t currenttime_mutex;
|
||||
|
||||
ldap_pvt_thread_mutex_t new_conn_mutex;
|
||||
|
||||
ldap_pvt_thread_mutex_t gmtime_mutex;
|
||||
#ifdef SLAPD_CRYPT
|
||||
ldap_pvt_thread_mutex_t crypt_mutex;
|
||||
#endif
|
||||
|
|
@ -64,6 +57,9 @@ ldap_pvt_thread_mutex_t replog_mutex;
|
|||
static char* slap_name;
|
||||
int slapMode = SLAP_UNDEFINED_MODE;
|
||||
|
||||
static time_t currenttime;
|
||||
static ldap_pvt_thread_mutex_t currenttime_mutex;
|
||||
|
||||
int
|
||||
slap_init( int mode, char *name )
|
||||
{
|
||||
|
|
@ -98,12 +94,13 @@ slap_init( int mode, char *name )
|
|||
ldap_pvt_thread_mutex_init( &active_threads_mutex );
|
||||
ldap_pvt_thread_cond_init( &active_threads_cond );
|
||||
|
||||
ldap_pvt_thread_mutex_init( &new_conn_mutex );
|
||||
ldap_pvt_thread_mutex_init( ¤ttime_mutex );
|
||||
ldap_pvt_thread_mutex_init( &entry2str_mutex );
|
||||
ldap_pvt_thread_mutex_init( &replog_mutex );
|
||||
ldap_pvt_thread_mutex_init( &ops_mutex );
|
||||
ldap_pvt_thread_mutex_init( &num_sent_mutex );
|
||||
|
||||
ldap_pvt_thread_mutex_init( &gmtime_mutex );
|
||||
#ifdef SLAPD_CRYPT
|
||||
ldap_pvt_thread_mutex_init( &crypt_mutex );
|
||||
#endif
|
||||
|
|
@ -162,3 +159,20 @@ int slap_destroy(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* should create a utils.c for these */
|
||||
|
||||
void slap_set_time(void)
|
||||
{
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
time( ¤ttime );
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
}
|
||||
|
||||
time_t slap_get_time(void)
|
||||
{
|
||||
time_t t;
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
t = currenttime;
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
return t;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,13 +56,15 @@ usage( char *name )
|
|||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
time_t starttime;
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int i;
|
||||
int inetd = 0;
|
||||
int rc = 0;
|
||||
struct sockaddr_in bind_addr;
|
||||
int status, rc;
|
||||
struct sockaddr_in bind_addr, *slapd_addr;
|
||||
int udp;
|
||||
#ifdef LOG_LOCAL4
|
||||
int syslogUser = DEFAULT_SYSLOG_USER;
|
||||
|
|
@ -207,131 +209,62 @@ main( int argc, char **argv )
|
|||
goto destroy;
|
||||
}
|
||||
|
||||
if ( slap_startup(-1) != 0 ) {
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
if ( ! inetd ) {
|
||||
int status;
|
||||
|
||||
(void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing );
|
||||
(void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown );
|
||||
(void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing );
|
||||
(void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown );
|
||||
#ifdef SIGPIPE
|
||||
(void) SIGNAL( SIGPIPE, SIG_IGN );
|
||||
(void) SIGNAL( SIGPIPE, SIG_IGN );
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
(void) SIGNAL( SIGHUP, slap_set_shutdown );
|
||||
(void) SIGNAL( SIGHUP, slap_set_shutdown );
|
||||
#endif
|
||||
(void) SIGNAL( SIGINT, slap_set_shutdown );
|
||||
(void) SIGNAL( SIGTERM, slap_set_shutdown );
|
||||
(void) SIGNAL( SIGINT, slap_set_shutdown );
|
||||
(void) SIGNAL( SIGTERM, slap_set_shutdown );
|
||||
|
||||
if(!inetd) {
|
||||
#ifdef LDAP_DEBUG
|
||||
lutil_detach( ldap_debug, 0 );
|
||||
#else
|
||||
lutil_detach( 0, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
time( &starttime );
|
||||
if ( slap_startup(-1) != 0 ) {
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
status = ldap_pvt_thread_create( &listener_tid, 0,
|
||||
slapd_daemon, &bind_addr );
|
||||
if ( status != 0 )
|
||||
if(!inetd) {
|
||||
FILE *fp;
|
||||
|
||||
slapd_addr = &bind_addr;
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
|
||||
|
||||
if (( slapd_pid_file != NULL ) &&
|
||||
(( fp = fopen( slapd_pid_file, "w" )) != NULL ))
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"listener ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
|
||||
fprintf( fp, "%d\n", (int) getpid() );
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
|
||||
} else {
|
||||
/* wait for the listener thread to complete */
|
||||
ldap_pvt_thread_join( listener_tid, (void *) NULL );
|
||||
if (( slapd_args_file != NULL ) &&
|
||||
(( fp = fopen( slapd_args_file, "w" )) != NULL ))
|
||||
{
|
||||
for ( i = 0; i < g_argc; i++ ) {
|
||||
fprintf( fp, "%s ", g_argv[i] );
|
||||
}
|
||||
fprintf( fp, "\n" );
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
} else {
|
||||
Connection c;
|
||||
BerElement ber;
|
||||
unsigned long len, tag;
|
||||
long msgid;
|
||||
int flen;
|
||||
struct sockaddr_in from;
|
||||
struct hostent *hp;
|
||||
|
||||
c.c_dn = NULL;
|
||||
c.c_cdn = NULL;
|
||||
c.c_ops = NULL;
|
||||
|
||||
lber_pvt_sb_init( &c.c_sb );
|
||||
lber_pvt_sb_set_desc( &c.c_sb, 0 );
|
||||
lber_pvt_sb_set_io( &c.c_sb,
|
||||
(udp) ? &lber_pvt_sb_io_udp : &lber_pvt_sb_io_tcp,
|
||||
NULL );
|
||||
/* FIXME: handle udp here */
|
||||
|
||||
ldap_pvt_thread_mutex_init( &c.c_dnmutex );
|
||||
ldap_pvt_thread_mutex_init( &c.c_opsmutex );
|
||||
ldap_pvt_thread_mutex_init( &c.c_pdumutex );
|
||||
#ifdef notdefcldap
|
||||
c.c_sb.sb_addrs = (void **) saddrlist;
|
||||
c.c_sb.sb_fromaddr = &faddr;
|
||||
c.c_sb.sb_useaddr = saddrlist[ 0 ] = &saddr;
|
||||
#endif
|
||||
flen = sizeof(from);
|
||||
if ( getpeername( 0, (struct sockaddr *) &from, &flen ) == 0 ) {
|
||||
#ifdef SLAPD_RLOOKUPS
|
||||
hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
|
||||
sizeof(from.sin_addr.s_addr), AF_INET );
|
||||
#else
|
||||
hp = NULL;
|
||||
#endif
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
|
||||
hp == NULL ? "unknown" : hp->h_name,
|
||||
inet_ntoa( from.sin_addr ), 0 );
|
||||
|
||||
c.c_addr = inet_ntoa( from.sin_addr );
|
||||
c.c_domain = ch_strdup( hp == NULL ? "" : hp->h_name );
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_ARGS, "connection from unknown\n",
|
||||
0, 0, 0 );
|
||||
}
|
||||
|
||||
c.c_state = SLAP_C_ACTIVE;
|
||||
|
||||
ber_init_w_nullc( &ber, 0 );
|
||||
|
||||
while ( (tag = ber_get_next( &c.c_sb, &len, &ber ))
|
||||
== LDAP_TAG_MESSAGE ) {
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
time( ¤ttime );
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
|
||||
if ( (tag = ber_get_int( &ber, &msgid ))
|
||||
!= LDAP_TAG_MSGID ) {
|
||||
/* log and send error */
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"ber_get_int returns 0x%lx\n", tag, 0, 0 );
|
||||
ber_free( &ber, 1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( (tag = ber_peek_tag( &ber, &len ))
|
||||
== LBER_ERROR ) {
|
||||
/* log, close and send error */
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
|
||||
ber_free( &ber, 1 );
|
||||
lber_pvt_sb_close( &c.c_sb );
|
||||
lber_pvt_sb_destroy( &c.c_sb );
|
||||
return 1;
|
||||
}
|
||||
|
||||
connection_activity( &c );
|
||||
|
||||
ber_free( &ber, 1 );
|
||||
}
|
||||
slapd_addr = NULL;
|
||||
}
|
||||
|
||||
time( &starttime );
|
||||
|
||||
rc = slapd_daemon( slapd_addr );
|
||||
|
||||
shutdown:
|
||||
/* remember an error during shutdown */
|
||||
rc |= slap_shutdown(-1);
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ add_lastmods( Operation *op, LDAPModList **modlist )
|
|||
LDAPModList **m;
|
||||
LDAPModList *tmp;
|
||||
struct tm *ltm;
|
||||
time_t currenttime;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "add_lastmods\n", 0, 0, 0 );
|
||||
|
||||
|
|
@ -249,7 +250,8 @@ add_lastmods( Operation *op, LDAPModList **modlist )
|
|||
tmp->ml_next = *modlist;
|
||||
*modlist = tmp;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
currenttime = slap_get_time();
|
||||
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
|
||||
#ifndef LDAP_LOCALTIME
|
||||
ltm = gmtime( ¤ttime );
|
||||
strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
|
||||
|
|
@ -257,7 +259,8 @@ add_lastmods( Operation *op, LDAPModList **modlist )
|
|||
ltm = localtime( ¤ttime );
|
||||
strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
|
||||
#endif
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
|
||||
|
||||
bv.bv_val = buf;
|
||||
bv.bv_len = strlen( bv.bv_val );
|
||||
tmp = (LDAPModList *) ch_calloc( 1, sizeof(LDAPModList) );
|
||||
|
|
|
|||
|
|
@ -10,13 +10,6 @@
|
|||
* is provided ``as is'' without express or implied warranty.
|
||||
*/
|
||||
|
||||
/* Revision history
|
||||
*
|
||||
* 5-Jun-96 jeff.hodges@stanford.edu
|
||||
* Added locking of new_conn_mutex when traversing the c[] array.
|
||||
* Added locking of currenttime_mutex to protect call(s) to localtime().
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -40,6 +33,8 @@ monitor_info( Connection *conn, Operation *op )
|
|||
int i, nconns, nwritewaiters, nreadwaiters;
|
||||
struct tm *ltm;
|
||||
char *p;
|
||||
Connection *c;
|
||||
time_t currenttime;
|
||||
|
||||
vals[0] = &val;
|
||||
vals[1] = NULL;
|
||||
|
|
@ -59,7 +54,9 @@ monitor_info( Connection *conn, Operation *op )
|
|||
}
|
||||
attr_merge( e, "version", vals );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
sprintf( buf, "%d", active_threads );
|
||||
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "threads", vals );
|
||||
|
|
@ -68,49 +65,49 @@ monitor_info( Connection *conn, Operation *op )
|
|||
nwritewaiters = 0;
|
||||
nreadwaiters = 0;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
for ( i = 0; i < dtblsize; i++ ) {
|
||||
if ( lber_pvt_sb_in_use(&(c[i].c_sb)) ) {
|
||||
nconns++;
|
||||
if ( c[i].c_writewaiter ) {
|
||||
nwritewaiters++;
|
||||
}
|
||||
if ( c[i].c_gettingber ) {
|
||||
nreadwaiters++;
|
||||
}
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
#ifndef LDAP_LOCALTIME
|
||||
ltm = gmtime( &c[i].c_starttime );
|
||||
strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
|
||||
#else
|
||||
ltm = localtime( &c[i].c_starttime );
|
||||
strftime( buf2, sizeof(buf2), "%y%m%d%H%M%SZ", ltm );
|
||||
#endif
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &c[i].c_dnmutex );
|
||||
sprintf( buf, "%d : %s : %d : %d : %s : %s%s%s%s", i,
|
||||
buf2, c[i].c_ops_received, c[i].c_ops_completed,
|
||||
c[i].c_cdn ? c[i].c_cdn : "NULLDN",
|
||||
c[i].c_gettingber ? "r" : "",
|
||||
c[i].c_writewaiter ? "w" : "",
|
||||
c[i].c_ops_executing ? "x" : "",
|
||||
c[i].c_ops_pending ? "p" : ""
|
||||
);
|
||||
ldap_pvt_thread_mutex_unlock( &c[i].c_dnmutex );
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "connection", vals );
|
||||
#ifdef LDAP_COUNTERS
|
||||
/* loop through the connections */
|
||||
for ( c = connection_first() ; c != NULL; c = connection_next(c) ) {
|
||||
nconns++;
|
||||
if ( c->c_writewaiter ) {
|
||||
nwritewaiters++;
|
||||
}
|
||||
if ( c->c_currentber != NULL ) {
|
||||
nreadwaiters++;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
|
||||
#ifndef LDAP_LOCALTIME
|
||||
ltm = gmtime( &c->c_starttime );
|
||||
strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
|
||||
#else
|
||||
ltm = localtime( &c->.c_starttime );
|
||||
strftime( buf2, sizeof(buf2), "%y%m%d%H%M%SZ", ltm );
|
||||
#endif
|
||||
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
|
||||
|
||||
sprintf( buf, "%d : %s : %d : %d : %s : %s%s%s%s", i,
|
||||
buf2, c[i].c_ops_received, c[i].c_ops_completed,
|
||||
c[i].c_cdn ? c[i].c_cdn : "NULLDN",
|
||||
c[i].c_gettingber ? "r" : "",
|
||||
c[i].c_writewaiter ? "w" : "",
|
||||
c[i].c_ops_executing ? "x" : "",
|
||||
c[i].c_ops_pending ? "p" : ""
|
||||
);
|
||||
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "connection", vals );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
connection_done(c);
|
||||
#endif
|
||||
|
||||
sprintf( buf, "%d", nconns );
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "currentconnections", vals );
|
||||
|
||||
sprintf( buf, "%d", num_conns );
|
||||
sprintf( buf, "%ld", connections_nextid() );
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "totalconnections", vals );
|
||||
|
|
@ -130,6 +127,7 @@ monitor_info( Connection *conn, Operation *op )
|
|||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "readwaiters", vals );
|
||||
|
||||
#ifdef LDAP_COUNTERS
|
||||
sprintf( buf, "%ld", ops_initiated );
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
|
|
@ -149,8 +147,12 @@ monitor_info( Connection *conn, Operation *op )
|
|||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "bytessent", vals );
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
slap_set_time();
|
||||
currenttime = slap_get_time();
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
|
||||
#ifndef LDAP_LOCALTIME
|
||||
ltm = gmtime( ¤ttime );
|
||||
strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
|
||||
|
|
@ -158,12 +160,10 @@ monitor_info( Connection *conn, Operation *op )
|
|||
ltm = localtime( ¤ttime );
|
||||
strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
|
||||
#endif
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "currenttime", vals );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
#ifndef LDAP_LOCALTIME
|
||||
ltm = gmtime( &starttime );
|
||||
strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
|
||||
|
|
@ -171,7 +171,8 @@ monitor_info( Connection *conn, Operation *op )
|
|||
ltm = localtime( &starttime );
|
||||
strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
|
||||
#endif
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
|
||||
|
||||
val.bv_val = buf;
|
||||
val.bv_len = strlen( buf );
|
||||
attr_merge( e, "starttime", vals );
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ slap_op_free( Operation *op )
|
|||
{
|
||||
assert( op->o_next == NULL );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
||||
|
||||
if ( op->o_ber != NULL ) {
|
||||
ber_free( op->o_ber, 1 );
|
||||
}
|
||||
|
|
@ -27,8 +25,8 @@ slap_op_free( Operation *op )
|
|||
free( op->o_ndn );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
||||
ldap_pvt_thread_mutex_destroy( &op->o_abandonmutex );
|
||||
|
||||
free( (char *) op );
|
||||
}
|
||||
|
||||
|
|
@ -37,8 +35,7 @@ slap_op_alloc(
|
|||
BerElement *ber,
|
||||
unsigned long msgid,
|
||||
unsigned long tag,
|
||||
int id,
|
||||
int connid
|
||||
long id
|
||||
)
|
||||
{
|
||||
Operation *op;
|
||||
|
|
@ -46,19 +43,17 @@ slap_op_alloc(
|
|||
op = (Operation *) ch_calloc( 1, sizeof(Operation) );
|
||||
|
||||
ldap_pvt_thread_mutex_init( &op->o_abandonmutex );
|
||||
op->o_abandon = 0;
|
||||
|
||||
op->o_ber = ber;
|
||||
op->o_msgid = msgid;
|
||||
op->o_tag = tag;
|
||||
op->o_abandon = 0;
|
||||
|
||||
op->o_dn = NULL;
|
||||
op->o_ndn = NULL;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
op->o_time = currenttime;
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
op->o_time = slap_get_time();
|
||||
op->o_opid = id;
|
||||
op->o_connid = connid;
|
||||
op->o_next = NULL;
|
||||
|
||||
return( op );
|
||||
|
|
|
|||
|
|
@ -109,8 +109,20 @@ int read_config LDAP_P(( char *fname ));
|
|||
/*
|
||||
* connection.c
|
||||
*/
|
||||
int connections_init LDAP_P((void));
|
||||
|
||||
void connection_activity LDAP_P(( Connection *conn ));
|
||||
long connection_init LDAP_P((
|
||||
int s,
|
||||
const char* name, const char* addr));
|
||||
|
||||
int connection_write LDAP_P((int s));
|
||||
int connection_read LDAP_P((int s));
|
||||
|
||||
long connections_nextid(void);
|
||||
|
||||
Connection* connection_first LDAP_P((void));
|
||||
Connection* connection_next LDAP_P((Connection *));
|
||||
void connection_done LDAP_P((Connection *));
|
||||
|
||||
/*
|
||||
* dn.c
|
||||
|
|
@ -173,7 +185,7 @@ void monitor_info LDAP_P(( Connection *conn, Operation *op ));
|
|||
void slap_op_free LDAP_P(( Operation *op ));
|
||||
Operation * slap_op_alloc LDAP_P((
|
||||
BerElement *ber, unsigned long msgid,
|
||||
unsigned long tag, int id, int connid ));
|
||||
unsigned long tag, long id ));
|
||||
|
||||
int slap_op_add LDAP_P(( Operation **olist, Operation *op ));
|
||||
int slap_op_remove LDAP_P(( Operation **olist, Operation *op ));
|
||||
|
|
@ -202,7 +214,8 @@ void send_ldap_result LDAP_P(( Connection *conn, Operation *op, int err, char *m
|
|||
char *text ));
|
||||
void send_ldap_search_result LDAP_P(( Connection *conn, Operation *op, int err,
|
||||
char *matched, char *text, int nentries ));
|
||||
void close_connection LDAP_P(( Connection *conn, int opconnid, int opid ));
|
||||
|
||||
void do_close( Connection *conn, long opid );
|
||||
|
||||
/*
|
||||
* schema.c
|
||||
|
|
@ -244,7 +257,6 @@ char *suffixAlias LDAP_P(( char *dn, Operation *op, Backend *be ));
|
|||
* Other...
|
||||
*/
|
||||
|
||||
extern char **g_argv;
|
||||
extern char *default_referral;
|
||||
extern char *replogfile;
|
||||
extern char Versionstr[];
|
||||
|
|
@ -257,35 +269,48 @@ extern int global_lastmod;
|
|||
extern int global_schemacheck;
|
||||
extern int lber_debug;
|
||||
extern int ldap_syslog;
|
||||
extern int num_conns;
|
||||
|
||||
#ifdef LDAP_COUNTERS
|
||||
extern ldap_pvt_thread_mutex_t num_sent_mutex;
|
||||
extern long num_bytes_sent;
|
||||
|
||||
extern long num_entries_sent;
|
||||
|
||||
extern ldap_pvt_thread_mutex_t ops_mutex;
|
||||
extern long ops_completed;
|
||||
extern long ops_initiated;
|
||||
#endif
|
||||
|
||||
extern char *slapd_pid_file;
|
||||
extern char *slapd_args_file;
|
||||
extern char **g_argv;
|
||||
extern time_t starttime;
|
||||
|
||||
time_t slap_get_time LDAP_P((void));
|
||||
void slap_set_time LDAP_P((void));
|
||||
|
||||
extern ldap_pvt_thread_mutex_t active_threads_mutex;
|
||||
extern ldap_pvt_thread_cond_t active_threads_cond;
|
||||
|
||||
extern ldap_pvt_thread_mutex_t currenttime_mutex;
|
||||
extern ldap_pvt_thread_mutex_t entry2str_mutex;
|
||||
extern ldap_pvt_thread_mutex_t new_conn_mutex;
|
||||
extern ldap_pvt_thread_mutex_t num_sent_mutex;
|
||||
extern ldap_pvt_thread_mutex_t ops_mutex;
|
||||
extern ldap_pvt_thread_mutex_t replog_mutex;
|
||||
|
||||
#ifdef SLAPD_CRYPT
|
||||
extern ldap_pvt_thread_mutex_t crypt_mutex;
|
||||
#endif
|
||||
extern ldap_pvt_thread_t listener_tid;
|
||||
extern ldap_pvt_thread_mutex_t gmtime_mutex;
|
||||
|
||||
extern struct acl *global_acl;
|
||||
extern struct objclass *global_oc;
|
||||
extern time_t currenttime;
|
||||
|
||||
extern int slap_init LDAP_P((int mode, char* name));
|
||||
extern int slap_startup LDAP_P((int dbnum));
|
||||
extern int slap_shutdown LDAP_P((int dbnum));
|
||||
extern int slap_destroy LDAP_P((void));
|
||||
|
||||
extern void * slapd_daemon LDAP_P((void *port));
|
||||
struct sockaddr_in;
|
||||
extern int slapd_daemon LDAP_P((struct sockaddr_in *addr));
|
||||
|
||||
extern void slap_set_shutdown LDAP_P((int sig));
|
||||
extern void slap_do_nothing LDAP_P((int sig));
|
||||
|
||||
|
|
@ -303,11 +328,7 @@ extern void do_unbind LDAP_P((Connection *conn, Operation *op));
|
|||
extern int send_search_entry LDAP_P((Backend *be, Connection *conn, Operation *op, Entry *e, char **attrs, int attrsonly));
|
||||
extern int str2result LDAP_P(( char *s, int *code, char **matched, char **info ));
|
||||
|
||||
#if defined( SLAPD_MONITOR_DN )
|
||||
extern Connection *c;
|
||||
extern int dtblsize;
|
||||
extern time_t starttime;
|
||||
#endif
|
||||
extern int dtblsize;
|
||||
|
||||
#endif /* _proto_slap */
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ replog(
|
|||
i++ ) {
|
||||
fprintf( fp, "replica: %s\n", be->be_replica[i] );
|
||||
}
|
||||
fprintf( fp, "time: %ld\n", (long) currenttime );
|
||||
fprintf( fp, "time: %ld\n", (long) slap_get_time() );
|
||||
fprintf( fp, "dn: %s\n", dn );
|
||||
|
||||
switch ( optype ) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include "slap.h"
|
||||
|
||||
|
||||
static void
|
||||
send_ldap_result2(
|
||||
Connection *conn,
|
||||
|
|
@ -25,7 +24,7 @@ send_ldap_result2(
|
|||
)
|
||||
{
|
||||
BerElement *ber;
|
||||
int rc;
|
||||
int rc, tmp;
|
||||
unsigned long tag, bytes;
|
||||
|
||||
if ( err == LDAP_PARTIAL_RESULTS && (text == NULL || *text == '\0') )
|
||||
|
|
@ -52,12 +51,14 @@ send_ldap_result2(
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifdef LDAP_COMPAT30
|
||||
if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER ))
|
||||
== NULLBER ) {
|
||||
== NULLBER )
|
||||
#else
|
||||
if ( (ber = der_alloc()) == NULLBER ) {
|
||||
if ( (ber = der_alloc()) == NULLBER )
|
||||
#endif
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
|
||||
return;
|
||||
}
|
||||
|
|
@ -83,14 +84,15 @@ send_ldap_result2(
|
|||
}
|
||||
|
||||
/* write only one pdu at a time - wait til it's our turn */
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_pdumutex );
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
|
||||
|
||||
/* lock the connection */
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
/* write the pdu */
|
||||
bytes = ber->ber_ptr - ber->ber_buf;
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
while ( conn->c_connid == op->o_connid && ber_flush( &conn->c_sb, ber,
|
||||
1 ) != 0 ) {
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
|
||||
while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
|
||||
/*
|
||||
* we got an error. if it's ewouldblock, we need to
|
||||
* wait on the socket being writable. otherwise, figure
|
||||
|
|
@ -102,35 +104,29 @@ send_ldap_result2(
|
|||
: "unknown", 0 );
|
||||
|
||||
if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
|
||||
close_connection( conn, op->o_connid, op->o_opid );
|
||||
conn->c_conn_state = SLAP_C_CLOSING;
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
|
||||
return;
|
||||
}
|
||||
|
||||
/* wait for socket to be write-ready */
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
active_threads--;
|
||||
conn->c_writewaiter = 1;
|
||||
slapd_set_write( conn->c_sb.sb_sd, 1 );
|
||||
|
||||
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
|
||||
|
||||
ldap_pvt_thread_cond_wait( &conn->c_wcv, &active_threads_mutex );
|
||||
|
||||
if( active_threads < 1 ) {
|
||||
ldap_pvt_thread_cond_signal(&active_threads_cond);
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
|
||||
|
||||
ldap_pvt_thread_yield();
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
|
||||
conn->c_writewaiter = 0;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
|
||||
|
||||
#ifdef LDAP_COUNTERS
|
||||
ldap_pvt_thread_mutex_lock( &num_sent_mutex );
|
||||
num_bytes_sent += bytes;
|
||||
ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
|
||||
#endif
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS,
|
||||
"conn=%d op=%d RESULT err=%d tag=%lu nentries=%d\n", conn->c_connid,
|
||||
|
|
@ -186,7 +182,7 @@ send_search_entry(
|
|||
{
|
||||
BerElement *ber;
|
||||
Attribute *a;
|
||||
int i, rc, bytes;
|
||||
int i, rc=-1, bytes;
|
||||
struct acl *acl;
|
||||
char *edn;
|
||||
|
||||
|
|
@ -261,7 +257,7 @@ send_search_entry(
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( ber_printf( ber, "{s[", a->a_type ) == -1 ) {
|
||||
if (( rc = ber_printf( ber, "{s[", a->a_type )) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
|
||||
ber_free( ber, 1 );
|
||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
||||
|
|
@ -278,9 +274,9 @@ send_search_entry(
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( ber_printf( ber, "o",
|
||||
if (( rc = ber_printf( ber, "o",
|
||||
a->a_vals[i]->bv_val,
|
||||
a->a_vals[i]->bv_len ) == -1 )
|
||||
a->a_vals[i]->bv_len )) == -1 )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"ber_printf failed\n", 0, 0, 0 );
|
||||
|
|
@ -293,7 +289,7 @@ send_search_entry(
|
|||
}
|
||||
}
|
||||
|
||||
if ( ber_printf( ber, "]}" ) == -1 ) {
|
||||
if (( rc = ber_printf( ber, "]}" )) == -1 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
|
||||
ber_free( ber, 1 );
|
||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
||||
|
|
@ -317,14 +313,16 @@ send_search_entry(
|
|||
return( 1 );
|
||||
}
|
||||
|
||||
/* write only one pdu at a time - wait til it's our turn */
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_pdumutex );
|
||||
|
||||
bytes = ber->ber_ptr - ber->ber_buf;
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
while ( conn->c_connid == op->o_connid && ber_flush( &conn->c_sb, ber,
|
||||
1 ) != 0 ) {
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
|
||||
/* write only one pdu at a time - wait til it's our turn */
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
|
||||
|
||||
/* lock the connection */
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
/* write the pdu */
|
||||
while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
|
||||
/*
|
||||
* we got an error. if it's ewouldblock, we need to
|
||||
* wait on the socket being writable. otherwise, figure
|
||||
|
|
@ -336,51 +334,40 @@ send_search_entry(
|
|||
: "unknown", 0 );
|
||||
|
||||
if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
|
||||
close_connection( conn, op->o_connid, op->o_opid );
|
||||
conn->c_conn_state = SLAP_C_CLOSING;
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* wait for socket to be write-ready */
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
active_threads--;
|
||||
conn->c_writewaiter = 1;
|
||||
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
|
||||
ldap_pvt_thread_cond_wait( &conn->c_wcv, &active_threads_mutex );
|
||||
slapd_set_write( conn->c_sb.sb_sd, 1 );
|
||||
|
||||
if( active_threads < 1 ) {
|
||||
ldap_pvt_thread_cond_signal(&active_threads_cond);
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
|
||||
|
||||
ldap_pvt_thread_yield();
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
|
||||
conn->c_writewaiter = 0;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
|
||||
|
||||
#ifdef LDAP_COUNTERS
|
||||
ldap_pvt_thread_mutex_lock( &num_sent_mutex );
|
||||
num_bytes_sent += bytes;
|
||||
num_entries_sent++;
|
||||
ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
if ( conn->c_connid == op->o_connid ) {
|
||||
rc = 0;
|
||||
Statslog( LDAP_DEBUG_STATS2, "conn=%d op=%d ENTRY dn=\"%s\"\n",
|
||||
conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
Statslog( LDAP_DEBUG_STATS2, "conn=%d op=%d ENTRY dn=\"%s\"\n",
|
||||
conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "<= send_search_entry\n", 0, 0, 0 );
|
||||
|
||||
return( rc );
|
||||
rc = 0;
|
||||
|
||||
error_return:;
|
||||
return( 1 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -436,26 +423,3 @@ str2result(
|
|||
|
||||
return( rc );
|
||||
}
|
||||
|
||||
/*
|
||||
* close_connection - close a connection. takes the connection to close,
|
||||
* the connid associated with the operation generating the close (so we
|
||||
* don't accidentally close a connection that's not ours), and the opid
|
||||
* of the operation generating the close (for logging purposes).
|
||||
*/
|
||||
void
|
||||
close_connection( Connection *conn, int opconnid, int opid )
|
||||
{
|
||||
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
|
||||
if ( lber_pvt_sb_in_use(&conn->c_sb) && conn->c_connid == opconnid ) {
|
||||
Statslog( LDAP_DEBUG_STATS,
|
||||
"conn=%d op=%d fd=%d closed errno=%d\n", conn->c_connid,
|
||||
opid, lber_pvt_sb_get_desc(&conn->c_sb), errno, 0 );
|
||||
lber_pvt_sb_close( &conn->c_sb );
|
||||
lber_pvt_sb_destroy( &conn->c_sb );
|
||||
conn->c_version = 0;
|
||||
conn->c_protocol = 0;
|
||||
conn->c_state = SLAP_C_INACTIVE;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -380,27 +380,33 @@ struct backend_info {
|
|||
*/
|
||||
|
||||
typedef struct slap_op {
|
||||
long o_opid; /* id of this operation */
|
||||
long o_msgid; /* msgid of the request */
|
||||
|
||||
ldap_pvt_thread_t o_tid; /* thread handling this op */
|
||||
|
||||
BerElement *o_ber; /* ber of the request */
|
||||
long o_msgid; /* msgid of the request */
|
||||
|
||||
unsigned long o_tag; /* tag of the request */
|
||||
time_t o_time; /* time op was initiated */
|
||||
char *o_dn; /* dn bound when op was initiated */
|
||||
char *o_ndn; /* normalized dn bound when op was initiated */
|
||||
int o_authtype; /* auth method used to bind dn */
|
||||
int o_authtype; /* auth method used to bind dn */
|
||||
/* values taken from ldap.h */
|
||||
/* LDAP_AUTH_* */
|
||||
int o_opid; /* id of this operation */
|
||||
int o_connid; /* id of conn initiating this op */
|
||||
|
||||
/* long o_connid; *//* id of conn initiating this op */
|
||||
|
||||
#ifdef LDAP_CONNECTIONLESS
|
||||
int o_cldap; /* != 0 if this came in via CLDAP */
|
||||
struct sockaddr o_clientaddr; /* client address if via CLDAP */
|
||||
char o_searchbase; /* search base if via CLDAP */
|
||||
#endif
|
||||
struct slap_op *o_next; /* next operation in list */
|
||||
ldap_pvt_thread_t o_tid; /* thread handling this op */
|
||||
int o_abandon; /* signals op has been abandoned */
|
||||
ldap_pvt_thread_mutex_t o_abandonmutex; /* signals op has been abandoned */
|
||||
|
||||
ldap_pvt_thread_mutex_t o_abandonmutex; /* protects o_abandon */
|
||||
int o_abandon; /* abandon flag */
|
||||
|
||||
struct slap_op *o_next; /* next operation in list */
|
||||
void *o_private; /* anything the backend needs */
|
||||
} Operation;
|
||||
|
||||
|
|
@ -408,41 +414,56 @@ typedef struct slap_op {
|
|||
* represents a connection from an ldap client
|
||||
*/
|
||||
|
||||
#define SLAP_C_INACTIVE 0x0
|
||||
#define SLAP_C_ACTIVE 0x1
|
||||
#define SLAP_C_BINDING 0x2
|
||||
#define SLAP_C_CLOSING 0x3
|
||||
|
||||
/* structure state (protected by connections_mutex) */
|
||||
#define SLAP_C_UNINITIALIZED 0x0 /* MUST BE ZERO (0) */
|
||||
#define SLAP_C_UNUSED 0x1
|
||||
#define SLAP_C_USED 0x2
|
||||
|
||||
/* connection state (protected by c_mutex ) */
|
||||
#define SLAP_C_INVALID 0x0 /* MUST BE ZERO (0) */
|
||||
#define SLAP_C_INACTIVE 0x1 /* zero threads */
|
||||
#define SLAP_C_ACTIVE 0x2 /* one or more threads */
|
||||
#define SLAP_C_BINDING 0x3 /* binding */
|
||||
#define SLAP_C_CLOSING 0x4 /* closing */
|
||||
|
||||
typedef struct slap_conn {
|
||||
int c_state; /* connection state */
|
||||
int c_struct_state; /* structure management state */
|
||||
int c_conn_state; /* connection state */
|
||||
|
||||
ldap_pvt_thread_mutex_t c_mutex; /* protect the connection */
|
||||
Sockbuf c_sb; /* ber connection stuff */
|
||||
char *c_cdn; /* DN provided by the client */
|
||||
char *c_dn; /* DN bound to this conn */
|
||||
ldap_pvt_thread_mutex_t c_dnmutex; /* mutex for c_dn field */
|
||||
|
||||
/* only can be changed by connect_init */
|
||||
time_t c_starttime; /* when the connection was opened */
|
||||
long c_connid; /* id of this connection for stats*/
|
||||
char *c_client_addr; /* address of client */
|
||||
char *c_client_name; /* name of client */
|
||||
|
||||
/* only can be changed by binding thread */
|
||||
char *c_cdn; /* DN provided by the client */
|
||||
char *c_dn; /* DN bound to this conn */
|
||||
int c_protocol; /* version of the LDAP protocol used by client */
|
||||
int c_authtype; /* auth method used to bind c_dn */
|
||||
#ifdef LDAP_COMPAT
|
||||
int c_version; /* for compatibility w/2.0, 3.0 */
|
||||
#endif
|
||||
char *c_addr; /* address of client on this conn */
|
||||
char *c_domain; /* domain of client on this conn */
|
||||
|
||||
Operation *c_ops; /* list of operations being processed */
|
||||
Operation *c_pending_ops; /* list of pending operations */
|
||||
ldap_pvt_thread_mutex_t c_opsmutex; /* mutex for c_ops list & stats */
|
||||
ldap_pvt_thread_mutex_t c_pdumutex; /* only one pdu written at a time */
|
||||
ldap_pvt_thread_cond_t c_wcv; /* used to wait for sd write-ready*/
|
||||
int c_gettingber; /* in the middle of ber_get_next */
|
||||
BerElement *c_currentber; /* ber we're getting */
|
||||
int c_writewaiter; /* signals write-ready sd waiter */
|
||||
int c_pduwaiters; /* signals threads waiting 4 pdu */
|
||||
time_t c_starttime; /* when the connection was opened */
|
||||
|
||||
long c_connid; /* id of this connection for stats*/
|
||||
ldap_pvt_thread_mutex_t c_write_mutex; /* only one pdu written at a time */
|
||||
ldap_pvt_thread_cond_t c_write_cv; /* used to wait for sd write-ready*/
|
||||
|
||||
long c_ops_received; /* num of ops received (next op_id) */
|
||||
long c_ops_executing; /* num of ops currently executing */
|
||||
long c_ops_pending; /* num of ops pending execution */
|
||||
long c_ops_completed; /* num of ops completed */
|
||||
BerElement *c_currentber; /* ber we're attempting to read */
|
||||
int c_writewaiter; /* true if writer is waiting */
|
||||
|
||||
long c_n_ops_received; /* num of ops received (next op_id) */
|
||||
#ifdef LDAP_COUNTERS
|
||||
long c_n_ops_executing; /* num of ops currently executing */
|
||||
long c_n_ops_pending; /* num of ops pending execution */
|
||||
long c_n_ops_completed; /* num of ops completed */
|
||||
#endif
|
||||
} Connection;
|
||||
|
||||
#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ PROGRAMS2=ldif2index-bdb2 ldif2ldbm-bdb2 \
|
|||
ldif2id2entry-bdb2 ldif2id2children-bdb2
|
||||
|
||||
SRCS = centipede.c ldbmcat.c ldbmtest.c sizecount.c \
|
||||
ldif.c ldif2id2children.c ldif2id2entry.c ldif2index.c ldif2ldbm.c
|
||||
ldif.c ldif2id2children.c ldif2id2entry.c ldif2index.c ldif2ldbm.c \
|
||||
mimic.c
|
||||
|
||||
SRCS2 = ldif2id2children-bdb2.c ldif2id2entry-bdb2.c \
|
||||
ldif2index-bdb2.c ldif2ldbm-bdb2.c
|
||||
|
|
@ -41,8 +42,9 @@ XSRCS = edb2-vers.c
|
|||
EDB2LDIFSRCS = edb2ldif.c ldapsyntax.c
|
||||
EDB2LDIFOBJS = edb2ldif.o ldapsyntax.o
|
||||
|
||||
OBJS2 = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
|
||||
../aclparse.o ../schema.o ../result.o ../filterentry.o \
|
||||
OBJS2 = mimic.o \
|
||||
../config.o ../ch_malloc.o ../backend.o ../charray.o \
|
||||
../aclparse.o ../schema.o ../filterentry.o \
|
||||
../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \
|
||||
../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \
|
||||
../schemaparse.o
|
||||
|
|
|
|||
48
servers/slapd/tools/mimic.c
Normal file
48
servers/slapd/tools/mimic.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Mimic unused interfaces of slapd...
|
||||
* needed for linking.
|
||||
*/
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../slap.h"
|
||||
|
||||
void
|
||||
send_ldap_result(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
int err,
|
||||
char *matched,
|
||||
char *text
|
||||
)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
send_ldap_search_result(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
int err,
|
||||
char *matched,
|
||||
char *text,
|
||||
int nentries
|
||||
)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int
|
||||
send_search_entry(
|
||||
Backend *be,
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
char **attrs,
|
||||
int attrsonly
|
||||
)
|
||||
{
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -41,7 +41,4 @@ do_unbind(
|
|||
|
||||
/* pass the unbind to all backends */
|
||||
backend_unbind( conn, op );
|
||||
|
||||
/* close the connection to the client */
|
||||
close_connection( conn, op->o_connid, op->o_opid );
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue