Commit Graph
177 Commits
Author SHA1 Message Date
Evgeny 6717c863e7 etcp_router: Ed25519 digital signature for service messages
- Add ed25519_public_key[32] to NODEINFO struct for pubkey distribution
- Add ed25519_public_key[32] to ROUTE_BGP (derived from X25519 privkey at init)
- Add ROUTER_FLAG_SIGNED (0x08) to SVC_ROUTE_HDR flags byte
- router_send_one_flags: when is_signed, sign [hdr][payload] and append 64-byte sig
- etcp_router_recv_cb: verify Ed25519 signature when ROUTER_FLAG_SIGNED set
- New API: etcp_router_conn_send_signed()
- Drop signed packets if sender node not in routing table or no Ed25519 key
- 5 unit tests in test_etcp_router_unit.c covering OK/tampered/unknown/no-key/short
2026-06-22 15:53:24 +03:00
Evgeny 0dd942be63 fix: стабилизация тестов test_tcp_io и test_bbr_integration
- test_bbr_integration: bbr_max_cwnd=100KB (16×BDP) — устранён overshoot очереди
- test_tcp_io: адаптирован под EPOLLHUP на socketpair (send до poll, error_cb вместо fin)
- tcp_io: расширенная диагностика error_cb с состоянием сокета
2026-06-11 13:16:48 +03:00
Evgeny 3419ff3a85 debug: single source of truth for category names, GUI dynamic labels
- debug_get_category_name(): replace switch/case with table lookup in g_debug_categories[]
- etcpmon_gui: remove hardcoded cat_names[], create labels/radios dynamically from server CSV
2026-06-11 10:16:14 +03:00
Evgeny 6b2b0f1360 etcp: per-link acked bytes/packets counters + BBR debug logging
- Add acked_bytes/acked_packets to struct ETCP_LINK (init, reset, increment per ACK)
- Add DEBUG_CATEGORY_BBR (23) for BBR-specific debug output
- Add BBR input/output DEBUG_DEBUG around bbr_main call in etcp_ack_recv
- Add "bbr" category name to debug_config and etcpmon GUI
2026-06-11 09:55:30 +03:00
Evgeny 23732039de SOCKET сообщения жизненного цикла: INFO→DEBUG 2026-06-10 11:18:55 +03:00
Evgeny f883c8da75 Убрал безусловный DEBUG_ERROR в memory_pool_destroy 2026-06-10 11:15:02 +03:00
Evgeny 4211e32f51 tcp_io: единый обработчик ошибок tcp_conn_handle_error
- Вынесена общая логика обработки фатальных ошибок сокета
- Обработчик: close сокета, обнуление коллбэков, аварийный drain, вызов on_error
- Устранён use-after-free: пулы освобождаются до вызова on_error
- flush_write_buf возвращает int (0=ok, 1=error/tc destroyed)
- Все ошибки аллокации write_buf ведут к вызову on_error (ENOMEM)
- Обновлён header: документация в актуальное состояние
2026-06-10 10:38:22 +03:00
Evgeny 075c4f4583 memory_pool: name field — идентификация пула в диагностике коррапшна 2026-06-09 22:20:25 +03:00
Evgeny 9e133699bf log_dump: level+category, memory_pool: дамп user_data через log_dump при коррапшне 2026-06-09 22:20:06 +03:00
Evgeny 81cad40e3b memory_pool: усиленная канарейка 4B + хранение alloc_loc для диагностики 2026-06-09 22:19:47 +03:00
Evgeny 48a4f182aa ll_queue: inline→static inline queue_waiter_call — fix link error with -Og 2026-06-09 22:18:29 +03:00
Evgeny 5982b011b4 etcp: restore etcp_link_update_inflight_lim + state machine fixes + diagnostics
- etcp_link_update_inflight_lim: self-contained method with clamping,
  send_blocked_inflight check, loadbalancer_link_ready on cwnd increase
