From: Ondřej Kuzník Date: Wed, 27 Sep 2017 10:33:28 +0000 (+0100) Subject: Move client related functions to client.c X-Git-Tag: OPENLDAP_REL_ENG_2_5_1ALPHA~18^2~107 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=abab7e46add81b7dbf8bb2f31e99ac435d52fa15;p=thirdparty%2Fopenldap.git Move client related functions to client.c --- diff --git a/servers/lloadd/bind.c b/servers/lloadd/bind.c index 36df6db215..54b9d541b0 100644 --- a/servers/lloadd/bind.c +++ b/servers/lloadd/bind.c @@ -259,48 +259,6 @@ fail: } #endif /* LDAP_API_FEATURE_VERIFY_CREDENTIALS */ -void -client_reset( Connection *c ) -{ - TAvlnode *root; - - root = c->c_ops; - c->c_ops = NULL; - - /* unless op->o_client_refcnt > op->o_client_live, there is noone using the - * operation from the client side and noone new will now that we've removed - * it from client's c_ops */ - if ( root ) { - TAvlnode *node = tavl_end( root, TAVL_DIR_LEFT ); - do { - Operation *op = node->avl_data; - - /* make sure it's useable after we've unlocked the connection */ - op->o_client_refcnt++; - } while ( (node = tavl_next( node, TAVL_DIR_RIGHT )) ); - } - - if ( !BER_BVISNULL( &c->c_auth ) ) { - ch_free( c->c_auth.bv_val ); - BER_BVZERO( &c->c_auth ); - } - if ( !BER_BVISNULL( &c->c_sasl_bind_mech ) ) { - ch_free( c->c_sasl_bind_mech.bv_val ); - BER_BVZERO( &c->c_sasl_bind_mech ); - } - CONNECTION_UNLOCK_INCREF(c); - - if ( root ) { - int freed; - freed = tavl_free( root, (AVL_FREE)operation_abandon ); - Debug( LDAP_DEBUG_TRACE, "client_reset: " - "dropped %d operations\n", - freed ); - } - - CONNECTION_LOCK_DECREF(c); -} - int request_bind( Connection *client, Operation *op ) { diff --git a/servers/lloadd/client.c b/servers/lloadd/client.c index 9d8cb9dd7f..fe22f5c606 100644 --- a/servers/lloadd/client.c +++ b/servers/lloadd/client.c @@ -28,6 +28,166 @@ slap_c_head clients = LDAP_CIRCLEQ_HEAD_INITIALIZER( clients ); ldap_pvt_thread_mutex_t clients_mutex; +int +request_abandon( Connection *c, Operation *op ) +{ + Operation *request, needle = { .o_client_connid = c->c_connid }; + int rc = LDAP_SUCCESS; + + if ( ber_decode_int( &op->o_request, &needle.o_client_msgid ) ) { + Debug( LDAP_DEBUG_STATS, "request_abandon: " + "connid=%lu msgid=%d invalid integer sent in abandon request\n", + c->c_connid, op->o_client_msgid ); + + if ( operation_send_reject_locked( op, LDAP_PROTOCOL_ERROR, + "invalid PDU received", 0 ) == LDAP_SUCCESS ) { + CONNECTION_DESTROY(c); + } + return -1; + } + + request = tavl_find( c->c_ops, &needle, operation_client_cmp ); + if ( !request ) { + Debug( LDAP_DEBUG_STATS, "request_abandon: " + "connid=%lu msgid=%d requests abandon of an operation " + "msgid=%d not being processed anymore\n", + c->c_connid, op->o_client_msgid, needle.o_client_msgid ); + goto done; + } else if ( request->o_tag == LDAP_REQ_BIND ) { + /* RFC 4511 states we must not allow Abandon on Binds */ + Debug( LDAP_DEBUG_STATS, "request_abandon: " + "connid=%lu msgid=%d requests abandon of a bind operation " + "msgid=%d\n", + c->c_connid, op->o_client_msgid, needle.o_client_msgid ); + goto done; + } + Debug( LDAP_DEBUG_STATS, "request_abandon: " + "connid=%lu msgid=%d abandoning %s msgid=%d\n", + c->c_connid, op->o_client_msgid, slap_msgtype2str( request->o_tag ), + needle.o_client_msgid ); + + if ( c->c_state == LLOAD_C_BINDING ) { + /* We have found the request and we are binding, it must be a bind + * request */ + assert( request->o_tag == LDAP_REQ_BIND ); + c->c_state = LLOAD_C_READY; + } + + CONNECTION_UNLOCK_INCREF(c); + operation_abandon( request ); + CONNECTION_LOCK_DECREF(c); + +done: + operation_destroy_from_client( op ); + return rc; +} + +int +request_process( Connection *client, Operation *op ) +{ + BerElement *output; + Connection *upstream; + ber_int_t msgid; + int rc = LDAP_SUCCESS; + + op->o_client_refcnt++; + CONNECTION_UNLOCK_INCREF(client); + + upstream = backend_select( op ); + if ( !upstream ) { + Debug( LDAP_DEBUG_STATS, "request_process: " + "connid=%lu, msgid=%d no available connection found\n", + op->o_client_connid, op->o_client_msgid ); + + operation_send_reject( + op, LDAP_UNAVAILABLE, "no connections available", 1 ); + goto fail; + } + op->o_upstream = upstream; + op->o_upstream_connid = upstream->c_connid; + + output = upstream->c_pendingber; + if ( output == NULL && (output = ber_alloc()) == NULL ) { + rc = -1; + goto fail; + } + upstream->c_pendingber = output; + + CONNECTION_LOCK_DECREF(upstream); + op->o_upstream_msgid = msgid = upstream->c_next_msgid++; + rc = tavl_insert( + &upstream->c_ops, op, operation_upstream_cmp, avl_dup_error ); + CONNECTION_UNLOCK_INCREF(upstream); + + Debug( LDAP_DEBUG_TRACE, "request_process: " + "client connid=%lu added %s msgid=%d to upstream connid=%lu as " + "msgid=%d\n", + op->o_client_connid, slap_msgtype2str( op->o_tag ), + op->o_client_msgid, op->o_upstream_connid, op->o_upstream_msgid ); + assert( rc == LDAP_SUCCESS ); + + if ( (lload_features & LLOAD_FEATURE_PROXYAUTHZ) && + client->c_type != LLOAD_C_PRIVILEGED ) { + CONNECTION_LOCK_DECREF(client); + Debug( LDAP_DEBUG_TRACE, "request_process: " + "proxying identity %s to upstream\n", + client->c_auth.bv_val ); + ber_printf( output, "t{titOt{{sbO}" /* "}}" */, LDAP_TAG_MESSAGE, + LDAP_TAG_MSGID, msgid, + op->o_tag, &op->o_request, + LDAP_TAG_CONTROLS, + LDAP_CONTROL_PROXY_AUTHZ, 1, &client->c_auth ); + CONNECTION_UNLOCK_INCREF(client); + + if ( !BER_BVISNULL( &op->o_ctrls ) ) { + ber_write( output, op->o_ctrls.bv_val, op->o_ctrls.bv_len, 0 ); + } + + ber_printf( output, /* "{{" */ "}}" ); + } else { + ber_printf( output, "t{titOtO}", LDAP_TAG_MESSAGE, + LDAP_TAG_MSGID, msgid, + op->o_tag, &op->o_request, + LDAP_TAG_CONTROLS, BER_BV_OPTIONAL( &op->o_ctrls ) ); + } + ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex ); + + connection_write_cb( -1, 0, upstream ); + + CONNECTION_LOCK_DECREF(upstream); + CONNECTION_UNLOCK_OR_DESTROY(upstream); + + CONNECTION_LOCK_DECREF(client); + if ( !--op->o_client_refcnt ) { + operation_destroy_from_client( op ); + } + return rc; + +fail: + if ( upstream ) { + Backend *b; + + ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex ); + CONNECTION_LOCK_DECREF(upstream); + upstream->c_n_ops_executing--; + b = (Backend *)upstream->c_private; + CONNECTION_UNLOCK_OR_DESTROY(upstream); + + ldap_pvt_thread_mutex_lock( &b->b_mutex ); + b->b_n_ops_executing--; + ldap_pvt_thread_mutex_unlock( &b->b_mutex ); + + operation_send_reject( op, LDAP_OTHER, "internal error", 0 ); + } + CONNECTION_LOCK_DECREF(client); + op->o_client_refcnt--; + operation_destroy_from_client( op ); + if ( rc ) { + CONNECTION_DESTROY(client); + } + return rc; +} + int handle_one_request( Connection *c ) { @@ -153,6 +313,48 @@ fail: return NULL; } +void +client_reset( Connection *c ) +{ + TAvlnode *root; + + root = c->c_ops; + c->c_ops = NULL; + + /* unless op->o_client_refcnt > op->o_client_live, there is noone using the + * operation from the client side and noone new will now that we've removed + * it from client's c_ops */ + if ( root ) { + TAvlnode *node = tavl_end( root, TAVL_DIR_LEFT ); + do { + Operation *op = node->avl_data; + + /* make sure it's useable after we've unlocked the connection */ + op->o_client_refcnt++; + } while ( (node = tavl_next( node, TAVL_DIR_RIGHT )) ); + } + + if ( !BER_BVISNULL( &c->c_auth ) ) { + ch_free( c->c_auth.bv_val ); + BER_BVZERO( &c->c_auth ); + } + if ( !BER_BVISNULL( &c->c_sasl_bind_mech ) ) { + ch_free( c->c_sasl_bind_mech.bv_val ); + BER_BVZERO( &c->c_sasl_bind_mech ); + } + CONNECTION_UNLOCK_INCREF(c); + + if ( root ) { + int freed; + freed = tavl_free( root, (AVL_FREE)operation_abandon ); + Debug( LDAP_DEBUG_TRACE, "client_reset: " + "dropped %d operations\n", + freed ); + } + + CONNECTION_LOCK_DECREF(c); +} + void client_destroy( Connection *c ) { diff --git a/servers/lloadd/operation.c b/servers/lloadd/operation.c index 1d321cbe39..d3c5bbbd8e 100644 --- a/servers/lloadd/operation.c +++ b/servers/lloadd/operation.c @@ -609,60 +609,6 @@ done: CONNECTION_UNLOCK(c); } -int -request_abandon( Connection *c, Operation *op ) -{ - Operation *request, needle = { .o_client_connid = c->c_connid }; - int rc = LDAP_SUCCESS; - - if ( ber_decode_int( &op->o_request, &needle.o_client_msgid ) ) { - Debug( LDAP_DEBUG_STATS, "request_abandon: " - "connid=%lu msgid=%d invalid integer sent in abandon request\n", - c->c_connid, op->o_client_msgid ); - - if ( operation_send_reject_locked( op, LDAP_PROTOCOL_ERROR, - "invalid PDU received", 0 ) == LDAP_SUCCESS ) { - CONNECTION_DESTROY(c); - } - return -1; - } - - request = tavl_find( c->c_ops, &needle, operation_client_cmp ); - if ( !request ) { - Debug( LDAP_DEBUG_STATS, "request_abandon: " - "connid=%lu msgid=%d requests abandon of an operation " - "msgid=%d not being processed anymore\n", - c->c_connid, op->o_client_msgid, needle.o_client_msgid ); - goto done; - } else if ( request->o_tag == LDAP_REQ_BIND ) { - /* RFC 4511 states we must not allow Abandon on Binds */ - Debug( LDAP_DEBUG_STATS, "request_abandon: " - "connid=%lu msgid=%d requests abandon of a bind operation " - "msgid=%d\n", - c->c_connid, op->o_client_msgid, needle.o_client_msgid ); - goto done; - } - Debug( LDAP_DEBUG_STATS, "request_abandon: " - "connid=%lu msgid=%d abandoning %s msgid=%d\n", - c->c_connid, op->o_client_msgid, slap_msgtype2str( request->o_tag ), - needle.o_client_msgid ); - - if ( c->c_state == LLOAD_C_BINDING ) { - /* We have found the request and we are binding, it must be a bind - * request */ - assert( request->o_tag == LDAP_REQ_BIND ); - c->c_state = LLOAD_C_READY; - } - - CONNECTION_UNLOCK_INCREF(c); - operation_abandon( request ); - CONNECTION_LOCK_DECREF(c); - -done: - operation_destroy_from_client( op ); - return rc; -} - /* * Called with op->o_client non-NULL and already locked. */ @@ -780,109 +726,3 @@ operation_lost_upstream( Operation *op ) operation_destroy_from_upstream( op ); CONNECTION_UNLOCK(c); } - -int -request_process( Connection *client, Operation *op ) -{ - BerElement *output; - Connection *upstream; - ber_int_t msgid; - int rc = LDAP_SUCCESS; - - op->o_client_refcnt++; - CONNECTION_UNLOCK_INCREF(client); - - upstream = backend_select( op ); - if ( !upstream ) { - Debug( LDAP_DEBUG_STATS, "request_process: " - "connid=%lu, msgid=%d no available connection found\n", - op->o_client_connid, op->o_client_msgid ); - - operation_send_reject( - op, LDAP_UNAVAILABLE, "no connections available", 1 ); - goto fail; - } - op->o_upstream = upstream; - op->o_upstream_connid = upstream->c_connid; - - output = upstream->c_pendingber; - if ( output == NULL && (output = ber_alloc()) == NULL ) { - rc = -1; - goto fail; - } - upstream->c_pendingber = output; - - CONNECTION_LOCK_DECREF(upstream); - op->o_upstream_msgid = msgid = upstream->c_next_msgid++; - rc = tavl_insert( - &upstream->c_ops, op, operation_upstream_cmp, avl_dup_error ); - CONNECTION_UNLOCK_INCREF(upstream); - - Debug( LDAP_DEBUG_TRACE, "request_process: " - "client connid=%lu added %s msgid=%d to upstream connid=%lu as " - "msgid=%d\n", - op->o_client_connid, slap_msgtype2str( op->o_tag ), - op->o_client_msgid, op->o_upstream_connid, op->o_upstream_msgid ); - assert( rc == LDAP_SUCCESS ); - - if ( (lload_features & LLOAD_FEATURE_PROXYAUTHZ) && - client->c_type != LLOAD_C_PRIVILEGED ) { - CONNECTION_LOCK_DECREF(client); - Debug( LDAP_DEBUG_TRACE, "request_process: " - "proxying identity %s to upstream\n", - client->c_auth.bv_val ); - ber_printf( output, "t{titOt{{sbO}" /* "}}" */, LDAP_TAG_MESSAGE, - LDAP_TAG_MSGID, msgid, - op->o_tag, &op->o_request, - LDAP_TAG_CONTROLS, - LDAP_CONTROL_PROXY_AUTHZ, 1, &client->c_auth ); - CONNECTION_UNLOCK_INCREF(client); - - if ( !BER_BVISNULL( &op->o_ctrls ) ) { - ber_write( output, op->o_ctrls.bv_val, op->o_ctrls.bv_len, 0 ); - } - - ber_printf( output, /* "{{" */ "}}" ); - } else { - ber_printf( output, "t{titOtO}", LDAP_TAG_MESSAGE, - LDAP_TAG_MSGID, msgid, - op->o_tag, &op->o_request, - LDAP_TAG_CONTROLS, BER_BV_OPTIONAL( &op->o_ctrls ) ); - } - ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex ); - - connection_write_cb( -1, 0, upstream ); - - CONNECTION_LOCK_DECREF(upstream); - CONNECTION_UNLOCK_OR_DESTROY(upstream); - - CONNECTION_LOCK_DECREF(client); - if ( !--op->o_client_refcnt ) { - operation_destroy_from_client( op ); - } - return rc; - -fail: - if ( upstream ) { - Backend *b; - - ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex ); - CONNECTION_LOCK_DECREF(upstream); - upstream->c_n_ops_executing--; - b = (Backend *)upstream->c_private; - CONNECTION_UNLOCK_OR_DESTROY(upstream); - - ldap_pvt_thread_mutex_lock( &b->b_mutex ); - b->b_n_ops_executing--; - ldap_pvt_thread_mutex_unlock( &b->b_mutex ); - - operation_send_reject( op, LDAP_OTHER, "internal error", 0 ); - } - CONNECTION_LOCK_DECREF(client); - op->o_client_refcnt--; - operation_destroy_from_client( op ); - if ( rc ) { - CONNECTION_DESTROY(client); - } - return rc; -} diff --git a/servers/lloadd/proto-slap.h b/servers/lloadd/proto-slap.h index ae2267dbe0..603ffb915e 100644 --- a/servers/lloadd/proto-slap.h +++ b/servers/lloadd/proto-slap.h @@ -64,14 +64,16 @@ LDAP_SLAPD_F (void) ch_free( void * ); /* * bind.c */ -LDAP_SLAPD_F (void) client_reset( Connection *c ); LDAP_SLAPD_F (int) request_bind( Connection *c, Operation *op ); /* * client.c */ +LDAP_SLAPD_F (int) request_abandon( Connection *c, Operation *op ); +LDAP_SLAPD_F (int) request_process( Connection *c, Operation *op ); LDAP_SLAPD_F (int) handle_one_request( Connection *c ); LDAP_SLAPD_F (Connection *) client_init( ber_socket_t s, Listener *url, const char *peername, struct event_base *base, int use_tls ); +LDAP_SLAPD_F (void) client_reset( Connection *c ); LDAP_SLAPD_F (void) client_destroy( Connection *c ); LDAP_SLAPD_F (void) clients_destroy( void ); @@ -171,8 +173,6 @@ LDAP_SLAPD_F (int) operation_send_reject_locked( Operation *op, int result, cons LDAP_SLAPD_F (void) operation_lost_upstream( Operation *op ); LDAP_SLAPD_F (void) operation_destroy_from_client( Operation *op ); LDAP_SLAPD_F (void) operation_destroy_from_upstream( Operation *op ); -LDAP_SLAPD_F (int) request_abandon( Connection *c, Operation *op ); -LDAP_SLAPD_F (int) request_process( Connection *c, Operation *op ); /* * sl_malloc.c