Полностью убрана фича периодического обмена CSV-метриками с Ed25519-подписью:
- ETCP_SECTION_METRICS и парсинг/верификация секции
- struct etcp_metrics, etcp_metrics_add_*/start/stop и снапшот-таймер
- мёртвый API on_metrics_rcvd/metrics_user_ptr (никто не подписан)
- link->remote_ed25519_pubkey (заполнялся только на клиенте → верификация на сервере всегда падала)
- stats_dir в UTUN_INSTANCE
Общий sc_stream_sign_* (деривация Ed25519 из X25519) и INIT-передача обоих ключей сохранены.
Добавлен 64-битный reset_id (эпоха ресета) в INIT-фреймы и STCP-handshake:
- генерится один раз при создании conn, меняется только при фатальном ресете
(normalizer desync / bad fragment size);
- при приёме чужого id slave принимает эпоху пира и ресетится, master держит свою;
- первый id принимается без ресета (свежие при init);
- «tcp peer clean» реинит гейтится по смене id — нет повторного сброса seq.
Это устраняет коллизию seq=1 (RX dup) из-за двойного реинита нескольких TCP-линков,
из-за которой NODEINFO пира терялся и member не возвращался online.
Также: chat member online теперь из topo_group (без БД/merkle), тест test_etcp_seq_collision.
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll
- stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close
- utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP),
add deferred drain in both Phase J and L
- stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39,
exchange ed25519_pubkey in both handshake directions
- etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in
etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb
- chat_sync.c: fix lk->conn NULL dereference for TCP links
- test_stcp.c: update stcp_server_create/stcp_client_connect callsites
- tools/chat_tcp_test: change transport udp→tcp
1. etcp_on_down: add down_link param — log the specific lost link + remaining
Connection DOWN — link 192.168.40.247:2122 lost, remaining: [::1]:6669, [::2]:9970
Connection DOWN — closing, links: ... (for reinit/close)
2. etcp_on_link_down: pass the triggering link through to etcp_on_down
3. etcp_update_log_name: always check registry for node_name
(n_5a1b... → SM-A525F when name is available in registry)
- member_sync apply_items: empty payload is normal sync completion, not error
- topo_node_sqlite node_load: no addresses is normal for stub/seed nodes
- conn_mgr_core: node skipped when not in routing (normal for nodes w/o addrs)
- topo_group send_nodeinfo: downgrade ERROR→WARN in DEBUG category
- db_sync INIT_RESP: protocol details belong in DEBUG, not INFO
ready_cbks/etcp_conn_set_ready_cbk/add_ready/remove_ready → init_cbks/..._init_cbk
ca_ready_cb → ca_init_cb
cm_direct_ready_cb → cm_direct_init_cb
cm_reverse_ready_cb → cm_reverse_init_cb
ntp_node_on_conn_ready → ntp_node_on_conn_init
connect_ready_cb → connect_init_cb
init accurately describes when conn->initialized=1, before keepalives establish UP.
Also fire etcp_fire_conn_status INIT at this point instead of create time.
Added callbacks_running flag to ETCP_CONN:
- set to 1 before up_cbks / down_cbks / ready_cbks iteration
- reset to 0 after iteration completes
- etcp_connection_close checks flag and does intentional SIGSEGV
with FATAL log message if called during callback chain
This catches illegal synchronous close from within callbacks
instead of producing cryptic UAF segfaults later.
Problem: when two peers connect simultaneously, each incoming
INIT_REQUEST(0x02) or INIT_RESPONSE(0x03) triggers etcp_conn_reinit
unconditionally, causing endless UP/DOWN flapping loop.
Fix: add reset_done flag to ETCP_CONN:
- 0 at creation and after explicit reinit (reinit allowed)
- set to 1 in etcp_conn_ready (connection stable, block reinit)
Three call sites guarded with !conn->reset_done:
- client: handle_init_response_client (INIT_RESPONSE 0x03)
- server: existing link INIT_REQUEST processing
- server: new link INIT_REQUEST processing
send_reset logic preserved unconditionally — only etcp_conn_reinit
itself is blocked when already stable.
- TRANSIT_QUEUE: отдельная очередь на каждую пару src+dst узлов
- ll_queue с хеш-индексом для быстрого поиска transit-очередей
- backpressure через waiter на send_input_q (threshold=0, один пакет за вызов, round-robin)
- Очередь создаётся при первом пакете который не получается отправить напрямую, удаляется при опустошении
- Унифицирован etcp_send: единый путь queue_data_put(send_input_q) для UDP (normalizer->input) и STCP (tx_queue)
- Убран STCP-ветвления из router_forward_transit/drain_cb
- Исправлено перекрытие ll.data и tq->q в TRANSIT_QUEUE (добавлены явные поля src_node_id/dst_node_id)
- Фикс лика dgram в tx_queue_cb/client_tx_queue_cb (добавлен queue_dgram_free)
- transit_queues живут внутри ETCP_CONN, инициализируются лениво, очищаются в etcp_connection_close (до pn_deinit) и stcp_link_close
- 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
- Added 32-bit session_id to ETCP_CONN struct (random per client)
- Session_id transmitted in INIT_REQUEST/RESPONSE after node_id
- Server: skip reinit if session_id matches existing connection
- Server: send INIT_RESPONSE (0x03) only when reinit actually done
- Server: send INIT_RESPONSE_NOINIT (0x05) for same session
- Client: ignore INIT_RESPONSE with wrong session_id
- Fixed tx_state initialization in etcp_conn_ready for noinit case
- All 26 tests passing
- Add rx_dup_count (local) and tx_dup_count (remote via ACK) to ETCP_CONN
- Extend ACK section format: add 16-bit rx_dup_count after last_delivered_id
- Reconstruct 32-bit tx_dup_count from received 16-bit diff
- Update etcpmon protocol and control_server to expose counters
- Update packet dumper for new ACK format