From: Ondřej Kuzník Date: Mon, 12 Dec 2022 15:51:51 +0000 (+0000) Subject: ITS#9959 Track actual connection local/peername X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=923483ccea4e380fd003466daeca4a590baf47cb;p=thirdparty%2Fopenldap.git ITS#9959 Track actual connection local/peername --- diff --git a/servers/lloadd/backend.c b/servers/lloadd/backend.c index d30284ecc3..c92abc9d4d 100644 --- a/servers/lloadd/backend.c +++ b/servers/lloadd/backend.c @@ -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; } diff --git a/servers/lloadd/client.c b/servers/lloadd/client.c index 1241286f29..866f7a1bbf 100644 --- a/servers/lloadd/client.c +++ b/servers/lloadd/client.c @@ -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; } diff --git a/servers/lloadd/connection.c b/servers/lloadd/connection.c index a3f5323f0b..9c5fc24177 100644 --- a/servers/lloadd/connection.c +++ b/servers/lloadd/connection.c @@ -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; diff --git a/servers/lloadd/daemon.c b/servers/lloadd/daemon.c index 7d19b0e81a..40b88919cb 100644 --- a/servers/lloadd/daemon.c +++ b/servers/lloadd/daemon.c @@ -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: " diff --git a/servers/lloadd/lload.h b/servers/lloadd/lload.h index f9144a5351..9425976ab6 100644 --- a/servers/lloadd/lload.h +++ b/servers/lloadd/lload.h @@ -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 */ diff --git a/servers/lloadd/proto-lload.h b/servers/lloadd/proto-lload.h index cfbbd9546a..3c59dc9c75 100644 --- a/servers/lloadd/proto-lload.h +++ b/servers/lloadd/proto-lload.h @@ -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; diff --git a/servers/lloadd/upstream.c b/servers/lloadd/upstream.c index 2784532243..aab4ad2ca9 100644 --- a/servers/lloadd/upstream.c +++ b/servers/lloadd/upstream.c @@ -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; }