From ce8f3bae6a7f1b4d40c1d866976d0c0ef038ac61 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Tue, 20 Jan 2026 20:02:37 +0300 Subject: [PATCH] Add real instance tests for connection establishment --- tests/test_etcp_connection_real.c | 235 ++++++++++++++++++++++++++++++ tests/test_etcp_simple_real.c | 107 ++++++++++++++ 2 files changed, 342 insertions(+) create mode 100644 tests/test_etcp_connection_real.c create mode 100644 tests/test_etcp_simple_real.c diff --git a/tests/test_etcp_connection_real.c b/tests/test_etcp_connection_real.c new file mode 100644 index 0000000..c73d8ba --- /dev/null +++ b/tests/test_etcp_connection_real.c @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../src/etcp.h" +#include "../src/etcp_connections.h" +#include "../src/config_parser.h" +#include "../src/utun_instance.h" +#include "../src/routing.h" +#include "../src/tun_if.h" +#include "../src/secure_channel.h" +#include "../lib/u_async.h" + +#define TEST_TIMEOUT_MS 5000 + +struct test_instance { + struct UTUN_INSTANCE* instance; + const char* config_file; + pthread_t thread; + int ready; +}; + +static void* instance_thread(void* arg) { + struct test_instance* ti = (struct test_instance*)arg; + + // Create instance + ti->instance = utun_instance_create(uasync_create(), ti->config_file, NULL); + if (!ti->instance) { + printf("Failed to create instance from %s\n", ti->config_file); + return NULL; + } + + printf("Instance %s created successfully\n", ti->config_file); + + // Debug: print config servers + if (ti->instance->config) { + printf("Config for %s has servers:\n", ti->config_file); + struct CFG_SERVER* srv = ti->instance->config->servers; + while (srv) { + printf(" Server '%s'\n", srv->name); + srv = srv->next; + } + } + + // Initialize instance (TUN, routing, etc) + if (utun_instance_init(ti->instance) < 0) { + printf("Failed to initialize instance %s\n", ti->config_file); + utun_instance_destroy(ti->instance); + ti->instance = NULL; + return NULL; + } + + // Register sockets with uasync + if (utun_instance_register_sockets(ti->instance) < 0) { + printf("Failed to register sockets for %s\n", ti->config_file); + utun_instance_destroy(ti->instance); + ti->instance = NULL; + return NULL; + } + + // Initialize connections (this will start handshake for clients) + if (init_connections(ti->instance) < 0) { + printf("Failed to init connections for %s\n", ti->config_file); + utun_instance_destroy(ti->instance); + ti->instance = NULL; + return NULL; + } + + ti->ready = 1; + printf("Instance %s ready (node_id=%llx)\n", ti->config_file, (unsigned long long)ti->instance->node_id); + + // Run event loop + while (ti->instance && ti->instance->running) { + uasync_poll(ti->instance->ua, 10); + } + + return NULL; +} + +static void dump_connections(struct UTUN_INSTANCE* instance, const char* name) { + printf("\n=== %s connections state ===\n", name); + + if (!instance->connections) { + printf("No connections\n"); + return; + } + + struct ETCP_CONN* conn = instance->connections; + int conn_idx = 0; + while (conn) { + printf("Connection %d: peer_node_id=%llx\n", conn_idx, (unsigned long long)conn->peer_node_id); + + struct ETCP_LINK* link = conn->links; + int link_idx = 0; + while (link) { + printf(" Link %d: initialized=%d, is_server=%d, init_timer=%s, timeout=%dms, retry=%d\n", + link_idx, + link->initialized, + link->is_server, + link->init_timer ? "active" : "null", + link->init_timeout, + link->init_retry_count); + + link = link->next; + link_idx++; + } + + conn = conn->next; + conn_idx++; + } +} + +int main() { + printf("=== ETCP Full Connection Test with Real Instances ===\n\n"); + + // Create config files in test directory + FILE* server_conf = fopen("test_server.conf", "w"); + fprintf(server_conf, "[global]\n"); + fprintf(server_conf, "my_node_id=0x1111111111111111\n"); + fprintf(server_conf, "my_private_key=1313912e5d34768983b0e06530a48c77816d228a5b5605e1ab3dc443d107a3dc\n"); + fprintf(server_conf, "my_public_key=dde6cec8a9023339a758f60883ef41534d24a1ffdc09bbb787a5c24ddfd891e3092461835a97d37944c681fc6b2c1f5acde8ad192f7d2cdc9920aa0d3ff78e99\n"); + fprintf(server_conf, "tun_ip=10.99.0.1/24\n"); + fprintf(server_conf, "tun_ifname=tun99\n"); + fprintf(server_conf, "\n[server:test]\n"); + fprintf(server_conf, "addr=127.0.0.1:9001\n"); + fprintf(server_conf, "type=public\n"); + fclose(server_conf); + + FILE* client_conf = fopen("test_client.conf", "w"); + fprintf(client_conf, "[global]\n"); + fprintf(client_conf, "my_node_id=0x2222222222222222\n"); + fprintf(client_conf, "my_private_key=1313912e5d34768983b0e06530a48c77816d228a5b5605e1ab3dc443d107a3dc\n"); + fprintf(client_conf, "my_public_key=dde6cec8a9023339a758f60883ef41534d24a1ffdc09bbb787a5c24ddfd891e3092461835a97d37944c681fc6b2c1f5acde8ad192f7d2cdc9920aa0d3ff78e99\n"); + fprintf(client_conf, "tun_ip=10.99.0.2/24\n"); + fprintf(client_conf, "tun_ifname=tun98\n"); + fprintf(client_conf, "\n[client:test_client]\n"); + fprintf(client_conf, "peer_node_id=0x1111111111111111\n"); + fprintf(client_conf, "keepalive=1\n"); + fprintf(client_conf, "link=127.0.0.1:9001\n"); + fclose(client_conf); + + // Create test instances + struct test_instance server = {.config_file = "test_server.conf"}; + struct test_instance client = {.config_file = "test_client.conf"}; + + printf("Starting server instance...\n"); + if (pthread_create(&server.thread, NULL, instance_thread, &server) != 0) { + printf("Failed to create server thread\n"); + return 1; + } + + printf("Starting client instance...\n"); + if (pthread_create(&client.thread, NULL, instance_thread, &client) != 0) { + printf("Failed to create client thread\n"); + return 1; + } + + // Wait for instances to be ready + int wait_count = 0; + while ((!server.ready || !client.ready) && wait_count < 100) { + usleep(50000); + wait_count++; + } + + if (!server.ready || !client.ready) { + printf("Instances failed to initialize\n"); + return 1; + } + + printf("\n=== Monitoring connection state ===\n"); + + // Monitor connection state for 5 seconds + int established = 0; + int elapsed = 0; + while (elapsed < TEST_TIMEOUT_MS) { + // Check client connection to server + struct ETCP_CONN* client_conn = client.instance->connections; + while (client_conn) { + if (client_conn->peer_node_id == 0x1111111111111111ULL) { + struct ETCP_LINK* link = client_conn->links; + while (link) { + if (link->initialized && link->is_server == 0) { + printf("SUCCESS: Client connection established!\n"); + established = 1; + break; + } + link = link->next; + } + } + if (established) break; + client_conn = client_conn->next; + } + + if (established) break; + + // Dump state every second + if (elapsed % 1000 == 0) { + dump_connections(server.instance, "Server"); + dump_connections(client.instance, "Client"); + } + + usleep(100000); + elapsed += 100; + } + + // Cleanup + printf("\n=== Cleaning up ===\n"); + if (server.instance) { + server.instance->running = 0; + } + if (client.instance) { + client.instance->running = 0; + } + + pthread_join(server.thread, NULL); + pthread_join(client.thread, NULL); + + // Cleanup config files + unlink("test_server.conf"); + unlink("test_client.conf"); + + if (established) { + printf("\n=== TEST PASSED ===\n"); + return 0; + } else { + printf("\n=== TEST FAILED ===\n"); + return 1; + } +} \ No newline at end of file diff --git a/tests/test_etcp_simple_real.c b/tests/test_etcp_simple_real.c new file mode 100644 index 0000000..2de8954 --- /dev/null +++ b/tests/test_etcp_simple_real.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../src/etcp.h" +#include "../src/etcp_connections.h" +#include "../src/config_parser.h" +#include "../src/utun_instance.h" +#include "../src/routing.h" +#include "../src/tun_if.h" +#include "../src/secure_channel.h" +#include "../lib/u_async.h" + +#define TEST_TIMEOUT_MS 5000 + +int main() { + printf("=== ETCP Real Instance Test ===\n\n"); + + // Create config file + FILE* conf = fopen("test_real.conf", "w"); + fprintf(conf, "[global]\n"); + fprintf(conf, "my_node_id=0x1111111111111111\n"); + fprintf(conf, "my_private_key=1313912e5d34768983b0e06530a48c77816d228a5b5605e1ab3dc443d107a3dc\n"); + fprintf(conf, "my_public_key=dde6cec8a9023339a758f60883ef41534d24a1ffdc09bbb787a5c24ddfd891e3092461835a97d37944c681fc6b2c1f5acde8ad192f7d2cdc9920aa0d3ff78e99\n"); + fprintf(conf, "tun_ip=10.99.0.1/24\n"); + fprintf(conf, "tun_ifname=tun99\n"); + fprintf(conf, "\n[server: test]\n"); + fprintf(conf, "addr=127.0.0.1:9001\n"); + fprintf(conf, "type=public\n"); + fclose(conf); + + // Create instance + printf("Creating UTUN instance...\n"); + struct UASYNC* ua = uasync_create(); + struct UTUN_INSTANCE* instance = utun_instance_create(ua, "test_real.conf", NULL); + if (!instance) { + printf("Failed to create instance\n"); + return 1; + } + + printf("Instance created (node_id=%llx)\n", (unsigned long long)instance->node_id); + + // Initialize + printf("Initializing instance...\n"); + if (utun_instance_init(instance) < 0) { + printf("Failed to initialize instance\n"); + utun_instance_destroy(instance); + return 1; + } + + // Register sockets + printf("Registering sockets...\n"); + if (utun_instance_register_sockets(instance) < 0) { + printf("Failed to register sockets\n"); + utun_instance_destroy(instance); + return 1; + } + + // Initialize connections + printf("Initializing connections...\n"); + if (init_connections(instance) < 0) { + printf("Failed to initialize connections\n"); + utun_instance_destroy(instance); + return 1; + } + + printf("Instance ready\n"); + + // Monitor for 5 seconds + printf("\nMonitoring connections for %d seconds...\n", TEST_TIMEOUT_MS/1000); + + int elapsed = 0; + while (elapsed < TEST_TIMEOUT_MS) { + // Dump connection state + struct ETCP_CONN* conn = instance->connections; + while (conn) { + printf("Connection to node %llx:\n", (unsigned long long)conn->peer_node_id); + + struct ETCP_LINK* link = conn->links; + while (link) { + printf(" Link: initialized=%d, is_server=%d, init_timer=%s, timeout=%dms, retry=%d\n", + link->initialized, link->is_server, + link->init_timer ? "active" : "null", + link->init_timeout, link->init_retry_count); + link = link->next; + } + conn = conn->next; + } + + uasync_poll(ua, 100); + elapsed += 100; + } + + // Cleanup + printf("Cleaning up...\n"); + unlink("test_real.conf"); + instance->running = 0; + utun_instance_destroy(instance); + + printf("\n=== Test completed ===\n"); + return 0; +} \ No newline at end of file