ITS#9959 Track actual connection local/peername

This commit is contained in:
Ondřej Kuzník 2022-12-12 15:51:51 +00:00 committed by Quanah Gibson-Mount
parent 100def6487
commit 923483ccea
7 changed files with 87 additions and 53 deletions

View file

@ -60,7 +60,8 @@ upstream_connect_cb( evutil_socket_t s, short what, void *arg )
return;
} else if ( error ) {
goto done;
} else if ( upstream_init( s, conn->backend ) == NULL ) {
} else if ( upstream_init( s, &conn->localbv, &conn->peerbv,
conn->backend ) == NULL ) {
goto done;
}
rc = LDAP_SUCCESS;
@ -99,6 +100,10 @@ upstream_name_cb( int result, struct evutil_addrinfo *res, void *arg )
{
LloadBackend *b = arg;
ber_socket_t s = AC_SOCKET_INVALID;
char localname[LDAP_IPADDRLEN], peername[LDAP_IPADDRLEN];
struct berval localbv = BER_BVC(localname), peerbv = BER_BVC(peername);
Sockaddr local_addr;
socklen_t addrlen = sizeof(local_addr);
epoch_t epoch;
int rc;
@ -223,11 +228,20 @@ upstream_name_cb( int result, struct evutil_addrinfo *res, void *arg )
struct sockaddr_in *ai = (struct sockaddr_in *)res->ai_addr;
ai->sin_port = htons( b->b_port );
rc = connect( s, (struct sockaddr *)ai, res->ai_addrlen );
ldap_pvt_sockaddrstr( (Sockaddr *)ai, &peerbv );
} else {
struct sockaddr_in6 *ai = (struct sockaddr_in6 *)res->ai_addr;
ai->sin6_port = htons( b->b_port );
rc = connect( s, (struct sockaddr *)ai, res->ai_addrlen );
ldap_pvt_sockaddrstr( (Sockaddr *)ai, &peerbv );
}
if ( !getsockname( s, (struct sockaddr *)&local_addr, &addrlen ) ) {
ldap_pvt_sockaddrstr( (Sockaddr *)&local_addr, &localbv );
} else {
ber_str2bv( "unknown", 0, 0, &localbv );
}
/* Asynchronous connect */
if ( rc ) {
LloadPendingConnection *conn;
@ -240,11 +254,20 @@ upstream_name_cb( int result, struct evutil_addrinfo *res, void *arg )
goto fail;
}
conn = ch_calloc( 1, sizeof(LloadPendingConnection) );
conn = ch_calloc( 1, sizeof(LloadPendingConnection) +
peerbv.bv_len + localbv.bv_len );
LDAP_LIST_ENTRY_INIT( conn, next );
conn->backend = b;
conn->fd = s;
conn->localbv.bv_val = (char *)(conn + 1);
memcpy( conn->localbv.bv_val, localbv.bv_val, localbv.bv_len );
conn->localbv.bv_len = localbv.bv_len;
conn->peerbv.bv_val = conn->localbv.bv_val + localbv.bv_len;
memcpy( conn->peerbv.bv_val, peerbv.bv_val, peerbv.bv_len );
conn->peerbv.bv_len = peerbv.bv_len;
conn->event = event_new( lload_get_base( s ), s, EV_WRITE|EV_PERSIST,
upstream_connect_cb, conn );
if ( !conn->event ) {
@ -261,7 +284,7 @@ upstream_name_cb( int result, struct evutil_addrinfo *res, void *arg )
Debug( LDAP_DEBUG_CONNS, "upstream_name_cb: "
"connection to backend uri=%s in progress\n",
b->b_uri.bv_val );
} else if ( upstream_init( s, b ) == NULL ) {
} else if ( upstream_init( s, &localbv, &peerbv, b ) == NULL ) {
goto fail;
}
@ -509,6 +532,8 @@ backend_connect( evutil_socket_t s, short what, void *arg )
if ( b->b_proto == LDAP_PROTO_IPC ) {
struct sockaddr_un addr;
ber_socket_t s = socket( PF_LOCAL, SOCK_STREAM, 0 );
char peerbuf[sizeof("PATH=")+sizeof(addr.sun_path)];
struct berval peerbv = BER_BVC(peerbuf);
int rc;
if ( s == AC_SOCKET_INVALID ) {
@ -528,6 +553,8 @@ backend_connect( evutil_socket_t s, short what, void *arg )
memset( &addr, '\0', sizeof(addr) );
addr.sun_family = AF_LOCAL;
strcpy( addr.sun_path, b->b_host );
peerbv.bv_len = snprintf( peerbuf, sizeof(peerbuf), "PATH=%s",
b->b_host );
rc = connect(
s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un) );
@ -561,7 +588,7 @@ backend_connect( evutil_socket_t s, short what, void *arg )
Debug( LDAP_DEBUG_CONNS, "backend_connect: "
"connection to backend uri=%s in progress\n",
b->b_uri.bv_val );
} else if ( upstream_init( s, b ) == NULL ) {
} else if ( upstream_init( s, &peerbv, &peerbv, b ) == NULL ) {
goto fail;
}

View file

