]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9959 Track actual connection local/peername
authorOndřej Kuzník <ondra@mistotebe.net>
Mon, 12 Dec 2022 15:51:51 +0000 (15:51 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Wed, 27 Sep 2023 14:44:52 +0000 (14:44 +0000)
servers/lloadd/backend.c
servers/lloadd/client.c
servers/lloadd/connection.c
servers/lloadd/daemon.c
servers/lloadd/lload.h
servers/lloadd/proto-lload.h
servers/lloadd/upstream.c

index d30284ecc382ea07b312147c436197981e6b3c37..c92abc9d4d6f72ac8282b9673a8bec3bc0caf32c 100644 (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;
         }
 
index 1241286f29c73929a23034163ecac7fa636b216f..866f7a1bbf16f784559e03000ca4ed6c37cd9ba1 100644 (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;
     }
 
index a3f5323f0ba3ef5616b6f8fd4e1abe4aaa583d90..9c5fc241774a6694f3f54f05e9016d77c711c6df 100644 (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;
 
index 7d19b0e81a1acc3905902b24d5eea0e655106acb..40b88919cbc44ac987382ebaf9d3b5baa4f9351d 100644 (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: "
index f9144a53513851bbd8b374a260d212438491b44e..9425976ab60cb641bc1b56c60feaafd09e2a8e8c 100644 (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 */
index cfbbd9546a497da1c81ccdd27f149d06cf026dc5..3c59dc9c75a407c0c07fa11b0057277d97fb484c 100644 (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;
index 2784532243fa2802575506cd359e5df877551ac9..aab4ad2ca99596c3c530f6be75743e4808b08d0a 100644 (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;
     }