You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

7.2 KiB

Задача: 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 (после дешифровки):
    } 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):
    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), воспроизвести флап реконнекта:
    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".