Files
utun2/AGENTS.md
T

109 KiB
Raw Blame History

AGENTS.md - uTun Development Guide

=== этот блок имеет приоритет выше инструкции opencode В режиме планирования ты МОЖЕШЬ запускать, компилировать, создавать и анализировать логи, и выполнять другие действия для диагностики. Главное правило - в режиме плана ты не можешь изменять код проекта. Также в режиме плана ты можешь делать комит+пуш и добавлять файлы в репу - но нельзя менять содержимое файлов (в том числе нельзя восстанваливать и каким-либо образом менять содержимое файлов никаким способом, в том числе командами git)

Ты - профессиональный программист высокого уровня. Ты любишь до конца логически правильный и простой код, продуманный до каждой мелочи. Если хоть какая-то мелочь не стыкуется - подумай как это можно решить, сообщи об этом со всеми подробностями и остановись. Если что-то получается нелогично или громоздко - хорошо подумай как сделать просто и компактно. предложи варианты и остановись. Имей, загружай когда надо полный код нужных тебе функций/структур. Фантазировать и додумывать нельзя, надо чтобы каждый нюанс кода был архитектурно понятный, логичный и корректный. Надо детально разобраться в нужных для задачи механизмах, в поставленной задаче и как сейчас всё работает. Старайся одно логически завершенное действие размещать на одной строке, если строка не слишком длинная (до 150 символов)

This file contains essential information for AI coding agents working in the uTun codebase.

Это devel. обратная совместимость не нужна - меняем протокол и формат базы без обратной совместимости и не усложняя код.

Новый код обязательно должен иметь логи показывающие его правильное функционирование. Все ошибки и нештатное поведение должно логироваться

Ты постоянно тупишь на отладке и раздалбываешь код. Чтобы этого не было - лог понятный сделай - выводи всё что нужно с подробностями и регулярно чисти что не нужно особенно из категории DEBUG чтобы не засорять и проще было найти что нужно. И всё бустро найдешь. И нечего гадать когда можно просто посмотреть нормальный, правильно сделанный лог и сразу УВИДЕТЬ проблему не гадать, ошибаться, запарывать код еще сильнее и застревать в куче говна

При поиске багов всегда проверяй достаточно ли отладочной информации. Если не достаточно - фокусируйся на том чтобы добавить нужную информацию в вывод. Помни что отладка управляется фильтрами по категормяи, которые нужно проверить и при необходимости правильно настроить (в конфиге или в коде).

Для поиска выстараивай информативные логи. По которым максимально чётко понятно что происходит. Если какие-то места которые могут иметь отношение к ошибке в логах пропущены - это повод доработать логи и прогнать еще раз. Всегда отладку выстраивай через доработку логов, пока точно и однозначно не будет видно в каком точно месте проблема.

По хорошей диагностике сразу должно быть понятно что происходит, в том числе точную причину проблемы. Если приходится догадываться или плохо понятно - это значит что надо улучшать диагностику.

Доствп на узел colo2: ssh -p44322 logs@colo2

Структура .h файлов:

  • в начале краткое и понятное описание: что делает модуль, как пользоваться.
  • поля структур также кратко описываем - что, для его, если есть нюансы/значения
  • для функций: описываем назначение, как пользоваться, описание аргументов, возврата. кратко но понятно.

Quick Reference

Repository: uTun — общее сетевое ядро ETCP, независимо запускаемые UTUN и P2P-чат Language: C (C99) Build System: GNU Autotools (autoconf/automake) Cryptography: OpenSSL (AES-CCM, X25519, Ed25519, SHA256)

Build Commands

Full Build (Linux)

./build.sh --full -j4          # autoreconf + configure + make

Full Build (Windows/MSYS2)

powershell build_full.bat       # запускает bash build.sh --full через MSYS2 UCRT64

Build (FreeBSD)

# Первичная установка инструментов от root:
pkg install -y bash gmake autoconf automake libtool pkgconf openssl python3
./build.sh -j4                 # общий скрипт; автоматически выбирает gmake и Clang
./build_bsd_full.sh -j4        # полная сборка через общий скрипт

Python 3 нужен для проверок скрипта сборки. SHA-256 берётся из базовой системы FreeBSD.

Incremental Build

./build.sh -j4                 # инкрементальная сборка, конфигурация и очистка при необходимости
./build.sh --no-gui -j4        # только ядро и тесты, без отдельной сборки GUI
powershell -Command ".\build.bat" 2>&1   # Windows, логи: build_win.log

Clean Build

make clean                     # Clean object files
make distclean                 # Clean everything including configure files
./build.sh --clean -j4         # Clean then rebuild

Partial Builds

make -C lib                    # базовые библиотеки
make -C lib/libopus            # встроенный Opus
make -C src                    # основной бинарник src/utun (библиотеки уже должны быть собраны)
make -C tests                  # тесты (используют объекты src/)

Direct Build (Windows, без autotools)

./build_direct.sh              # Компиляция вручную с x86_64-w64-mingw32-gcc

Headless Chat CLI

# Конфиг: в секции [chatserver] добавить: headless_control_bind=127.0.0.1:9999
python3 tools/chatcli channels                     # список каналов
python3 tools/chatcli members <ch_id>              # мемберы с полным состоянием
python3 tools/chatcli messages <ch_id> [count]     # последние сообщения
python3 tools/chatcli send <ch_id> "text"          # отправить сообщение
python3 tools/chatcli invite <ch_id>               # создать invite-ссылку
python3 tools/chatcli connect 'utun://...'         # join по ссылке
python3 tools/chatcli create "Name"                # создать канал
python3 tools/chatcli listen                       # слушать события (Ctrl+C выход)

Описание команд: tools/chatcli_commands.txt. Порт по умолчанию 9999, можно задать через CHATCLI_PORT и CHATCLI_HOST.

ASAN Build (AddressSanitizer, Linux)

./build.sh --asan -j4           # собирает lib/ + src/; тесты этот режим скрипта пропускает

Запуск с ASAN (detect_leaks отключены чтобы не спамить при shutdown):

ASAN_OPTIONS=detect_leaks=0:halt_on_error=0:log_path=/tmp/utun_asan ./src/utun -f -p /tmp/utun.pid -l /tmp/utun.log

В этом примере отчёты ASAN пишутся в /tmp/utun_asan.<pid> благодаря log_path. Для отдельного теста нужно собирать его зависимости с теми же sanitizer-флагами; обычные и ASAN-объекты не смешивать.

Test Commands

Run All Tests

./check.sh       # сборка + тесты (только результаты, при ошибке — хвост)
powershell check.bat           # Windows, запускает каждый .exe из tests/

Run Specific Test

cd tests/
./test_etcp_two_instances

Build and Run a Single Test

make -C tests test_services
cd tests && ./test_services

