- Extend MEMBER_DETAIL_LINK_SIZE to 63B with 20B sock_name per link
- Replace link_count with links_up/links_down (two uint16) in sock snap
- Add BGP hop list collection via topo_node_best_hop_list, post as CHAT_EVT_BGP_INFO
- Add direct RTT summary text via same event
- Rework AccountList detail panel: header + QTextEdit with monospace layout
- Display protocol (TCP/UDP), socket name line, colored dots for connections
- Show [up/down] link counts for self listen sockets
- Remove * prefix from link count display in Android
When etcp_link_close() frees a link while INFLIGHT_PACKET entries
still reference it via last_link, a later ACK causes SIGSEGV in
bbr_main(link->bbr=NULL).
Fix:
- etcp_inflight_nullify_link(): nullifies last_link in both
input_wait_ack and input_send_q for entries pointing to dead_link
- Called from etcp_link_close() before u_free(link)
- Guard etcp_ack_recv: check acked_pkt->last_link->bbr before
accessing BBR/inflight stats
- Also fix bbr leak in etcp_link_close !link->conn path
Verified: 30/30 runs of test_etcp_link_stress pass (was ~50% crash)
Full suite: 71/71 pass
utun_instance_init() did not call instance_init_common(), leaving
instance->client_type and instance->keepalive_interval as 0.
This broke the INIT handshake in V4 protocol: server wrote
keepalive=0 into INIT_RESPONSE, causing negotiate_keepalive
to see 0 and client to receive empty keepalive.
Also added guard: keepalive < 100ms clamped to 100ms with ERROR log.
bb0866b changed close/restart notifications from NULL to loopback_conn().
Remove !conn check — use entry->len==9 alone to distinguish (9 bytes = svc_id+node_id, data always longer).
- Добавлен device_type (1 байт, CLIENT_TYPE_*) в INIT_REQUEST и INIT_RESPONSE
- Добавлен keepalive_interval (2 байта) в INIT_RESPONSE
- STCP handshake расширен с 43 до 46 байт (device_type+keepalive)
- negotiate_keepalive(): оба desktop/server → min, иначе (есть mobile) → max
- keepalive_interval вынесен в UTUN_INSTANCE для использования в handshake
- stcp_client_connect() принимает device_type и keepalive_interval
- peer_device_type/peer_keepalive_interval передаются через stcp_link в ETCP_LINK
10 spammers (1-30ms random) + 2 observers (1-10ms), star topology via hub.
5s of concurrent modifications, then verify all 13 merkle root hashes
are identical and tree is internally consistent (recompute vs stored).
- _recompute_bucket: skip INSERT OR REPLACE when hash unchanged,
also skip DELETE when row doesn't exist (was always writing)
- bg_check interval: 100ms → 5000ms (was writing 10x/sec × 4KB/page
into WAL = ~1.4GB over hours)
- bg_timer: round-robin across channels instead of only first
- bg_timer: periodic WAL checkpoint (every ~60s) to prevent
unbounded WAL growth from any source
- test: sync ms_session struct copy with real definition
- stcp_link: handle race where conn already CLOSED before close
- stcp_client: remove double-free c->free_on_close = cli
- etcp_connections: stcp_link_close on TCP link down
- u_async: round sub-ms timeouts to 1ms to avoid busy-loop
- ntp_node_time.c: respond to TIME_SYNC only when peer is unsynced (not always)
Prevents infinite 10-byte ping-pong that ate bandwidth when both sides synced.
- pkt_normalizer.c: add in_total_pkts/in_total_bytes increments in
etcp_input_ready_cb (real send path), matching pn_packer_send (test path).
- conn_mgr_core.c/conn_mgr_priv.h: full INVITE_INFO_RESP with channel info
auto_socket.c: create_iface_tcp_socket returns stcp_server* instead of int,
ifa->v4_tcp/ifa->v6_tcp now properly track the created server, preventing
duplicate bind/listen on every reconcile_iface call.
etcp_connections.c: tcp_socket_add now resolves interface_addr via
get_interface_ip_by_index/get_interface_ipv6_addr_nl for any type (not just
PUBLIC), preventing NAT TCP v4 sockets from being destroyed due to INADDR_ANY.
auto_socket.c: remove tsrv from inst->stcp_servers before stcp_link_server_destroy
when TCP socket has null addr — freed pointer stayed in linked list corrupting it
on next stcp_server_listen->stcp_server_list_add, causing hang
utun_instance.c: apply debug_level + per-category debug from config in
utun_instance_create_from_config (was only in utun_instance_create)
chat_core.c: verbose error log on invalid args
1a: tcp_server_on_link — close existing TCP links before creating new ETCP_LINK
1b: etcp_tcp_send — skip send if stcp_link not ready
3a+3b+3c: stcp_conn_set_on_close → stcp_link_on_stcp_close → marks link DOWN → triggers reconnect
- 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