# Задача: BGP NODEINFO теряется при флапающем реконнекте (chatgui member online не возвращается) ## Кратко После рестарта Android-пира и реконнекта локальный chatgui показывает мембера **offline** и не возвращает **online**. Корневая причина — **не в chat/member коде**, а в ETCP: BGP-пакет NODEINFO (347 байт) расшифровывается, но **не доходит до BGP-обработчика** `topo_group_receive_cbk()`. Нужно: **точно локализовать точку потери NODEINFO в receive-пути ETCP и починить её.** ## Что уже сделано (исправлено и работает) 1. `tools/chatgui/src/mainwindow.cpp` — **исправлен** `onMemberUpdatedCallback`/`onMemberRemovedCallback`: проверка `len < 1+64+1+79` отбрасывала все события с channel_id короче 64 симв. Теперь `len < 1` + точная проверка. (Это была причина «не обновляется вообще».) 2. `src/chat/chat_member.c/h` — добавлен `chat_core_member_online(ch_id,node_id)` = присутствие в `topo_group` (`topo_node_find_by_id`). Используется в `chat_core_get_member_list`/`get_single_member`. Убран `nodes.online` из SQL и блок `connected→2`. 3. `src/chat/chat_core.c`, `src/chat/chat_sync.c`, `src/chat/member_sync.c/h` — удалён онлайн-статус из БД + merkle-online gossip (`member_sync_set_online`, `_ms_apply_update`, `push_update`). 4. `src/chat/chat_status.c` + `tools/chatgui/src/accountlist.cpp` — флаг «bgp present» (0x08) для detail-панели. 5. `tools/chatgui/src/nodespage.cpp` — убрана колонка Online из диагностики. Эти правки корректны; статус работает на чистом connect/disconnect/стабильном реконнекте. ## Найденная причина (подтверждено логами) - Android **шлёт** свой NODEINFO: `send_nodeinfo: node 1657b3ea8281c0a8 ver=2` (bgp-debug на Android). - Локально пакет **расшифровывается**: `decrypt: code=01 dlen=347 plen=350` (347-байтный BGP-пакет, `code=0x01` = `ETCP_ID_TOPO_ENTRY`). - Но `BGP recv NODEINFO nid=1657` (строка 193 в `topo_group.c`) **не появляется** — до обработчика пакет не доходит. - При этом маленький `TABLE_COMPLETE` (10 байт) **доходит** (виден в логе как «mislabeled» `nid=aaaaaaaaaadeadbe` — это строка 193 логирует не-NODEINFO пакет как NODEINFO, garbage-поля). - Признак: в стабильных рестартах (18:18/18:20) узел **добавляется** каждый раз, в флапающем (18:07) — нет. Т.е. потеря привязана к флапу (TCP-линки + ETCP reinit). ## Receive-путь ETCP (где искать потерю) ``` decrypt (etcp_connections.c:2262, лог "decrypt: code=.. dlen=..") → if (link_state==CONNECTED) etcp_conn_input(pkt) else memory_pool_free(pkt) ← добавлен WARN "decrypted pkt DROPPED" → etcp_conn_input (etcp.c:1506, "RX pkt dlen=%d") → нормализатор (reassembly) → int_queue → etcp_int_recv (etcp_api.c) ← добавлен WARN "int_recv BGP id=0x01 len=.." → dispatch по route id (0x01) → topo_group_receive_cbk (topo_group.c:193 "BGP recv NODEINFO") ``` ## Уже добавленный дебаг (для локализации) 1. `src/transport_layer/etcp_connections.c` (после дешифровки): ```c } else { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] decrypted pkt DROPPED: link_state=%d code=0x%02x dlen=%u", link->etcp->log_name, link->link_state, pkt_code, pkt->data_len); memory_pool_free(e_sock->instance->pkt_pool, pkt); } ``` 2. `src/transport_layer/etcp_api.c` (`etcp_int_recv`, после чтения `id`): ```c uint8_t id = e->dgram[0]; if (id == 0x01) DEBUG_WARN(DEBUG_CATEGORY_ETCP, "int_recv BGP id=0x01 conn=%s len=%zu", conn->log_name, e->len); ``` 3. Android: `tools/chatgui-android/libutun_lite/instance_lite.c` добавлено `debug_set_category_level(DEBUG_CATEGORY_BGP, DEBUG_LEVEL_DEBUG);` (пересобрать APK: `cd tools/chatgui-android && ./build.sh`). 4. chatgui конфиг `tools/chatgui/build/vibechat.cfg` — включены `bgp=debug`, `chat_sync=debug`, `member_sync=debug`, `debug=debug`. Как читать (по таймстампу флапа): - есть `decrypt code=01 dlen=..` + `DROPPED` → потеря в проверке `link_state==CONNECTED`; - есть `decrypt` + нет `DROPPED` + нет `int_recv BGP` → потеря в `etcp_conn_input`/нормализаторе; - есть `int_recv BGP` + нет `BGP recv NODEINFO` → потеря в BGP-обработчике. ## Задача для агента 1. Пересобрать chatgui (`cd tools/chatgui && cmake --build build -j4`) и Android APK (`cd tools/chatgui-android && ./build.sh`). 2. Запустить chatgui (DISPLAY=:0, `./vibechat`), воспроизвести флап реконнекта: ```bash adb shell am force-stop com.utun.chat && adb shell am start -n com.utun.chat/.MainActivity ``` (повторить несколько раз; флап ловится не каждый раз). 3. В логах (`tools/chatgui/build/chatgui.log`) найти потерю NODEINFO и **точно определить точку** по таблице выше. 4. Починить первопричину (варианты): - буферизовать расшифрованный пакет до `LINK_STATE_CONNECTED` вместо `memory_pool_free`; - либо гарантированный BGP-retry (после conn UP, если узел пира не в `group->nodes` через N мс — повторно `topo_group_send_table_request`). 5. Убрать весь диагностический мусор: - WARN "DROPPED" (etcp_connections.c), WARN "int_recv BGP" (etcp_api.c); - DEBUG-логи в `chat_member.c` (`on_member_props_changed`), `chat_sync.c` (`cs_on_peer_status_changed`), `memberlistmodel.cpp`; - `instance_lite.c` BGP-debug; - `vibechat.cfg` — вернуть категории в закомментированное состояние. 6. Прогнать: connect→online, disconnect→offline, реконнект (флап)→online. `./check.sh` (или `cd src && make -j4`). ## Воспроизведение / ключевые артефакты - Пир: Android SM-A525F (`com.utun.chat`), node_id `0x1657b3ea8281c0a8`. - Локальный: chatgui (`tools/chatgui/build/vibechat`), node_id `0x24cd036a6e659b9a`. - Канал: `ch_id=7206723622466219923`, `group_id=0x64036cf3a783ef93`. - Лог chatgui: `tools/chatgui/build/chatgui.log` (debug_file из конфига). - Лог Android: `adb logcat -d | grep -iE "send_nodeinfo|NOT in registry|NODEINFO|DROPPED|int_recv"`.