- etcp_conn_on_inflight_lim_changed: recalc optimal_inflight + resume input
- etcp_ack_recv: use etcp_link_update_inflight_lim instead of manual set
- etcp_request_pkt: fix line 928 check old link (inf_pkt->last_link) not new
- etcp_link_close: recalc optimal_inflight on link removal (both branches)
- etcp_socket_remove: fix dangling pointer loop (nullify after close)
- uasync_print_resources: show timer names, remain time, deleted entries
- diagnostics in utun_instance_destroy and test_etcp_reconnect
2026-06-09 16:40:37 +03:00
Evgeny 40c7a5b487 1 2026-06-05 22:34:49 +03:00
Evgeny 3217f744f9 memory_pool_is_freed + стратегические проверки на висячие указатели
memory_pool: memory_pool_is_freed(pool,obj) — поиск obj в free-списке

tw_pcbs (3 места): !ctx→halt и is_freed→halt в начале итерации
  — ловит висячий PCB до re-alloc и после re-alloc

etcp: is_freed→halt перед etcp_conn_input (caller + callee)
  — ловит pkt освобождённый до входа

tcp_alloc: убран старый скан tw_pcbs (заменён на is_freed)
все dangling проверки — halt (while(1)) вместо break/return
2026-06-05 20:45:42 +03:00
Evgeny 24a5de9398 memory_pool: канарейка (0xAA) + счётчик double-free; lwip_tcp: убраны TCP_TW_MAX/tw_iter, добавлен хук в tcp_alloc
memory_pool: +2 байта за объектом — canary 0xAA для детекции buffer overflow,
counter для детекции double-free. При free проверяется canary и counter==0,
при alloc выставляется новый counter.

lwip_tcp: убраны TCP_TW_MAX и счётчики tw_iter (толку нет, краш на 2й итерации).
Оставлены: !pcb->ctx (dangling pointer), self-loop checks, next_owner диагностика.
Добавлена проверка в tcp_alloc: если новый PCB найден в tw_pcbs → halt.
2026-06-05 20:01:28 +03:00
Evgeny 01dbd76834 1 2026-06-05 00:17:17 +03:00
Evgeny 57281a975e 1 2026-06-04 21:59:40 +03:00
Evgeny b953a6daf0 tcp_io: FIN/close через write_queue, отладка всех этапов закрытия
- tcp_io.h/c: push_fin/push_close через очередь отправки
  Кодирование: dgram=NULL→close, len=0+dgram!=NULL→FIN (sentinel)
  FIN: shutdown(SHUT_WR), стоп чтения, on_fin_sent
  CLOSE: close сокета, on_closed
  read_cb: отбрасывание входящих после fin_sent
  guard wq_fetch: error||closed (не fin)
- tcp_proxy_server: адаптация handle_fin→push_fin, handle_close→push_close
  read_queue_drain_cb: discard при fin_sent
  DEBUG_INFO на всех точках закрытия
- tcp_proxy_client: send_fin, handle_fin — DEBUG_INFO
- test_tcp_io: +6 тестов (push_fin, push_close, ordering, double-push, fin+close)
2026-06-04 19:20:20 +03:00
Evgeny 612b6bf1bf tcp_io: add DEBUG_TRACE for POLLOUT/busy-loop diagnostics 2026-06-04 16:37:07 +03:00
Evgeny 58e45e9232 proxy: implement CLOSE and FIN relay protocol
- CLOSE: admin connection teardown (drain queues, shutdown, free)
  Server: handle_close — pause read, drain rq (discard), drain wq to socket, shutdown, free
  Client: handle_close — drain to_lwip/tx_buf (discard), tcp_close pcb, free
  ERROR calls handle_close on both sides
- FIN: transparent relay event through ETCP (TCP_PROXY_SUBCMD_FIN=0x06)
  Server: on_fin_cb relays FIN_MSG to client, on_flushed_cb relays FIN_MSG
  Server: handle_fin relays FIN to remote socket via shutdown(SHUT_WR)
  Client: recv_cb relays FIN_MSG to exit, tx_waiter_cb relays FIN_MSG
  Client: handle_fin relays FIN to local TCP via tcp_shutdown(pcb,0,1)
- new tcp_conn_pause_read() in tcp_io (EPOLLIN off + cancel waiter)
- poll_cb simplified: remove tun_closed&&rem_closed wait block
- conn_free drains close_pending before free on both sides
- handle_data WARN→INFO for drops after close
- tcp_shutdown declared in lwip_tcp.h
2026-06-04 16:02:32 +03:00
Evgeny c56ec0b0ed uasync: добавить отладку poll→fd/rev, timer→имя при разрешении событий 2026-06-04 01:57:10 +03:00
Evgeny d784b2bfbe fix: use-after-free in tcp_conn_destroy + throttle consumer_ack
tcp_conn_destroy: set read/write queue callbacks to NULL before
queue_free to stop deferred autofetch (drain_cb on freed rc).

