Commit Graph
143 Commits
Author SHA1 Message Date
evgeny 73fe99b33f dm: прямой обмен сообщениями (DM) + soundtouch + архитектура звонков
- src/dm/: dm_core/dm_crypto/dm_mailbox — прямой обмен сообщениями (DM)
- lib/soundtouch-master/: vendored SoundTouch (изменение темпа/высоты аудио)
- doc/dm_arch.md, doc/chat_call_arch.md: архитектура DM и звонков
- tests: test_dm.c, test_dm_e2e.c
- chat: рефакторинг chat_* модулей, member_sync, invite_build
- chatgui/chatgui-android: синхронизация с новым API чата
- lib/u_async, debug_config, utun_instance: сопутствующие изменения
2026-09-15 21:09:17 +03:00
evgeny 481872d5db chat: invite-ссылки с несколькими адресами + ncd-адреса узлов (join) 2026-09-15 05:16:04 +03:00
evgeny 75e39d2fee chat_join: модуль join-протокола, invite-ссылки v2, синхронизация мемберов 2026-09-14 19:57:27 +03:00
evgeny 9ee61dce6c fix: ncd handle UAF in topo_recovery and topo_group_invite callbacks
topo_recovery_callback: detach cb on UP handoff and close handle on
DOWN/TIMEOUT so no handle with cb_arg==ctx outlives ctx (ASAN
heap-buffer-overflow in topo_recovery_callback).

tgi_to_channel_cb: force_close handle on NCD_EVENT_TIMEOUT so a late UP
cannot fire into the freed tgi_conn_ctx.

Also: android chatgui reverseLayout scroll + msg order/stable pagination.
2026-09-14 15:10:04 +03:00
evgeny fc3295ce12 nat_detection: гасить NAT-чек при закрытии линка через link-status коллбэк (UAF na->link) 2026-09-14 14:37:34 +03:00
evgeny d78d652bf5 shutdown: закрывать shared sqlite (topo_sqlite_db) в самом конце utun_instance_destroy (UAF при teardown) 2026-09-14 11:47:45 +03:00
evgeny f2f4a37344 routing: fix use-after-free в route_ping_cancel_for_conn (чтение request_id после u_free) + формат %08x 2026-09-14 11:29:31 +03:00
evgeny 7c8d65db78 chat: локальное удаление канала (Android) + db_sync инстансы в куче 2026-09-13 22:08:33 +03:00
evgeny ddfffad1ed conn: сопоставление сокетов по ролям (direct/nat/local) + hairpin; NTP-детект оффлайна
- sock_match: единая классификация сокетов (DIRECT/NAT/LOCAL) и адресов (PUB/PRIV/UNREACH)
- eim приравнен к direct; на приватный адрес — только с приватного интерфейса;
  оба EIM за одним NAT (одинаковый публичный IP) — только через LAN
- topo_node: LOCAL-сокеты рекламируются (INTERFACE), private скрыт,
  NAT-адрес не рекламируется для strict и при оффлайне
- ntp: флаг reachable по циклам + пере-анонс nodeinfo при смене доступности
- cm_direct_add_links / ncd_create_links / conn_match_candidate_sockets на sock_match
- test_sock_match: unit-тесты классификации и сопоставления
2026-09-13 16:48:00 +03:00
evgeny 7bba39ddcb nodeinfo: 2 адреса на сокет (до/после NAT) + типы адресов local/public/nat/nat_eim/nat_strict
- topo_node: сокет рекламирует INTERFACE (до NAT) + NAT (после NAT, EIM);
  strict/direct отдельным адресом не передаются
- topo_node_sqlite: addr_type_classify различает NAT_VERIFIED_*; добавлен
  ADDR_TYPE_NAT (тип неизвестен), fallback больше не даёт DIRECT по IP
- chat_member: бейдж NAT-типа по приоритету (public>nat_eim>nat>nat_strict>local)
  вместо MIN(addr_type)
