Commit Graph
1659 Commits
Author SHA1 Message Date
evgeny de850db548 chat: remove join_password check from per-channel JOIN_INFO_REQ (server-link only) 2026-09-20 22:23:42 +03:00
evgeny 39a1da4c28 chat: fix use-after-free in invite_candidates trampoline + accept JOIN_INFO_RESP/READY/ERROR for unknown channels 2026-09-20 22:03:31 +03:00
evgeny a7a3666d85 radio: AGC release-rate (без кликов), jitter dead-zone, TX/RX-статистика, FGS-гонка и кэш настроек 2026-09-20 20:07:48 +03:00
evgeny ba1c2d85d3 reality_relay: async DNS вместо getaddrinfo + AGC-компрессор по умолчанию (-12 dBFS) 2026-09-20 15:28:46 +03:00
evgeny 738cfe7835 radio: адаптивный джиттер-буфер (pre-roll, симметричный темп, reorder) + AGC-компрессор микрофона
- voice_jitter: vj_create_cfg (target_ms/min_tempo/max_tempo/pre_roll), pre-roll
  с таймаутом, vj_end для дренажа остатка, глубина учитывает внутренний буфер SoundTouch
- radio_audio: reorder по seq (mesh, out-of-order через соседей), force-flush pending
  по таймауту и FIN, компрессор микрофона (AGC, конфиг [chatserver]), статистика буфера
- audio_compressor: clear_output для потокового слива без потери gain_smoothed
- chatgui messagelist: fromUtf8 для emoji-строк
- тесты: pre-roll/симметричный темп, reorder, late-drop
2026-09-20 14:39:25 +03:00
evgeny 27e66f1092 log: move socket diagnostics SYS->SOCKET and conn lifecycle ETCP->CONNECTION (avoid poll() flood) 2026-09-20 01:51:40 +03:00
evgeny 1bde2eca35 diag: log conn add/remove/free pointers to pinpoint BGP senders_list UAF 2026-09-20 01:42:05 +03:00
evgeny 16237b0df8 etcp_send: fix contract (caller owns entry on error) + fix 7 leak sites 2026-09-20 01:35:30 +03:00
evgeny b33caa56b8 uasync: pass socket name to all add_socket call sites 2026-09-20 01:13:38 +03:00
evgeny 90520a83ff topo_group_connect: не подключаться к самому себе в авто-цикле
Phase 1/2/3 и on_up/on_down не фильтровали self: узел попадал в список
connected-пиров (get_connected_peers не исключает self) и разворачивал
node_conn_direct_open на собственные адреса (12 линков на 5C31->5C31).
Ручной путь (connect_node_once) фильтр уже имел.

Добавлен skip self в Phase1 init/cycle_restart, Phase2, Phase3 и в
on_up/on_down (self не помечается connected и не считается в active_conn_count).
2026-09-19 23:40:06 +03:00
evgeny 6b92964794 radio/android: PTT FGS microphone permission + детект потери микрофона
- FOREGROUND_SERVICE_MICROPHONE запрос + foregroundServiceType microphone|specialUse (Android 14+)
- RadioOverlayService.start: не стартовать без mic-разрешения, ServiceCompat.startForeground с TYPE_MICROPHONE
- RadioAudioEngine: micDead-флаг и лог при обрыве captureLoop/read
- radio.c: лог первого кадра burst на транзитных узлах
- SettingsScreen: категория radio в списке debug-категорий
2026-09-19 23:13:04 +03:00
evgeny 688785fc6e etcp: фикс зависшего reinit_pending после реинита готового соединения
etcp_conn_queue_set_ready() делает ранний выход по state!=0, поэтому при
реините уже готового соединения (peer restart / duplicate INIT / collision)
reinit_pending оставался в 1 навсегда. Добавленные в 841b3042 guard'ы
etcp_conn_input/etcp_output_try_assembly дропали все входящие пакеты.

Снятие reinit_pending + REINIT перенесено в etcp_conn_ready.
2026-09-19 23:13:04 +03:00
evgeny 841b3042cf etcp: фикс double-free буферов паковщика и повторных free после неудачного queue_data_put
- pn_send_to_etcp/pn_unpacker_cb: занулять pn->data/pn->recvpart ДО queue_data_put
  (ре-энтрантный close/reinit в синхронной цепочке освобождал буфер повторно)