write_on_get_cb: throttle consumer_ack to every 8th write_queue
dequeue instead of every single one (was 30+ ACK/sec).

ack_batch field in tcp_proxy_server_conn.
2026-06-03 22:47:23 +03:00
Evgeny bbf39c091d feat: send_q backpressure + ll_queue on_get callback + consumer_ack flow control
etcp_router: ROUTER_MAX_SEND_Q_PACKETS=256, router_enqueue_send returns
error when send_q full, etcp_route_send propagates -1 on backpressure.

ll_queue: queue_set_on_get — deferred callback after each queue_data_get.
Replaces manual consumer_ack polling with queue-driven notification.

tcp_proxy_server: consumer_ack=1, write_on_get_cb triggers ACK on
each write_queue dequeue. Full backpressure chain:
  write_queue full → no dequeue → no ACK → sender stops → all queues pause
  write_queue drains → dequeue → on_get → ACK → sender resumes
2026-06-03 18:51:12 +03:00
Evgeny 04f6b3e040 refactor: remove tcp_conn_push_write, use direct queue put with chunking
External code pushes to write_queue directly (entry_pool + data_pool).
Added queue_set_threshold(write_queue, 32, 0) for write backpressure.
Tests split data into write_chunk_size chunks before queue put.
2026-06-03 16:38:09 +03:00
Evgeny 63f019530b feat: tcp_io library + uasync socket toggle + ll_queue empty_callback
lib/u_async: uasync_set_socket_read/write — O(1) EPOLL_CTL_MOD toggle per socket
lib/ll_queue: queue_set_empty_callback — one-shot deferred callback on queue drain
lib/tcp_io: TCP connection management via uasync + ll_queue with pool alloc
  - read: direct recv into pool buffer, high/low water flow control
  - write: autofetch via ll_queue callback, partial send via write_buf
  - on_fin/on_error/on_flushed callbacks, FIN deferred until read_queue drained
  - getpeername for pre-connected socket detection
tcp_proxy_server: migrated to tcp_io (22→13 fields, 437→270 lines, -7 functions)
tests: test_tcp_io (5 tests), test_tcp_proxy_server rewritten for tcp_conn
2026-06-03 16:24:46 +03:00
Evgeny ac3fe79db8 etcp_router: consumer-driven ACK with interval throttle (10ms)
- consumer_ack flag: ACK sent only on consumption, not assembly
- etcp_router_consumer_ack() — called from tcp_proxy_client feed_from_transport
- last_ack_sent_tb: interval-based throttle — send immediately if >=10ms passed,
  otherwise timer for remaining time