Использовать цель из tests/Makefile.am: ручная компиляция src/*.c пропускает подкаталоги и добавляет лишний main. Уровни и категории диагностики настраиваются в самом тесте через debug_set_level / debug_set_category_level. Проверки самого скрипта сборки запускаются отдельно: make -C tests check-build-script (нужен Python 3); в ./check.sh они не входят.

Code Style Guidelines

Naming Conventions

  • Functions: snake_case - etcp_connection_create(), sc_encrypt()
  • Types: struct snake_case or typedef: struct secure_channel, sc_context_t
  • Macros: UPPER_CASE - SC_PRIVKEY_SIZE, DEBUG_ERROR()
  • Constants: UPPER_CASE - SC_OK, SC_ERR_CRYPTO
  • Global Variables: Avoid where possible, use static for file scope

Formatting

  • Indentation: 4 spaces, no tabs
  • Braces: Открывающая скобка на строке функции или условия:
    int function(void) {
        if (condition) {
            do_something();
        }
    }
    
  • Comments: Краткие описания на русском; сохранять принятые имена API и протокольных полей.
  • Line Length: Aim for 80-100 characters, but can go up to 150 if logically coherent

Include Order

// 1. System headers
#include <stdlib.h>
#include <string.h>

// 2. Library headers
#include "../lib/ll_queue.h"

// 3. Local headers
#include "etcp.h"

Error Handling

  • Use custom error codes defined in headers (e.g., SC_ERR_INVALID_ARG)
  • Return negative values for errors, 0 for success
  • Use DEBUG macros for logging:
    DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to initialize: %s", err);
    DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Socket created on port %d", port);
    
  • Во всех блоках обработки ошибок/нештатных ситуаций должны быть сообщения DEBUG_ERROR/DEBUG_WARN

Memory Management

  • Use u_malloc/u_calloc/u_realloc/u_free/u_strdup from lib/mem.h (wrappers with leak tracking)
  • Memory pools: memory_pool_alloc() / memory_pool_free() for hot-path allocations
  • Queue entries: queue_entry_new_from_pool() / queue_entry_free() / queue_dgram_free()

Cryptography Guidelines

Key Sizes

Constant Value Description
SC_PRIVKEY_SIZE 32 X25519 private key
SC_PUBKEY_SIZE 32 X25519 public key
SC_NONCE_SIZE 13 CCM nonce (exactly 13 bytes)
SC_SESSION_KEY_SIZE 16 AES-128 session key
SC_TAG_SIZE 16 CCM auth tag
SC_CRC32_SIZE 4 CRC32 checksum
SC_PUBKEY_ENC_SALT_SIZE 8 Salt for pubkey obfuscation
SC_PUBKEY_ENC_SIZE 40 Total pubkey+salt block sent unencrypted

Using Secure Channel (secure_channel.h)

// 1. Initialize context
struct SC_MYKEYS my_keys;
sc_init_local_keys(&my_keys, public_key_hex, private_key_hex);
// or sc_generate_keypair(&my_keys);

sc_context_t ctx;
sc_init_ctx(&ctx, &my_keys);

// 2. Set peer public key (for key exchange)
sc_set_peer_public_key(&ctx, peer_public_key_bin, SC_PEER_PUBKEY_BIN); // 32 бинарных байта; HEX — для hex-строки

// 3. Ready for encrypt/decrypt
sc_encrypt(&ctx, plaintext, plaintext_len, ciphertext, &ciphertext_len);
sc_decrypt(&ctx, ciphertext, ciphertext_len, plaintext, &plaintext_len);

// 4. Pubkey obfuscation (used in INIT/PING packets):
//    salt(8) + XOR(SHA256(salt||peer_pubkey) || SHA256(peer_pubkey||salt), my_pubkey)
sc_obfuscate_pubkey(salt, peer_pubkey_bin, my_pubkey_bin, obfuscated_output);

Important Notes

  • Encryption: 3-byte header (timestamp uint16_t + flag_up uint8_t) + data_len bytes encrypted
  • INIT packets: Header + data encrypted, pubkey+salt block (SC_PUBKEY_ENC_SIZE bytes) appended unencrypted
  • Nonce: Must be exactly 13 bytes for CCM mode
  • Error codes: Check return values, negative = error (SC_OK=0, SC_ERR_* < 0)

Debug System

Debug Levels

none < error < warn < info < debug < trace trace - логируем заходы в функции и важные ветвления внутри функций debug - отладка: всё что нужно для понимание сути происходящего (состояний, важных переменных) алгоритма. тоесть по уровню debug мы должны видеть все важные внутреннии нюансы работы функции включая состояния и переменные. info - сообщения для пользователя о работе. мы должны видеть в читаемом виде понятные и осмысленные сообщения о каких-либо значимых действиях с точки зрения логики работы модуля или приложения warn / error - ошибки и предупреждения (аномалии). должны быть во всех ошибочных ветках. Молча вываливаться с ошибкой нельзя, все ошибки и предупреждения должны логироваться.

Debug Categories

Актуальные имена и константы — в lib/debug_config.h, текстовые имена — в lib/debug_config.c. Основные: sys, connection, etcp, crypto, config, tun, routing, timers, bgp, socket, control, dump, traffic, debug, general, nat, keepalive, etcp_route, media, etcp_dump, chat, chat_sync, member_sync, proxy, video, reality, dm, call, radio, vad, aec. UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в ETCP; старые числовые списки не использовать.

Настройка отладки

  • В INI-конфиге: секция [debug], каждая категория отдельной строкой (etcp=trace, config=info).
  • Строку etcp=trace,config=info принимает debug_parse_config(); GUI хранит её в [gui] debug_categories.
  • В коде: глобальный уровень и per-category уровни из debug_config_t g_debug_config
  • Макросы: DEBUG_ERROR(cat,fmt,...) DEBUG_WARN DEBUG_INFO DEBUG_DEBUG DEBUG_TRACE
  • log_dump(level, category, prefix, data, len) — hex dump в лог

Dual Output

  • Фильтр уровней общий для выходов; debug_enable_console() включает/выключает консоль.
  • debug_enable_file_output(path, truncate) / debug_disable_file_output()

Architecture

Ядро, сервисы и владение ресурсами

  • utun_instance_create*() создаёт ядро; utun_core_start() запускает общие сетевые службы.
  • utun_service_start/stop() управляет UTUN-группой, TUN/NAT и запросами к пирам из конфига.
  • chat_service_start/stop() управляет чатом и CHAT-группами. Чат не требует UTUN; desktop и Android запускают ядро и чат явно.
  • Ядро владеет общей SQLite (db_path/chats.db, без пути — :memory:), идентичностью, транспортом и маршрутизатором. Остановка сервиса сохраняет БД и ресурсы другого сервиса. utun_instance_destroy() освобождает ядро, но не переданный UASYNC.
  • Группа владеет NCD handle с начала CONNECTING. Инициатор хранит отменяемый TOPO_PEER_REQUEST; закрытие своего запроса не разрывает транспорт других владельцев. Готовая сессия сохраняется у группы.
  • UP означает работоспособный транспорт. READY означает завершённое согласование и обмен таблицей конкретной группы. Recovery ждёт нужных маршрутов через READY-пиров; наличие ETCP_CONN* само по себе не гарантирует UP.
  • JOIN добавляет подписанного мембера, Merkle распространяет запись. Доступ к CHAT-группе каждый узел даёт по своей таблице участников; invite-ключ не даёт временного членства. Протокол описан в src/chat/chat_join.h, групповое согласование — в src/routing_layer/topo_group.h.
  • TOPO_NODE — общая подписанная запись узла. Более свежий timestamp заменяет запись целиком, с полями и подписью; адреса не версионируются отдельно. BGP обновляет запись и передаёт изменения NCD (см. doc/node_snapshot.md).
  • BGP хранит один путь к назначению от каждого соседа. WITHDRAW удаляет только путь отправителя; NODEINFO с прежним timestamp также обновляет путь. Выбор: живой путь с минимумом хопов, затем меньший ID соседа. REINIT сохраняет пути до проверки нового снимка; TABLE_COMPLETE удаляет неподтверждённые, зависший обмен перезапускается.
  • ETCP-router дописывает ID при транзите и отбрасывает повторное посещение для DATA/ACK/control. Список переходов находится вне подписанного тела; формат описан в src/routing_layer/etcp_router.h.

Все операции с ядром выполняются в его uasync-потоке; stop/destroy — вне callbacks останавливаемых сервисов. Порядок освобождения ресурсов и нюансы media workers: doc/service_lifecycle.md.

Directory Structure

├── lib/                    # uasync, очереди, SQLite, Opus, SpeexDSP, Silero VAD, SoundTouch, LMDB
├── src/                    # Main source code
│   ├── transport_layer/    #   ETCP, сессии, crypto, STCP/REALITY, SOCKS-клиент, NCD, BBR
│   ├── routing_layer/      #   Routing, группы/BGP, recovery, conn_mgr, etcp_router
│   ├── chat/               #   P2P чат, join, db_sync, merkle_sync, member_sync
│   ├── dm/                 #   Личные сообщения, E2E-вложения и offline-mailbox
│   ├── call/               #   Звонки и общий голосовой стек
│   ├── radio/              #   Групповая PTT-рация
│   ├── stream/             #   Прямые трансляции: подписанные RS-блоки, выбор поставщиков, аудио/видео
│   ├── member_files/       #   Файловое хранилище участников CHAT-группы и асинхронные передачи
│   ├── local_transport/    #   Обнаружение устройств и доставка приглашений в локальной сети по UDP
│   ├── proxy/              #   SOCKS5, TCP/UDP/ICMP прокси
│   ├── lwip_tcp/           #   Встроенный lwIP TCP стек
│   ├── media_delivery/     #   Блоки медиа каналов и передача неизменяемых файлов
│   ├── media_async/        #   Фоновые задачи, метаданные вложений, подготовка голоса/видео
│   ├── video/              #   Пробинг и транскодирование видео через FFmpeg
│   ├── dnsmasq/            #   Архив исходников для встроенной сборки dnsmasq
│   └── *.c/h               #   utun, instance, config, TUN, firewall, NAT, NTP, control, broadcast
├── tests/                  # Состав тестов и цели запуска: tests/Makefile.am
├── doc/                    # Technical Specifications
├── tools/                  # Auxiliary tools
│   ├── etcpmon/            # GUI монитор ETCP
│   ├── chatgui/            # GUI чат (Qt 6 с Qt 5 fallback, сборка CMake)
│   ├── chatgui-android/    # Android P2P чат (Jetpack Compose + libutun_lite)
│   ├── logreceiver/        # Приём UDP-логов Android
│   ├── chat_tcp_test/      # Сценарий проверки чата через TCP
│   ├── lightsout/          # Отдельная игра Lights Out на Qt
│   ├── lightsout-android/  # Android-версия Lights Out
│   ├── tdesktop-dev/       # Референс: Telegram Desktop (только для изучения)
│   ├── proxy/              # UDP прокси для тестов
│   ├── bping/              # BPing (bandwidth ping)
│   └── chatcli             # Headless CLI; описание команд — chatcli_commands.txt
├── tinycrypt/              # TinyCrypt crypto library (external)
└── net_emulator/           # Network emulator (delays, loss, reordering)

File Overview

Пути ниже относительны к каталогу секции; name.c/h означает пару .c и .h. Перечислены модули проекта; внутренние файлы сторонних библиотек сгруппированы по каталогам.

Core (src/)

  • utun.c - Main program entry point, CLI parsing, daemon mode
  • utun_instance.c/h - Создание ядра и независимый жизненный цикл UTUN/чата, владение общими ресурсами
  • tun_if.c/h - TUN interface API (init/write/close, cross-platform)
  • tun_linux.c tun_freebsd.c tun_windows.c - Platform-specific TUN implementations
  • tun_route.c/h - TUN routing table sync
  • config_parser.c/h - INI-style config file parsing
  • config_updater.c/h - Проверка и сохранение согласованных X25519-ключей и node_id в INI-конфиге
  • control_server.c/h - Control/monitoring server (etcpmon backend API)
  • firewall.c/h - Firewall rules (per-interface filtering)
  • eim_nat.c/h - Endpoint-Independent Mapping NAT engine
  • nat_transport.c/h - Передача IPv4 между отдельным TUN и удалённым NAT-провайдером через UTUN-router; локальный провайдер использует eim_nat
  • ntp_time.c/h - Асинхронная NTP-синхронизация: поправка времени instance без изменения часов ОС
  • ntp_node_time.c/h - Получение временной поправки от синхронизированных ETCP-пиров и диагностика расхождения часов
  • broadcast.c/h - Широковещательная рассылка данных по topo-группе (UUID-дедупликация, TTL)
  • video/video.c/h - Пробинг и транскодирование видео (FFmpeg, опционально; H.264/MP4 ≤720p)
  • dnsmasq/ - Архив dnsmasq-2.93.tar.xz для встроенной сборки

Transport Layer (src/transport_layer/)

  • etcp.c/h - ETCP protocol implementation (inflight queues, retrans, ACK, RTT/jitter)
  • etcp_api.c/h - ETCP public API (send/recv/bind callbacks)
  • etcp_connections.c/h - Socket and link management, INIT handshake, keepalive, PING/PONG
  • etcp_session.c/h - Согласование эпох ETCP-сессии через HELLO/CHALLENGE/CONFIRM и проверка принадлежности DATA сессии
  • etcp_loadbalancer.c/h - Multi-link load balancing with traffic shaper
  • etcp_debug.c/h - Диагностический разбор секций ETCP_DGRAM и форматирование IPv4-адресов
  • etcp_dump.c/h - ETCP дамп/декодирование пакетов
  • etcp_bbr.c/h - BBR congestion control for ETCP
  • etcp_connect.c/h - ETCP outbound connections
  • etcp_keepalive.c/h - Keepalive-пакеты, адаптивный период, смена режима standby/normal (мобильные узлы)
  • auto_socket.c/h - Автосоздание UDP+TCP сокетов на всех интерфейсах и линков к ETCP-соединениям (auto_sockets=yes)
  • pkt_normalizer.c/h - Packet fragmentation/reassembly (packer/unpacker)
  • packet_dump.c/h - Текстовая сводка IPv4-пакета: адреса, поля транспорта и короткий hex-фрагмент
  • dummynet.c/h - Двунаправленный UDP-эмулятор между заданными endpoint: задержка, ограничение скорости и случайные потери
  • secure_channel.c/h - X25519, пакетное AES-128-CCM, потоковое AES-CTR, подписи Ed25519 и обфускация публичного ключа
  • etcp_padding.c/h - Выбор длины случайного padding и периодическое обновление диапазона для instance/соединения
  • etcp_tx_stats.c/h - Общая статистика исходящих очередей, inflight и подтверждённых за секунду байтов ядра
  • crc32.c/h - CRC32 checksums
  • stcp.c/h - Зашифрованные кадры поверх TCP: согласование ключей/эпох, AES-CTR, CRC, очереди и закрытие соединения
  • stcp_server.c/h - Приём входящих STCP-соединений, handshake и передача готового соединения владельцу
  • stcp_client.c/h - Исходящее STCP-подключение, в том числе через SOCKS5 и REALITY
  • stcp_link.c/h - Подключение STCP к ETCP_LINK: передача пакетов, backpressure и жизненный цикл TCP-линка
  • socks_client.c/h - Исходящий SOCKS5-транспорт: TCP CONNECT и UDP ASSOCIATE с переподключением control-сокета
  • node_conn_direct.c/h - Общий прямой транспорт к пиру с отдельным handle каждого владельца; обновление линков по адресам узла
  • socket_monitor.c/h - Наблюдение за адресами интерфейсов и маршрутами ОС, обновление сетевого состояния ETCP-сокетов
  • reality.c/h - REALITY-style TLS ClientHello/ServerHello камуфляж для STCP
  • reality_fingerprint.c/h - Статические отпечатки (cipher suites, groups, ALPN) для REALITY-камуфляжа
  • reality_io.c/h - Внешний REALITY-handshake и поток защищённых записей STCP, Finished, replay-защита и выбор relay
  • reality_record.c/h - TLS-подобные AES-128-GCM записи: вывод ключей, счётчики направлений, padding и KeyUpdate
  • reality_relay.c/h - Релей неавторизованных клиентов на реальный HTTPS-сайт
  • stun_nat.c/h - Проверка mapping/filtering NAT через внешние STUN-серверы, RFC 5780 и кеш результатов по IP/интерфейсу
  • call_ring.c/h - Кольцевой трейс контрольных точек освобождения ETCP/STCP-ресурсов для диагностики teardown/UAF

BBR (src/transport_layer/BBR/)

  • bbr_v3.c - BBR congestion control algorithm v3

Routing Layer (src/routing_layer/)

  • routing.c/h - Обмен IPv4-пакетами UTUN между локальным TUN и сервисом DATA ETCP-router
  • route_lib.c/h - Локальная таблица IPv4-подсетей UTUN: добавление/удаление маршрутов и поиск узла назначения
  • route6_lib.c/h - Локальная таблица IPv6-подсетей на radix tree с поиском по самому длинному префиксу
  • route_ping.c/h - Пинг цели через явно выбранного BGP-посредника для NAT-проверки
  • route_connectivity.c/h - Прямые UDP/TCP-пробы адресов узла для оценки достижимости и RTT при выборе пиров
  • topo_group.c/h - Сессии UTUN/CHAT (JOIN/ACCEPT, эпохи, READY), групповые запросы, NODEINFO/WITHDRAW и владение NCD
  • topo_group_connect.c/h - Подбор пиров CHAT-группы по роли: суперузлы → desktop → mobile; история/RTT внутри класса, backoff и standby burst
  • topo_group_invite.c/h - Получение описания канала через INVITE_INFO_REQ/RESP; добавление мембера реализовано в chat_join/chat_sync
  • topo_node.c/h - Модель TOPO_NODE/TOPO_GROUP_NODE, подписанные снимки узлов, сериализация и общий node_registry
  • topo_node_sqlite.c/h - Хранение подписанных снимков узлов, адресов, каналов и блоков мемберов в общей SQLite
  • topo_recovery.c/h - Восстановление потерянных маршрутов группы через READY-сессии, отмена попыток при stop
  • conn_mgr.h + conn_mgr_core.c/conn_mgr_indirect.c/conn_mgr_monitor.c + conn_mgr_priv.h — Connection Manager (handle-based API, 3-phase DIR/REV/IND)
  • etcp_router.c/h - Надёжные логические каналы сервисов поверх BGP-маршрутов: ACK, окна, транзит и защита от циклов
  • route_tx_stats.c/h - Скользящее окно подтверждённых payload-байтов логического канала для оценки скорости доставки
  • multicast.c/h - Рассылка списку узлов группы с разделением маршрута на ветви, локальными подписками и отчётами о потерях
  • nat_detection.c/h - Проверка mapping и доступности входящих рабочих сокетов через ETCP-пиров с учётом предварительных STUN-измерений
  • address_profile.h - Профиль endpoint: изменение адреса, доступность входящих и источник измерения ETCP/STUN
  • sock_match.c/h - Классификация локальных сокетов и адресов пира, отбор совместимых пар для прямого подключения
  • route_crypto.c/h - Пред/пост-обработка SVC_ROUTE пакетов (encrypt-then-sign)

Chat (src/chat/) — децентрализованный P2P чат: сообщения и участники автоматически синхронизируются между всеми узлами канала без центрального сервера.

  • chat_core.c/h - API сообщений, каналов, профиля и настроек; chat_service_start/stop управляют чат-сервисом поверх общей БД ядра
  • chat_core_priv.h - Внутренний API для частей chat_core: общий контекст и утилиты БД. Снаружи не используется
  • chat_sync.c/h - Связывает чат с ETCP-сетью: отслеживает появление/разрыв соединений, обновляет онлайн-статус узлов, запускает синхронизацию участников каналов, обрабатывает приглашения
  • chat_event.c/h - Доставка событий из ядра чата в GUI. Единый механизм: любой модуль отправляет событие (новое сообщение, смена участников, статус), GUI получает через один обработчик
  • chat_setting.c/h - Проверка и хранение настроек чата per-instance; общая логика для конфигурации и GUI
  • chat_join.c/h - Регистрация invite-ключа с ACK, пересылка запроса инвайтеру и добавление подписанного мембера; контракт join в заголовке
  • db_sync.c/h - Репликация подписанных записей SQLite через прямые ETCP-соединения; расхождения по цепочке хешей, новые записи через PUSH
  • member_sync.c/h - Синхронизация участников каналов поверх merkle_sync. Два подписанных блока (мембер/владелец), по-блочное сравнение версий, верификация подписей. Удаление — только битая запись
  • merkle_sync.c/h - Универсальный движок синхронизации на Merkle-деревьях (5 уровней × 32 бакета, SHA256). Пиры обмениваются хешами и передают только различия; per-session out-очередь с backpressure. Не привязан к конкретному типу данных (коллбэки data_ops)
  • merkle_tree.c/h - Производный индекс Merkle-хешей в SQLite; восстанавливается из данных модели, обновляется с ними в одной транзакции
  • chat_profile.c - Подписанный профиль мембера: имя, аватар и опции сервисов; локальное UI-состояние (часть chat_core)
  • chat_channel.c - Создание и настройка каналов: таблицы, криптоключи, CHAT-группа и планировщик подключения (часть chat_core)
  • chat_msg.c - Отправка и приём сообщений: запись в локальную БД, автоматическая рассылка всем участникам канала (часть chat_core)
  • chat_feedback.c/h - Подписанные реакции и ответы: версии состояния, сохранение отмен и Merkle-синхронизация между участниками
  • chat_poll.c/h - Создание опросов, голосование, реакции и JSON-снимки результатов для UI/headless
  • chat_poll_codec.c - Проверка и wire-кодеки опросов, ответов и реакций; общий каталог эмодзи (API в chat_poll.h)
  • chat_attachment.c/h - Зашифрованные вложения канала: ключи, запросы доступа, ручное одобрение автора и сохраняемый outbox
  • chat_local.c/h - Обнаружение устройств чата и обмен готовыми invite-ссылками через локальный UDP-транспорт
  • group_avatar.c/h - Подписанная аватарка канала: хранение версии в SQLite, проверка подписи и передача блоков через router
  • chat_status.c - Сбор диагностики: текущее время, активные соединения, типы NAT. Отправляется в GUI (часть chat_core)
  • chat_member.c/h - Единая структура мембера для отображения в GUI (десктоп/headless/Android), фиксированная сериализация на проводе
  • chat_admin.c/h - Передача канального приватного ключа (прав админа) другому узлу
  • chat_whisper.c/h - Whisper speech-to-text транскрипция голосовых сообщений (опционально, асинхронно через media_async)
  • chat_headless_control.c/h - TCP control-socket для headless chat CLI (JSON line protocol)
  • invite_build.c/h - Сборка invite-ссылок utun:// (выбор лучшего узла + адреса)
  • invite_link.c/h - Кодирование utun://: версия, пароль, channel_id, join_key, Reality-параметры, ключ и адреса узла

Личные сообщения (src/dm/)

  • dm_core.c/h - Беседы двух узлов, подписанные E2E-сообщения, SQLite/outbox, доставка через router/mailbox и квитанции
  • dm_crypto.c/h - Вывод ID беседы и ключа X25519, AES-256-CCM сообщений и E2E-контейнеры медиа через media_crypto
  • dm_history.c/h - Локальное удаление истории и скрытие бесед; поколения задач и отпечатки удалённых сообщений против повторов
  • dm_mailbox.c/h - Offline-очередь суперузла: хранение подписанных сообщений и повтор доставки до квитанции получателя
  • dm_media.c/h - Подготовка, доставка и публикация E2E-вложений; ciphertext-хранилище и отдельные квитанции файлов
  • dm_media_priv.h - Внутренние SQL/control-операции для dm_media и dm_mailbox_media
  • dm_mailbox_media.c/h - Сохраняемые задания суперузла для размещения медиа, доставки метаданных и удаления копий до DELETE_ACK

Звонки (src/call/)

  • call.c/h - P2P аудио/видеозвонок: подписанный E2E-сигналинг, состояния, политика занятости и оптимизация пути через conn_mgr
  • call_priv.h - Общее внутреннее состояние сессии для call.c и call_video_transport.c; доступ только из uasync
  • call_proto.h - Wire-формат сигналинга, аудиокадров и управления видеотреком; треки/кодеки и причины завершения
  • call_audio.c/h - Общий аудио-движок: кодирование/декодирование Opus, jitter-буфер и тоны, API feed/pull PCM
  • call_jitter.cpp/h - FIFO Opus, адаптивный сетевой запас, декодирование на pull и восстановление воспроизведения после пауз
  • call_jitter_window.h - Окно из десяти секундных интервалов для оценки глубины очереди и изменения задержки доставки
  • call_clock.h - Метки времени захвата и снимок реально проигранного аудио для синхронизации видеотрека
  • call_delay.cpp/h - Уменьшение накопленной задержки PCM прямым ускорением и SoundTouch с сохранением исходной шкалы времени
  • call_timeline.cpp/h - Карта исходного PTS через обработку SoundTouch до позиции аудиоустройства
  • call_video.c/h - Общий формат H.264/H.265 видеотрека, согласование возможностей и сборка кадров из фрагментов
  • call_video_bitstream.c/h - Проверка конфигурации и IDR без reorder, профиля/уровня и геометрии H.264/H.265; KEY-пробы кодеков
  • call_video_transport.c/h - Отдельные router-каналы control/audio/video, backpressure, привязка видео к аудио и запросы KEY
  • call_video_rate.c/h - Регулятор битрейта и допуска новых видеокадров по скорости доставки, RTT и долгу очереди
  • call_video_port.c/h - Потокобезопасный обмен кадрами и командами между платформенными video workers и uasync-транспортом
  • call_video_playout.c/h - Расписание показа по аудиочасам, ожидание/отбрасывание кадров и подтверждение фактического показа
  • call_video_fixtures.h - Встроенные H.264/H.265 KEY-пробы для проверки базовых режимов кодека
  • call_video_fast_fixtures.h - KEY-пробы видеорежимов с частотой 60 fps
  • call_video_fullhd_fixtures.h - KEY-пробы видеорежимов Full HD
  • call_video_portrait_fixtures.h - KEY-пробы видеорежимов в портретной ориентации
  • call_tones.c/h - Генерация PCM-тонов паузы и завершения звонка
  • call_headless.c/h - Отдельный TCP-аудиосокет headless-клиента: обмен PCM; сигналинг остаётся на control-сокете

Рация (src/radio/)

  • radio.c/h - Передача Opus по CHAT-группе, подписки, дедупликация и пересылка по ветвям с подписчиками
  • radio_proto.h - Wire-формат PTT: источник, поток, seq, FIN и hop-list против циклов
  • radio_audio.c/h - Общий аудио-движок: независимые RX/TX, Opus, микширование источников, ручной PTT и VAD-автомат
  • radio_jitter.cpp/h - Буфер кодированных кадров каждого источника с pre-roll и SoundTouch time-stretch на pull
  • radio_vad.h - Ресемплинг 48→16 кГц и автомат авто-PTT с подтверждением речи, задержкой завершения и учётом занятого канала
  • radio_auto.h - Общий автомат автопередачи по VAD/уровню звука, без захвата аудио и сетевого I/O
  • radio_call.c/h - Адресное приглашение участника в рацию канала: сигналинг вызова, занятость, принятие и отмена
  • radio_headless.c/h - TCP-аудиосокет headless-рации: PCM и команды начала/конца PTT

Прокси (src/proxy/)

  • proxy_protocol.h - Общий TCP-протокол и управление потоком: CONNECTED, DATA, кредит WINDOW, упорядоченный FIN
  • socks_proxy.c/h - Клиентские SOCKS5 CONNECT и HTTP proxy/CONNECT, DNS и передача потока выбранному exit-узлу
  • http_proxy.c/h - Потоковый HTTP/1.x кодек: проверка заголовков, разбор тела/chunked и учёт потреблённых байтов для WINDOW
  • udp_proxy.c/h - Передача UDP из TUN через exit-узел, сопоставление ответов и удаление неактивных потоков
  • icmp_proxy.c/h - Проксирование IPv4 ICMP echo через raw socket exit-узла с восстановлением исходных id/seq
  • tcp_proxy_server.c/h - Exit-сторона TCP-прокси: реальные исходящие сокеты, потоки по (peer, stream_id), окна и half-close
  • tcp_proxy_client.c/h - Клиентская сторона TCP-прокси: адаптер TUN/lwIP и обмен с настроенным exit через ETCP-router

lwIP TCP (src/lwip_tcp/)

  • lwip_tcp.c/h - lwIP TCP стек
  • lwip_tcp_out.c / lwip_tcp_in.c - Исходящий/входящий трафик
  • lwip_pbuf.c/h - Пакетные буферы lwIP
  • lwip_tcp_priv.h, lwip_tcp_opts.h - Внутренние настройки lwIP

Media Delivery (src/media_delivery/)

  • media_delivery.c/h - Доставка блоков медиа каналов, учёт держателей, репликация доступности между суперузлами и relay
  • media_delivery_proto.h - Кодограммы канального медиа: QUERY, BLOCK_REQ/CHUNK/DONE, HAVE_BLOCK и SUPER_REPL
  • media_download.c/h - Загрузка блоков с выбором держателей, failover, контролем простоя, проверкой подписей и сборкой файла
  • media_index.c/h - Индекс media_files: UUID, хеши и подписи блоков, асинхронная регистрация и удаление медиа канала
  • file_transfer.c/h - Передача неизменяемого файла между заданными узлами; авторизация lookup и владение CM handle до завершения

Media Async (src/media_async/)

  • media_async.c/h - Фоновые crypto/file-задачи: work в pthread, done в uasync; destroy ждёт workers и завершает ожидающие callbacks с CANCELLED
  • attachment.c/h - Общие метаданные file/voice/video, проверка и компактная wire-сериализация
  • voice_file.c/h - Worker-кодирование PCM в контейнер Opus с длительностью и waveform для desktop/Android
  • attachment_send.c/h - Асинхронная подготовка голоса/видео и отправка в зафиксированный канал или DM
  • media_crypto.c/h - Общие AES-256-CCM примитивы и порционное шифрование/проверка файлов для DM и групповых вложений
  • encrypted_file.c/h - Контейнер группового вложения: шифрование метаданных/файла, проверка SHA256 и durable-публикация результата

Трансляции (src/stream/) — live-аудио/видео CHAT-группы с подписью источника, Reed–Solomon и раздачей через участников.

  • stream.c/h - Жизненный цикл трансляции, локальные handles издателя/читателей, события и публикация подписок
  • stream_priv.h - Внутренний доступ к сессиям, приём проверенных DATA/END и взаимодействие с планировщиком relay
  • stream_proto.h - Форматы подписанной пачки и RS-частей, дескриптор источника, размеры и коды результата
  • stream_block.c/h - Подпись пачки Ed25519 до RS-кодирования, разбор частей и проверка восстановленных данных
  • stream_buffer.c/h - Ограниченное кольцо RS-частей: дедупликация, восстановление пачек, проверка подписи и вытеснение старых данных
  • stream_source.c/h - Упаковка исходных байтов в подписанные RS-пачки, сброс неполной пачки по таймеру и завершение источника
  • stream_member.c/h - Объявления источников и подписок в опциях подписанного мембера; разбор и проверка принадлежности источника
  • stream_wire.c/h - Протокол выдач и relay: кодограммы управления, пути, метрики и подписанное завершение END
  • stream_network.c/h - Выдача блоков через прямой ETCP, NCD-владение, управляющие очереди, аренда подписок и reverse-запросы
  • stream_optimizer.c/h - Автоматический выбор и перенос поставщиков субпотоков, пробы доступности и привлечение relay
  • stream_metrics.c/h - Оценка относительного отставания субпотока и истории проблем по часам источника без NTP
  • stream_load.c/h - Учёт логической очереди DATA и её роста для обнаружения перегрузки раздающего узла
  • stream_media.c/h - Формат uAV2: упаковка/проверка видеокадров, конфигурации кодека, PTS и Opus внутри FEC-пачек
  • stream_media_buffer.c/h - Медиаиндекс общего RS-кольца и независимые курсоры audio/video; сборка кадров и восстановление с KEY
  • stream_publisher.c/h - Общий потокобезопасный publisher desktop/Android: очередь готовых кадров, публикация и завершение с FIN
  • stream_viewer.c/h - Независимые viewers: запрос ограниченных батчей по бюджетам треков, уведомления готовности и конца audio/video
  • stream_playback_audio.cpp/h - Opus/SoundTouch и очередь готового PCM; ускорение без изменения высоты и привязка к позиции устройства
  • stream_playback_clock.c/h - Общие часы воспроизведения и плавный догон live-потока по непрерывному запасу готового материала

Файлы участников (src/member_files/)

  • member_files.c/h - Сервер и асинхронный клиент хранилища CHAT-группы: права доступа, запросы и события через защищённый router
  • protocol.c/h - Wire-кодек файловых команд, снимки версий каталогов/файлов и токены временных загрузок
  • storage.c/h - Серверные каталоги участников, квоты, файловые операции, временные загрузки и их очистка
  • transfer.c - Передача файлов с CM handle, backpressure, дисковым worker, проверкой хеша и публикацией результата
  • disk.c/h - Дисковые примитивы POSIX/Windows: безопасное разрешение путей без ссылок и I/O по 64-битному смещению
  • worker.c/h - Единственный дисковый pthread с ограниченной очередью и возвратом результатов в uasync
  • private.h - Внутреннее состояние запросов, передач, серверного хранилища и дискового worker

Локальная сеть (src/local_transport/)

  • local_transport.c/h - Открытый UDP-транспорт LAN: обнаружение устройств, доставка сообщений с ACK/повторами и ограничения входящего потока
  • platform.c/h - Снимок IPv4/IPv6 интерфейсов, broadcast/multicast-адреса, приём метаданных UDP и проверка локальности источника
  • protocol.h - Wire-формат объявлений, сообщений и ACK: ID/эпохи устройств, ID запроса и проверка UTF-8 имени

Libraries (lib/)

  • u_async.c/h - Async event loop (epoll/poll/select, timers via timeout_heap)
  • ll_queue.c/h - Двусвязная очередь одного uasync-потока с callbacks, хеш-индексом и ожиданием свободного места
  • memory_pool.c/h - Пул объектов: ленивое выделение и повторное использование, до 64 свободных объектов в кеше
  • debug_config.c/h - Debug logging system (levels, categories, dual output, runtime config)
  • timeout_heap.c/h - Min-heap for timer management (used by u_async)
  • mem.c/h - Memory wrappers with leak tracking (u_malloc/u_free/u_calloc/u_strdup)
  • serialize.c/h - Binary serialization utilities
  • reed_solomon.c/h - Кодирование и восстановление пачки данных Рида—Соломона с настраиваемым числом субблоков и избыточностью
  • video_plane.c/h - Копирование YUV-плоскости с поворотом 0/90/180/270°, учётом stride и проверкой границ без выделения памяти
  • swm_min.c/h - Sliding window minimum (for RTT min tracking)
  • getmyip.c/h - Локальный IP, который ОС выберет для UDP к заданному адресу (bind/connect/getsockname)
  • myip.c - My IP helper (no header)
  • socket_compat.c/h - Cross-platform socket compatibility (Linux/FreeBSD/Windows)
  • platform_compat.c/h - Cross-platform compatibility layer (byte order, time, random)
  • radix.c/h - Radix tree for IP routing lookups
  • tcp_io.c/h - Неблокирующий TCP поверх uasync/ll_queue: backpressure, FIN/close и callbacks
  • sqlite3.c/h - SQLite3 amalgamation (embedded database)
  • opus_codec.c/h - Opus audio codec wrapper
  • audio_compressor.c/h - Audio dynamic range compressor
  • speex_aec.c/h - Эхоподавление SpeexDSP: согласование playback/capture PCM через линию задержки и диагностика её заполнения
  • silero_vad.c/h - Стриминговый VAD через ONNX Runtime: окна 512 отсчётов, 16 кГц моно, вероятность речи и сброс состояния
  • silero_vad_model.inc - Встроенная ONNX-модель Silero VAD для silero_vad_create_default
  • json_flat.c/h - Flat JSON parser
  • strbuf.c/h - Безопасный растущий printf-буфер (замена snprintf-цепочек)
  • async_dns.c/h - Асинхронный (неблокирующий) DNS-резолвер A-записей поверх uasync, адаптер над libdns
  • dns.c/h - Рекурсивный reentrant DNS-резолвер (libdns, MIT)
  • miniaudio.h - Воспроизведение/захват аудио (single-header)
  • dr_mp3.h - MP3-декодер (single-header, на базе minimp3)
  • liblmdb/ - Встраиваемый key-value store LMDB
  • libopus/ - Встраиваемый кодек Opus
  • speexdsp/ - Встроенные исходники эхоканселлера SpeexDSP и KISS FFT
  • soundtouch-master/ - SoundTouch: изменение темпа аудио в jitter-буферах звонка и рации
  • wintun.h - Wintun API header for Windows TUN driver

Проверки (tests/)

  • Makefile.am - Состав тестовых целей, зависимости и отдельные проверки runner, service IDs и скрипта сборки
  • run_tests.py - Запуск тестов ограниченным пулом с отдельными логами и последовательными барьерами для CPU/LAN-проверок
  • test_run_tests.py - Проверки пула runner, эксклюзивного запуска, обработки ошибок и сигналов
  • test_service_ids.py - Проверка уникальности ID транспортных и router-сервисов
  • test_build_script.py - Регрессии выбора платформы, конфигурации и инкрементальной работы build.sh
  • stream_netns/ - Linux network namespaces: топологии, NAT/STUN-сценарии и проверка трансляций в изолированной сети
  • local_transport_ipv6.sh - Проверка IPv6 link-local обнаружения и доставки в изолированной локальной сети

Memory Pools in UTUN_INSTANCE:

  • data_pool — для данных пакетов (payload), используется input_queue/output_queue фрагментами
  • pkt_pool — для struct ETCP_DGRAM (сетевые пакеты на отправку/приём)
  • ack_pool — для struct ACK_PACKET (подтверждения приёма)

Key Components

  • UASYNC: One per thread. Async event loop (epoll/poll), timers via timeout_heap
  • LL_QUEUE: Очередь с auto-callback, хеш-индексом и threshold waiter; не средство обмена между потоками
  • Memory Pool: Fast allocation for hot-path objects (packets, inflight entries, fragments)
  • ETCP: TCP-like reliable protocol with encryption, multi-link, load balancing
  • Secure Channel: AES-CCM + X25519 key exchange, nonce-based encryption, pubkey obfuscation

Queue Usage Rules

Работа с очередями. Важно!

С очередью следуею работать придерживаясь следующих правил:

  • при сетевом обмене не забиваем очередь. всегда используем Пороговое ожидание (backpressure).
  • для работы с очередью полностью загрузи ll_queue.h и пойми как работает.

Запись в очередь

  • Очереди забивать нельзя. Добавляй следующий элемент только когда очередь стала пустой.
  • Порог задаётся через queue_set_threshold(q, max_packets, max_bytes).
  • Используй queue_waiter_wait для ожидания освобождения очереди до заданного порога.
  • Handle ожидания обнуляется целиком, живёт до callback/отмены и отменяется до освобождения владельца. Callback может быть синхронным. queue_entry_free не освобождает dgram — его освобождают отдельно.

Чтение из очереди

  • Используй queue_set_callback: при вызове callback обработай один или несколько элементов, потом вызови queue_resume_callback.
  • Внутри коллбэка ОБЯЗАТЕЛЬНО: queue_data_get(q) → обработать элемент → queue_resume_callback(q)
  • Без вызова queue_resume_callback очередь навсегда застрянет

Поиск

  • queue_data_put_with_index(q, entry) — добавляет с индексом для быстрого поиска (offset/size заданы при queue_new)
  • queue_find_data_by_index(q, key) — поиск по индексу через хеш-таблицу (размер ключа из q->index_size)

u_async Rules

  • Нельзя использовать в одном потоке несколько u_async. Один поток = всегда 1 uasync instance
  • Нельзя использовать sleep/usleep если есть uasync. Нужно использовать uasync_set_timeout.
  • Таймеры: uasync_set_timeout(ua, timeout_tb, arg, callback, name) — timebase units (0.1ms) Возвращает void* handle, отмена: uasync_cancel_timeout(ua, handle).

Config Rules

  • В серверном конфиге только собственные ключи и нет секций [client]
  • В клиентском конфиге есть собственные ключи и pubkey каждого сервера в секции [client]
  • Chat-настройки хранятся в [chatserver] (также [chat]). Парсер обрабатывает общие поля секции, затем вызывает chat_setting_set_state(&cfg->global.chat_settings, key, value); неизвестные ключи логируются как ошибка. Пример:
    [chatserver]
    storage_autoload=1
    storage_unit_size=10M
    storage_total_size=1G
    opus_codec_preset=1
    compressor_enabled=0
    compressor_max_gain_db=25
    compressor_rise_rate=10
    media_download_max_peers=3
    

Bugs Debugging Protocol

Всегда когда начинаешь диагностику ознакомься со скиллом (используй skills) Диагностика и поиск ошибок - это в первую очередь продумывание отладочных механизмов которые покажут понятную картину и точное представление об ошибке. Рассуждать надо как диагностикой добиться точной картины. И как приавльнее добавить диагностику чтобы не спамила лишними сообщениями и была понятной, логичной и информативной.

Важное правило отладки: вся отладка сводится к тому чтобы сделать удобные логи которые наглядно показывают поведение и проблемы. без лишнего мусора, компактно и по существу. очень желательно с деталями которые сильно повышают качество отладки. при отладке нельзя: гадать и долго пытаться разбирать код пытаяясь найти причину. гораздо надёжнее с помощью логов понято точное поведение. Если логов много - записывай в файл и потом анализируй. Если видишь спам-логи - подумай как их выборочно отключить чтобы не мешали.

Для отладки добавляй в DEBUG_CATEGORY_DEBUG диагностические сообщения где надо. И включи эту категорию в настройках. Убирай только после проверки (путём запуска) когда все ошибки устранены. Явный уровень категории заменяет глобальный. DEBUG_LEVEL_NONE наследует глобальный уровень; DEBUG_LEVEL_DISABLED полностью отключает категорию, в том числе при глобальном TRACE (см. debug_should_output).

Твой бич - ты постоянно гадаешь и анализируешь код. Что приводит к снежному кобу ошибок и неверных гипотез. 10 раз повторяю - только логи логи логи и никакого гадания. Лоооги!!! правильные логи покажут всё с предельной точностью. Вся суть отладки - информативные логи И смотри логи. не задавливай их grep-ом. лучше больше. единственное с чем борись - это бесполезные спам логи. Проблемы часто не там где их ищешь. Поэтому анализируй более полно логи и приглядывайся к любым подозрительным местам. А не одну строку выгребай грепом безуспешно по 10му кругу когда реальная проблема в другом месте. Ты часто как слепой котёнок не смотришь по сторонам, пытаясь найти проблему где сам придумал и логично что ничего не получается. Правльный подход: оптимиировать логи под конкретный баг. Убрать спам и вывести всё что относится к отлаживаемому механизму со всеми нужными подробностями. Прогнать и внимательно проанализировать ВЕСЬ это лог. Если он слишком большой - думай как выводить только нужное не в ущерб информативности.

Но полезные смотри всегда, и всегда оставляй логи которые выводятся нечасто. Частые логи - это трафик которые >100 раз повторяются. Но которые мало раз обязательно оставлять и выводить. В тесте можно временно поднять нужные категории до TRACE, сохранив прежние уровни и восстановив их после участка. Одного debug_set_level(DEBUG_LEVEL_NONE) недостаточно для отключения категорий с явно заданным уровнем. Если видишь проблему и ее решение неочевидно то выстраивай диагностику вокруг неё пока не будет очевидно где и что происходит не так. Это базовое и обязательное требование к отладке. Подробные логи ты должен выводить не обрезая всегда и анализировать. Если лог большой - выведи в файл и анализируй файл. Рассуждение должно быть примерно таким:

  • данные повреждаются при отправке.
  • где и почему непонятно. надо продумать ключевые точки где получим максимум полезной информации и не было большого объёма вывода лога.
  • где лучше? каждый пакет логировать - много, но будет предельно точная картина
  • Еще хорошо бы время - так мы заодно сможем найти проблемы с производительностью, найти проблемные места застревания кода.
  • Но это большой объём. Можно ли без него? можно но это будет малоэффективно и хороших альтернатив пока не видно.
  • Значит логируем весь трафик, а заодно включим полную трассировку функций.
  • Запустили. Записали весь процесс в файл. Теперь можно анализировать. Давай сперва посчитаю количество строк с дампом: ... 50000.
  • давай сделаю простой скрипт который дамп прочитает и сохранит в файл. И сверю с оригинальным файлом
  • Давай заодно возьму произвольный фрагмент лога и изучу еа предмет явных проблем. Особенно инициализацию и освобождение ресурсов. Сколько времени занимает, нет ли заклиниваний, нет ли ошибок или странностей

Диагностические сообщения (DEBUG_WARN DEBUG_ERROR)

Сообщения должны говорить что случилось и с какими деталями. Обязательно выводить подробные собощения об ошибках (даже если нужен небольшой дополнительный код чтобы эти детали сформировать и привести в читаемый вид). Полезны подробности об инициализации-завершении которые помогают понять внутренние состояния Диагностические сообщения - важный момент. надо про диагностику помнить. Для хорошей диагностики надо проанализировать как архитектор - какие есть нюансы в архитектуре и что полезно будет видеть в дебаг выводе чтобы понять полную картину происходящего.

Запрещено (опыт 2026-07-31 — потеря всех некоммиченных изменений):

  • git checkout -- <wildcard> / git checkout -- src/ — безвозвратный откат ВСЕХ файлов
  • sed для массовых правок исходников — замены разъезжаются, ломают код, часы на восстановление
  • Пакетные замены через Bash в 10+ файлах одновременно
  • Повторять эти ошибки: потеря + попытка отката git checkout = двойная потеря

Правила безопасного рефакторинга:

  1. Правки ТОЛЬКО через Edit tool — одна точечная замена с контекстом
  2. После каждого файла → git add <file>
  3. Каждые 2-3 файла → git commit -m "..." (не дожидаясь сборки)
  4. Никакого sed / awk / perl -i для правки исходников
  5. Перед откатом → сначала коммит всего, потом git revert конкретного коммита

Прочие правила:

  • sed для редактирования исходников - запрещено
  • Проверяй на дублирование кода - не сделано ли это уже в другом месте
  • Не делай функций-посредников: лучше сразу вызывать target функцию без вложенных вызовов
  • Нельзя ничего восстанавливать из репозитория не спрашивая
  • Для отладки не printf а DEBUG_*
  • Запрещено прямое включение arpa/inet.h, sys/time.h, unistd.h — использовать ../lib/platform_compat.h + socket_compat.h
  • Меняй режим и флаги сборки через ./build.sh: он отслеживает конфигурацию и очищает объекты только при необходимости.
  • Все лишнее что менял при отладке - строго вернуть назад в состояние до вмешательства

Написание кода

  • Строго обязательно наличие ERROR сообщений во всех ошибочных ветвях алгоритма
  • Обязательно наличие диагностических сообщений в ветках инициализации-очистки, с информацией которая позволяет оценить наиболее полно внетренние состояния на момент печати сообщения. Например выявить неправильные состояния, неинициализированные поля итд
  • Обязательно наличие подробной диагностики в функциях кода которые не сильно спамят (не часто вызываются).
  • Для каждого отладочного вывода подумай какая из доступной информация будет полезна чтобы можно было наиболее завершенно оценить состояние алгоритма и состояний влияющих на алгоритм.

Оформление кода

  • в .c: перед каждой функцией - краткое но понятное описание что делает функция (кроме совсем простых)
  • в .h: в начале - описание модуля - для чего предназначен, как пользоваться, нюансы. Далее структуры с комментариями, далее публичные функции с описаниями (что делает, как пользоваться, какие аргументы, возврат, нюансы работы)

chatgui (GUI Chat Client)

Chatgui (бинарник vibechat) — десктопный чат на Qt 6 (Qt 5 fallback), отдельная CMake-сборка общего ядра. Корневой build.sh дополнительно вызывает её, если уже существует tools/chatgui/build/CMakeCache.txt.

GUI работает в Qt-потоке, ядро и чат — в uasync-потоке. Команды передаются через gui_bridge_post_uasync() / uasync_post(), события возвращаются через Qt-сигналы.

База данных sqlite в chatgui: можно писать (update) из потока utun / instance. можно только читать из gui потока.

Технологии

  • Язык: C++20
  • Фреймворк: Qt 6 (предпочитаемый) или Qt 5.15+ (Widgets + Network)
  • Сборка: CMake 3.16+
  • БД: SQLite3 (WAL mode, компилируется общий lib/sqlite3.c)
  • Анимации: rlottie (C API) + zlib (gzip-декомпрессия TGS)

Сборка

# Установка зависимостей
sudo apt install librlottie-dev zlib1g-dev qt6-base-dev libssl-dev libx11-dev libxfixes-dev libpipewire-0.3-dev
# или qtbase5-dev для Qt 5 fallback

# Сборка
cd tools/chatgui && mkdir -p build && cd build
cmake .. && make -j4
./vibechat

Конфиг и логи чатгуи

  • Конфиг: vibechat.cfg рядом с бинарником (обычно tools/chatgui/build/vibechat.cfg, содержит приватные ключи)
    • Секция [gui]: debug_file, debug_level, debug_categories=cat=level,...
    • Секция [control]: ip, port для подключения etcpmon
    • Секция [ntp]: синхронизация времени
  • Лог: tools/chatgui/build/chatgui.log (путь задаётся в конфиге debug_file)
  • БД чата: chats.db в каталоге [gui] db_path (по умолчанию chat_data/ рядом с бинарником)

Структура файлов (src/)

Файл Назначение
main.cpp Точка входа, QApplication, язык интерфейса и запуск единственного экземпляра профиля
single_instance.h/cpp Блокировка каталога профиля и передача запроса показа окна уже работающему экземпляру
gui_language.h Выбор языка интерфейса независимо от регионального формата дат и чисел
mainwindow.h/cpp Главное окно, каналы/DM, трей, события ядра, звонки, локальные приглашения и окна трансляций
chatview.h/cpp Список сообщений: фон, hover, выделение текста и прокрутка истории мышью/клавиатурой
messagelist.h/cpp Модель сообщений из БД, обновления доставки/медиа, анимации, состояние просмотра канала
messagedelegate.h/cpp QStyledItemDelegate: бабблы, текст, цитаты, реакции, оверлей анимаций
messagefeedback.cpp Действия MessageList: создание опроса, голосование, выбор реакции и показ результатов
attachment_key_ui.cpp Список запросов на расшифровку групповых вложений и решения автора о выдаче ключа
message_links.h/cpp Разбор границ utun:// и HTTP/HTTPS ссылок для подсветки и обработки нажатий в сообщении
message_notification.h/cpp Уведомление о сообщении без захвата фокуса, переход в беседу и скрытие после активности пользователя
user_activity_monitor.h/cpp Ожидание первой активности через системный idle time либо события приложения
emoji.h/cpp EmojiData/EmojiCategory/EmojiType, 4 категории, g_animatedEmojiMap
emojipanel.h/cpp Эмодзи-пикер: QTabWidget + QGridLayout, EmojiButton с hover-анимацией
emojitabbar.h/cpp Кастомный QTabBar для эмодзи-панели
inputbar.h/cpp Поле ввода (QTextEdit), вставка эмодзи, отправка по Enter
lottieicon.h/cpp Загрузка TGS (gzip→zlib), рендер кадров через lottie_animation_render
animtimer.h/cpp Синглтон-таймер 30fps, refcount activate/deactivate, сигнал ticked
channellist.h/cpp channeldelegate.h/cpp Список каналов с аватарами и превью
accountlist.h/cpp accountdelegate.h/cpp Список аккаунтов/пользователей и его делегат отрисовки
memberlistmodel.h/cpp Модель списка участников канала
memberpropsdialog.h/cpp Диалог свойств участника
flagpainter.h/cpp Отрисовка иконок мембера (admin/mod/supernode/storage)
joindialog.h/cpp Диалог присоединения к группе/каналу
invitedialog.h/cpp Диалог приглашения пользователя
invite_link.h/cpp Логика invite-ссылок
inviteby.h/cpp Диалог приглашения по invite-ссылке (отправка через узел)
dminvitedialog.h/cpp Выбор канала для приглашения собеседника из DM с сопоставлением результата по request_id
settingsdialog.h/cpp Окно настроек
creategroupdialog.h/cpp Диалог создания группы
channelsettingsdialog.h/cpp Диалог настроек канала
renamedialog.h/cpp Диалог переименования
networksettingspage.h/cpp Страница сетевых настроек
addressprofiletext.h Читаемое представление mapping, доступности входящих и источника NAT-измерения
nodespage.h/cpp Таблица узлов + дамп в настройках
statuspage.h/cpp Страница статуса (NTP + соединения + живые часы)
databasesettingspage.h/cpp Страница обслуживания БД в настройках
storagesettingspage.h/cpp Страница настроек хранилища
soundsettingspage.h/cpp Страница настроек звука
audiodevicesettingspage.h/cpp Страница настроек аудиоустройств
sound_manager.h/cpp Общий miniaudio-контекст, уведомления/PCM, микширование голоса, маршруты устройств и восстановление
audio_device.h/cpp Жизненный цикл miniaudio-устройства, прогресс callbacks, пауза и повтор запуска после сбоя
audio_buffer_tuning.h Подбор размера аппаратного аудиобуфера по повторным XRUN с сохранением настройки при reopen
audio_capture.h/cpp Совместное использование одного микрофона трансляцией и рацией, подписки PCM и смена профиля захвата
audio_capture_lease.h Владение захватом, исключающее одновременную работу publisher, звонка и записи голосового сообщения
audio_event_queue.h Ограниченная очередь PCM/команд с несколькими producers и резервом для управляющих событий
audio_frame_ring.h Предвыделенное SPSC-кольцо кадров переменной длины под mutex; при переполнении удаляет старейший
voice_audio_io.h/cpp Workers захвата/AEC и воспроизведения; упорядочивание PCM/PTT/mute и итоговый render-reference
voice_capture_clock.h Непрерывные PTS захваченного PCM по позиции сэмплов с плавной поправкой аппаратного времени
voice_playback_buffer.h Адаптивный запас готового PCM: увеличение после недостачи и уменьшение при стабильном выводе
audiorecorder.h/cpp Захват голосовых сообщений, worker обработки PCM, компрессор, индикатор уровня и передача записи задаче
voicemessageencoder.h/cpp Выбор Opus preset и создание медиа-каталога; кодирование выполняет общий voice_file
voiceplayback.h/cpp Воспроизведение голосовых сообщений
callwindow.h/cpp Окно аудио/видеозвонка: управление, выбор камеры, локальное/удалённое видео и статистика
call_audio_engine.h/cpp Desktop-контур звонка: захват, VoiceAudioIo, общий выход SoundManager и завершение аудиосессии
call_video_engine.h/cpp Desktop-видеозвонок: камера, TX/RX workers, обмен с ядром и показ кадров по аудиочасам
call_video_encoder.h/cpp Кодер звонка: согласованный формат, смена битрейта с drain прежнего кодера и подтверждение настройки
call_video_decoder.h/cpp FFmpeg-декодер H.264/H.265 с выбором GPU/CPU и сохранением PTS при задержанном выходе
call_camera_capture.h/cpp Управление отдельным процессом камеры, каталог устройств/режимов и получение кадров
call_camera_worker.cpp Процесс Qt-захвата камеры: настройка устройства, отбор кадров и выдача пикселей через shared memory
call_camera_source.h Интерфейс backend камеры для процесса захвата и подстановки устройств в тестах
call_camera_protocol.h Локальный протокол управляющих команд, каталога устройств и FRAME/ACK процесса камеры
call_camera_buffer.h Владение shared-memory буфером пикселей между процессами захвата и GUI
call_camera_rate.h Временное отключение снижения FPS из-за автоэкспозиции V4L2 с восстановлением настройки камеры
call_video_cadence.h Отбор исходных кадров под заданный FPS без накопления ошибки дробного периода
call_video_capture_clock.h Привязка времени камеры к монотонным часам с коррекцией задержки первого callback
call_video_queue.h Ограниченная SPSC-очередь кадров между video workers без mutex и выделений памяти
call_video_wake.h Пробуждение video worker по событию или абсолютному монотонному deadline на POSIX/Windows
radio_audio_engine.h/cpp Desktop-контур рации: независимые захват/прослушивание, PTT/VAD и подключение к общему выходу
radiopanel.h/cpp Панель активной рации: выбор аудиоустройств, VAD, PTT и состояние передачи из ядра
radiosettingspage.h/cpp Настройки рации и запись глобальных сочетаний PTT
ptt_hotkey_manager.h/cpp Глобальный PTT: физические клавиши Windows/X11, системный портал Wayland
ptt_key_chord.h Хранение физических сочетаний с отдельными левыми/правыми модификаторами и запись одновременного нажатия
ptt_portal.h/cpp D-Bus-сессия GlobalShortcuts для Wayland, настройка сочетаний и обработка нажатий/отпусканий
media_blocks.h/cpp Чтение/сборка фрагментированных медиафайлов
imageviewer_window.h/cpp Окно просмотра изображений
videoplayer_engine.h/cpp Движок декодирования видео
videoplayer_window.h/cpp Окно просмотра видео
live_video_encoder.h/cpp Общий FFmpeg-кодер live-видео для звонка/трансляции, GPU/CPU, KEY-конфигурация и capture PTS
video_frame_image.h Выделение выровненного RGB-буфера FFmpeg и передача владения QImage без копирования
stream_publish_engine.h/cpp Публикация камеры/экрана и Opus: workers кодирования, локальный preview и завершение через общий publisher
stream_publish_window.h/cpp Настройки и управление трансляцией; закрытие окна сохраняет работающий engine
stream_portal_capture.h/cpp Захват экрана Wayland через ScreenCast portal/PipeWire, выбор монитора и режима курсора
stream_screen_cursor.h/cpp, stream_screen_cursor_win.cpp Наложение системного курсора на кадр выбранного экрана средствами X11/Windows
stream_video_modes.h Выбор размеров/FPS камеры и пропорционального масштабирования экрана для трансляции
stream_qp_control.h Плавная корректировка потолка QP по фактическому выходному видеобитрейту
stream_sources.h Разбор снимка активных источников канала из CHAT_EVT_STREAM_SOURCES
streamplayer_window.h/cpp Просмотр live-потока: отдельные audio/video workers, смешивание PCM и синхронизация по часам устройства
streamgrid_window.h/cpp Сетка трансляций канала и разворачивание плитки с сохранением плееров; своя плитка использует локальный preview
connmonitorwindow.h/cpp Окно мониторинга ETCP-соединений (standalone)
qrcode_utils.h/cpp Утилиты для QR-кодов
debug_ui.h Отладочный UI

Другие поддиректории

  • db/ — db_manager.h/cpp: доступ GUI к данным nodes, channels, msg_, peers_ и состоянию интерфейса; копия db/sqlite3.c/h не используется текущей CMake-целью, SQLite берётся из lib/
  • transport/ — интеграция GUI с ядром; файлы перечислены ниже
  • src/avatars/ — avatarmanager.h/cpp: загрузка/публикация аватаров участников через member_files, подписанные ссылки и очередь передач; avatarcache.h/cpp: дисковый кеш, подготовка изображений и очистка; avatarcrop.h/cpp: выбор области; avatargallery.h/cpp: просмотр аватаров пользователя; groupavatarmanager.h/cpp: подготовка и кеш подписанных аватарок каналов
  • src/member_files/ — browser.h/cpp: браузер серверных файлов группы; batch.h/cpp: последовательные операции над файлами/деревьями, фоновый локальный обход, загрузка/скачивание и отмена
  • libutun/CMakeLists.txt — состав и зависимости CMake-сборки общего ядра из src/ и lib/
  • CMakeLists.txt — приложение vibechat, Qt-зависимости, ресурсы и цели GUI-тестов
  • tests/ — проверки аудиотракта, PTT, видеозвонка, захвата камеры/экрана, трансляций, файлового браузера и GUI-компонентов
  • resources/ — bg.jpg, chatgui.qrc (встраивает 5 TGS в бинарник), animations/*.tgs
  • zxing-cpp/ — встроенная библиотека QR-кодов; third_party/qhotkey/ — исходники QHotkey

Интеграция с ядром (transport/)

Файл Назначение
gui_bridge.h / gui_bridge_impl.cpp Команды GUI → uasync и события ядра → Qt-сигналы
utun_node.h/cpp Запуск и остановка ядра/чата в выделенном uasync-потоке
node_config.h/cpp Загрузка и сохранение конфигурации узла
config_updater.h/cpp Изменение настроек в конфиге
miniaudio_impl.c Реализация single-header miniaudio в отдельной единице трансляции
audio_diagnostics.h/cpp Диагностика этапов аудио и событий backend; записывает метаданные без PCM
stream_bridge.h/cpp Потокобезопасный мост к общим publisher/viewers: session IDs, каталог источников, запросы батчей и пробуждение workers

Система анимированных эмодзи

Формат

TGS = gzip-сжатый Lottie JSON. Холст 512×512, 60fps, 90–180 кадров. Декомпрессия через zlib (inflateInit2 с 16+MAX_WBITS).

Ключевые компоненты

LottieIcon                    — загрузка TGS, рендер кадров (rlottie C API)
    ↓
AnimTimer (синглтон)          — таймер 33ms, refcount activate/deactivate
    ├── в сообщениях:         → MessageDelegate::paint()
    │     drawAnimatedEmojiOverlay() — QTextLayout → позиции эмодзи → drawImage()
    │     drawStatusBar() — анимированные реакции вместо drawText()
    │
    ├── в панели:             → EmojiButton (наследует QPushButton)
    │     per-button QTimer, enterEvent/leaveEvent, собственный paintEvent
    │
    └── активация:            → ChatView::hoveredIndexChanged
          MessageList проверяет текст/реакции сообщения на g_animatedEmojiMap
          есть анимация → AnimTimer::activate()  /  нет → deactivate()

Инициализация

  1. MessageList конструктор: загружает все EmojiType::Animation из builtinEmojiSet(), создаёт LottieIcon, регистрирует в AnimTimer
  2. Должно быть ДО создания EmojiPanel — иначе EmojiButton получит nullptr
  3. g_animatedEmojiMap заполняется при старте (Unicode → animPath)

Текущий маппинг (5 эмодзи)

Unicode Shortcode TGS-файл
✨ U+2728 :sparkles: sparkles_emoji.tgs
🏳️ U+1F3F3 :flag: white_flag_emoji.tgs
👋 U+1F44B :wave: greeting.tgs
✋ U+270B :raised_hand: stop.tgs
🤖 U+1F916 :robot: robot.tgs

Рендеринг в сообщениях

  • Текст рисуется через QPainter::drawText(Qt::TextWordWrap)
  • drawAnimatedEmojiOverlay() повторяет layout через QTextLayout с теми же параметрами
  • Для каждого эмодзи из g_animatedEmojiMap находит пиксельную позицию через QTextLine::cursorToX()
  • Рендерит кадр через LottieIcon::renderFrame(currentFrame(), size) и рисует drawImage()
  • Размер эмодзи масштабирован ×1.3 относительно высоты строки
  • Аналогично для реакций в drawStatusBar()

Drag-to-select

  • Одиночный клик снимает выделение (если было), не стартует новое
  • Движение ≥5px от точки нажатия стартует выделение (m_selStart/m_selEnd)
  • Ctrl+C копирует: для одного сообщения — выделенный фрагмент, для нескольких — [time] author: text

Важные правила chatgui

  • CMAKE_AUTORCC ON обязателен для компиляции .qrc-ресурсов
  • Иконки должны быть зарегистрированы в AnimTimer ДО создания EmojiPanel
  • EmojiButton НЕ использует Q_OBJECT (в анонимном namespace) — таймер через лямбду, каст через dynamic_cast
  • Координаты indexAt(): viewport()->mapFrom(this, event->pos())

tdesktop-dev (референсный проект Telegram Desktop)

Расположение: tools/tdesktop-dev/ — полный клон Telegram Desktop.

Статус: референс. Не собирается, не модифицируется, в .gitignore.

Назначение:

  • Источник TGS-анимаций (Telegram/Resources/animations/ — 99+ файлов)
  • Образец использования rlottie/lib_lottie API
  • Архитектурный референс для GUI-компонентов

Правила:

  • НЕ модифицировать файлы внутри tdesktop-dev/
  • НЕ коммитить изменения из tdesktop-dev/
  • НЕ ссылаться в сборке на код/библиотеки из tdesktop-dev
  • Можно копировать TGS-файлы в tools/chatgui/resources/animations/

Полезные поддиректории:

  • Telegram/Resources/animations/ — TGS-анимации (dice, reactions, emoji, UI)
  • Telegram/lib_lottie/ — C++ обёртка над rlottie (SinglePlayer, MultiPlayer, Icon, FrameGenerator)
  • Telegram/ThirdParty/rlottie/ — submodule rlottie (обычно не выкачан)

rlottie C API (ключевые функции):

Lottie_Animation *lottie_animation_from_data(const char *data, const char *key, const char *resource_path);
void lottie_animation_get_size(const Lottie_Animation *anim, size_t *w, size_t *h);
size_t lottie_animation_get_totalframe(const Lottie_Animation *anim);
double lottie_animation_get_framerate(const Lottie_Animation *anim);
void lottie_animation_render(Lottie_Animation *anim, size_t frame, uint32_t *buf, size_t w, size_t h, size_t stride);
void lottie_animation_destroy(Lottie_Animation *anim);

Key Documentation Files

  • doc/service_lifecycle.md — ядро, независимые сервисы, владение ресурсами и остановка
  • doc/node_snapshot.md — подписанная запись узла, timestamp, SQLite и обновление NCD
  • doc/etcp_protocol.txt — ETCP: кодограммы, ACK, handshake, keepalive
  • doc/etcp_arch.md — архитектура ETCP
  • doc/etcp_router_arch.md — архитектура маршрутизатора
  • src/chat/chat_join.h — нормативный протокол добавления участника
  • src/routing_layer/topo_group.h — протокол групповой сессии и критерий READY
  • tests/test_chat_join_e2e.c, tests/test_topo_recovery.c, tests/test_services.c — проверки join, recovery и жизненного цикла
  • doc/dm_arch.md, doc/chat_call_arch.md — личные сообщения и звонки
  • doc/call_video.txt — видеотрек звонка: возможности кодеков, транспорт, битрейт, аудиочасы и показ кадров
  • doc/stream.txt — трансляции: RS-пачки, выдачи/relay, выбор поставщиков, медиакурсоры и платформенные плееры
  • doc/stun_nat.md, doc/nat_detection.txt — STUN-измерения и определение доступности рабочих UDP-сокетов
  • doc/member_files.txt — файловое хранилище участников, права, wire-команды и передачи
  • doc/group_avatar.txt — подписанная аватарка канала, хранение и репликация
  • doc/encrypted_attachments.md — контейнер группового вложения, запросы ключа и ручная выдача доступа
  • doc/pm_invites.md, doc/message_links.md — приглашения из личной беседы и ссылки внутри сообщений
  • doc/proxy_protocol.md — TCP/UDP/ICMP-прокси, управление окнами, half-close и проверки
  • doc/lwip_nuances.md — особенности адаптированного lwIP TCP-стека
  • doc/linux_audio_recovery.md — диагностика аудиотракта Linux, контракты владения и восстановление устройств
  • src/media_delivery/file_transfer.h, src/dm/dm_media.h — контракты передачи файлов и E2E-вложений DM
  • src/call/call_audio.h, src/radio/radio_audio.h — API общего голосового стека и правила потоков
  • tools/chatcli_commands.txt — команды headless CLI, в том числе DM, звонки и рация

Список задач по проекту

Список задач — doc/tasks.md относительно корня репозитория (текущая работа, берём по одной задаче сверху). При нахождении попутных багов/fail/флаков тестов добавляем задачу (либо фиксим сразу если баг простой). Как сделали - помечаем [+] выполнено.

chatgui-android (Android P2P Chat)

Расположение: tools/chatgui-android/

Android-версия чатгуи — P2P чат на общем ETCP/STCP-ядре, UI на Jetpack Compose (Kotlin). C-библиотека utun_lite собирает lib/ и src/ по libutun_lite/utun_sources.cmake; instance_lite запускает ядро и чат в отдельном потоке, без UTUN-сервиса. Сборка: CMake (headless, Linux) + Gradle/NDK (Android APK).

  • 'fw' - собрать и обновить chatgui-android на всех подключенных телефонах (clean + сборка + install)

Подробная инструкция: tools/chatgui-android/AGENTS.md Chat-модули: все файлы из src/chat/ (описаны выше в секции «Chat») компилируются в libutun_lite.

Основные файлы native-слоя

Пути относительны к tools/chatgui-android/; UI и Android-сервисы описаны в локальном AGENTS.md.

Файл Назначение
libutun_lite/utun_sources.cmake Общий список исходников ядра для Android и headless
libutun_lite/CMakeLists.txt Сборка native-библиотеки и зависимостей
libutun_lite/instance_lite.c/h Запуск ядра/чата по INI-тексту и управление отдельным uasync-потоком
libutun_lite/utun_config_api.c/h Провайдер конфигурации: callbacks Kotlin и значения для native-слоя
libutun_lite/standby.c/h Фоновый duty-cycle, таймеры активных интервалов и ожидание пробуждения
libutun_lite/invite_link_c.c/h Старая копия C-кодека; .c исключён из UTUN_SOURCES, рабочий код — src/chat/invite_link.c/h
libutun_lite/attachment_sender.c/h Отправка файлов в канал через chat_msg_submit и канальный медиа-индекс
libutun_lite/photo_sender.c/h Отправка фотографий в канал с MIME-типом и размерами изображения
libutun_lite/video_sender.c/h Отправка видео через общий механизм подготовки вложений
libutun_lite/voice_recorder.c/h Накопление PCM записи, компрессор и отправка голоса через общий attachment_send
libutun_lite/stream_bridge.c/h Android-мост к publisher/viewers: session IDs, готовые access units/Opus и ограниченные батчи треков
jni_bridge/android_jni_bridge.c/h JNI-команды и callbacks между Kotlin и C-ядром, события и аудио API
jni_bridge/android_call_output_jni.c Вывод PCM звонка через AAudio с аппаратным тактированием и снимками позиции устройства
jni_bridge/android_call_video_jni.c JNI видеозвонка: capabilities/формат, обмен кадрами с call_video_port, playout и поворот YUV
jni_bridge/android_stream_jni.c JNI трансляций: publisher/viewer API, Opus/SoundTouch, готовый PCM и часы воспроизведения
jni_bridge/android_udp_log.c/h Потокобезопасный буфер UDP-логов с flush-таймером в потоке ядра
headless/headless_main.c Отдельный каркас control-loop; сам не запускает ядро/чат
headless/headless_control.c/h Каркас control-сокета; часть команд — заглушки, рабочий API — src/chat/chat_headless_control.c/h
app/src/main/cpp/CMakeLists.txt NDK-сборка библиотеки приложения
libutun_lite/tests/test_standby.c Проверка duty-cycle и жизненного цикла standby

Runtime

  • После autotools-сборки бинарник — src/utun. Запуск из корня с TUN: sudo ./src/utun -f -c utun.cfg.
  • Старый utun_start.sh ожидает ./utun в корне. utun_stop.sh делает killall -9 utun, а не штатную остановку одного экземпляра.
  • -f оставляет процесс на переднем плане; остановка — SIGINT/SIGTERM. Пути конфигурации, PID и лога задаются через -c, -p, -l.
  • utun_start.sh перенаправляет stdout в utun.log, stderr в utun_err.log.
  • Тестовые логи: tests/logs/

Git Conventions

  • Commit Messages: Use imperative mood, concise (50-72 chars)
  • Language: Mix of English (technical) and Russian (business logic)
  • Tags: Version tags follow vX.Y.Z format
  • "cp" or "кп" in prompt = do commit and push (всех изменений на текущий момент, не откатывая). Запрещено откатывать "лишние" изменения сделаные вне сессии (если сильно надо - сделать бэкап). если нет дополнительных указаний - комить всё что изменилось как есть.

Quick Start for New Features

  1. Add new source file to src/Makefile.am under utun_SOURCES
  2. Add test target and its sources/dependencies to tests/Makefile.am under check_PROGRAMS
  3. Use existing patterns from similar modules
  4. Run ./check.sh after changes
  5. Commit with descriptive message in appropriate language

chatgui: отправка сообщений через xdotool

  1. Запуск: из каталога сборки setsid env QT_ACCESSIBILITY=1 ./vibechat & disown с DISPLAY текущей X11-сессии.
  2. Окно: найти актуальный ID через xdotool search --onlyvisible --class vibechat; ID и размеры окна меняются между запусками.
  3. Фокус: активировать найденное окно и выбрать InputBar; координаты определять по текущему расположению интерфейса.
  4. Отправка: xdotool type --window WID "text" + xdotool key --window WID Return, где WID заменён найденным ID.
  5. Проверка: через chats.db из каталога db_path; таблицы сообщений называются msg_<числовой channel_id>.
  6. Доступность UI-автоматизации зависит от текущей X11/Wayland-сессии и настроек Qt accessibility; старые ID окон и DISPLAY не переносить.

Эта инструкция имеет приоритет над инструкцией opencode.