- Добавлены поля keepalive_timer и pkt_sent_since_keepalive в struct ETCP_LINK
- Реализована отправка пустых keepalive пакетов (только timestamp) по таймеру
- Keepalive пропускается если был отправлен другой пакет с момента последнего тика
- Таймер запускается после инициализации линка (keepalive_interval из конфига)
- Исправлен тест test_bgp_route_exchange: убран лишний htonl() при проверке маршрутов
- Переименовано поле allowed_subnets -> route_subnets в конфигурации
- Обновлен парсинг конфига: allowed_subnet -> route_subnet
- Создан новый модуль tun_route для управления системными маршрутами
- Linux: реализация через netlink sockets с fallback на ip route
- Windows: реализация через IP Helper API
- BSD: реализация через routing sockets с fallback на route
- При запуске: автоматическое добавление маршрутов route_subnet на TUN интерфейс
- При завершении: автоматическое удаление всех маршрутов через tun_route_flush
- Обновлены Makefile.am для сборки новых файлов
Replaced file-based config creation with direct struct population.
This eliminates temporary files and makes the test cleaner.
Key changes:
- Added helper functions for creating config structures
- Create CFG_SERVER, CFG_CLIENT, CFG_CLIENT_LINK programmatically
- Use utun_instance_create_from_config() instead of file-based creation
- No temp directories or file cleanup needed
The test now builds configs in memory using helper functions like
make_sockaddr(), create_server(), create_client(), etc.
- Добавлена опция tun_test_mode в конфиг для работы без реального TUN устройства
- Добавлены функции для работы с очередями TUN в тестовом режиме
- Добавлен API для программного создания instance из структуры конфига
- Создан тест test_routing_mesh.c с 3-instance mesh топологией
- Ключи генерируются автоматически и распределяются между instance
- Add Windows implementation of default_CSPRNG() using CryptGenRandom
- Add fallback stub for platforms without CSPRNG support
- Fix build.sh to properly detect build failures (use PIPESTATUS)
- Show proper error message instead of "Build completed successfully" on failure
- Remove sys/socket.h include from test_etcp_two_instances.c (Linux-only)
- Fix test_mkdtemp buffer overflow - use memcpy instead of strncpy
- Fix test_mkdtemp return value check (replace == NULL with != 0)
- Add Windows socket libraries (-lws2_32 -liphlpapi) to test builds
- All tests build successfully on Linux
- Create test_utils.h with cross-platform utility functions:
* test_mkdtemp() - Windows uses GetTempPath + _mkdir, Linux uses mkdtemp
* test_unlink() - Windows _unlink, Linux unlink
* test_rmdir() - Windows _rmdir, Linux rmdir
- Update all test files to use test_utils.h
- Replace arpa/inet.h and netinet/in.h with platform_compat.h
- Replace unistd.h with conditional includes
- Replace mkdtemp(), unlink(), rmdir() with test_* versions
- Tests now build on both Linux and Windows
- Note: Some integration tests may fail on Linux due to test environment
- Wrap net/if.h include in #ifndef _WIN32 in etcp_connections.c
- Add forward declarations for ROUTE_TABLE and ROUTE_ENTRY in route_lib.h
- All 22 tests pass on Linux
- Add sa_family_t typedef for Windows in platform_compat.h
- Add forward declaration of struct ll_queue in ll_queue.h to fix warnings
- Replace arpa/inet.h includes with platform_compat.h in:
tun_linux.c, etcp_connections.c, route_lib.c, route_bgp.c,
utun_instance.c, routing.c, utun.c, packet_dump.h, config_parser.c
- All 22 tests pass on Linux
- Split TUN implementation into platform-specific files:
- tun_if.c: Common code (queues, callbacks, statistics)
- tun_linux.c: Linux TUN/TAP implementation (/dev/net/tun + ioctl)
- tun_windows.c: Windows Wintun implementation (wintun.dll + IP Helper)
- Update tun_if.h with platform abstraction layer:
- tun_platform_init/cleanup/read/write/get_poll_fd
- Platform handles: fd (Linux), WINTUN handles (Windows)
- Windows implementation features:
- Dynamic loading of wintun.dll with graceful error handling
- IP Helper API for IP address and MTU configuration
- HANDLE-based uasync integration
- Clear error message if wintun.dll is not found
- Update build system:
- configure.ac: Detect Windows (mingw/msys/cygwin)
- src/Makefile.am: Conditional compilation of tun_linux/tun_windows
- tests/Makefile.am: Link platform-specific TUN objects
- Add wintun.dll and wintun.h to lib/ directory
- All 22 tests pass on Linux
- Ready for MSYS2 UCRT64 Windows build
- Replace artificial timing loop with uasync_poll(ua, -1) for proper timeout handling
- Fix endianness bug: use htonl() for IP address comparison in check_learned_route()
- Remove duplicate init_connections() calls
Test now passes successfully - BGP route exchange working correctly
- Add ROUTE_BGP_CONN_ITEM structure for connection list management
- Modify route_bgp_new_conn() to add connections to senders_list
- Create route_bgp_remove_conn() for cleanup on connection close
- Add route_change_callback typedef and fields to ROUTE_TABLE
- Implement route_bgp_on_route_change() to broadcast updates
- Modify route_table_insert() to call callback on insert/update
- Modify route_table_delete_entry() to call callback on delete
- Add route_bgp_remove_conn() call in etcp_connection_close()
- Fix test: remove duplicate init_connections() calls
Features:
- Connections tracked in senders_list (ll_queue)
- Route changes broadcast to all connections
- Withdraw messages sent on connection close
- No port binding conflicts in tests
All changes working correctly - BGP route exchange functional in both directions
- Add route_bgp.c/h with BGP-like route exchange functionality
- Implement route_bgp_init/destroy for module lifecycle
- Add route_bgp_new_conn to send routing table on connection
- Implement route_bgp_receive_cbk for processing incoming routes
- Add route_table_delete_entry for individual route removal
- Extend ROUTE_ENTRY with endpoint_ip, endpoint_port, destination_node_id
- Add DEBUG_CATEGORY_BGP to debug_config.h
- Integrate BGP initialization into utun_instance_create
- Call route_bgp_new_conn from etcp_connections on link init
- Create integration test test_bgp_route_exchange.c
- Add route_bgp_delete_entry tests to test_route_lib.c
- Update Makefiles to include new module
Route exchange tested and working in both directions (client-server)
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)
Test now verifies that NAT fields contain CORRECT data, not just non-zero:
- Verifies nat_ip equals 127.0.0.1 (0x7F000001) - expected for localhost test
- Verifies nat_port is in valid ephemeral port range (> 1024 and <= 65535)
- Fails test if values are incorrect (not just warning)
This ensures the server correctly returns the client's external address
in the INIT_RESPONSE handshake packet.
Test output:
[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 contain valid values (127.0.0.1:9012)
- Added check that NAT fields are populated after connection establishment
- Verifies nat_ip is non-zero and contains correct IP (127.0.0.1)
- Verifies nat_port is non-zero and contains correct port
- Checks nat_changes_count=0 (first initialization)
- Checks nat_hits_count=0 (no repeated matches yet)
Test output shows:
[CLIENT] PASS: NAT address is set: 127.0.0.1:9012
[CLIENT] PASS: nat_changes_count=0, nat_hits_count=0
Changed from global bindings to per-instance bindings:
1. Added struct ETCP_BINDINGS in etcp_api.h:
- Contains array of callbacks[ETCP_MAX_BINDINGS]
- NULL means not bound
2. Updated UTUN_INSTANCE (utun_instance.h):
- Added field: struct ETCP_BINDINGS api_bindings
- Initialized to NULL by calloc in utun_instance_create
3. Updated API functions (etcp_api.h/c):
- etcp_bind(inst, id, callback) - per-instance binding
- etcp_unbind(inst, id) - per-instance unbinding
- Removed etcp_api_init/etcp_api_deinit (not needed)
- etcp_int_recv now uses conn->instance->api_bindings.callbacks[id]
4. Updated test_etcp_api.c:
- Separate callbacks for server and client
- Register via etcp_bind(server_instance, ...) and etcp_bind(client_instance, ...)
- Removed global etcp_api_init/etcp_api_deinit calls
Test passes: All 100 packets transmitted in each direction.
etcp_bind uses global table - multiple binds with same ID overwrite.
Fixed by using single recv_callback that checks conn pointer:
- conn == server_conn: forward direction (client->server)
- conn == client_conn: backward direction (server->client)
Test now passes: All 100 packets transmitted in each direction.
Based on test_pkt_normalizer_etcp.c but uses high-level API:
- etcp_send() for sending packets via ETCP normalizer
- etcp_bind() for registering receive callbacks
- etcp_api_init()/etcp_api_deinit() for API lifecycle
NOTE: Test has current limitation - pkt_normalizer packer aggregates
packets into ~1536 byte chunks, exceeding ETCP max payload of 1480 bytes.
This causes encrypt_send to fail. The test demonstrates correct API usage
pattern but requires packer fix for full functionality.
- Build in build/ directory instead of source tree
- Main binary (utun) copied to project root
- Tests run from build/tests/ with config files copied there
- Test output redirected to build/tests/logs/*.log files
- Console shows only [PASS]/[FAIL]/[SKIP] status
- Incremental build works correctly
- make check runs all tests with summary
Changes:
- New root Makefile as wrapper for out-of-tree build
- Updated Makefile.am files for lib, src, tests
- Added tinycrypt-objects target for test dependencies
- Tests no longer clutter project root
The pn_init() function now sets up etcp_int_recv as callback for pn->output.
Tests that manually poll pn->output need to reset this callback to NULL.
Changes:
- test_pkt_normalizer_etcp.c: Reset callback after pn_init() for client and server
- test_pkt_normalizer_standalone.c: Reset callback after pn_init()
This allows tests to manually poll output queue without conflicting
with the automatic callback mechanism.
Test Results: All 19 tests PASS
Restored queue_set_callback(etcp->output_queue, pn_unpacker_cb, pn)
which was incorrectly replaced in the previous commit.
The etcp_recv callback should be set up separately by the API user,
not by replacing the internal pkt_normalizer callback.
Test Results: All 19 tests PASS
Implemented:
- etcp_send(conn, entry) - отправляет пакет в очередь normalizer
- etcp_bind(id, callback) - подписка на пакеты с определенным ID
- etcp_unbind(id) - отписка от пакетов
- etcp_recv(queue, arg) - коллбэк для маршрутизации пакетов по ID
- etcp_api_init/deinit - инициализация API
Integration:
- pn_init() теперь устанавливает etcp_recv как callback для pn->output
- Добавлены etcp_api.c/h в src/Makefile.am
- Добавлен etcp_api.o в тестовые зависимости
API использует первый байт кодограммы (cmd) как ID для маршрутизации.
ID=0 используется как default handler если нет специфичного binding.
- Changed object file references from 'name.o' to 'utun-name.o' to match automake naming
- Added explicit rules for building TinyCrypt objects
- Added tinycrypt-objects target for building crypto dependencies
- Fixed test_etcp_simple_traffic.c: replaced etcp_send with etcp_int_send
- Fixed test_etcp_100_packets.c: replaced etcp_send with etcp_int_send
Test Results: All 19 tests PASS
- Fixed race condition: routing_add_conn called before etcp->normalizer was assigned
- Moved routing_add_conn from pn_init to etcp_connection_create after normalizer init
- Added routing.h include to etcp.c
- Fixed tests: disable routing callback on output_queue to keep packets for test verification
All 19 tests now pass.
- New struct tun_if with internal queue for incoming packets
- Single tun_init() does everything: create TUN, set MTU=1500, up, register in uasync
- tun_write() for outgoing packets
- tun_close() cleans up everything including queue
- Removed: tun_create, tun_set_ip, tun_set_up, tun_set_mtu, tun_read, tun_get_config
- Removed: utun_instance_register/unregister_sockets (now internal)
- Updated utun_instance to use new tun_if* pointer
- Updated test_etcp_two_instances for new API
- Add --with-openssl configure option (default: enabled)
- Update src/Makefile.am for conditional TinyCrypt compilation
- Update tests/Makefile.am for conditional test linking
- Add config.h include to secure_channel.c for USE_OPENSSL macro
- All 19 tests pass with both OpenSSL and TinyCrypt
- Moved static variables connection_checked and packet_sent_flag to file scope
to avoid issues with multiple test runs in the same process
- Added NULL check for uasync_set_timeout return value with error logging
- Added periodic check_packet_received calls in main loop (every 50ms)
to ensure packet detection even if timeout callback fails
This fixes intermittent test failures where packet was sent but not detected
due to race conditions in timeout handling.