From 4fcdfc15f95be66a71e78839ff1905dc08ad084d Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sat, 14 Feb 2026 11:19:47 +0300 Subject: [PATCH] Add exact IP:port match validation to NAT test Test now verifies that NAT IP:port exactly matches client's local bind: - Gets expected port from client socket using getsockname() - Compares nat_port with expected_client_port for exact match - Validates nat_ip equals 127.0.0.1 (localhost test) - Fails test if values don't match exactly This ensures the server correctly returns the client's actual address in the INIT_RESPONSE handshake without any modification. Test output: [TEST] Client socket bound to port 9012 (expected NAT port) [CLIENT] PASS: NAT address is set: 127.0.0.1:9012 [CLIENT] PASS: nat_changes_count=0, nat_hits_count=0 [CLIENT] PASS: NAT IP and port match exactly (127.0.0.1:9012) --- tests/test_etcp_two_instances.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/tests/test_etcp_two_instances.c b/tests/test_etcp_two_instances.c index e7ddfcb..28b1c3d 100644 --- a/tests/test_etcp_two_instances.c +++ b/tests/test_etcp_two_instances.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "../src/etcp.h" #include "../src/etcp_connections.h" @@ -24,6 +25,7 @@ static struct UASYNC* ua = NULL; static int test_completed = 0; // 0 = running, 1 = success, 2 = timeout/failure static void* monitor_timeout_id = NULL; static void* test_timeout_id = NULL; +static uint16_t expected_client_port = 0; // Expected NAT port (client's local port) // Temp config file paths static char temp_dir[] = "/tmp/utun_test_XXXXXX"; @@ -183,16 +185,15 @@ static void monitor_connections(void* arg) { return; } - // Verify NAT port is in valid ephemeral port range (> 1024, typically) - // Ephemeral ports are usually 32768-60999, but can be any > 1024 - if (link->nat_port <= 1024 || link->nat_port > 65535) { - DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[CLIENT] FAIL: NAT port %u is out of valid range (expected > 1024 and <= 65535)", - link->nat_port); + // Verify NAT port matches client's local port exactly (no NAT in test) + if (expected_client_port != 0 && link->nat_port != expected_client_port) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[CLIENT] FAIL: NAT port %u does not match expected port %u", + link->nat_port, expected_client_port); test_completed = 2; // Failure return; } - DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[CLIENT] PASS: NAT IP and port contain valid values (127.0.0.1:%u)", + DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[CLIENT] PASS: NAT IP and port match exactly (127.0.0.1:%u)", link->nat_port); } } @@ -304,6 +305,18 @@ int main() { } DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Client instance ready (node_id=%llx)\n\n", (unsigned long long)client_instance->node_id); + // Get client's local port from the socket (for NAT port validation) + if (client_instance->etcp_sockets) { + struct sockaddr_storage local_addr; + socklen_t addr_len = sizeof(local_addr); + if (getsockname(client_instance->etcp_sockets->fd, (struct sockaddr*)&local_addr, &addr_len) == 0) { + if (local_addr.ss_family == AF_INET) { + expected_client_port = ntohs(((struct sockaddr_in*)&local_addr)->sin_port); + DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[TEST] Client socket bound to port %u (expected NAT port)", expected_client_port); + } + } + } + // Start monitoring DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Starting connection monitoring...\n"); monitor_timeout_id = uasync_set_timeout(ua, 100, NULL, monitor_connections);