- GUI (desktop+android): адреса мембера с socket_id и ролью (local/public/nat/nat_eim/nat_strict)
2026-09-13 01:05:25 +03:00
evgeny 5ee6bf53d8 conn_mgr: ping активных кандидатов с noop-колбэком вместо NULL (bad args) 2026-09-12 21:07:24 +03:00
evgeny c6118280bd conn_mgr: не удалять как stale кандидатов с активным соединением 2026-09-12 20:00:48 +03:00
evgeny 265008961a conn_mgr: кандидаты-посредники из topo_node-списка (активные соединения); гейт md_super_connect по is_supernode; откат ping→best_candidates 2026-09-12 19:38:48 +03:00
evgeny 2045d4a169 media: восстановить conn_mgr_open (DIR/REV/IND) + популяция best_candidates из RTT + watchdog не трогает CONN-блоки 2026-09-12 18:47:01 +03:00
evgeny 42a94aa916 BGP: фикс владения адресами в реестре (мульти-группа), проброс group_id в сервис (conn_mgr per-group), membership-фильтр create_group; тест media через chat-группу 2026-09-12 02:13:34 +03:00
evgeny 6c9a47b201 media_delivery: диагностика маршрутизации md_send/md_dl_send/router_deliver (conn, subcmd, no-route) + тест test_media_delivery_chat 2026-09-11 23:48:31 +03:00
evgeny d7bb58c6fb chat: автоподключение к узлам группы (вкл/выкл) + ручной connect к узлу (desktop+android); фикс reinit при QR-join 2026-09-11 19:46:02 +03:00
evgeny be1f08b43e etcp: защита от UAF в start_keepalive_timer/enter_ready_tcp + диагностика указателей
- start_keepalive_timer: guard !link->etcp->instance->ua (SIGSEGV на 80 строке)
- etcp_link_enter_ready_tcp: return при etcp->state==2 после reinit/apply_reset/conn_ready
- tcp_server_on_link/enter_ready_tcp: DEBUG_CATEGORY_DEBUG с адресами link/etcp/inst/ua
- topo_node: убрать лишние DEBUG_CATEGORY_DEBUG (chain_rtt)
2026-09-11 17:13:35 +03:00
evgeny 7de636be6e topo: убрать ALTER-миграции, backfill deleted из adm_tags 2026-09-11 16:48:15 +03:00
evgeny b7da6547c1 connection: логировать только connect/reconnect/disconnect; фиксы конфига чатгуи
- категория connection теперь только жизненный цикл соединения; INIT/PING/keepalive
  переклассифицированы в ETCP/SOCKET/KEEPALIVE/REALITY/ROUTING, удалены дубли
