X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fconnection.c;h=7d14e0c81875bdfd0ff815b358c1f78308a8e38e;hb=ef7f5f5e32e6e0f129aee7fa1626017a7dadcb48;hp=80edfb0fd0685d7c56546d412d3e009e6dfea79a;hpb=99381a43e12d9ea051dce6f1b037e867e76931d1;p=openldap diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 80edfb0fd0..7d14e0c818 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2009 The OpenLDAP Foundation. + * Copyright 1998-2011 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,10 @@ #include "lutil.h" #include "slap.h" +#ifdef LDAP_CONNECTIONLESS +#include "../../libraries/liblber/lber-int.h" /* ber_int_sb_read() */ +#endif + #ifdef LDAP_SLAPI #include "slapi/slapi.h" #endif @@ -48,28 +52,10 @@ static ldap_pvt_thread_mutex_t connections_mutex; static Connection *connections = NULL; static ldap_pvt_thread_mutex_t conn_nextid_mutex; -static unsigned long conn_nextid = 0; +static unsigned long conn_nextid = SLAPD_SYNC_SYNCCONN_OFFSET; static const char conn_lost_str[] = "connection lost"; -/* structure state (protected by connections_mutex) */ -enum sc_struct_state { - SLAP_C_UNINITIALIZED = 0, /* MUST BE ZERO (0) */ - SLAP_C_UNUSED, - SLAP_C_USED, - SLAP_C_PENDING -}; - -/* connection state (protected by c_mutex ) */ -enum sc_conn_state { - SLAP_C_INVALID = 0, /* MUST BE ZERO (0) */ - SLAP_C_INACTIVE, /* zero threads */ - SLAP_C_CLOSING, /* closing */ - SLAP_C_ACTIVE, /* one or more threads */ - SLAP_C_BINDING, /* binding */ - SLAP_C_CLIENT /* outbound client conn */ -}; - const char * connection_state2str( int state ) { @@ -239,6 +225,7 @@ int connections_timeout_idle(time_t now) */ if(( c->c_n_ops_executing && !c->c_writewaiter) || c->c_conn_state == SLAP_C_CLIENT ) { + connection_done( c ); continue; } @@ -257,16 +244,40 @@ int connections_timeout_idle(time_t now) connection_closing( c, "writetimeout" ); connection_close( c ); i++; + continue; } } + connection_done( c ); } - connection_done( c ); if ( old && !writers ) slapd_clr_writetime( old ); return i; } +/* Drop all client connections */ +void connections_drop() +{ + Connection* c; + int connindex; + + for( c = connection_first( &connindex ); + c != NULL; + c = connection_next( c, &connindex ) ) + { + /* Don't close a slow-running request or a persistent + * outbound connection. + */ + if(( c->c_n_ops_executing && !c->c_writewaiter) + || c->c_conn_state == SLAP_C_CLIENT ) { + connection_done( c ); + continue; + } + connection_closing( c, "dropping" ); + connection_close( c ); + } +} + static Connection* connection_get( ber_socket_t s ) { Connection *c; @@ -290,12 +301,11 @@ static Connection* connection_get( ber_socket_t s ) if( c->c_struct_state != SLAP_C_USED ) { /* connection must have been closed due to resched */ - assert( c->c_conn_state == SLAP_C_INVALID ); - assert( c->c_sd == AC_SOCKET_INVALID ); - Debug( LDAP_DEBUG_CONNS, "connection_get(%d): connection not used\n", s, 0, 0 ); + assert( c->c_conn_state == SLAP_C_INVALID ); + assert( c->c_sd == AC_SOCKET_INVALID ); ldap_pvt_thread_mutex_unlock( &c->c_mutex ); return NULL; @@ -561,9 +571,9 @@ Connection * connection_init( slap_sasl_external( c, ssf, authid ); slapd_add_internal( s, 1 ); - ldap_pvt_thread_mutex_unlock( &c->c_mutex ); backend_connection_init(c); + ldap_pvt_thread_mutex_unlock( &c->c_mutex ); return c; } @@ -717,7 +727,6 @@ static void connection_abandon( Connection *c ) Operation *o, *next, op = {0}; Opheader ohdr = {0}; - SlapReply rs = {0}; op.o_hdr = &ohdr; op.o_conn = c; @@ -725,6 +734,8 @@ static void connection_abandon( Connection *c ) op.o_tag = LDAP_REQ_ABANDON; for ( o = LDAP_STAILQ_FIRST( &c->c_ops ); o; o=next ) { + SlapReply rs = {REP_RESULT}; + next = LDAP_STAILQ_NEXT( o, o_next ); op.orn_msgid = o->o_msgid; o->o_abandon = 1; @@ -1380,8 +1391,8 @@ connection_read( ber_socket_t s, conn_readinfo *cri ) c->c_connid, (int) s, c->c_tls_ssf, c->c_ssf, 0 ); slap_sasl_external( c, c->c_tls_ssf, &authid ); if ( authid.bv_val ) free( authid.bv_val ); - } else if ( rc == 1 ) { /* need to retry */ - slapd_set_read( s, 0 ); + } else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb, + LBER_SB_OPT_NEEDS_WRITE, NULL )) { /* need to retry */ slapd_set_write( s, 1 ); connection_return( c ); return 0; @@ -1489,12 +1500,20 @@ connection_input( Connection *conn , conn_readinfo *cri ) #ifdef LDAP_CONNECTIONLESS if ( conn->c_is_udp ) { char peername[sizeof("IP=255.255.255.255:65336")]; + const char *peeraddr_string = NULL; len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(struct sockaddr)); if (len != sizeof(struct sockaddr)) return 1; +#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) + char addr[INET_ADDRSTRLEN]; + peeraddr_string = inet_ntop( AF_INET, &peeraddr.sa_in_addr.sin_addr, + addr, sizeof(addr) ); +#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ + peeraddr_string = inet_ntoa( peeraddr.sa_in_addr.sin_addr ); +#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ sprintf( peername, "IP=%s:%d", - inet_ntoa( peeraddr.sa_in_addr.sin_addr ), + peeraddr_string, (unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) ); Statslog( LDAP_DEBUG_STATS, "conn=%lu UDP request from %s (%s) accepted.\n", @@ -1540,8 +1559,8 @@ connection_input( Connection *conn , conn_readinfo *cri ) #ifdef LDAP_CONNECTIONLESS if( conn->c_is_udp ) { if( tag == LBER_OCTETSTRING ) { - ber_get_stringa( ber, &cdn ); - tag = ber_peek_tag(ber, &len); + if ( (tag = ber_get_stringa( ber, &cdn )) != LBER_ERROR ) + tag = ber_peek_tag( ber, &len ); } if( tag != LDAP_REQ_ABANDON && tag != LDAP_REQ_SEARCH ) { Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, 0 );