- timer rules: NULL handle after cancel/fire, NULL check before start
- ROUTER_ACK_INTERVAL_TB 1000→100 (100ms→10ms)
- test_etcp_router_unit: updated test 14 for new immediate-send behavior
2026-06-03 11:50:50 +03:00
Evgeny 2a259191b9 feat: queue_set_waiter_defer — immediate or call_soon callback mode
queue_waiter_handle stores defer_q/cb/arg, no extra malloc.
queue_set_waiter_defer(q, 1) enables call_soon dispatch for waiter callbacks.
bbr_integration uses it instead of manual send_waiter_cb wrapper.
2026-06-03 02:18:46 +03:00
Evgeny 331d43c6f7 fix: proxy ERROR loop, BBR test backpressure, O(1) u_free, test ordering
- tcp_proxy: ERROR silently dropped (no ERROR->ERROR loop), Russian removed from logs
- etcp_bbr: swap min(lo) and max(4*mss) in bbr_bound_cwnd_for_inflight_model
- test_etcp_bbr: fix cwnd comparison (packets vs bytes)
- ll_queue: double-put detection (abort), Floyd cycle detection in consistency check
- ll_queue: QUEUE_DEBUG commented out (was always-on, O(N) per put)
- mem: u_free_impl now O(1) via doubly-linked list, double-free detection
- bbr_integration: queue_waiter_wait + call_soon backpressure (threshold=1)
- tests/Makefile.am: fast tests first, *.log cleanup before run
2026-06-03 02:06:09 +03:00
Evgeny fceec1aea6 fix: move debug logs before async operations (queue_put, timer_set, resume) for meaningful log ordering 2026-06-02 21:53:51 +03:00
Evgeny 4556f327c2 1 2026-06-02 21:05:06 +03:00
Evgeny 1f4fe37fe5 proxy: rename + simplify + backpressure
- tcp_proxy/remote_proxy → tcp_proxy_client/tcp_proxy_server
- Все proxy файлы перенесены в src/proxy/
- Конфиг: [tcp_proxy]→[tcp_proxy_client], [remote_proxy]→[tcp_proxy_server]
- Убран subcmd CONNECTED (0x02) — клиент шлёт DATA сразу после CONNECT
- Backpressure: etcp_router_waiter_register/cancel через ll_queue threshold waiter
- Клиент: recv_cb send fail → tx_buf+waiter, не tcp_recved() (окно lwIP=0)
- Сервер: read_cb send fail → pause_buf+waiter, пауза read_id
- CLOSE/ERROR отправляется только после drain всех очередей
- Fail: conn не найден/closed → send ERROR вместо CLOSE/silent drop
- PROTOCOL.md: полная архитектура с диаграммами состояний и потоков
2026-06-02 18:02:37 +03:00
Evgeny ed6b4d1046 debug: выделить link keepalive в отдельную категорию KEEPALIVE (21), добавить DEBUG_DEBUG при приёме keepalive-пакета 2026-06-01 10:03:14 +03:00
Evgeny 4e6d57e371 clear freed memory in u_free_impl to catch UAF earlier 2026-05-30 20:03:33 +03:00
Evgeny 6521451493 disable BACKTRACE_ENABLED to fix lld linker error with backtrace symbols 2026-05-30 02:17:46 +03:00
Evgeny 7c71ef683c add lwIP TCP stack test with fixes: rcv_wnd tracking, FIN compensation, tmr_phase dual-counter, trace ring buffer, stats counters 2026-05-30 01:39:34 +03:00
Evgeny 8994d7a834 update timeout_heap and u_async: O(1) cancel, heap cancel bubble-up fix, epoll callback safety, uasync_stop, socket_array u_realloc 2026-05-29 01:11:37 +03:00
Evgeny 4d5afe5ae9 fix uasync: posted_tasks delivery on Linux, create cleanup leaks, atomic array expand 2026-05-14 03:32:23 +03:00
Evgeny 1a4b0a9de6 fix stale pointer after realloc in uasync socket/event handlers 2026-05-14 01:24:06 +03:00
Evgeny d0af315ff6 fix uasync set_timeout(0) ordering, dummynet shaper initial delay, add tests
- uasync_set_timeout(0): use FIFO immediate_queue instead of timeout_heap
  to guarantee execution AFTER all currently-expired heap timers
- uasync_cancel_timeout: search immediate_queue for timeout=0 timers
- dummynet: start initial shaper with bandwidth-based delay instead of 0
  (prevents queue from never filling up when packets arrive sequentially)
- test_dummynet: rename get_time_us -> now_us (conflict with u_async.h)
- test_u_async_comprehensive: fix immediate_timeouts, add timeout_ordering test
2026-05-12 13:42:16 +03:00
Evgeny a0e5446790 migrate NAT and DATA to etcp_router, fix warnings and destroy order 2026-05-10 14:00:49 +03:00
Evgeny c24a6367cc add IPv6 default route interface auto-detection for permanent/temporary IPv6 without netif
- get_default_route_netif_index(): UDP connect trick + getifaddrs to find default route iface
- etcp_socket_add(): auto-detect netif_index when not specified in config
- queue_new() API: explicit index_offset/index_size params instead of implicit from hash_size
- radix: cleanup types (uint8_t*), replace bzero/bcmp with memset/memcmp, remove kernel ifdefs
- route6_lib: new IPv6 routing library + get_node_v6_routes()
2026-05-10 00:05:23 +03:00
Charlie Root e1f051856f radix 2026-05-09 12:19:20 +03:00
Evgeny d0d4199273 etcp: unified send hook via etcp_udp_send, remove loss_rate, add dummynet_filter inline mode, rewrite BGP test
- Add etcp_udp_send_fn_t hook typedef, send_hook/send_hook_ctx fields to ETCP_LINK
- Implement etcp_udp_send() wrapper — all UDP sends go through one point
- Remove loss_rate from ETCP_SOCKET, CFG_SERVER, config parser, send path
- Add dummynet_filter: inline send-hook with loss/delay, no proxy socket needed
- Rewrite test_bgp_route_exchange: 3-node chain A(2 links)↔B↔C, 7 phases
  with dummynet_filter-based link failure/recovery simulation