- settingsdialog: устранён дубль my_node_name в конфиге (двухпроходная запись + только при изменении)
- storagesettingspage: канонические ключи storage_total_size/storage_unit_size с суффиксом M/G
- audiodevicesettingspage: compressor_max_gain_db min 0→1
- etcp_connections: %s-баг в логе TCP link (addr → sockaddr_storage_to_str)
- docs/sample: [chatserver], актуализированы ключи хранилища
2026-09-11 15:24:56 +03:00
evgeny ee8b2a4a45 chat: deleted-флаг выводить из adm_tags — member_block_put вместо деструктивного member_put, удалить member_put, фильтр deleted=0 в списках 2026-09-10 17:20:18 +03:00
evgeny d886a2ff84 Диагностика коллизии линков + детектор дубликата node_id + reality-конфиг autogen 2026-09-10 14:40:45 +03:00
evgeny 898a0a4a66 reality: реклама reality-параметров сокетов через BGP и применение к исходящим TCP-линкам 2026-09-10 11:24:17 +03:00
evgeny 22da6bd832 chatgui: открывать SQLite-БД до auto_socket_init (переиспользование портов) 2026-09-09 21:29:27 +03:00
evgeny e3168d1e55 Удалить обмен метриками ETCP (ETCP_SECTION_METRICS)
Полностью убрана фича периодического обмена CSV-метриками с Ed25519-подписью:
- ETCP_SECTION_METRICS и парсинг/верификация секции
- struct etcp_metrics, etcp_metrics_add_*/start/stop и снапшот-таймер
- мёртвый API on_metrics_rcvd/metrics_user_ptr (никто не подписан)
- link->remote_ed25519_pubkey (заполнялся только на клиенте → верификация на сервере всегда падала)
- stats_dir в UTUN_INSTANCE
Общий sc_stream_sign_* (деривация Ed25519 из X25519) и INIT-передача обоих ключей сохранены.
2026-09-09 19:59:29 +03:00
evgeny aa166a2030 topo_group: RESYNC — пассивная сторона перезапускает BGP-обмен после флэпа
Сервер (пассивная сторона) на UP шлёт общий RESYNC, клиент по нему
заново анонсирует группы (JOIN_GROUP), которые ему положены по конфигу.
Чинит потерю маршрутов при одностороннем флэпе, когда клиент не замечает
разрыв и не перешлёт JOIN_GROUP повторно.
2026-09-08 16:39:55 +03:00
evgeny a17a85a383 chat: deleted-аккаунты — колонка deleted, скрытие/зачёркивание, не подключаемся 2026-09-07 01:40:53 +03:00
evgeny 631a176944 chat: права админа + member tags (verified/deleted) + ncd revive
- chat_admin: передача канальных privkey другому узлу (encrypted+signed,
  ETCP_RT_ID_ADMIN_KEY), событие ADMIN_KEY_RECEIVED
- member_sync/bridge: tags verified/deleted, is_channel_owner, transfer_admin
  (android JNI + chatgui memberpropsdialog)
- node_conn_direct: оживление timed_out entry — обновление линков в существующем
  conn (убрать старые, добавить новые) + немедленная очистка не поднявшегося
  conn без fin_wait — фикс invite/reconnect
2026-09-07 00:53:41 +03:00
evgeny 6163f34ce1 etcp_router: эпоха reset_id на wire + master/slave — фикс потери пакетов при рестарте пира 2026-09-06 22:20:08 +03:00
evgeny 61c572cae4 etcp: reset_id эпоха ресета — фикс потери NODEINFO при флапе
Добавлен 64-битный reset_id (эпоха ресета) в INIT-фреймы и STCP-handshake:
- генерится один раз при создании conn, меняется только при фатальном ресете
  (normalizer desync / bad fragment size);
- при приёме чужого id slave принимает эпоху пира и ресетится, master держит свою;
- первый id принимается без ресета (свежие при init);
- «tcp peer clean» реинит гейтится по смене id — нет повторного сброса seq.

Это устраняет коллизию seq=1 (RX dup) из-за двойного реинита нескольких TCP-линков,
из-за которой NODEINFO пира терялся и member не возвращался online.

Также: chat member online теперь из topo_group (без БД/merkle), тест test_etcp_seq_collision.
2026-09-06 21:50:06 +03:00
evgeny f7c08f8f5e nat_detection: применять NAT-тип через topo_node_update_my_addresses с переподписью 2026-09-06 01:29:07 +03:00
evgeny 53bce51201 etcp_router: корректный handshake/restart без таймаут-петли
- START на первом пакете сеанса (seq=0), гейт отправки до первого ACK
- дедуп рестарта по payload init-пакета (ретрансмит START не триггерит рестарт)
- RST переинициализирует только отправку (без CLOSE_ALL), дедуп повторных RST
2026-09-06 00:33:45 +03:00
evgeny 232ad2de6b etcp_router: разделить служебные функции и API в хедере + чистка мёртвого кода
- etcp_router.h: 4 секции (протокол / внутренние структуры / API / служебные)
- переименование router_set_max_inflight -> etcp_router_set_max_inflight
- удалены неиспользуемые: input_q_count, waiter_register/cancel, conn_close_async
  (+ поля close_callback/close_callback_arg)