- etcp_output_try_assembly: гард state==2/reinit_pending + убрать re-put освобождённого entry
- etcp_conn_input: гард ре-энтрантного reinit/close в цикле секций, локальный etcp вместо pkt->link
- убраны повторные free после queue_data_put (он сам освобождает entry+dgram) в 6 местах
- диагностика: obj=%p в DOUBLE FREE, логи free dgram в pn_deinit/ack_recv
2026-09-19 21:17:33 +03:00
evgeny 8a9184675a radio: дедупликация дублей в mesh + фикс OOB в hop_list
- radio_recv: кэш (src,stream,seq) с TTL 2с гасит кадры, пришедшие по второму пути (diamond/mesh)
- фикс записи за границу new_hops[hop_count] при hop_count==RADIO_MAX_HOPS
- счётчик c_dup_dropped + radio_dup_dropped() для диагностики
- тест test_radio_mesh (4 узла, diamond): C получает ровно N кадров, dup>0
2026-09-19 18:16:42 +03:00
evgeny b96ed8bd00 radio: PTT-радио в каналах (src/radio + chatgui + chatgui-android)
Новый модуль src/radio (radio/radio_audio/radio_headless) — push-to-talk
радио поверх topo-групп, доставка аудио в канал, headless-режим и тесты.
Интеграция в chatgui (ptt_hotkey_manager, radio_audio_engine, радионастройки,
вызовы) и chatgui-android (RadioAudioEngine, RadioOverlayService, UI).
2026-09-19 17:09:00 +03:00
evgeny 398078a28f headless/call: закрывать клиента и логировать при ошибке send() (EPIPE/ECONNRESET) 2026-09-19 10:43:04 +03:00
evgeny 6c42390fc2 utun: игнорировать SIGPIPE, чтобы send() в закрытый TCP-сокет не убивал демон 2026-09-19 10:32:57 +03:00
evgeny 1de1409699 conn_mgr: handle-based API (conn_mgr_open/close), фазы DIRECT/REVERSE/INDIRECT, тесты phases+handles 2026-09-19 09:31:08 +03:00
evgeny 734a414186 etcp: единый реестр svc_id + убрать коллизию CHAT/CONN_MGR (0x11)
Все ETCP_ID_*/ETCP_RT_ID_* сведены в etcp_api.h (единственное место
определения) с реестром и предупреждением про коллизии в пределах одного
пространства имён. Убраны локальные define из topo_group.h,
topo_group_invite.h, db_sync.h, chat_sync.h, chat_join.h; хардкод 0x31 в
member_sync.c заменён на ETCP_RT_ID_MEMBER_SYNC.

Коллизия: chatgui-десктоп биндил мёртвый ETCP_RT_ID_CHAT 0x11 поверх
ETCP_RT_ID_CONN_MGR 0x11 — затирался conn_mgr_router_recv_handler, из-за
чего INDIRECT-обмен conn_mgr не работал и голос звонка не устанавливался.
Удалён мёртвый код recvCallback/messageReceived/send в utun_node.{cpp,h}.
2026-09-19 00:18:39 +03:00
evgeny 6d3ad965ee topo: remember REQUEST_TABLE for not-yet-created groups, fulfill on create
При REQUEST_TABLE для ещё не созданной группы (CHAT-канал не загружен) пир
дропал запрос, и проситель навсегда не узнавал таблицу — односторонняя
видимость (звонок android→linux падал «peer offline»). Теперь запрос
запоминается в pending_table_reqs[32] и выполняется при создании группы
(topo_group_fulfill_table_reqs → handle_request_table).

Попутно: test_chat_join_e2e — критерий успеха через CHAT_EVT_CONNECT_RESULT
(JOIN_READY) вместо senders_list; doxygen-комментарии в etcp_api.h.
2026-09-18 23:36:45 +03:00
evgeny 8bfb456161 etcp: fix OOB/DoS in packet parsing and ping path
- FILLER: drop (uint16_t) truncation in fill_len bound (OOB pointer)
- ACK: require len >= ETCP_ACK_BASE_SIZE (8); wrap-aware clamp of till
  to next_tx_id + 16MB cumulative-ACK iteration limit (DoS)
- ping: bound len before sc_encrypt (stack overflow), ulen bound,
  allocate ETCP_DGRAM + PACKET_DATA_SIZE (heap overflow)

