db_sync/merkle_sync/chat_sync шлют group_id (uint64 BE) вместо текстового
channel_id/namespace. Приёмная сторона находит группу/таблицу через
topo_groups_find(group_id) и требует существующую CHAT-группу. db_sync:
instance key заменён с SHA256(ch_id) на strtoull(ch_id)=group_id.
media_download/медиа-ответы и суперузловая репликация теперь берут группу
из контекста (dl->group_id, group_id из пакета, peer->group_id) вместо
хардкода TOPO_GROUP_UTUN. node_props_changed получает channel_id.
SUPER_HELLO несёт group_id.
При асимметричной топологии topo_group_find_conn_for_node возвращает NULL,
ACK не уходит → ретрансмит-шторм → no-ACK close → inflight сбрасывается в 0.
Теперь ACK уходит через тот же коннект, с которого пришли данные (recv_conn),
с фолбэком на топологию. Довершает фикс из e08956e (deliver), который
аналогично не трогал router_send_ack.
Заодно удалён неиспользуемый ETCP_ID_ROUTE_ENTRY.
router_handle_data_packet выбрасывал физический conn, а router_incoming_q_cb
восстанавливал его через topo_group_find_conn_for_node, который возвращает NULL,
когда у узла-источника нет пути в топологии. В итоге callback сервиса (routing,
conn_mgr) получал conn=0x0. Теперь физический conn сохраняется в rconn->recv_conn
и прокидывается в deliver.
topo_node_update_my_addresses теперь собирает адреса во временные списки,
сравнивает со старыми и при отсутствии изменений выходит без бампа ver,
записи в БД и broadcast. Гейт member_exists убран: self-адреса пишутся
в node_addresses при любом запуске/изменении (с гарантией строки nodes для FK).
addrs_put логирует ошибки INSERT.
standby.h/c: duty-cycle ACTIVE/SLEEP, standby_wait() будит в burst сразу,
в SLEEP — до следующего burst; notify_network_activity для раннего пробуждения.
Интеграция (по флагу UTUN_HAVE_STANDBY, десктоп без изменений):
- conn_mgr: bg_ping/candidate_ping в SLEEP defer через standby_wait
- route_connectivity: probe_node откладывается (PROBE_STATUS_DEFERRED)
- topo_group_connect: пауза между попытками — активный режим 1с, фон standby_wait
- jni_bridge/ConfigProvider/NetworkActivityMonitor: set_active + сетевая активность
- chat_setting: standby_active_sec/sleep_sec/min_sleep_sec
+ юнит-тест test_standby (31 проверок)
- 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_keepalive.c/h: keepalive-пакеты, таймер, адаптивный период,
согласование при handshake вынесены из etcp_connections.c как есть
- протокол KEEPALIVE_REQ/RESP (0x09/0x0A): мобильный узел при смене active mode
шлёт желаемый режим; отвечающий считает max (standby при любом standby), не-мобильный
применяет как есть; инициатор применяет согласованный режим после RESP
- режимы: NORMAL (3с, адаптивный рост), STANDBY (30с, ka_pinned=1 без роста)
- active mode как событие: utun_add/remove_activity_cbk; подписчики topo_group
(nodeinfo) и etcp_keepalive (рассылка REQ всем линкам)
- dedup double ETCP_CONN_STATUS_UP (UDP+TCP links) in topo_group_new_conn
- close conn_mgr handle on TIMEOUT in Phase2/3 (fix stuck 'already connecting')
- infinite Phase1→2→3 cycle with pause (1s active / 30s standby)
- CHAT_EVT_CONNECTING_NODES: yellow circle in member list while connecting
- Android: client_activity wiring via onStart/onStop + nativeSetActive
- function-level comments in topo_group_connect.c
- client_activity: desktop/server now ACTIVE by default, only mobile starts STANDBY
- topo_group_connect: endless Phase1→2→3→1 cycle until connected
- Pause between failed Phase2/3 attempts: 1s active, 30s standby
- on_down always triggers cycle_restart when active_conn_count=0
- re-init destroys previous state and starts fresh
- CHAT_EVT_CONNECTING_NODES event notifies GUI of current connecting nodes
- Android: ConfigProvider default mode='auto', PTT fix, UDP log timer fix
- 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