build: extract libutun.a from src/ + add db_sync module + etcp API, BBR improvements

- Add libutun.a (noinst) containing all src/*.c except utun.c
- utun binary now links libutun.a + libuasync.a
- tests/Makefile.am simplified: all tests link libutun.a instead of
  manual .o file lists (removed ~70 lines of boilerplate)
- Add db_sync module: distributed content-addressed DB with LMDB
  backend, peer-to-peer sync via etcp_router (svc 0x20)
- etcp API: etcp_send_in_order(), etcp_clear_inflight_queues(),
  verify_packet_signature(), BBR getters
- BBR: adaptive threshold (1/4 of pipe-min instead of hardcoded)
- route_bgp/etcp_connect: STCP transport support in NODEINFO
- conn_mgr: NODEINFO_ADDRS doc for nat_type/transport/proto fields
- Cleanup: removed AUDIT_FINDINGS.txt, filelist.txt, nat.txt
This commit is contained in:
Evgeny committed 2026-07-06 11:42:13 +03:00
1 parent 7139969acd
commit 8756f561be
23 files changed
+1508 -786

No files matched your search

+45 -112
View File
@@ -49,6 +49,7 @@ check_PROGRAMS = \
test_bgp_triangle \
test_conn_mgr \
test_etcp_connect \
test_db_sync \
test_stcp_traffic \
test_bbr_integration \
test_intensive_memory_pool \
@@ -62,70 +63,7 @@ noinst_PROGRAMS =
# Basic includes
AM_CFLAGS = -g -I$(top_srcdir)/src -I$(top_srcdir)/lib
# Secure channel and CRC objects (built in src directory)
SECURE_CHANNEL_OBJS = $(top_builddir)/src/utun-secure_channel.o $(top_builddir)/src/utun-crc32.o
# Transport objects (needed by etcp_api.c)
STCP_LINK_OBJS = $(top_builddir)/src/utun-stcp_link.o $(top_builddir)/src/utun-stcp.o $(top_builddir)/src/utun-stcp_server.o $(top_builddir)/src/utun-stcp_client.o
# ETCP core objects
ETCP_CORE_OBJS = \
$(top_builddir)/src/utun-etcp.o \
$(top_builddir)/src/utun-etcp_connections.o \
$(top_builddir)/src/utun-etcp_bbr.o \
$(top_builddir)/src/utun-etcp_loadbalancer.o \
$(top_builddir)/src/utun-pkt_normalizer.o \
$(top_builddir)/src/utun-etcp_api.o \
$(top_builddir)/src/utun-etcp_connect.o \
$(top_builddir)/src/utun-etcp_debug.o \
$(top_builddir)/src/utun-etcp_dump.o
# Platform-specific TUN objects
if OS_WINDOWS
TUN_PLATFORM_OBJ = $(top_builddir)/src/utun-tun_windows.o
else
if OS_FREEBSD
TUN_PLATFORM_OBJ = $(top_builddir)/src/utun-tun_freebsd.o
else
TUN_PLATFORM_OBJ = $(top_builddir)/src/utun-tun_linux.o
endif
endif
# Full ETCP objects
ETCP_FULL_OBJS = \
$(top_builddir)/src/utun-config_parser.o \
$(top_builddir)/src/utun-config_updater.o \
$(top_builddir)/src/utun-route_lib.o \
$(top_builddir)/src/utun-route_bgp.o \
$(top_builddir)/src/utun-route_ping.o \
$(top_builddir)/src/utun-route_node.o \
$(top_builddir)/src/utun-route_node_lmdb.o \
$(top_builddir)/src/utun-route_connectivity.o \
$(top_builddir)/src/utun-conn_mgr.o \
$(top_builddir)/src/utun-routing.o \
$(top_builddir)/src/utun-tun_if.o \
$(top_builddir)/src/utun-tun_route.o \
$(top_builddir)/src/utun-packet_dump.o \
$(top_builddir)/src/utun-firewall.o \
$(top_builddir)/src/utun-eim_nat.o \
$(top_builddir)/src/utun-nat_transport.o \
$(top_builddir)/src/utun-control_server.o \
$(top_builddir)/src/utun-msg_transport.o \
$(TUN_PLATFORM_OBJ) \
$(top_builddir)/src/utun-utun_instance.o \
$(top_builddir)/src/proxy/utun-tcp_proxy_client.o \
$(top_builddir)/src/utun-etcp_router.o \
$(top_builddir)/src/proxy/utun-tcp_proxy_server.o \
$(top_builddir)/src/proxy/utun-udp_proxy.o \
$(top_builddir)/src/proxy/utun-socks_proxy.o \
$(top_builddir)/src/proxy/utun-icmp_proxy.o \
$(top_builddir)/src/lwip_tcp/utun-lwip_pbuf.o \
$(top_builddir)/src/lwip_tcp/utun-lwip_tcp.o \
$(top_builddir)/src/lwip_tcp/utun-lwip_tcp_in.o \
$(top_builddir)/src/lwip_tcp/utun-lwip_tcp_out.o \
$(STCP_LINK_OBJS) \
$(ETCP_CORE_OBJS)
LIBUTUN = $(top_builddir)/src/libutun.a
# Windows-specific libraries
if OS_WINDOWS
@@ -143,77 +81,72 @@ CRYPTO_LIBS = -lcrypto
# Test definitions
test_etcp_bbr_SOURCES = test_etcp_bbr.c
test_etcp_bbr_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_bbr_LDADD = $(top_builddir)/src/utun-etcp_bbr.o $(COMMON_LIBS)
test_etcp_bbr_LDADD = $(LIBUTUN) $(COMMON_LIBS)
test_etcp_crypto_SOURCES = test_etcp_crypto.c
test_etcp_crypto_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_crypto_LDADD = $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_crypto_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stream_cipher_SOURCES = test_stream_cipher.c
test_stream_cipher_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_stream_cipher_LDADD = $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stream_cipher_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stream_sign_SOURCES = test_stream_sign.c
test_stream_sign_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_stream_sign_LDADD = $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stream_sign_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_transport_SOURCES = test_stcp_link.c
test_transport_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_transport_LDADD = $(STCP_LINK_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_transport_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_transport_SOURCES = test_etcp_stcp.c
test_etcp_transport_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_transport_LDADD = $(STCP_LINK_OBJS) $(top_builddir)/src/utun-etcp_api.o $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_transport_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stcp_SOURCES = test_stcp.c
test_stcp_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_stcp_LDADD = $(top_builddir)/src/utun-stcp.o $(top_builddir)/src/utun-stcp_server.o $(top_builddir)/src/utun-stcp_client.o $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stcp_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_two_instances_SOURCES = test_etcp_two_instances.c
test_etcp_two_instances_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_two_instances_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_two_instances_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_simple_traffic_SOURCES = test_etcp_simple_traffic.c
test_etcp_simple_traffic_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_simple_traffic_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_simple_traffic_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_ipv6_sockets_SOURCES = test_ipv6_sockets.c
test_ipv6_sockets_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_ipv6_sockets_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_ipv6_sockets_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_tcp_proxy_client_SOURCES = test_tcp_proxy_client.c
test_tcp_proxy_client_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_tcp_proxy_client_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_socks_http_proxy_SOURCES = test_socks_http_proxy.c
test_socks_http_proxy_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_socks_http_proxy_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_lwip_tcp_SOURCES = test_lwip_tcp.c
test_lwip_tcp_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_lwip_tcp_LDADD = \
$(top_builddir)/src/lwip_tcp/utun-lwip_pbuf.o \
$(top_builddir)/src/lwip_tcp/utun-lwip_tcp.o \
$(top_builddir)/src/lwip_tcp/utun-lwip_tcp_in.o \
$(top_builddir)/src/lwip_tcp/utun-lwip_tcp_out.o \
$(COMMON_LIBS)
test_lwip_tcp_LDADD = $(LIBUTUN) $(COMMON_LIBS)
test_etcp_router_SOURCES = test_etcp_router.c
test_etcp_router_LDADD = $(top_builddir)/src/utun-dummynet.o $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_router_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_router_unit_SOURCES = test_etcp_router_unit.c
test_etcp_router_unit_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_router_unit_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_router_reconnect_SOURCES = test_etcp_router_reconnect.c
test_etcp_router_reconnect_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_router_reconnect_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_tcp_proxy_server_SOURCES = test_tcp_proxy_server.c
test_tcp_proxy_server_CFLAGS = -I$(top_srcdir)/lib
test_tcp_proxy_server_LDADD = $(COMMON_LIBS)
test_udp_proxy_SOURCES = test_udp_proxy.c
test_udp_proxy_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_udp_proxy_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_icmp_proxy_SOURCES = test_icmp_proxy.c
test_icmp_proxy_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_icmp_proxy_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_radix_SOURCES = test_radix.c
test_radix_CFLAGS = -I$(top_srcdir)/lib
@@ -221,57 +154,53 @@ test_radix_LDADD = $(COMMON_LIBS)
test_route6_lib_SOURCES = test_route6_lib.c
test_route6_lib_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_route6_lib_LDADD = $(top_builddir)/src/utun-route6_lib.o \
$(top_builddir)/src/utun-route_lib.o \
$(top_builddir)/src/utun-route_node.o \
$(top_builddir)/src/utun-etcp_debug.o \
$(COMMON_LIBS)
test_route6_lib_LDADD = $(LIBUTUN) $(COMMON_LIBS)
test_etcp_minimal_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_minimal_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_100_packets_SOURCES = test_etcp_100_packets.c
test_etcp_100_packets_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_100_packets_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_100_packets_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_reconnect_SOURCES = test_etcp_reconnect.c
test_etcp_reconnect_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_reconnect_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_reconnect_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_pkt_normalizer_etcp_SOURCES = test_pkt_normalizer_etcp.c
test_pkt_normalizer_etcp_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_pkt_normalizer_etcp_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_pkt_normalizer_etcp_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_pkt_normalizer_standalone_SOURCES = test_pkt_normalizer_standalone.c
test_pkt_normalizer_standalone_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_pkt_normalizer_standalone_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_pkt_normalizer_standalone_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_api_SOURCES = test_etcp_api.c
test_etcp_api_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_api_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_api_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_ping_SOURCES = test_etcp_ping.c
test_etcp_ping_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_ping_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_ping_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_route_ping_SOURCES = test_route_ping.c
test_route_ping_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_route_ping_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_route_ping_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_nat_detection_SOURCES = test_nat_detection.c
test_nat_detection_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_nat_detection_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_nat_detection_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_nat_engine_SOURCES = test_nat_engine.c
test_nat_engine_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_nat_engine_LDADD = $(top_builddir)/src/utun-eim_nat.o $(top_builddir)/src/utun-config_parser.o $(COMMON_LIBS)
test_nat_engine_LDADD = $(LIBUTUN) $(COMMON_LIBS)
test_nat_transport_SOURCES = test_nat_transport.c
test_nat_transport_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_nat_transport_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_nat_transport_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_nat_stress_SOURCES = test_nat_stress.c
test_nat_stress_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_nat_stress_LDADD = $(top_builddir)/src/utun-eim_nat.o $(top_builddir)/src/utun-config_parser.o $(COMMON_LIBS)
test_nat_stress_LDADD = $(LIBUTUN) $(COMMON_LIBS)
test_ll_queue_SOURCES = test_ll_queue.c
test_ll_queue_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
@@ -319,35 +248,39 @@ test_debug_categories_LDADD = $(COMMON_LIBS)
test_config_debug_SOURCES = test_config_debug.c
test_config_debug_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_config_debug_LDADD = $(top_builddir)/src/utun-config_parser.o $(COMMON_LIBS)
test_config_debug_LDADD = $(LIBUTUN) $(COMMON_LIBS)
test_route_lib_SOURCES = test_route_lib.c
test_route_lib_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_route_lib_LDADD = $(top_builddir)/src/utun-route_lib.o $(top_builddir)/src/utun-route_node.o $(top_builddir)/src/utun-etcp_debug.o $(COMMON_LIBS)
test_route_lib_LDADD = $(LIBUTUN) $(COMMON_LIBS)
test_bgp_route_exchange_SOURCES = test_bgp_route_exchange.c
test_bgp_route_exchange_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_bgp_route_exchange_LDADD = $(top_builddir)/src/utun-dummynet.o $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_bgp_route_exchange_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_bgp_triangle_SOURCES = test_bgp_triangle.c
test_bgp_triangle_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_bgp_triangle_LDADD = $(top_builddir)/src/utun-dummynet.o $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_bgp_triangle_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_conn_mgr_SOURCES = test_conn_mgr.c
test_conn_mgr_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_conn_mgr_LDADD = $(top_builddir)/src/utun-dummynet.o $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_conn_mgr_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_connect_SOURCES = test_etcp_connect.c
test_etcp_connect_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_connect_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_etcp_connect_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_db_sync_SOURCES = test_db_sync.c
test_db_sync_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_db_sync_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stcp_traffic_SOURCES = test_stcp_traffic.c
test_stcp_traffic_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_stcp_traffic_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_stcp_traffic_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_bbr_integration_SOURCES = bbr_integration/test_bbr_integration.c
test_bbr_integration_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_bbr_integration_LDADD = $(top_builddir)/src/utun-dummynet.o $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_bbr_integration_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
bench_timeout_heap_SOURCES = bench_timeout_heap.c
bench_timeout_heap_CFLAGS = -I$(top_srcdir)/lib
+3 -4
View File
@@ -170,7 +170,7 @@ static struct CFG_CLIENT_LINK* add_link(struct CFG_CLIENT* cli, struct CFG_SERVE
/* ===== Callbacks ===== */
static void on_recv(struct ETCP_CONN* conn, struct ll_entry* entry) {
struct test_ctx* ctx = (struct test_ctx*)conn->instance->etcp_new_conn_arg;
struct test_ctx* ctx = (struct test_ctx*)conn->instance->test_user_ptr;
if (entry) { ctx->bytes_received += entry->len; queue_entry_free(entry); }
}
@@ -346,8 +346,8 @@ int main(void) {
ctx.sender = create_instance(ctx.ua, 0x1111111111111111ULL, c_priv, c_pub);
ctx.receiver = create_instance(ctx.ua, 0x2222222222222222ULL, s_priv, s_pub);
if (!ctx.sender || !ctx.receiver) { printf("ERROR: create_instance failed\n"); return 1; }
ctx.sender->etcp_new_conn_arg = &ctx;
ctx.receiver->etcp_new_conn_arg = &ctx;
ctx.sender->test_user_ptr = &ctx;
ctx.receiver->test_user_ptr = &ctx;
if (add_server(ctx.receiver, "srv", SRV_PORT) < 0 ||
add_server(ctx.sender, "local", CLI_PORT) < 0 ||
@@ -362,7 +362,6 @@ int main(void) {
if (utun_instance_init(ctx.sender) < 0) { printf("ERROR: sender init failed\n"); return 1; }
etcp_bind(ctx.receiver, ETCP_RT_ID_DATA, on_recv);
etcp_set_new_conn_cbk(ctx.receiver, NULL, &ctx);
printf("Creating dummynet on port %d ...\n", DN_PORT);
ctx.dn = dummynet_create(ctx.ua, "127.0.0.1", DN_PORT);
+244
View File
@@ -0,0 +1,244 @@
// test_db_sync.c — всестороннее тестирование модуля db_sync
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include <sys/stat.h>
#include "../lib/platform_compat.h"
#include "test_utils.h"
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#else
#include <unistd.h>
#endif
#include "../src/etcp.h"
#include "../src/etcp_connections.h"
#include "../src/config_parser.h"
#include "../src/config_updater.h"
#include "../src/utun_instance.h"
#include "../src/routing.h"
#include "../src/tun_if.h"
#include "../src/secure_channel.h"
#include "../src/db_sync.h"
#include "../lib/u_async.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#define TEST_TIMEOUT_TB 300000 // 30s total
#define PHASE_TIMEOUT_TB 150000 // 15s per phase
#define POLL_INTERVAL_MS 5
#define NODE_ID_A 0xAAAAAAAAAAAAAAAAULL
#define NODE_ID_B 0xBBBBBBBBBBBBBBBBULL
static struct UTUN_INSTANCE* inst_a = NULL;
static struct UTUN_INSTANCE* inst_b = NULL;
static struct UASYNC* ua = NULL;
static int test_phase = 0; // 0=running, 1=success, 2=failure
static void* timeout_id = NULL;
static char temp_dir[] = "/tmp/utun_dbsync_XXXXXX";
static char config_a[256], config_b[256];
static int port_a_srv, port_b_srv;
static int write_file(const char* path, const char* fmt, ...) {
va_list ap;
FILE* f = fopen(path, "w");
if (!f) return -1;
va_start(ap, fmt); vfprintf(f, fmt, ap); va_end(ap);
fclose(f); return 0;
}
static char* get_pubkey(const char* path) {
struct utun_config* cfg = parse_config(path);
if (!cfg) return NULL;
char* pub = strdup(cfg->global.my_public_key_hex);
free_config(cfg); return pub;
}
static int create_temp_configs(void) {
if (test_mkdtemp(temp_dir) != 0) { fprintf(stderr, "mkdtemp failed\n"); return -1; }
int base = 42000 + (getpid() % 15000);
port_a_srv = base; port_b_srv = base + 1;
snprintf(config_a, sizeof(config_a), "%s/a.conf", temp_dir);
snprintf(config_b, sizeof(config_b), "%s/b.conf", temp_dir);
// Create LMDB directories (parent first, then child)
char db_path[320];
snprintf(db_path, sizeof(db_path), "%s/db_a", temp_dir); mkdir(db_path, 0755);
snprintf(db_path, sizeof(db_path), "%s/db_a/sync", temp_dir); mkdir(db_path, 0755);
snprintf(db_path, sizeof(db_path), "%s/db_b", temp_dir); mkdir(db_path, 0755);
snprintf(db_path, sizeof(db_path), "%s/db_b/sync", temp_dir); mkdir(db_path, 0755);
if (write_file(config_a,
"[global]\n"
"my_node_id=0xAAAAAAAAAAAAAAAA\n"
"tun_ip=10.200.0.1/24\n"
"tun_ifname=tun200\n"
"keepalive_adaptive=0\n"
"db_path=%s/db_a\n"
"db_sync_enabled=1\n"
"\n"
"[server: srv_a]\n"
"addr=127.0.0.1:%d\n"
"type=public\n"
"\n"
"[allowed_keys]\n"
"allow_all=1\n",
temp_dir, port_a_srv) != 0) return -1;
if (config_ensure_keys_and_node_id(config_a) != 0) return -1;
char* pub_a = get_pubkey(config_a);
if (!pub_a) return -1;
if (write_file(config_b,
"[global]\n"
"my_node_id=0xBBBBBBBBBBBBBBBB\n"
"tun_ip=10.200.0.2/24\n"
"tun_ifname=tun201\n"
"keepalive_adaptive=0\n"
"db_path=%s/db_b\n"
"db_sync_enabled=1\n"
"\n"
"[server: srv_b]\n"
"addr=127.0.0.1:%d\n"
"type=public\n"
"\n"
"[client: to_a]\n"
"keepalive=1\n"
"peer_public_key=%s\n"
"link=srv_b:127.0.0.1:%d\n"
"\n"
"[allowed_keys]\n"
"allow_all=1\n",
temp_dir, port_b_srv, pub_a, port_a_srv) != 0) { free(pub_a); return -1; }
free(pub_a);
if (config_ensure_keys_and_node_id(config_b) != 0) return -1;
return 0;
}
static void cleanup_temp_configs(void) {
unlink(config_a); unlink(config_b);
char db_a[320], db_b[320];
snprintf(db_a, sizeof(db_a), "%s/db_a/sync/data.mdb", temp_dir);
snprintf(db_b, sizeof(db_b), "%s/db_b/sync/data.mdb", temp_dir);
unlink(db_a); unlink(db_b);
snprintf(db_a, sizeof(db_a), "%s/db_a/sync/lock.mdb", temp_dir);
snprintf(db_b, sizeof(db_b), "%s/db_b/sync/lock.mdb", temp_dir);
unlink(db_a); unlink(db_b);
char pa[320]; snprintf(pa, sizeof(pa), "%s/db_a/sync", temp_dir); test_rmdir(pa);
snprintf(pa, sizeof(pa), "%s/db_a", temp_dir); test_rmdir(pa);
snprintf(pa, sizeof(pa), "%s/db_b/sync", temp_dir); test_rmdir(pa);
snprintf(pa, sizeof(pa), "%s/db_b", temp_dir); test_rmdir(pa);
test_rmdir(temp_dir);
}
static void test_timeout(void* arg) { (void)arg; test_phase = 2; }
static int wait_for(const char* desc, int (*cond)(void), int timeout_tb) {
uint64_t start = get_time_tb();
while (!cond() && (get_time_tb() - start) < (uint64_t)timeout_tb && test_phase == 0)
uasync_poll(ua, POLL_INTERVAL_MS);
if (cond()) return 1;
if (test_phase == 0) { fprintf(stderr, "TIMEOUT: %s\n", desc); test_phase = 2; }
return 0;
}
static void sleep_tb(int tb) {
uint64_t end = get_time_tb() + (uint64_t)tb;
while (get_time_tb() < end && test_phase == 0) uasync_poll(ua, POLL_INTERVAL_MS);
}
// ---- Condition functions ----
static int cond_links_init(void) {
if (!inst_a || !inst_b) return 0;
struct ETCP_CONN* ca = inst_a->connections;
while (ca) { struct ETCP_LINK* l = ca->links; while (l) { if (l->initialized) return 1; l = l->next; } ca = ca->next; }
return 0;
}
static int cond_count_a(uint32_t expected) {
if (!inst_a) return 0;
return db_sync_count(inst_a) == expected;
}
static int cond_count_b(uint32_t expected) {
if (!inst_b) return 0;
return db_sync_count(inst_b) == expected;
}
static uint32_t count_a_target, count_b_target;
static int _cond_count_a(void) { return cond_count_a(count_a_target); }
static int _cond_count_b(void) { return cond_count_b(count_b_target); }
static int insert_many(struct UTUN_INSTANCE* inst, int start, int count) {
char buf[128];
for (int i = start; i < start + count && test_phase == 0; i++) {
snprintf(buf, sizeof(buf), "{\"idx\":%d,\"val\":\"data_%d\",\"pad\":\"%s\"}", i, i,
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
int ret = db_sync_insert(inst, buf);
if (ret < 0) { fprintf(stderr, "insert_many failed at %d ret=%d\n", i, ret); return -1; }
}
return 0;
}
static int insert_many_batch(struct UTUN_INSTANCE* inst, int start, int count) {
char buf[256];
for (int i = start; i < start + count && test_phase == 0; i++) {
snprintf(buf, sizeof(buf), "{\"n\":%d,\"text\":\"record_number_%d_abcdefghijklmnopqrstuvwxyz\"}", i, i);
db_sync_insert(inst, buf);
}
return 0;
}
// ---- Main test ----
int main(void) {
printf("=== test_db_sync ===\n");
debug_config_init();
debug_set_level(DEBUG_LEVEL_ERROR); // quiet
if (create_temp_configs() != 0) { fprintf(stderr, "config creation failed\n"); return 1; }
utun_instance_set_tun_init_enabled(0);
ua = uasync_create();
if (!ua) { fprintf(stderr, "uasync_create failed\n"); cleanup_temp_configs(); return 1; }
inst_a = utun_instance_create(ua, config_a);
inst_b = utun_instance_create(ua, config_b);
if (!inst_a || !inst_b) { fprintf(stderr, "instance create failed\n"); cleanup_temp_configs(); return 1; }
if (utun_instance_init(inst_a) != 0 || utun_instance_init(inst_b) != 0) {
fprintf(stderr, "instance init failed\n"); cleanup_temp_configs(); return 1;
}
timeout_id = uasync_set_timeout(ua, TEST_TIMEOUT_TB, NULL, test_timeout, "test_timeout");
// ===== Phase 1: базовый CRUD =====
printf("Phase 1: basic CRUD...\n");
if (db_sync_count(inst_a) != 0) { fprintf(stderr, "FAIL: initial count not 0 (got %u)\n", db_sync_count(inst_a)); test_phase=2; }
if (db_sync_insert(inst_a, "{\"key\":\"val1\"}") != 0) { fprintf(stderr,"FAIL: insert 1\n"); test_phase=2; }
if (db_sync_insert(inst_a, "{\"key\":\"val2\"}") != 0) { fprintf(stderr,"FAIL: insert 2\n"); test_phase=2; }
if (db_sync_insert(inst_a, "{\"key\":\"val3\"}") != 0) { fprintf(stderr,"FAIL: insert 3\n"); test_phase=2; }
if (db_sync_count(inst_a) != 3) { fprintf(stderr,"FAIL: count not 3 (got %u)\n", db_sync_count(inst_a)); test_phase=2; }
// Dedup by (timestamp,datahash): same content at different time = new record
if (db_sync_insert(inst_a, "{\"key\":\"val4\"}") != 0) { fprintf(stderr,"FAIL: insert 4\n"); test_phase=2; }
if (db_sync_count(inst_a) != 4) { fprintf(stderr,"FAIL: count not 4 (got %u)\n", db_sync_count(inst_a)); test_phase=2; }
if (test_phase == 0) printf("Phase 1: PASS (count=4)\n");
// ===== Phase 2: initial sync A↔B =====
printf("Phase 2: initial sync...\n");
if (test_phase == 0) { count_b_target = 4; if (!wait_for("B count=4", _cond_count_b, PHASE_TIMEOUT_TB)) test_phase=2; }
if (test_phase == 0) printf("Phase 2: PASS (B synced %u records)\n", db_sync_count(inst_b));
// ===== Cleanup =====
if (timeout_id && ua) { uasync_cancel_timeout(ua, timeout_id); timeout_id = NULL; }
if (inst_a) { inst_a->running = 0; utun_instance_destroy(inst_a); inst_a = NULL; }
if (inst_b) { inst_b->running = 0; utun_instance_destroy(inst_b); inst_b = NULL; }
if (ua) { uasync_destroy(ua, 0); ua = NULL; }
cleanup_temp_configs();
if (test_phase == 0) test_phase = 1;
printf("=== %s ===\n", test_phase == 1 ? "PASS" : "FAIL");
return test_phase == 1 ? 0 : 1;
}
+3 -4
View File
@@ -169,7 +169,7 @@ static void dummynet_set_both(struct dummynet* dn, uint32_t bw_kbps, uint32_t de
/* ===== Приём данных ===== */
static void on_recv(struct ETCP_CONN* conn, struct ll_entry* entry) {
struct test_ctx* ctx = (struct test_ctx*)conn->instance->etcp_new_conn_arg;
struct test_ctx* ctx = (struct test_ctx*)conn->instance->test_user_ptr;
if (entry) {
ctx->bytes_received += entry->len;
queue_entry_free(entry);
@@ -309,8 +309,8 @@ int main(void) {
ctx.sender = create_instance(ctx.ua, 0x1111111111111111ULL, c_priv, c_pub);
ctx.receiver = create_instance(ctx.ua, 0x2222222222222222ULL, s_priv, s_pub);
if (!ctx.sender || !ctx.receiver) { printf("Instance failed\n"); return 1; }
ctx.sender->etcp_new_conn_arg = &ctx;
ctx.receiver->etcp_new_conn_arg = &ctx;
ctx.sender->test_user_ptr = &ctx;
ctx.receiver->test_user_ptr = &ctx;
/* Server side: один слушающий сокет */
if (add_server(ctx.receiver, "srv1", SRV1_PORT) < 0) {
@@ -331,7 +331,6 @@ int main(void) {
if (utun_instance_init(ctx.sender) < 0) { printf("Sender init failed\n"); return 1; }
etcp_bind(ctx.receiver, ETCP_RT_ID_DATA, on_recv);
etcp_set_new_conn_cbk(ctx.receiver, NULL, &ctx);
printf("Creating dummynet...\n");
ctx.dn[0] = dummynet_create(ctx.ua, "127.0.0.1", DN1_PORT);