- docs: актуализировать backpressure (on_send_ready на send_q) вместо удалённого waiter API
2026-09-05 22:34:00 +03:00
evgeny 01ea6913ae etcp_router: sess_id как локальный счётчик переустановок (не в протоколе) 2026-09-05 20:38:17 +03:00
evgeny 2d04bf941b etcp_router: вынести подпись/шифрование в route_crypto, одна функция отправки с флагами
- route_crypto_encode/decode: автономный пред/пост-обработчик пакета
  (encrypt-then-sign, стандартный Ed25519 вместо sc_stream_sign)
- одна функция отправки etcp_route_send/etcp_router_conn_send с bitmask mode
- формат доставки: [svc_id][src][dst][rx_flags][payload] (статус подписи/шифрования)
- ROUTER_INFLIGHT хранит финальный wire-пакет (чинит потерю подписи при ретрансмите)
- дедуп инициализации: router_conn_reset/free_queues
- учёт inflight через inflight_q count (seq присваивается на enqueue)
2026-09-05 17:40:43 +03:00
evgeny 7817bb96aa etcp_router: START/RST handshake для переживания рестарта пира
Раньше START ставился один раз при первой отправке и терялся в ретрансмите,
а принимающая сторона молча авто-синкала rx_seq на любой первый пакет —
после рестарта пира/среднего узла seq рассинхронизировались (тихий data loss
или no-ACK close). Теперь:

- Клиент: флаг start_sent «новый» до первого ACK; пока он стоит, первый
  seq (0) шлётся со START, включая ретрансмит. Первый принятый ACK
  (tx_acked>0) сбрасывает флаг. При рестарте conn флаг снова «новый».
- Сервер: после рестарта peer_sync_done=0 («ждёт START»). Не-START пакет →
  отправка RST (через recv_conn). START → синк rx_seq + ACK → обычный режим.
- RST на принимающей стороне теперь сбрасывает локальное состояние
  (etcp_router_conn_restart), а не закрывает conn.

Тесты unit обновлены: первый data-пакет сессии инжектится со START.
2026-09-05 15:03:44 +03:00
evgeny 84015176b3 etcp_router: досылать потерянный ACK при дубле (рестарт среднего узла)
При рестарте транзитного узла ACK приёмника терялся и не пересылался:
router_schedule_ack выходит рано при rx_seq==last_sent_ack_seq, поэтому
пир ретранслил 17 циклов (~5с), роутер-conn закрывался и цикл повторялся
бесконечно — лечилось только рестартом клиента. Теперь при дубле
(ретрансмите пира) ACK досылается с троттлингом ROUTER_ACK_INTERVAL_TB.
2026-09-05 01:17:37 +03:00
evgeny 23fbdf4584 chat: запуск BGP-обмена при подключении узла к группе (invite + auto-connect) 2026-09-04 21:04:18 +03:00
evgeny 5b8c725c01 etcp_router: round-robin send + контроль заполненности send_q через waiter на send_input_q 2026-09-04 19:30:08 +03:00
evgeny 1a88ea88a8 topo_group: узлы меняются только по BGP (NODEINFO/WITHDRAW), удаление по link down через BGP-коллбэк 2026-09-04 17:57:37 +03:00
evgeny b0f149092f BGP: log node add/remove per group at info level 2026-09-04 16:45:33 +03:00
evgeny c049788c08 etcp_router: при no route выводить список узлов группы (<10) 2026-09-04 16:39:23 +03:00
evgeny ed2df9fe88 etcp_router: добавить кол-во узлов группы в лог no route 2026-09-04 16:25:21 +03:00
evgeny 656da48e35 topo_group: асимметричный старт BGP (JOIN_GROUP) + вынос group_id/flags из TOPO_NODE
- UTUN: BGP инициирует только сторона-клиент ([client]) и явные etcp_connect;
  сервер добавляет пира по JOIN_GROUP (фикс обратного маршрута: сервер не
  создавал узел клиента из-за дедупа senders_list)