- Clean up tests: remove skeleton test_routing_mesh, 6 debug/stale test files
- Refactor test_etcp_simple_traffic and test_pkt_normalizer_etcp (remove debug spam)
- Fix test_etcp_two_instances: remove private field access, fix false PASS on timeout
2026-04-27 12:43:52 +03:00
Evgeny 61fee27478 congestion: burst-based BW measurement + adaptive inflight (slow start/cong avoidance/loss response)
New features:
- get_time_us() in lib/u_async.c/h for µs-precision timing
- Burst measurement (ETCP_SECTION_MEAS_TS 0x07, MEAS_RESP 0x08, FILLER 0x09)
  - 12 MTU packets sent at line rate, receiver measures inter-packet gaps
  - Burst triggered when link saturated + min 500ms interval
  - Result: measured BW -> bandwidth for shaper, burst_target_bdp for window cap
- 3-phase adaptive inflight in link_stats_timer_cb:
  - Slow start: windows doubles each RTT, exits on loss/RTT spike/threshold
  - Congestion avoidance: additive increase, proportional RTT shrink, multiplicative loss shrink
  - Burst target cap: inflight_lim <= burst_target_bdp * 1.1
- Dynamic optimal_inflight = sum(link->inflight_lim_bytes), recalculated on change
- Adaptive win_timebase = rtt/2 (was hardcoded 10ms)

Fixes:
- dummynet.c: shaper formula fixed (80000 -> 80)
- dummynet.c: queue_data_put call fixed (3 args -> 2)
- etcp.c: SIZE ERROR format string (missing log_name argument)
- etcp_request_pkt: FILLER leaves room for PAYLOAD overhead

Tests:
- test_etcp_congestion.c: single-threaded, 5-phase BW/delay/loss test
  - sender + receiver + dummynet in one uasync
  - CSV metrics output every 100ms
- All 29 existing tests pass
2026-04-26 00:17:32 +03:00
Evgeny 39544e6b2b Fix: Add bounds/mtu checks, underflow protection and null deref fix for ETCP robustness 2026-04-25 12:38:05 +03:00
Evgeny 595d2b177b Refactor: Replace custom tc_hton*/tc_ntoh* with standard htobe16/be16toh/htobe32/be32toh, move htobe16/be16toh to platform_compat.h 2026-04-25 01:16:09 +03:00
Evgeny 69b49d424b Fix: Include platform_compat.h before winsock2.h in debug_config.h so tc_htonl/tc_htons macros are defined first 2026-04-25 01:02:50 +03:00
Evgeny 6284a95267 Fix: Define tc_htonl/tc_htons as macros before winsock2.h to avoid struct-in_addr redefinition 2026-04-25 00:59:50 +03:00
Evgeny aafa0cfcab Fix: Add portable tc_htonl/tc_htons/tc_ntohl/tc_ntohs macros, replace winsock2-incompatible hton*/nto* in NAT test files 2026-04-25 00:52:33 +03:00
Evgeny 907ef244c6 NAT: Full Cone (EIM) NAT with ETCP_ID_NAT protocol, per-node routing, and comprehensive test suite
- New ETCP protocol ETCP_ID_NAT (0x02) for NAT traffic between nodes
- eim_nat.c/h: Pure NAT engine (table, port allocation, checksum updates, egress/ingress)
- nat_transport.c/h: Transport layer (NAT TUN, ETCP binding, client/provider roles)
- route_bgp_find_conn_for_node(): shared utility for optimal connection lookup
- tun_init_nat(): dedicated TUN creation for NAT
- Config: [nat] section with tun_ip, port_start/end, nat_via, forward rules
- Fix: csum_update_ip/transport use htonl() halves (correct on LE systems)
- Fix: IP_FRAG_MF_MASK changed to 0x2000 (after ntohs, MF is bit 13)
- Tests: 26 engine unit + 4 transport integration + 7 stress (29 total)
2026-04-25 00:43:25 +03:00