1
/* $OpenLDAP: pkg/ldap/servers/slapd/connection.c,v 1.358.2.24 2009/01/30 18:51:16 quanah Exp $ */
1
/* $OpenLDAP: pkg/ldap/servers/slapd/connection.c,v 1.358.2.31 2009/06/28 19:41:27 quanah Exp $ */
2
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
4
* Copyright 1998-2009 The OpenLDAP Foundation.
53
53
static const char conn_lost_str[] = "connection lost";
55
55
/* structure state (protected by connections_mutex) */
56
#define SLAP_C_UNINITIALIZED 0x00 /* MUST BE ZERO (0) */
57
#define SLAP_C_UNUSED 0x01
58
#define SLAP_C_USED 0x02
59
#define SLAP_C_PENDING 0x03
56
enum sc_struct_state {
57
SLAP_C_UNINITIALIZED = 0, /* MUST BE ZERO (0) */
61
63
/* connection state (protected by c_mutex ) */
62
#define SLAP_C_INVALID 0x00 /* MUST BE ZERO (0) */
63
#define SLAP_C_INACTIVE 0x01 /* zero threads */
64
#define SLAP_C_ACTIVE 0x02 /* one or more threads */
65
#define SLAP_C_BINDING 0x03 /* binding */
66
#define SLAP_C_CLOSING 0x04 /* closing */
67
#define SLAP_C_CLIENT 0x05 /* outbound client conn */
65
SLAP_C_INVALID = 0, /* MUST BE ZERO (0) */
66
SLAP_C_INACTIVE, /* zero threads */
67
SLAP_C_CLOSING, /* closing */
68
SLAP_C_ACTIVE, /* one or more threads */
69
SLAP_C_BINDING, /* binding */
70
SLAP_C_CLIENT /* outbound client conn */
70
74
connection_state2str( int state )
73
77
case SLAP_C_INVALID: return "!";
74
78
case SLAP_C_INACTIVE: return "|";
79
case SLAP_C_CLOSING: return "C";
75
80
case SLAP_C_ACTIVE: return "";
76
81
case SLAP_C_BINDING: return "B";
77
case SLAP_C_CLOSING: return "C";
78
82
case SLAP_C_CLIENT: return "L";
219
223
int connections_timeout_idle(time_t now)
225
int i = 0, writers = 0;
230
old = slapd_get_writetime();
225
232
for( c = connection_first( &connindex );
227
234
c = connection_next( c, &connindex ) )
229
236
/* Don't timeout a slow-running request or a persistent
230
* outbound connection */
231
if( c->c_n_ops_executing || c->c_conn_state == SLAP_C_CLIENT ) {
237
* outbound connection. But if it has a writewaiter, see
238
* if the waiter has been there too long.
240
if(( c->c_n_ops_executing && !c->c_writewaiter)
241
|| c->c_conn_state == SLAP_C_CLIENT ) {
237
247
connection_closing( c, "idletimeout" );
238
248
connection_close( c );
252
if ( c->c_writewaiter ) {
254
if( difftime( c->c_activitytime+global_writetimeout, now) < 0 ) {
256
connection_closing( c, "writetimeout" );
257
connection_close( c );
242
262
connection_done( c );
264
slapd_clr_writetime( old );
680
int connection_state_closing( Connection *c )
702
int connection_valid( Connection *c )
682
704
/* c_mutex must be locked by caller */
685
706
assert( c != NULL );
686
assert( c->c_struct_state == SLAP_C_USED );
688
state = c->c_conn_state;
690
assert( state != SLAP_C_INVALID );
692
return state == SLAP_C_CLOSING;
708
return c->c_struct_state == SLAP_C_USED &&
709
c->c_conn_state >= SLAP_C_ACTIVE &&
710
c->c_conn_state <= SLAP_C_CLIENT;
695
713
static void connection_abandon( Connection *c )
1004
1022
connection_operation( void *ctx, void *arg_v )
1006
int rc = LDAP_OTHER;
1024
int rc = LDAP_OTHER, cancel;
1007
1025
Operation *op = arg_v;
1008
1026
SlapReply rs = {REP_RESULT};
1009
1027
ber_tag_t tag = op->o_tag;
1107
1125
INCR_OP_COMPLETED( opidx );
1110
if ( op->o_cancel == SLAP_CANCEL_REQ ) {
1111
if ( rc == SLAPD_ABANDON ) {
1112
op->o_cancel = SLAP_CANCEL_ACK;
1114
op->o_cancel = LDAP_TOO_LATE;
1118
while ( op->o_cancel != SLAP_CANCEL_NONE &&
1119
op->o_cancel != SLAP_CANCEL_DONE )
1121
ldap_pvt_thread_yield();
1124
1128
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
1130
if ( opidx == SLAP_OP_BIND && conn->c_conn_state == SLAP_C_BINDING )
1131
conn->c_conn_state = SLAP_C_ACTIVE;
1133
cancel = op->o_cancel;
1134
if ( cancel != SLAP_CANCEL_NONE && cancel != SLAP_CANCEL_DONE ) {
1135
if ( cancel == SLAP_CANCEL_REQ ) {
1136
op->o_cancel = rc == SLAPD_ABANDON
1137
? SLAP_CANCEL_ACK : LDAP_TOO_LATE;
1141
/* Fake a cond_wait with thread_yield, then
1142
* verify the result properly mutex-protected.
1144
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
1146
ldap_pvt_thread_yield();
1147
} while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE
1148
&& cancel != SLAP_CANCEL_DONE );
1149
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
1150
} while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE
1151
&& cancel != SLAP_CANCEL_DONE );
1126
1154
ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
1128
1156
LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
1257
connection_hangup( ber_socket_t s )
1261
c = connection_get( s );
1263
if ( c->c_conn_state == SLAP_C_CLIENT ) {
1264
connection_return( c );
1265
connection_read_activate( s );
1267
connection_closing( c, "connection lost" );
1268
connection_close( c );
1269
connection_return( c );
1275
1285
connection_read( ber_socket_t s, conn_readinfo *cri )
1527
1537
ctx = cri->ctx;
1528
1538
op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++, ctx );
1540
Debug( LDAP_DEBUG_TRACE, "op tag 0x%lx, time %ld\n", tag,
1541
(long) op->o_time, 0);
1530
1543
op->o_conn = conn;
1531
1544
/* clear state if the connection is being reused from inactive */
1532
1545
if ( conn->c_conn_state == SLAP_C_INACTIVE ) {
1712
1725
static int connection_bind_cb( Operation *op, SlapReply *rs )
1714
1727
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
1715
if ( op->o_conn->c_conn_state == SLAP_C_BINDING )
1716
op->o_conn->c_conn_state = SLAP_C_ACTIVE;
1717
1728
op->o_conn->c_sasl_bind_in_progress =
1718
1729
( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS );
1966
1977
conn->c_send_ldap_result = slap_send_ldap_result;
1967
1978
conn->c_send_search_entry = slap_send_search_entry;
1968
1979
conn->c_send_search_reference = slap_send_search_reference;
1980
conn->c_send_ldap_extended = slap_send_ldap_extended;
1981
conn->c_send_ldap_intermediate = slap_send_ldap_intermediate;
1969
1982
conn->c_listener = (Listener *)&dummy_list;
1970
1983
conn->c_peer_domain = slap_empty_bv;
1971
1984
conn->c_peer_name = slap_empty_bv;