- topo_group_new_conn: conn_add_path до дедупа; handle_request_table без add_to_senders
- TOPO_NODE: убраны group_id/flags (shared-реестр), передаются в topo_node_serialize
- routing/control_server: явный TOPO_GROUP_UTUN
- CHAT: гейт по peers_* (get_member_channels) + пассивное add/remove в member_sync
- tests: тесты адаптированы (route_ping ждёт registry+v4_addrs)
- chatgui-android: voice_recorder_init в utun_bridge_voice_start (idempotent)
2026-09-04 13:21:24 +03:00
evgeny 01b61a457a etcp_router: fix ACK no-route — слать ACK через recv_conn
При асимметричной топологии 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.
2026-09-03 20:05:59 +03:00
evgeny f47ad7d87f tcp_proxy: fix throughput (tx_queue backpressure) + connect timeout + integration test
- Router: unified service delivery format [svc_id][src][dst][payload] (end-to-end src/dst from SVC_ROUTE header)
- tcp_proxy_client: replace single tx_buf drop-on-backpressure with bounded tx_queue + send_q waiter + retry timer (no data loss, bulk window reopen — removes 62.5ms delayed-ACK stall)
- tcp_io: configurable connect timeout (tcp_conn_set_connect_timeout)
- tcp_proxy_server: connect_timeout config option (ms, default 2000, 0=off)
- check.sh: run tcp_proxy_full integration test with sudo (skip if passwordless sudo unavailable)
- test_tcp_io: connect timeout unit test; docs (lwip_nuances.md)
2026-09-03 13:49:09 +03:00
evgeny e08956e5dc etcp_router: fix NULL conn в deliver при отсутствии пути к узлу
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.
2026-09-02 23:59:41 +03:00
evgeny 3d59e5f322 chat: headless invite_to command + invite-flow integration test
- chat_headless_control.c: новая команда invite_to (inviter-side invite по адресам)
- chat_client.py / chatcli: клиентский метод и CLI-команда invite_to
- tools/chat_invite_test.py: headless-тест инвайтера-side (CHANNEL_INVITE → autojoin → member_sync)
- topo: guard node_id=0 в cm_open/process_nodeinfo + детализация send_nodeinfo warn
- cleanup: удалить устаревшие doc/*.txt, *.md заметки
2026-08-17 11:22:40 +03:00
evgeny eb24736e27 topo: держать актуальные self-адреса в node_addresses, обновлять/рассылать только при изменении
topo_node_update_my_addresses теперь собирает адреса во временные списки,
сравнивает со старыми и при отсутствии изменений выходит без бампа ver,
записи в БД и broadcast. Гейт member_exists убран: self-адреса пишутся
в node_addresses при любом запуске/изменении (с гарантией строки nodes для FK).
addrs_put логирует ошибки INSERT.
2026-08-16 22:34:10 +03:00
evgeny d04e9d58b6 etcp: TCP-ping через STCP-хендшейк с флагом PING
- STCP-хендшейк: добавлен байт флагов (STCP_HANDSHAKE_FLAG_PING), HS_ENC 46→47
- stcp_client: stcp_ping_send() — connect+handshake(PING)+rtt+close; ошибка/таймаут → success=0
- stcp_server: детект флага, ответ с эхо-флагом, мягкое закрытие (close_after_send)
- etcp_connections: etcp_send_tcp_ping(), guard is_tcp/fd и проверка возврата send_ping_raw
- route_connectivity: probe TCP-адресов через TCP-ping (1 попытка), UDP-кандидаты без TCP-сокетов
- tests: test_stcp_ping (success+failure path), обновлена сигнатура stcp_client_connect
2026-08-16 10:10:58 +03:00