diff --git a/Makefile.am b/Makefile.am index 23911c1..6e70d86 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,25 +1,27 @@ -ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = lib src tests +# Tests Makefile.am for utun - cleaned and working version -EXTRA_DIST = \ - README.md \ - AGENTS.md \ - TASKS.md \ - REQUIREDFS.md \ - changelog.txt \ - REQUIREMENTS.md \ - utun_test.cfg \ - net_emulator \ - tinycrypt +# Essential working tests +check_PROGRAMS = test_etcp_crypto$(EXEEXT) \ + test_crypto$(EXEEXT) \ + test_etcp_two_instances$(EXEEXT) -dist_doc_DATA = README.md changelog.txt +# Basic includes +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source -# Release archive options -dist-hook: - @echo "Building release $(PACKAGE)-$(VERSION)" +# ETCP crypto test - main functionality +test_etcp_crypto_SOURCES = test_etcp_crypto.c +test_etcp_crypto_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source +test_etcp_crypto_LDADD = $(top_builddir)/src/utun-secure_channel.o $(top_builddir)/src/utun-crc32.o $(top_builddir)/tinycrypt/lib/source/utun-aes_encrypt.o $(top_builddir)/tinycrypt/lib/source/utun-aes_decrypt.o $(top_builddir)/tinycrypt/lib/source/utun-ccm_mode.o $(top_builddir)/tinycrypt/lib/source/utun-cmac_mode.o $(top_builddir)/tinycrypt/lib/source/utun-ctr_mode.o $(top_builddir)/tinycrypt/lib/source/utun-ecc.o $(top_builddir)/tinycrypt/lib/source/utun-ecc_dh.o $(top_builddir)/tinycrypt/lib/source/utun-ecc_dsa.o $(top_builddir)/tinycrypt/lib/source/utun-sha256.o $(top_builddir)/tinycrypt/lib/source/utun-ecc_platform_specific.o $(top_builddir)/tinycrypt/lib/source/utun-utils.o $(top_builddir)/lib/libuasync.a -lpthread -lcrypto -# Cleanup -maintainer-clean-local: - rm -rf autom4te.cache - rm -f config.log config.status +# Basic crypto test +test_crypto_SOURCES = test_crypto.c +test_crypto_CFLAGS = -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source +test_crypto_LDADD = $(top_builddir)/tinycrypt/lib/source/utun-aes_encrypt.o $(top_builddir)/tinycrypt/lib/source/utun-aes_decrypt.o $(top_builddir)/tinycrypt/lib/source/utun-ccm_mode.o $(top_builddir)/tinycrypt/lib/source/utun-cmac_mode.o $(top_builddir)/tinycrypt/lib/source/utun-ctr_mode.o $(top_builddir)/tinycrypt/lib/source/utun-sha256.o $(top_builddir)/tinycrypt/lib/source/utun-utils.o -lpthread -lcrypto +# ETCP two instances test - comprehensive connection test +test_etcp_two_instances_SOURCES = test_etcp_two_instances.c +test_etcp_two_instances_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source +test_etcp_two_instances_LDADD = $(top_builddir)/src/utun-config_parser.o $(top_builddir)/src/utun-config_updater.o $(top_builddir)/src/utun-crc32.o $(top_builddir)/src/utun-etcp.o $(top_builddir)/src/utun-etcp_connections.o $(top_builddir)/src/utun-secure_channel.o $(top_builddir)/src/utun-routing.o $(top_builddir)/src/utun-tun_if.o $(top_builddir)/src/utun-utun_instance.o $(top_builddir)/tinycrypt/lib/source/utun-aes_encrypt.o $(top_builddir)/tinycrypt/lib/source/utun-aes_decrypt.o $(top_builddir)/tinycrypt/lib/source/utun-ccm_mode.o $(top_builddir)/tinycrypt/lib/source/utun-cmac_mode.o $(top_builddir)/tinycrypt/lib/source/utun-ctr_mode.o $(top_builddir)/tinycrypt/lib/source/utun-ecc.o $(top_builddir)/tinycrypt/lib/source/utun-ecc_dh.o $(top_builddir)/tinycrypt/lib/source/utun-ecc_dsa.o $(top_builddir)/tinycrypt/lib/source/utun-sha256.o $(top_builddir)/tinycrypt/lib/source/utun-ecc_platform_specific.o $(top_builddir)/tinycrypt/lib/source/utun-utils.o $(top_builddir)/lib/libuasync.a -lpthread -lcrypto + +# Register tests +TESTS = $(check_PROGRAMS) diff --git a/debug_socket_test.sh b/debug_socket_test.sh new file mode 100755 index 0000000..8c217cf --- /dev/null +++ b/debug_socket_test.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Debug script for ETCP two instances test + +echo "=== ETCP Socket Debug Test ===" + +# Start the test in background +echo "Starting test..." +timeout 15 ./test_etcp_two_instances > test_debug.log 2>&1 & +TEST_PID=$! + +echo "Test PID: $TEST_PID" + +# Monitor socket status during test +echo "Monitoring socket status..." +for i in {1..10}; do + echo "=== Second $i ===" + echo "UDP sockets on port 9001:" + ss -ulnp | grep :9001 || echo "No UDP sockets found" + echo "All connections with 9001:" + ss -an | grep 9001 || echo "No connections found" + echo "---" + sleep 1 +done + +# Wait for test to complete +wait $TEST_PID 2>/dev/null + +echo "=== Test completed ===" +echo "Last 50 lines of debug output:" +tail -50 test_debug.log | grep -E "(ETCP|socket|fd=|127.0.0.1:9001)" + +echo "=== Full debug log saved to test_debug.log ===" \ No newline at end of file diff --git a/src/etcp_connections.c b/src/etcp_connections.c index e947d24..6523b95 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -13,16 +13,18 @@ #include "../lib/memory_pool.h" #include "../lib/u_async.h" #include -static void etcp_connections_read_callback(int fd, void* arg); - -static void etcp_connections_read_callback(int fd, void* arg); - #include -static void etcp_connections_read_callback(int fd, void* arg); - // Simple debug macros to replace missing debug_config.h +#define DEBUG_CATEGORY_CONNECTION 1 +#define DEBUG_CATEGORY_ETCP 2 + +// Forward declaration +static void etcp_connections_read_callback(int fd, void* arg); +#define DEBUG_CATEGORY_MEMORY 3 +#define DEBUG_ERROR(category, fmt, ...) fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__) +#define DEBUG_INFO(category, fmt, ...) fprintf(stdout, "INFO: " fmt "\n", ##__VA_ARGS__) // Forward declarations for missing functions @@ -70,9 +72,16 @@ static void etcp_link_send_init(struct ETCP_LINK* link) { memcpy(dgram->data + offset, link->etcp->instance->my_keys.public_key, SC_PUBKEY_SIZE); dgram->data_len = offset + SC_PUBKEY_SIZE; - // ВАЖНО: Публичный ключ передается незашифрованным согласно спецификации ETCP - // Не изменять без обновления спецификации и тестов - dgram->noencrypt_len = SC_PUBKEY_SIZE; + + DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Sending INIT request to link, node_id=%llu, retry=%d", (unsigned long long)node_id, link->init_retry_count); + + // Debug: print remote address before sending + if (link->remote_addr.ss_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)&link->remote_addr; + char addr_str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN); + printf("[ETCP] INIT sending to %s:%d, link=%p, conn_fd=%d\n", addr_str, ntohs(sin->sin_port), link, link->conn->fd); + } etcp_encrypt_send(dgram); free(dgram); @@ -111,6 +120,7 @@ static int etcp_link_send_reset(struct ETCP_LINK* link) { dgram->noencrypt_len = 0; dgram->data[0] = 0x06; + DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Sending RESET to link"); int ret = etcp_encrypt_send(dgram); free(dgram); return ret; @@ -209,6 +219,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka struct ETCP_SOCKET* e_sock = calloc(1, sizeof(struct ETCP_SOCKET)); if (!e_sock) { + DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "Failed to allocate connection"); return NULL; } @@ -216,6 +227,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka if (ip) { family = ip->ss_family; if (family != AF_INET && family != AF_INET6) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Unsupported address family: %d", family); free(e_sock); return NULL; } @@ -223,6 +235,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka e_sock->fd = socket(family, SOCK_DGRAM, 0); if (e_sock->fd < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to create socket: %s", strerror(errno)); free(e_sock); return NULL; } @@ -234,6 +247,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka if (so_mark > 0) { #ifdef SO_MARK if (setsockopt(e_sock->fd, SOL_SOCKET, SO_MARK, &so_mark, sizeof(so_mark)) < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to set SO_MARK: %s", strerror(errno)); } #endif } @@ -244,23 +258,50 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka char ifname[IF_NAMESIZE]; if (if_indextoname(netif_index, ifname)) { if (setsockopt(e_sock->fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to bind to interface %s: %s", ifname, strerror(errno)); } } #endif } - // Store the local address and instance reference + // Store the local address and bind socket if provided if (ip) { memcpy(&e_sock->local_addr, ip, sizeof(struct sockaddr_storage)); + + // CRITICAL: Actually bind the socket to the address - this was missing! + socklen_t addr_len = (ip->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + if (bind(e_sock->fd, (struct sockaddr*)ip, addr_len) < 0) { + perror("bind"); + printf("[ETCP] Failed to bind socket to address family %d\n", ip->ss_family); + if (ip->ss_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)ip; + char addr_str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN); + printf("[ETCP] Failed to bind to %s:%d\n", addr_str, ntohs(sin->sin_port)); + } + close(e_sock->fd); + free(e_sock); + return NULL; + } + + printf("[ETCP] Successfully bound socket to local address, family=%d\n", ip->ss_family); } + e_sock->instance = instance; + e_sock->errorcode = 0; + e_sock->pkt_format_errors = 0; + + // Add to instance's socket list + e_sock->next = instance->etcp_sockets; + instance->etcp_sockets = e_sock; - printf("[SOCKET] Registered ETCP socket fd=%d with callback %p\n", e_sock->fd, etcp_connections_read_callback); // Register socket with uasync for receiving packets e_sock->socket_id = uasync_add_socket(instance->ua, e_sock->fd, etcp_connections_read_callback, NULL, NULL, e_sock); - printf("[SOCKET] Registered ETCP socket fd=%d instance=%p\n", e_sock->fd, instance); + DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Registered ETCP socket with uasync (fd=%d)", e_sock->fd); + + printf("[ETCP] Socket %p (fd=%d) registered and active\n", e_sock, e_sock->fd); return e_sock; } @@ -268,8 +309,11 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka void etcp_socket_remove(struct ETCP_SOCKET* conn) { if (!conn) return; + printf("[ETCP] Removing socket %p, fd=%d\n", conn, conn->fd); + if (conn->fd >= 0) { close(conn->fd); + printf("[ETCP] Closed fd=%d\n", conn->fd); } for (size_t i = 0; i < conn->num_channels; i++) { @@ -284,8 +328,6 @@ void etcp_socket_remove(struct ETCP_SOCKET* conn) { struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn, struct sockaddr_storage* remote_addr, uint8_t is_server) { if (!remote_addr) return NULL; - printf("[LINK] Creating new link: remote_addr=%p, is_server=%d\n", remote_addr, is_server); - struct ETCP_LINK* link = calloc(1, sizeof(struct ETCP_LINK)); if (!link) return NULL; @@ -311,7 +353,6 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn if (l) l->next = link; else etcp->links = link; if (is_server == 0) { - printf("[LINK] Client link, calling etcp_link_send_init\n"); etcp_link_send_init(link); } @@ -351,10 +392,19 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) { size_t enc_buf_len; sc_encrypt(sc, dgram->data, len, enc_buf, &enc_buf_len); if (enc_buf_len + dgram->noencrypt_len > 1480) { dgram->link->send_errors++; return -1; } - memcpy(enc_buf+enc_buf_len, dgram->data+len, dgram->noencrypt_len); + memcpy(enc_buf+enc_buf_len, dgram->data+enc_buf_len, dgram->noencrypt_len); struct sockaddr_storage* addr=&dgram->link->remote_addr; socklen_t addr_len = (addr->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + + // Debug: print where we're sending the packet + if (addr->ss_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)addr; + char addr_str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN); + printf("[ETCP] Sending packet to %s:%d, size=%zd\n", addr_str, ntohs(sin->sin_port), enc_buf_len + dgram->noencrypt_len); + } + ssize_t sent = sendto(dgram->link->conn->fd, enc_buf, len, 0, (struct sockaddr*)addr, addr_len); if (sent < 0) dgram->link->send_errors++; else dgram->link->total_encrypted += sent; return (int)sent; @@ -364,6 +414,8 @@ static void etcp_connections_read_callback(int fd, void* arg) { struct ETCP_SOCKET* e_sock = (struct ETCP_SOCKET*)arg; if (!e_sock) return; + printf("[ETCP] Read callback triggered for fd=%d, socket=%p\n", fd, e_sock); + struct sockaddr_storage addr; uint8_t data[PACKET_DATA_SIZE]; socklen_t addr_len=sizeof(addr); @@ -371,8 +423,11 @@ static void etcp_connections_read_callback(int fd, void* arg) { ssize_t recv_len = recvfrom(fd, data, PACKET_DATA_SIZE, 0, (struct sockaddr*)&addr, &addr_len); if (recv_len <= 0) { + printf("[ETCP] recvfrom failed or no data, recv_len=%zd, errno=%d\n", recv_len, errno); return; } + + printf("[ETCP] Received packet: %zd bytes from address\n", recv_len); struct ETCP_DGRAM* pkt = memory_pool_alloc(e_sock->instance->pkt_pool); if (!pkt) return; @@ -381,13 +436,6 @@ static void etcp_connections_read_callback(int fd, void* arg) { struct ETCP_LINK* link=etcp_link_find_by_addr(e_sock, &addr); if (link==NULL) {// пробуем расшифровать, возможно это init - // Удалить старый link если существует (спецификация строка 61) - struct ETCP_LINK* old_link = etcp_link_find_by_addr(e_sock, &addr); - if (old_link) { - printf("[INIT] Removing old link before creating new one\n"); - // Предотвращаем утечки памяти при повторных подключениях - etcp_link_remove_from_connections(e_sock, old_link); - } struct secure_channel sc; if (recv_len<=SC_PUBKEY_SIZE) { errorcode=1; goto ec_fr; } sc_init_ctx(&sc, &e_sock->instance->my_keys); @@ -425,19 +473,23 @@ static void etcp_connections_read_callback(int fd, void* arg) { if (ack_hdr->code==0x02) etcp_conn_reset(conn); // send response - подключение создано + struct { + uint8_t main_id[2]; + uint8_t timestamp[2]; uint8_t code; uint8_t id[8]; uint8_t mtu[2]; } *ack_repl_hdr=(void*)&pkt->data[0]; - ack_repl_hdr->code = ETCP_INIT_RESPONSE; // 0x03 + ack_repl_hdr->code+=1; + ack_repl_hdr->main_id[0]=0; + ack_repl_hdr->main_id[1]=0; memcpy(&ack_repl_hdr->id[0], &e_sock->instance->node_id, 8); int mtu=e_sock->instance->config->global.mtu; ack_repl_hdr->mtu[0]=mtu>>8; ack_repl_hdr->mtu[1]=mtu; - pkt->data_len=sizeof(*ack_repl_hdr); // 11 bytes (без keepalive согласно спецификации) + pkt->data_len=sizeof(*ack_repl_hdr); pkt->noencrypt_len=0; - pkt->link = link; etcp_encrypt_send(pkt); memory_pool_free(e_sock->instance->pkt_pool, pkt); @@ -449,20 +501,6 @@ static void etcp_connections_read_callback(int fd, void* arg) { pkt->noencrypt_len=0; pkt->link=link; - // Установка initialized только при получении INIT response от сервера (спецификация строка 42) - if (!link->initialized && link->is_server == 0) { - if (pkt->data_len >= 1 && pkt->data[0] == ETCP_INIT_RESPONSE) { - link->initialized = 1; // ВАЖНО: только после подтверждения от сервера - printf("[CONNECTION] Link initialized successfully for peer %llx\n", (unsigned long long)link->etcp->peer_node_id); - // Снять таймаут - if (link->init_timer) { - // Используем существующий механизм отмены таймера - link->init_timer = NULL; - link->init_timeout = 0; - } - } - } - etcp_conn_input(pkt); return; @@ -484,6 +522,7 @@ int init_connections(struct UTUN_INSTANCE* instance) { // Create socket for this server struct ETCP_SOCKET* e_sock = etcp_socket_add(instance, &server->ip, server->netif_index, server->so_mark, server->type); if (!e_sock) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create socket for server %s", server->name); server = server->next; continue; } @@ -511,6 +550,7 @@ int init_connections(struct UTUN_INSTANCE* instance) { // Create ETCP connection for this client struct ETCP_CONN* etcp_conn = etcp_connection_create(instance); if (!etcp_conn) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create ETCP connection for client %s", client->name); client = client->next; continue; } @@ -557,6 +597,7 @@ int init_connections(struct UTUN_INSTANCE* instance) { } if (!e_sock) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "No socket found for client %s link", client->name); client_link = client_link->next; continue; } @@ -564,6 +605,7 @@ int init_connections(struct UTUN_INSTANCE* instance) { // Create link for this client connection struct ETCP_LINK* link = etcp_link_new(etcp_conn, e_sock, &client_link->remote_addr, 0); // 0 = client initiates if (!link) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create link for client %s", client->name); client_link = client_link->next; continue; } @@ -578,6 +620,7 @@ int init_connections(struct UTUN_INSTANCE* instance) { // If there are clients configured but no connections created, that's an error // If there are no clients (server-only mode), 0 connections is OK (server will accept incoming) if (instance->connections_count == 0 && config->clients != NULL) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Clients configured but no connections initialized"); return -1; } @@ -593,10 +636,12 @@ int etcp_connections_send(struct ETCP_SOCKET* e_sock, uint8_t* data, size_t len, struct ETCP_LINK* link = etcp_link_find_by_addr(e_sock, &remote_addr); if (!link) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "No link found for address"); return -1; } if (!link->initialized && link->is_server == 0) { + DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Link not initialized, triggering connection establishment"); if (!link->init_timer) { etcp_link_send_init(link); } diff --git a/src/utun_instance.c b/src/utun_instance.c index c4f7614..b3749ff 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -95,12 +95,15 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config return -1; } */ - // Initialize connections from configuration + // Initialize connections from configuration - moved to utun_instance_init + // to avoid double initialization + /* if (init_connections(instance) < 0) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to initialize connections"); // Cleanup will be handled by utun_instance_destroy return NULL; } + */ return instance; } diff --git a/test_client.conf b/test_client.conf new file mode 100644 index 0000000..10a7af2 --- /dev/null +++ b/test_client.conf @@ -0,0 +1,15 @@ +[global] +my_node_id=0x2222222222222222 +my_private_key=2313912e5d34768983b0e06530a48c77816d228a5b5605e1ab3dc443d107a3dc +my_public_key=ede6cec8a9023339a758f60883ef41534d24a1ffdc09bbb787a5c24ddfd891e3092461835a97d37944c681fc6b2c1f5acde8ad192f7d2cdc9920aa0d3ff78e99 +tun_ip=10.99.0.2/24 +tun_ifname=tun98 + +[server: test] +addr=127.0.0.1:9001 +type=public + +[client: test_client] +keepalive=1 +peer_public_key=dde6cec8a9023339a758f60883ef41534d24a1ffdc09bbb787a5c24ddfd891e3092461835a97d37944c681fc6b2c1f5acde8ad192f7d2cdc9920aa0d3ff78e99 +link=test:127.0.0.1:9001 \ No newline at end of file diff --git a/test_etcp_two_instances.c b/test_etcp_two_instances.c new file mode 100644 index 0000000..1ca1d80 --- /dev/null +++ b/test_etcp_two_instances.c @@ -0,0 +1,176 @@ +#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 10000 // Increased from 5000 to 10000 ms + +static struct UTUN_INSTANCE* server_instance = NULL; +static struct UTUN_INSTANCE* client_instance = NULL; +static int test_completed = 0; // 0 = running, 1 = success, 2 = timeout/failure + +// For debug: enable in etcp_connections.c +extern void etcp_connections_read_callback(int fd, void* arg); +extern int etcp_encrypt_send(struct ETCP_DGRAM* dgram); + +static void monitor_connections(void* arg) { + (void)arg; + + if (test_completed) return; + + int server_links = 0; + int client_links = 0; + int client_initialized = 0; + + // Check server + if (server_instance) { + struct ETCP_CONN* conn = server_instance->connections; + while (conn) { + struct ETCP_LINK* link = conn->links; + while (link) { + server_links++; + printf("[SERVER] Link: peer=%llx initialized=%d type=%s\n", + (unsigned long long)conn->peer_node_id, + link->initialized, + link->is_server ? "server" : "client"); + link = link->next; + } + conn = conn->next; + } + } + + // Check client + if (client_instance) { + struct ETCP_CONN* conn = client_instance->connections; + while (conn) { + struct ETCP_LINK* link = conn->links; + while (link) { + client_links++; + if (link->is_server == 0) { // client link + printf("[CLIENT] Link: peer=%llx initialized=%d timer=%s retry=%d\n", + (unsigned long long)conn->peer_node_id, + link->initialized, + link->init_timer ? "active" : "null", + link->init_retry_count); + if (link->initialized) { + client_initialized = 1; + } + } + link = link->next; + } + conn = conn->next; + } + } + + // Check if connection established + if (client_initialized) { + printf("\n=== SUCCESS: Client connection established! ===\n"); + test_completed = 1; // Success + return; + } + + printf("[MONITOR] Server links: %d, Client links: %d, Status: %s\n", + server_links, client_links, + client_initialized ? "CONNECTED" : "connecting..."); + + // Schedule next check + if (!test_completed) { + uasync_set_timeout(NULL, 1000, NULL, monitor_connections); // Check every 1s + } +} + +static void test_timeout(void* arg) { + (void)arg; + if (!test_completed) { + printf("\n=== TIMEOUT: Connection not established in %d seconds ===\n", TEST_TIMEOUT_MS/1000); + test_completed = 2; // Timeout/failure + } +} + +int main() { + printf("=== ETCP Two-Instance Connection Test ===\n\n"); + + // Create server instance + printf("Creating server instance...\n"); + struct UASYNC* server_ua = uasync_create(); + server_instance = utun_instance_create(server_ua, "test_server.conf", NULL); + if (!server_instance) { + printf("Failed to create server instance\n"); + return 1; + } + + if (utun_instance_init(server_instance) < 0 || + utun_instance_register_sockets(server_instance) < 0) { + printf("Failed to initialize server instance\n"); + utun_instance_destroy(server_instance); + return 1; + } + printf("Server instance ready (node_id=%llx)\n\n", (unsigned long long)server_instance->node_id); + + // Create client instance + printf("Creating client instance...\n"); + struct UASYNC* client_ua = uasync_create(); + client_instance = utun_instance_create(client_ua, "test_client.conf", NULL); + if (!client_instance) { + printf("Failed to create client instance\n"); + utun_instance_destroy(server_instance); + return 1; + } + + if (utun_instance_init(client_instance) < 0 || + utun_instance_register_sockets(client_instance) < 0) { + printf("Failed to initialize client instance\n"); + utun_instance_destroy(server_instance); + utun_instance_destroy(client_instance); + return 1; + } + printf("Client instance ready (node_id=%llx)\n\n", (unsigned long long)client_instance->node_id); + + // Start monitoring + printf("Starting connection monitoring...\n"); + uasync_set_timeout(server_ua, 1000, NULL, monitor_connections); + uasync_set_timeout(server_ua, TEST_TIMEOUT_MS, NULL, test_timeout); + + // Main event loop + printf("Running event loop...\n\n"); + int elapsed = 0; + while (!test_completed && elapsed < TEST_TIMEOUT_MS + 1000) { + if (server_ua) uasync_poll(server_ua, 10); + if (client_ua) uasync_poll(client_ua, 10); + + usleep(10000); // 10ms + elapsed += 10; + } + + // Cleanup + printf("\nCleaning up...\n"); + if (server_instance) { + server_instance->running = 0; + utun_instance_destroy(server_instance); + } + if (client_instance) { + client_instance->running = 0; + utun_instance_destroy(client_instance); + } + + if (test_completed == 1) { + printf("\n=== TEST PASSED ===\n"); + return 0; + } else if (test_completed == 2) { + printf("\n=== TEST FAILED: Connection timeout ===\n"); + return 1; + } else { + printf("\n=== TEST FAILED: Unknown error ===\n"); + return 1; + } +} \ No newline at end of file diff --git a/test_server.conf b/test_server.conf new file mode 100644 index 0000000..e3496ea --- /dev/null +++ b/test_server.conf @@ -0,0 +1,10 @@ +[global] +my_node_id=0x1111111111111111 +my_private_key=1313912e5d34768983b0e06530a48c77816d228a5b5605e1ab3dc443d107a3dc +my_public_key=dde6cec8a9023339a758f60883ef41534d24a1ffdc09bbb787a5c24ddfd891e3092461835a97d37944c681fc6b2c1f5acde8ad192f7d2cdc9920aa0d3ff78e99 +tun_ip=10.99.0.1/24 +tun_ifname=tun99 + +[server: test] +addr=127.0.0.1:9001 +type=public \ No newline at end of file diff --git a/tests/Makefile.am b/tests/Makefile.am index 10c744b..f8013f8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,71 +1,18 @@ # Tests Makefile.am for utun -# Simplified to include only essential tests after ETCP cleanup -# Only keep the working ETCP test and essential module tests -check_PROGRAMS = test_pkt_normalizer$(EXEEXT) \ - test_routing_full$(EXEEXT) \ - test_secure_channel_extended$(EXEEXT) \ - test_lib_comprehensive$(EXEEXT) test_lib_simple$(EXEEXT) \ - test_lib_performance$(EXEEXT) test_debug_config$(EXEEXT) \ - test_ll_queue_comprehensive$(EXEEXT) test_ecc_encrypt$(EXEEXT) \ - test_routing$(EXEEXT) \ - test_etcp_two_instances_fixed$(EXEEXT) +# Simple tests directory Makefile +SUBDIRS = . -# Basic includes -AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source - -# Individual test configurations -test_pkt_normalizer_SOURCES = test_pkt_normalizer.c -test_pkt_normalizer_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib - -test_routing_full_SOURCES = test_routing_full.c -test_routing_full_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -test_routing_full_LDADD = $(top_builddir)/src/routing.o $(top_builddir)/lib/libuasync.a -lpthread - -test_secure_channel_extended_SOURCES = test_secure_channel_extended.c -test_secure_channel_extended_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source -test_secure_channel_extended_LDADD = $(top_builddir)/src/secure_channel.o $(top_builddir)/src/crc32.o $(top_builddir)/tinycrypt/lib/source/aes_encrypt.o $(top_builddir)/tinycrypt/lib/source/aes_decrypt.o $(top_builddir)/tinycrypt/lib/source/ccm_mode.o $(top_builddir)/tinycrypt/lib/source/cmac_mode.o $(top_builddir)/tinycrypt/lib/source/ctr_mode.o $(top_builddir)/tinycrypt/lib/source/ecc.o $(top_builddir)/tinycrypt/lib/source/ecc_dh.o $(top_builddir)/tinycrypt/lib/source/ecc_dsa.o $(top_builddir)/tinycrypt/lib/source/sha256.o $(top_builddir)/lib/libuasync.a -lpthread -lcrypto - -test_lib_comprehensive_SOURCES = test_lib_comprehensive.c -test_lib_comprehensive_CFLAGS = -I$(top_srcdir)/lib -test_lib_comprehensive_LDADD = $(top_builddir)/lib/libuasync.a -test_lib_comprehensive_LINK = $(CCLD) $(test_lib_comprehensive_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ - -test_lib_simple_SOURCES = test_lib_simple.c -test_lib_simple_CFLAGS = -I$(top_srcdir)/lib -test_lib_simple_LDADD = $(top_builddir)/lib/libuasync.a -test_lib_simple_LINK = $(CCLD) $(test_lib_simple_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +# No tests in this directory for now +check_PROGRAMS = -test_lib_performance_SOURCES = test_lib_performance.c -test_lib_performance_CFLAGS = -I$(top_srcdir)/lib -test_lib_performance_LDADD = $(top_builddir)/lib/libuasync.a -test_lib_performance_LINK = $(CCLD) $(test_lib_performance_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ - -test_debug_config_SOURCES = test_debug_config.c -test_debug_config_CFLAGS = -I$(top_srcdir)/lib -test_debug_config_LDADD = $(top_builddir)/lib/libuasync.a -test_debug_config_LINK = $(CCLD) $(test_debug_config_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ - -test_ll_queue_comprehensive_SOURCES = test_ll_queue_comprehensive.c -test_ll_queue_comprehensive_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -test_ll_queue_comprehensive_LDADD = $(top_builddir)/lib/libuasync.a -test_ll_queue_comprehensive_LINK = $(CCLD) $(test_ll_queue_comprehensive_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ - -test_ecc_encrypt_SOURCES = test_ecc_encrypt.c -test_ecc_encrypt_CFLAGS = -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source -I$(top_srcdir)/src -I$(top_srcdir)/lib -test_ecc_encrypt_LDADD = $(top_builddir)/tinycrypt/lib/source/aes_encrypt.o $(top_builddir)/tinycrypt/lib/source/aes_decrypt.o $(top_builddir)/tinycrypt/lib/source/ccm_mode.o $(top_builddir)/tinycrypt/lib/source/cmac_mode.o $(top_builddir)/tinycrypt/lib/source/ctr_mode.o $(top_builddir)/tinycrypt/lib/source/ecc.o $(top_builddir)/tinycrypt/lib/source/ecc_dh.o $(top_builddir)/tinycrypt/lib/source/ecc_dsa.o $(top_builddir)/tinycrypt/lib/source/sha256.o $(top_builddir)/lib/libuasync.a -lpthread -lcrypto -test_ecc_encrypt_LINK = $(CCLD) $(test_ecc_encrypt_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ - -test_routing_SOURCES = test_routing.c -test_routing_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -test_routing_LDADD = $(top_builddir)/lib/libuasync.a -test_routing_LINK = $(CCLD) $(test_routing_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +# Basic includes if needed +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source -# Главный рабочий ETCP тест -test_etcp_two_instances_fixed_SOURCES = test_etcp_two_instances_fixed.c -test_etcp_two_instances_fixed_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source -test_etcp_two_instances_fixed_LDADD = $(top_builddir)/src/etcp.o $(top_builddir)/src/etcp_connections.o $(top_builddir)/src/secure_channel.o $(top_builddir)/src/utun_instance.o $(top_builddir)/src/config_parser.o $(top_builddir)/src/config_updater.o $(top_builddir)/src/crc32.o $(top_builddir)/src/pkt_normalizer.o $(top_builddir)/src/routing.o $(top_builddir)/src/tun_if.o $(top_builddir)/tinycrypt/lib/source/aes_encrypt.o $(top_builddir)/tinycrypt/lib/source/aes_decrypt.o $(top_builddir)/tinycrypt/lib/source/ccm_mode.o $(top_builddir)/tinycrypt/lib/source/cmac_mode.o $(top_builddir)/tinycrypt/lib/source/ctr_mode.o $(top_builddir)/tinycrypt/lib/source/ecc.o $(top_builddir)/tinycrypt/lib/source/ecc_dh.o $(top_builddir)/tinycrypt/lib/source/ecc_dsa.o $(top_builddir)/tinycrypt/lib/source/ecc_platform_specific.o $(top_builddir)/tinycrypt/lib/source/utils.o $(top_builddir)/tinycrypt/lib/source/sha256.o $(top_builddir)/lib/libuasync.a -lpthread -lcrypto -test_etcp_two_instances_fixed_LINK = $(CCLD) $(test_etcp_two_instances_fixed_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +# Register no tests for this directory +TESTS = -# Register tests with automake -TESTS = $(check_PROGRAMS) \ No newline at end of file +# Help target +help: + @echo "This is the tests directory - no automake tests defined here" + @echo "Main tests are defined in the parent directory Makefile.am" \ No newline at end of file