@ -538,7 +538,8 @@ fail:
LloadConnection *
client_init(
ber_socket_t s,
const char *peername,
struct berval *localname,
struct berval *peername,
struct event_base *base,
int flags )
{
@ -547,7 +548,8 @@ client_init(
event_callback_fn read_cb = connection_read_cb,
write_cb = connection_write_cb;
if ( (c = lload_connection_init( s, peername, flags) ) == NULL ) {
if ( (c = lload_connection_init(
s, localname, peername, flags )) == NULL ) {
return NULL;
}

View file

@ -409,6 +409,14 @@ connection_destroy( LloadConnection *c )
ber_memfree( c->c_sasl_bind_mech.bv_val );
BER_BVZERO( &c->c_sasl_bind_mech );
}
if ( !BER_BVISNULL( &c->c_local_name ) ) {
ber_memfree( c->c_local_name.bv_val );
BER_BVZERO( &c->c_local_name );
}
if ( !BER_BVISNULL( &c->c_peer_name ) ) {
ber_memfree( c->c_peer_name.bv_val );
BER_BVZERO( &c->c_peer_name );
}
#ifdef HAVE_CYRUS_SASL
if ( c->c_sasl_defaults ) {
lutil_sasl_freedefs( c->c_sasl_defaults );
@ -578,11 +586,16 @@ lload_connection_close( LloadConnection *c, void *arg )
}
LloadConnection *
lload_connection_init( ber_socket_t s, const char *peername, int flags )
lload_connection_init(
ber_socket_t s,
struct berval *localname,
struct berval *peername,
int flags )
{
LloadConnection *c;
assert( peername != NULL );
assert( localname && !BER_BVISNULL( localname ) );
assert( peername && !BER_BVISNULL( peername ) );
if ( s == AC_SOCKET_INVALID ) {
Debug( LDAP_DEBUG_ANY, "lload_connection_init: "
@ -598,6 +611,8 @@ lload_connection_init( ber_socket_t s, const char *peername, int flags )
c->c_fd = s;
c->c_sb = ber_sockbuf_alloc();
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &s );
ber_dupbv( &c->c_local_name, localname );
ber_dupbv( &c->c_peer_name, peername );
#ifdef LDAP_PF_LOCAL
if ( flags & CONN_IS_IPC ) {
@ -636,7 +651,7 @@ lload_connection_init( ber_socket_t s, const char *peername, int flags )
Debug( LDAP_DEBUG_CONNS, "lload_connection_init: "
"connection connid=%lu allocated for socket fd=%d peername=%s\n",
c->c_connid, s, peername );
c->c_connid, s, peername->bv_val );
c->c_state = LLOAD_C_ACTIVE;

View file

@ -382,7 +382,8 @@ lload_open_listener(
struct sockaddr **sal = NULL, **psal;
int socktype = SOCK_STREAM; /* default to COTS */
ber_socket_t s;
char ebuf[128];
char ebuf[LDAP_IPADDRLEN];
struct berval namebv = BER_BVC(ebuf);
#if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
/*
@ -598,51 +599,22 @@ lload_open_listener(
switch ( (*sal)->sa_family ) {
#ifdef LDAP_PF_LOCAL
case AF_LOCAL: {
case AF_LOCAL: /* {
char *path = ((struct sockaddr_un *)*sal)->sun_path;
l.sl_name.bv_len = strlen( path ) + STRLENOF("PATH=");
l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len + 1 );
snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, "PATH=%s",
path );
} break;
} break; */
#endif /* LDAP_PF_LOCAL */
case AF_INET: {
char addr[INET_ADDRSTRLEN];
const char *s;
#if defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP)
s = inet_ntop( AF_INET,
&((struct sockaddr_in *)*sal)->sin_addr, addr,
sizeof(addr) );
#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
s = inet_ntoa( ((struct sockaddr_in *)*sal)->sin_addr );
#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
if ( !s ) s = SLAP_STRING_UNKNOWN;
port = ntohs( ((struct sockaddr_in *)*sal)->sin_port );
l.sl_name.bv_val =
ch_malloc( sizeof("IP=255.255.255.255:65535") );
snprintf( l.sl_name.bv_val,
sizeof("IP=255.255.255.255:65535"), "IP=%s:%d", s,
port );
l.sl_name.bv_len = strlen( l.sl_name.bv_val );
} break;
case AF_INET:
#ifdef LDAP_PF_INET6
case AF_INET6: {
char addr[INET6_ADDRSTRLEN];
const char *s;
s = inet_ntop( AF_INET6,
&((struct sockaddr_in6 *)*sal)->sin6_addr, addr,
sizeof(addr) );
if ( !s ) s = SLAP_STRING_UNKNOWN;
port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
l.sl_name.bv_len = strlen( s ) + sizeof("IP=[]:65535");
l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len );
snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=[%s]:%d", s,
port );
l.sl_name.bv_len = strlen( l.sl_name.bv_val );
} break;
case AF_INET6:
#endif /* LDAP_PF_INET6 */
ldap_pvt_sockaddrstr( (Sockaddr *)*sal, &namebv );
ber_dupbv( &l.sl_name, &namebv );
break;
default:
Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
@ -920,7 +892,8 @@ lload_listener(
cflag |= CONN_IS_IPC;
/* FIXME: apparently accept doesn't fill the sun_path member */
sprintf( peername, "PATH=%s", sl->sl_sa.sa_un_addr.sun_path );
peerbv.bv_len = sprintf(
peername, "PATH=%s", sl->sl_sa.sa_un_addr.sun_path );
break;
#endif /* LDAP_PF_LOCAL */
@ -939,7 +912,7 @@ lload_listener(
#ifdef HAVE_TLS
if ( sl->sl_is_tls ) cflag |= CONN_IS_TLS;
#endif
c = client_init( s, peername, lload_daemon[tid].base, cflag );
c = client_init( s, &sl->sl_name, &peerbv, lload_daemon[tid].base, cflag );
if ( !c ) {
Debug( LDAP_DEBUG_ANY, "lload_listener: "

View file

@ -207,6 +207,8 @@ struct LloadPendingConnection {
struct event *event;
ber_socket_t fd;
struct berval localbv, peerbv;
LDAP_LIST_ENTRY(LloadPendingConnection) next;
};
@ -442,6 +444,7 @@ struct LloadConnection {
/* set by connection_init */
unsigned long c_connid; /* unique id of this connection */
struct berval c_peer_name; /* peer name (trans=addr:port) */
struct berval c_local_name; /* local name (trans=addr:port) */
time_t c_starttime; /* when the connection was opened */
time_t c_activitytime; /* when the connection was last used */

View file

@ -62,7 +62,11 @@ LDAP_SLAPD_F (int) request_abandon( LloadConnection *c, LloadOperation *op );
LDAP_SLAPD_F (int) request_process( LloadConnection *c, LloadOperation *op );
LDAP_SLAPD_F (int) handle_one_request( LloadConnection *c );
LDAP_SLAPD_F (void) client_tls_handshake_cb( evutil_socket_t s, short what, void *arg );
LDAP_SLAPD_F (LloadConnection *) client_init( ber_socket_t s, const char *peername, struct event_base *base, int use_tls );
LDAP_SLAPD_F (LloadConnection *) client_init( ber_socket_t s,
struct berval *localname,
struct berval *peername,
struct event_base *base,
int use_tls );
LDAP_SLAPD_F (void) client_reset( LloadConnection *c );
LDAP_SLAPD_F (void) client_destroy( LloadConnection *c );
LDAP_SLAPD_F (void) clients_destroy( int gentle );
@ -94,7 +98,10 @@ LDAP_SLAPD_F (void *) handle_pdus( void *ctx, void *arg );
LDAP_SLAPD_F (void) connection_write_cb( evutil_socket_t s, short what, void *arg );
LDAP_SLAPD_F (void) connection_read_cb( evutil_socket_t s, short what, void *arg );
LDAP_SLAPD_F (int) lload_connection_close( LloadConnection *c, void *arg );
LDAP_SLAPD_F (LloadConnection *) lload_connection_init( ber_socket_t s, const char *peername, int use_tls );
LDAP_SLAPD_F (LloadConnection *) lload_connection_init( ber_socket_t s,
struct berval *localname,
struct berval *peername,
int use_tls );
LDAP_SLAPD_F (void) connection_destroy( LloadConnection *c );
LDAP_SLAPD_F (void) connections_walk_last( ldap_pvt_thread_mutex_t *cq_mutex,
lload_c_head *cq,
@ -220,7 +227,10 @@ LDAP_SLAPD_F (int) lload_upstream_entry_cmp( const void *l, const void *r );
LDAP_SLAPD_F (int) forward_final_response( LloadConnection *client, LloadOperation *op, BerElement *ber );
LDAP_SLAPD_F (int) forward_response( LloadConnection *client, LloadOperation *op, BerElement *ber );
LDAP_SLAPD_F (void *) upstream_bind( void *ctx, void *arg );
LDAP_SLAPD_F (LloadConnection *) upstream_init( ber_socket_t s, LloadBackend *b );
LDAP_SLAPD_F (LloadConnection *) upstream_init( ber_socket_t s,
struct berval *localbv,
struct berval *peerbv,
LloadBackend *b );
LDAP_SLAPD_F (void) upstream_destroy( LloadConnection *c );
LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_client;

View file

@ -922,7 +922,11 @@ fail:
* We must already hold b->b_mutex when called.
*/
LloadConnection *
upstream_init( ber_socket_t s, LloadBackend *b )
upstream_init(
ber_socket_t s,
struct berval *localbv,
struct berval *peerbv,
LloadBackend *b )
{
LloadConnection *c;
struct event_base *base = lload_get_base( s );
@ -932,7 +936,7 @@ upstream_init( ber_socket_t s, LloadBackend *b )
assert( b != NULL );
flags = (b->b_proto == LDAP_PROTO_IPC) ? CONN_IS_IPC : 0;
if ( (c = lload_connection_init( s, b->b_host, flags )) == NULL ) {
if ( (c = lload_connection_init( s, localbv, peerbv, flags )) == NULL ) {
return NULL;
}