Select frontend network callbacks for auto_sockets=android instead of opening a denied netlink monitor. Preserve monitor descriptor ownership, keep native monitoring failures fatal, and release caller config on failed Android core creation and restart.
Register ConnectivityManager before requesting startup, report readiness after SERVICE_STARTED, and refresh addresses after initialization with serialized updates and generation checks. Add regression coverage for denied netlink, socket failures, address updates, and fd=0 preservation. Record the separate cancellation issue for startup before readiness.
Validation: full check.sh passed, including proxy/burst/load integrations. Clean Android build installed successfully on SM-A525F and Q8; logcat confirms both cores initialized and entered the poll loop with external monitoring and post-start address refresh.
Receive keepalive through the owning ETCP link, preserve RX deadlines, and report routing metrics without TUN. Use independent netlink requests and track installed routes for rollback. Reject incomplete resource initialization and release partially constructed cores while preserving caller config ownership.
Validated startup failure and rollback, padded keepalive, standby, STCP traffic, transport lifecycle, dynamic sockets, and daemon startup. Real TUN/netlink checks passed in an isolated Linux network namespace; modified modules passed FreeBSD compilation checks.
ip_is_public() вынесен в lib/platform_compat (единый классификатор IPv4 с ntohl).
auto_socket_reconcile_config: тип сокета выставляется по фактическому адресу.
sock_collect_views: has_priv/has_inet/is_eim — по классификации адреса и NAT-детекции.
is_local_subnet упрощён до !ip_is_public(). Тест test_sock_match обновлён.
- etcp_link_enter_ready_tcp: убраны прямые записи got_initial_pkt/initialized/
links_up/tx_state и fire UP/INIT; переход через etcp_conn_ready +
loadbalancer_link_ready (как в UDP INIT-обработчиках)
- tcp_server_on_link: убран дублирующий gop/session-блок (проверка в
etcp_link_enter_ready_tcp единообразно), sc_init_ctx перед
sc_set_peer_public_key (фикс ctx not initialized)
- stcp_link_connect(etcp_link, addr, port) вместо config-структуры;
stcp_conn.etcp_conn для live-чтения gop/session_id при handshake
- etcp_link_enter_init: new link on live conn sends NOINIT, not full reset
- etcp_link_enter_reinit: don't conn_reinit on single link recovery, preserve inflight
- handle_nl_link: fall through to remove_iface_sockets when if_indextoname fails
- duplicate INIT: add INFO log for diagnostic
Test: sequence checking (gaps=0 dups=0), exact socket/link counts, stale link
detection, conn health checks, full disconnect+reconnect phase
When ip link del removes an interface, the kernel sends RTM_DELLINK after the interface is unregistered from the name table.
if_indextoname fails and handle_nl_link silently returned without calling remove_iface_sockets,
causing old ETCP sockets to accumulate indefinitely.
Fix: fall through to remove_iface_sockets(ifindex) even when if_indextoname fails.
Test: added diagnostics (diag_dump_state, per-category debug levels to file) to verify socket/links cleanup.
- Добавлен 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
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
- 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
- auto_socket.c/h: создание/удаление UDP сокетов автоматически при изменении интерфейсов через netlink/route socket
При auto_sockets=yes пропускает ручные [server] сокеты
Тип сокета: PUBLIC если публичный IP, иначе NAT
Для новых сокетов добавляются линки ко всем активным NCD-соединениям
При удалении интерфейса линки убираются, сокет закрывается
Platform-agnostic API для использования из Android/chatgui
- node_conn_direct.h/c: ncd_add_socket_links / ncd_remove_socket_links — управление линками на конкретном сокете
- socket_monitor.h/c: экспорт socket_monitor_update_if_addr для auto_socket
- config_parser.h/c: опция auto_sockets в [global]
- init_sockets(): пропуск ручных сокетов при auto_sockets=yes
- utun_instance: интеграция auto_socket_init/destroy
- media_delivery: fix stack-buffer-overflow ack[3] → ack[9]
- topo_node: fix heap-use-after-free в topo_group_update_my_nodeinfo — сохранение node_id/ver перед registry_store, использование return value