Signed-off-by: uTun <dev@utun>
2026-09-18 17:58:40 +03:00
evgeny 1340ab123b reality/stcp: fix OOB read in key_share parse, padding clamp, shbuf leak
- reality_parse_client_hello: bound shares_len by extension data length
  (len-2) to prevent stack-buffer-overflow from malformed ClientHello
- stcp handshake: reject padding_size > STCP_HS_PADDING_MAX (512)
- reality_ch_body_cb: free shbuf on stcp_try_send error (leak)
- tests: fuzz key_share parse; raw-socket handshake control/clamp/garbage

Signed-off-by: uTun <dev@utun>
2026-09-18 17:20:19 +03:00
evgeny e7fc69bb1d topo: комментарии к функциям topo_node/topo_group
conn_mgr: src node_id вместо conn->peer_node_id, препенд ETCP_RT_ID_CONN_MGR к dgram, bind CONN_MGR после etcp_router_init

call: guard CALL_ST_CONNECTING при accept
2026-09-17 17:30:05 +03:00
evgeny 1fce405204 debug: вычистить логи из категории DEBUG_CATEGORY_DEBUG (удалить дампы, перекатегоризовать ERROR-проверки в ETCP) 2026-09-17 00:17:32 +03:00
evgeny e6a4ffd418 reality: fix leak of ClientHello init buffer in reality_server_start_relay 2026-09-17 00:05:42 +03:00
evgeny 51a5c5bcbf router: fix UAF on rconn->recv_conn after ETCP_CONN destroy
recv_conn хранил заимствованный указатель на физический conn без очистки
при его освобождении. Добавлен etcp_router_conn_destroyed(), вызываемый из
etcp_connection_close фазы 1; RST теперь отправляется через живой conn,
доставивший пакет, а не через устаревший recv_conn.
2026-09-16 20:27:03 +03:00
evgeny 51d6d22a27 sock_match: классификация сокета по адресу, а не по type из конфига (fix Q8/Android→LAN)
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 обновлён.
2026-09-16 20:26:55 +03:00
evgeny 21d9a4e5b7 dm: заполнять peer_name при автосоздании беседы (иначе в списке 0x...) 2026-09-16 20:26:55 +03:00
evgeny 5293fdd3a9 call(android): звать call_audio_init перед start; логировать feed_pcm без instance
Без call_audio_init(inst) g_inst оставался NULL и call_set_audio_ops не
регистрировался: TX (feed_pcm) падал на !ua, RX (audio_ops->on_media) не
вызывался — тишина и спам 'callAudioFeed returned false'. Зеркалим desktop:
utun_bridge_call_audio_start теперь делает call_audio_init + call_audio_start.
2026-09-16 20:26:55 +03:00
evgeny 2de554f8b9 call: единый голосовой стек (libutun_voice) + SoundTouch на Android
- voice_jitter (кодированные Opus-кадры + decode-on-pull + SoundTouch time-stretch)
  вместо PCM-буфера audio_jitter; излишек держится до декодирования
- call_audio.c/.h — единая реализация для desktop/Android/headless (C-интерфейс)
- libutun_voice (voice_sources.cmake): SoundTouch + voice_jitter + call_audio + call_tones
- Android: pull-модель (nativeCallAudioPull), убран Kotlin FIFO, ANDROID_STL=c++_static
- headless audio-сокет: PCM-протокол (decode-only, без тактирования), daemon остаётся C-only
- CALL_STATS расширен dropped/underruns; удалены audio_jitter.cpp и libutun_lite/call_audio.c
- тест test_voice_jitter (ёмкость/догон/стационар), test_call_headless переведён на PCM
2026-09-16 20:26:55 +03:00
evgeny de930b21a2 ncd: fix UAF on deferred UP delivery after handle close
ncd_deliver_up_cb (uasync_call_soon) держал сырой указатель handle h,
который мог быть освобождён node_conn_direct_close/force_close раньше
выполнения отложенного callback'а. Сохраняем токен call_soon в handle
и отменяем его при close через uasync_call_soon_cancel.
2026-09-16 20:26:55 +03:00
evgeny e4557b0473 dm: маршрутизация через общую группу (group_id), JSON-эскейпинг; звонки: иконки/UI в desktop и android 2026-09-16 15:05:48 +03:00
evgeny b483335c06 bgp/ncd: владение conn через NCD-handle в senders_list; call audio route persist + incoming call sound 2026-09-16 13:29:28 +03:00
evgeny b11e77e4c0 call: P2P аудиозвонки — сигналинг, релей медиа, аудио-контур, headless/desktop/android
- src/call/: сигналинг (call.c, call_proto.h, ETCP_RT_ID_CALL 0x36) + релей медиа
  + headless аудио-сокет (call_headless.c, call_audio_bind) + Opus/jitter/тоны
