~ttx/openldap/lucid-gssapi-495418

« back to all changes in this revision

Viewing changes to servers/slapd/connection.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2009-07-28 10:17:15 UTC
  • mto: (0.3.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20090728101715-g0isvetelfeqm48k
Tags: upstream-2.4.17
ImportĀ upstreamĀ versionĀ 2.4.17

Show diffs side-by-side

added added

removed removed

Lines of Context:
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/>.
3
3
 *
4
4
 * Copyright 1998-2009 The OpenLDAP Foundation.
53
53
static const char conn_lost_str[] = "connection lost";
54
54
 
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) */
 
58
        SLAP_C_UNUSED,
 
59
        SLAP_C_USED,
 
60
        SLAP_C_PENDING
 
61
};
60
62
 
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 */
 
64
enum sc_conn_state {
 
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 */
 
71
};
68
72
 
69
73
const char *
70
74
connection_state2str( int state )
72
76
        switch( 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";
79
83
        }
80
84
 
218
222
 */
219
223
int connections_timeout_idle(time_t now)
220
224
{
221
 
        int i = 0;
 
225
        int i = 0, writers = 0;
222
226
        int connindex;
223
227
        Connection* c;
 
228
        time_t old;
 
229
 
 
230
        old = slapd_get_writetime();
224
231
 
225
232
        for( c = connection_first( &connindex );
226
233
                c != NULL;
227
234
                c = connection_next( c, &connindex ) )
228
235
        {
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.
 
239
                 */
 
240
                if(( c->c_n_ops_executing && !c->c_writewaiter)
 
241
                        || c->c_conn_state == SLAP_C_CLIENT ) {
232
242
                        continue;
233
243
                }
234
244
 
237
247
                        connection_closing( c, "idletimeout" );
238
248
                        connection_close( c );
239
249
                        i++;
 
250
                        continue;
 
251
                }
 
252
                if ( c->c_writewaiter ) {
 
253
                        writers = 1;
 
254
                        if( difftime( c->c_activitytime+global_writetimeout, now) < 0 ) {
 
255
                                /* close it */
 
256
                                connection_closing( c, "writetimeout" );
 
257
                                connection_close( c );
 
258
                                i++;
 
259
                        }
240
260
                }
241
261
        }
242
262
        connection_done( c );
 
263
        if ( !writers )
 
264
                slapd_clr_writetime( old );
243
265
 
244
266
        return i;
245
267
}
677
699
        }
678
700
}
679
701
 
680
 
int connection_state_closing( Connection *c )
 
702
int connection_valid( Connection *c )
681
703
{
682
704
        /* c_mutex must be locked by caller */
683
705
 
684
 
        int state;
685
706
        assert( c != NULL );
686
 
        assert( c->c_struct_state == SLAP_C_USED );
687
 
 
688
 
        state = c->c_conn_state;
689
 
 
690
 
        assert( state != SLAP_C_INVALID );
691
 
 
692
 
        return state == SLAP_C_CLOSING;
 
707
 
 
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;
693
711
}
694
712
 
695
713
static void connection_abandon( Connection *c )
1003
1021
static void *
1004
1022
connection_operation( void *ctx, void *arg_v )
1005
1023
{
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 );
1108
1126
        }
1109
1127
 
1110
 
        if ( op->o_cancel == SLAP_CANCEL_REQ ) {
1111
 
                if ( rc == SLAPD_ABANDON ) {
1112
 
                        op->o_cancel = SLAP_CANCEL_ACK;
1113
 
                } else {
1114
 
                        op->o_cancel = LDAP_TOO_LATE;
1115
 
                }
1116
 
        }
1117
 
 
1118
 
        while ( op->o_cancel != SLAP_CANCEL_NONE &&
1119
 
                op->o_cancel != SLAP_CANCEL_DONE )
1120
 
        {
1121
 
                ldap_pvt_thread_yield();
1122
 
        }
1123
 
 
1124
1128
        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
1125
1129
 
 
1130
        if ( opidx == SLAP_OP_BIND && conn->c_conn_state == SLAP_C_BINDING )
 
1131
                conn->c_conn_state = SLAP_C_ACTIVE;
 
1132
 
 
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;
 
1138
                }
 
1139
 
 
1140
                do {
 
1141
                        /* Fake a cond_wait with thread_yield, then
 
1142
                         * verify the result properly mutex-protected.
 
1143
                         */
 
1144
                        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
1145
                        do {
 
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 );
 
1152
        }
 
1153
 
1126
1154
        ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
1127
1155
 
1128
1156
        LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
1253
1281
        return rc;
1254
1282
}
1255
1283
 
1256
 
void
1257
 
connection_hangup( ber_socket_t s )
1258
 
{
1259
 
        Connection *c;
1260
 
 
1261
 
        c = connection_get( s );
1262
 
        if ( c ) {
1263
 
                if ( c->c_conn_state == SLAP_C_CLIENT ) {
1264
 
                        connection_return( c );
1265
 
                        connection_read_activate( s );
1266
 
                } else {
1267
 
                        connection_closing( c, "connection lost" );
1268
 
                        connection_close( c );
1269
 
                        connection_return( c );
1270
 
                }
1271
 
        }
1272
 
}
1273
 
 
1274
1284
static int
1275
1285
connection_read( ber_socket_t s, conn_readinfo *cri )
1276
1286
{
1527
1537
        ctx = cri->ctx;
1528
1538
        op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++, ctx );
1529
1539
 
 
1540
        Debug( LDAP_DEBUG_TRACE, "op tag 0x%lx, time %ld\n", tag,
 
1541
                (long) op->o_time, 0);
 
1542
 
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 )
1713
1726
{
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 );
1719
1730
 
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;