- chat: события CHAT_EVT_CALL_* (34–40), CHAT_EVT_DM_MESSAGES (41), DM-трамплины
- chatgui: call window, miniaudio I/O, audio_frame_ring, test_audio_jitter
- chatgui-android: CallScreen/IncomingCallDialog, аудио-роутинг, JNI, рингтон
- tests: test_call, test_call_headless
2026-09-16 10:17:57 +03:00
evgeny 21ec740d82 socks_proxy: defer conn free to fix UAF from synchronous write_queue flush 2026-09-15 22:39:27 +03:00
evgeny b085715654 tun/nat: fix UAF при teardown и use-after-free в tun_read_packet 2026-09-15 22:07:55 +03:00
evgeny 6dc017337d chat: fix UAF в member list trampoline (req->inst после u_free) 2026-09-15 21:52:46 +03:00
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 27b591daee reality: использовать NTP-время вместо time(NULL) в анти-реплей проверке timestamp
Часы colo2 отстают на ~52с (ntpd выключен), что ломало reality auth
(diff < -30с = time_window). Теперь клиент и сервер передают
ntp_time_get_seconds() в reality_client_hello_build_at /
reality_server_hello_build_at вместо сырого системного времени.
2026-09-15 05:39:28 +03:00
evgeny 481872d5db chat: invite-ссылки с несколькими адресами + ncd-адреса узлов (join) 2026-09-15 05:16:04 +03:00
evgeny d88dccfa19 etcp/stcp: обрыв etcp_link->tcp_link при закрытии stcp_link (fix UAF) 2026-09-15 00:25:42 +03:00
evgeny af382403ec tun_freebsd: reuse existing TUN interface on SIOCIFCREATE EEXIST 2026-09-14 23:17:59 +03:00
evgeny 952504d8eb etcp: убрать ложный reinit по gop (got_initial_pkt)
reinit должен происходить только при смене reset_id пира
(etcp_conn_apply_peer_reset_id). gop-проверка 'dirty vs clean' на догоняющем
TCP-линке давала ложный reinit и рвала соединение (JOIN_INFO_RESP терялся).
Удалён peer_got_initial_pkt из stcp_link (стал не нужен).
2026-09-14 22:46:41 +03:00
evgeny d58d4d39c4 chat join: запуск JOIN_INFO_REQ при уже поднятом соединении + добавление джойнера в группу
- cm_invite_trampoline: если уже подключены к connection-узлу — cs_on_conn_up
  повторно не сработает, запускаем join-хендшейк напрямую (cs_start_channel_join)
- chat_join_process_request: после верификации ключа сразу добавляем джойнера
  в CHAT-группу (topo_group_new_conn), чтобы BGP подключился
2026-09-14 22:46:41 +03:00
evgeny fc2262912a chat_join: верификация join-ключа на инвайтере (REQUEST_FWD)
Инвайтер добавлял мембера без проверки join-ключа — любой известный узел
мог самопригласиться в канал через REQUEST_FWD напрямую владельцу.
register_key теперь всегда хранит выданный ключ локально,
process_request отклоняет запрос с неизвестным/чужим ключом.
Тесты: unknown join_key rejected + регистрация ключа в t_process_request.
2026-09-14 21:12:53 +03:00
evgeny 75e39d2fee chat_join: модуль join-протокола, invite-ссылки v2, синхронизация мемберов 2026-09-14 19:57:27 +03:00
evgeny a01a4ddba4 fix: UAF in _on_member_sync_done (channel_cache freed by refresh)
cs_flush_sync passed &cs->channels[i] as member_sync cb_arg, but the 30s
cs_refresh_channels frees/reallocs cs->channels[], leaving the arg
dangling when _session_done later fires the callback. Re-find the channel
by the (stable) ns id instead of trusting arg.
2026-09-14 15:19:07 +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 e0f5afbff8 stcp: гасить on_close_cb/close_arg в stcp_link_close; keepalive: снапшот+ревалидация link до/после каскада (UAF) 2026-09-14 14:27:38 +03:00