docs: update file inventory and module header contracts
Refresh both AGENTS guides and clarify module purpose, usage, ownership, threading, return values and wire formats in headers. Remove the unused timeout_heap freed_count field and unimplemented getter.
This commit is contained in:
1 parent
c19eff67f6
commit
a97e8bcc1f
118 files changed
+628
-406
No files matched your search
@@ -1,3 +1,8 @@
|
||||
/* broadcast — рассылка данных соседям topo-группы с пересылкой и дедупликацией UUID.
|
||||
* Контекст и кеш увиденных UUID принадлежат группе; TTL — срок хранения UUID, не счётчик сетевых хопов.
|
||||
* init_instance регистрирует общий ETCP-диспетчер, init(group) создаёт состояние отдельной группы.
|
||||
* Все вызовы/callbacks — uasync-поток; recv получает заимствованные uuid/data только на время callback.
|
||||
* send копирует данные и возвращает 0 / -1; 0 не подтверждает доставку каждому участнику. */
|
||||
#ifndef BROADCAST_H
|
||||
#define BROADCAST_H
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* chat_core_priv.h — внутренний заголовок для под-модулей chat_core
|
||||
*
|
||||
* Предоставляет доступ к глобальному состоянию g_cc и общим хелперам.
|
||||
* Не включать извне chat/ — только для chat_core*.c.
|
||||
* Предоставляет per-instance chat_core_ctx через CC(inst), общие SQL/сериализационные хелперы
|
||||
* и внутренние операции частей chat_core/member_sync. Не включать извне chat/.
|
||||
*/
|
||||
|
||||
#ifndef CHAT_CORE_PRIV_H
|
||||
@@ -73,7 +73,7 @@ static inline size_t b64_decode(const char* src, size_t src_len, uint8_t* dst, s
|
||||
return out;
|
||||
}
|
||||
|
||||
/* ── Глобальное состояние (определено в chat_core.c) ── */
|
||||
/* ── Состояние одного экземпляра (создаётся в chat_core.c) ── */
|
||||
|
||||
struct ms_props_cbk; /* member_sync.c */
|
||||
struct ms_apply_cbk; /* member_sync.c */
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
* Response: {"id":N,"ok":true,"data":{...}} | {"id":N,"ok":false,"error":"..."}
|
||||
* Event: {"event":"<type>",...}
|
||||
*
|
||||
* Commands: ping, status, channels, members, messages, send, invite,
|
||||
* invite_nodes, connect, create_channel, subscribe, quit
|
||||
* Команды каналов, DM, звонков/рации и настроек — в tools/chatcli_commands.txt;
|
||||
* диспетчер реализации — chat_headless_control.c. Аудио PCM использует отдельные call/radio_headless сокеты.
|
||||
* init регистрирует listener и события chat_event, destroy закрывает клиентов и снимает подписку.
|
||||
* Все вызовы и команды исполняются в uasync-потоке экземпляра.
|
||||
*/
|
||||
#ifndef CHAT_HEADLESS_CONTROL_H
|
||||
#define CHAT_HEADLESS_CONTROL_H
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Общий модуль для всех GUI (desktop chatgui, Android, headless CLI).
|
||||
* Логика выбора «лучшего узла» перенесена из tools/chatgui-android/jni_bridge.
|
||||
* Работает в uasync-потоке, использует общий контекст g_cc.
|
||||
* Работает в uasync-потоке, использует chat_core_ctx конкретного UTUN_INSTANCE.
|
||||
*/
|
||||
#ifndef INVITE_BUILD_H
|
||||
#define INVITE_BUILD_H
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/*
|
||||
* invite_link.h — invite-ссылки utun:// для каналов
|
||||
*
|
||||
* Формат: utun:// + base64(version | password? | channel_id | [header | pubkey | addrs]+)
|
||||
* Совместим с десктопной (Qt) и Android (Kotlin) версиями.
|
||||
* Версия 0x03: utun:// + base64(version | pass_len/password | channel_id | join_key |
|
||||
* reality_has/params | блоки pubkey/addrs). ID/port кодируются big-endian; nodeId выводится из pubkey.
|
||||
* Общий формат с desktop Qt и Android Kotlin. Сам кодек не подключает узел и не регистрирует join_key.
|
||||
* decode: 0/-1; encode: длина base64 без utun:// и NUL/-1; serialize_addrs: число байтов/-1.
|
||||
* Буферы предоставляет вызывающий; encode завершает строку NUL.
|
||||
*/
|
||||
#ifndef INVITE_LINK_H
|
||||
#define INVITE_LINK_H
|
||||
|
||||
+4
-1
@@ -1,4 +1,7 @@
|
||||
// config_parser.h - Configuration parser for utun application
|
||||
/* INI-конфигурация ядра: слушающие сокеты, исходящие пиры, сети/подсети и настройки сервисов.
|
||||
* parse_config читает файл, parse_config_from_buf — текст; filename задаёт источник в диагностике.
|
||||
* Успех возвращает выделенную utun_config со списками; освобождение — только free_config.
|
||||
* Парсер заполняет модель, запуск сетевых ресурсов выполняет utun_instance. */
|
||||
#ifndef CONFIG_PARSER_H
|
||||
#define CONFIG_PARSER_H
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// config_updater.h - Configuration file updater
|
||||
/* Обеспечивает идентичность X25519/node_id в INI-файле: проверяет поля и сохраняет исправленные ключи.
|
||||
* config_ensure_keys_and_node_id меняет файл на диске; bytes_to_hex только форматирует буфер вызывающего. */
|
||||
#ifndef CONFIG_UPDATER_H
|
||||
#define CONFIG_UPDATER_H
|
||||
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* dm_core.h — прямой p2p чат между двумя пользователями (DM)
|
||||
*
|
||||
* Отдельная подсистема (НЕ канал): без TOPO_GROUP/member_sync/merkle.
|
||||
* Личная беседа не создаёт отдельную TOPO_GROUP и не синхронизируется через member_sync/Merkle.
|
||||
* Для доставки использует маршрут из общей CHAT-группы участников.
|
||||
* - conv_id и content_key детерминированно выводятся обеими сторонами
|
||||
* из своих ключей и pubkey пира (см. dm_crypto.h) — без переговоров.
|
||||
* - сообщения идут через etcp_router (прямое соединение или релей),
|
||||
|
||||
+10
-1
@@ -1,3 +1,9 @@
|
||||
/* eim_nat — таблица Endpoint-Independent Mapping для IPv4 TCP/UDP и ICMP echo.
|
||||
* init_ctx создаёт состояние из global_config; при отключённом NAT оставляет initialized=0.
|
||||
* egress/ingress меняют IP/порты и checksums на месте, не отправляют пакеты и не владеют TUN/ETCP.
|
||||
* Перед обработкой нужен инициализированный ctx; вызовы последовательны в uasync-потоке.
|
||||
* gateway/internal IP — host order, internal_port — network order, внешний порт — host order.
|
||||
* src_conn заимствован; срок жизни и выбор транспорта обратной отправки контролирует nat_transport. */
|
||||
#ifndef EIM_NAT_H
|
||||
#define EIM_NAT_H
|
||||
|
||||
@@ -31,7 +37,7 @@ struct eim_nat_entry {
|
||||
struct ETCP_CONN* src_conn; // cached connection for sendback
|
||||
};
|
||||
|
||||
// Pure NAT engine state (no transport/TUN/ETCP fields)
|
||||
// Состояние преобразования; TUN и транспортные ресурсы принадлежат nat_transport.
|
||||
struct eim_nat_ctx {
|
||||
uint32_t gateway_ip;
|
||||
uint16_t port_start;
|
||||
@@ -47,8 +53,11 @@ struct global_config;
|
||||
int eim_nat_init_ctx(struct eim_nat_ctx* ctx, const struct global_config* g);
|
||||
void eim_nat_destroy_ctx(struct eim_nat_ctx* ctx);
|
||||
|
||||
/* 0 — обработано или пакет не подлежит NAT, -1 — ошибка; буфер принадлежит вызывающему. */
|
||||
int eim_nat_egress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len,
|
||||
uint64_t src_node_id, struct ETCP_CONN* src_conn);
|
||||
/* out_entry изменяется только при найденном mapping; заранее установить *out_entry=NULL.
|
||||
* Запись заимствована у ctx. 0 само по себе не означает, что пакет был преобразован. */
|
||||
int eim_nat_ingress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len,
|
||||
struct eim_nat_entry** out_entry);
|
||||
|
||||
|
||||
+4
-1
@@ -1,4 +1,7 @@
|
||||
// firewall.h - Firewall rules for utun
|
||||
/* firewall — список разрешённых пар IPv4/порт из global_config, без изменения системного firewall.
|
||||
* init/обнуление → load_rules (копия и сортировка правил) → check → free; контекст использует один поток.
|
||||
* check: 1 разрешено, 0 запрещено; port=0 в правиле разрешает все порты IP, bypass_all разрешает всё.
|
||||
* IP и порт передавать в host order, как в CFG_FIREWALL_RULE. */
|
||||
#ifndef FIREWALL_H
|
||||
#define FIREWALL_H
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// lwip_pbuf.h — simplified packet buffer (PBUF_RAM only)
|
||||
/* Буферы TCP-пакетов: одна RAM-аллокация с запасом перед payload и ручным refcount.
|
||||
* alloc создаёт ref=1; free уменьшает ссылки всех элементов цепочки и освобождает элементы с ref=0.
|
||||
* header сдвигает payload в пределах запаса; header_force не проверяет запас при добавлении.
|
||||
* chain только связывает элементы, без увеличения refcount и пересчёта tot_len. Синхронизации нет. */
|
||||
#ifndef LWIP_PBUF_H
|
||||
#define LWIP_PBUF_H
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// lwip_tcp.h — lwIP TCP public API (adapted for uTun)
|
||||
/* Адаптированный lwIP TCP для TUN-прокси: TCP-состояния, retransmit, окна и callbacks потоков.
|
||||
* init создаёт контекст с uasync-таймером; input получает TCP-сегмент после IPv4-заголовка,
|
||||
* output callback передаёт сегмент внешнему IP/TUN-слою. destroy освобождает PCB и таймер.
|
||||
* API и callbacks требуют последовательного выполнения; input использует общий рабочий контекст. */
|
||||
#ifndef LWIP_TCP_H
|
||||
#define LWIP_TCP_H
|
||||
|
||||
@@ -85,7 +88,7 @@ typedef err_t (*tcp_poll_fn) (void *arg, struct tcp_pcb *pcb);
|
||||
typedef void (*tcp_err_fn) (void *arg, err_t err);
|
||||
typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *pcb, err_t err);
|
||||
|
||||
// Output callback — called when TCP wants to send an IP packet
|
||||
// Output callback получает TCP-сегмент и IP адреса отдельно; IPv4-заголовок строит вызывающий слой.
|
||||
typedef err_t (*tcp_output_fn)(void *arg, struct pbuf *p, uint32_t src_ip, uint32_t dst_ip);
|
||||
|
||||
#define TCP_TRACE_SIZE 384
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// lwip_tcp_opts.h — hardcoded TCP configuration (no #ifdefs)
|
||||
/* Параметры встроенного TCP: MSS, окна, лимиты повторов и таймеры в миллисекундах.
|
||||
* Используются lwip_tcp/in/out; runtime-интервал и пределы RTO меняет lwip_tcp_set_timer. */
|
||||
#ifndef LWIP_TCP_OPTS_H
|
||||
#define LWIP_TCP_OPTS_H
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// lwip_tcp_priv.h — lwIP TCP internal API
|
||||
/* Внутренний API адаптированного lwIP TCP: wire TCP header, сегменты, контекст и межфайловые функции.
|
||||
* Используется lwip_tcp/in/out; внешние пользователи включают lwip_tcp.h. */
|
||||
#ifndef LWIP_TCP_PRIV_H
|
||||
#define LWIP_TCP_PRIV_H
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/* Общие метаданные готового вложения. Подготовка не знает адресата и транспорта.
|
||||
* PM шифрует компактный wire-формат; GUI получает разобранные поля.
|
||||
* encode/decode возвращают длину/0 или -1; неизвестные типы и лишние байты запрещены. */
|
||||
/* attachment — общие метаданные file/voice/video, без хранения файла, адресата и транспорта.
|
||||
* validate/decode возвращают 0 / -1, encode — число записанных байтов / -1.
|
||||
* Формат: kind:1, name_len:2, duration_ms:4, width:2, height:2, UTF-8 basename, waveform:100 только для voice.
|
||||
* Числа big-endian; имя 1..255 байт без разделителей пути, лишние wire-байты запрещены.
|
||||
* Caller владеет struct/буферами; DM шифрует эти метаданные, GUI получает разобранные поля. */
|
||||
#ifndef ATTACHMENT_H
|
||||
#define ATTACHMENT_H
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/* Подготовить голос/видео и отправить в зафиксированную беседу. Вызывать trampoline
|
||||
/* attachment_send — подготовить голос/видео и отправить в зафиксированный канал или DM. Вызывать trampoline
|
||||
* через uasync_post. Request и PCM/compressor переходят во владение задачи;
|
||||
* pcm_release освобождает pcm_owner, NULL означает PCM из u_malloc.
|
||||
* Qt/Android используют общий результат подготовки, доставка остаётся в chat/dm. */
|
||||
* Qt/Android используют общий результат подготовки, доставка остаётся в chat/dm.
|
||||
* req выделяется u_calloc; caller заполняет target/is_dm, info и source либо PCM. inst должен жить до done.
|
||||
* Подготовка выполняется в media_async worker, публикация и attachment-события — в uasync.
|
||||
* output/id/error заполняет задача; temporary_source разрешает удалить принадлежащий приложению source. */
|
||||
#ifndef ATTACHMENT_SEND_H
|
||||
#define ATTACHMENT_SEND_H
|
||||
#include "attachment.h"
|
||||
@@ -12,14 +15,14 @@ extern "C" {
|
||||
#endif
|
||||
struct attachment_send_req {
|
||||
struct UTUN_INSTANCE* inst;
|
||||
char target[64];
|
||||
char target[64]; /* Десятичный channel_id либо conv_id без префикса dm:, зафиксированный до подготовки. */
|
||||
int is_dm;
|
||||
struct attachment_info info;
|
||||
uint8_t id[16];
|
||||
char source[1024], output[1024];
|
||||
int transcode, temporary_source;
|
||||
const int16_t* pcm;
|
||||
size_t pcm_count;
|
||||
size_t pcm_count; /* Для voice: int16, 48 кГц моно, число отсчётов. */
|
||||
void* pcm_owner;
|
||||
void (*pcm_release)(void* owner);
|
||||
struct audio_compressor* compressor;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/* Существующий контейнер Opus голосовых Qt/Android. Вызывать только в worker.
|
||||
/* voice_file — кодирование PCM в общий контейнер Opus голосовых сообщений Qt/Android. Вызывать только в worker.
|
||||
* PCM принадлежит вызывающему; encode заполняет duration/waveform по реально
|
||||
* записанным кадрам. При ошибке неполный файл удаляется. */
|
||||
* записанным кадрам. При ошибке неполный файл удаляется; возврат 0 / -1.
|
||||
* count — число interleaved int16 отсчётов; rate — 8/12/16/24/48 kHz, channels — 1/2, preset — 0..2.
|
||||
* Пишутся полные кадры по 20мс (хвост отбрасывается), минимум 500мс, максимум 24ч.
|
||||
* name задаёт caller; encode устанавливает kind=VOICE и обнуляет width/height. */
|
||||
#ifndef VOICE_FILE_H
|
||||
#define VOICE_FILE_H
|
||||
#include "attachment.h"
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
// media_delivery.h — распространение медиа (аудио/видео стриминг)
|
||||
/* media_delivery — канальные медиафайлы: поиск держателей блоков, выдача/relay и репликация доступности.
|
||||
* Суперузлы обмениваются block_availability, держатели отдают подписанные блоки, media_download собирает файл.
|
||||
* init создаёт per-instance состояние, bind подключает протокол к router; destroy отменяет сетевую работу.
|
||||
* Все операции — uasync-поток; долгие файловые/crypto-задачи выполняет media_async.
|
||||
* E2E-файлы личных бесед используют dm_media/file_transfer, а не канальную таблицу доступности. */
|
||||
#ifndef MEDIA_DELIVERY_H
|
||||
#define MEDIA_DELIVERY_H
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// media_delivery_proto.h — протокольные структуры media_delivery
|
||||
/* media_delivery_proto — wire-структуры и подкоманды доставки блоков медиа CHAT-группы.
|
||||
* Описывает запросы держателей, чанки, подтверждения наличия и репликацию между суперузлами.
|
||||
* Это формат payload сервиса router, без группового маршрутизационного заголовка; обработчики — media_delivery/download. */
|
||||
#ifndef MEDIA_DELIVERY_PROTO_H
|
||||
#define MEDIA_DELIVERY_PROTO_H
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// media_download.h — скачивание блоков медиа
|
||||
/* media_download — загрузка канального файла по media_index_result: QUERY держателей → блоки → проверка/сборка.
|
||||
* Состояние хранит inst->media_delivery; каждый подключённый держатель удерживается через CM handle.
|
||||
* Старт копирует метаданные result; callbacks и обработчики — uasync-поток, файловая проверка — media_async.
|
||||
* Failover/таймер простоя ограничивают повторы; done сообщает результат, а не гарантирует доставку другим участникам. */
|
||||
#ifndef MEDIA_DOWNLOAD_H
|
||||
#define MEDIA_DOWNLOAD_H
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// media_index.h — таблица media_files + регистрация медиа с async-обработкой
|
||||
/* media_index — индекс блоков канального файла в SQLite media_files: UUID, SHA256, Ed25519-подписи и location.
|
||||
* init создаёт таблицу; register_async копирует/хеширует/подписывает файл в worker, затем commit и callback в uasync.
|
||||
* db/ma/ua заимствованы и должны жить до завершения; доступ к БД выполняется в потоке ядра.
|
||||
* Результат callback заимствован только до возврата. result_free освобождает block_ids/block_sigs, но не саму структуру. */
|
||||
#ifndef MEDIA_INDEX_H
|
||||
#define MEDIA_INDEX_H
|
||||
|
||||
@@ -40,6 +43,7 @@ int media_index_register_downloaded(sqlite3* db, const uint8_t* media_id, const
|
||||
const char* location, uint64_t node_id,
|
||||
int64_t file_size, int64_t chunk_size, int chunk, int64_t offset);
|
||||
|
||||
/* Callback может быть синхронным при отказе запуска. err=0 даёт result, иначе result=NULL. */
|
||||
void media_index_register_async(
|
||||
struct media_async* ma, struct UASYNC* ua, sqlite3* db,
|
||||
uint64_t node_id, const uint8_t* ed25519_privkey,
|
||||
|
||||
+4
-1
@@ -1,4 +1,7 @@
|
||||
// nat_transport.h — NAT transport layer (TUN + ETCP protocol handling)
|
||||
/* IPv4 NAT через отдельный TUN и сервис ETCP_RT_ID_NAT в UTUN-router.
|
||||
* nat_via_node_id задаёт удалённого провайдера; при 0 узел сам выполняет eim_nat для клиентов.
|
||||
* init создаёт TUN/обработчики по nat_enabled; destroy снимает их и освобождает ресурсы.
|
||||
* Контекст принадлежит UTUN_INSTANCE; очереди и callbacks работают в uasync. */
|
||||
#ifndef NAT_TRANSPORT_H
|
||||
#define NAT_TRANSPORT_H
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* ntp_node_time — обмен временем с прямыми ETCP-пирами, дополнение к интернет-NTP.
|
||||
* Несинхронизированный узел принимает коррекцию синхронизированного пира с оценкой половины RTT,
|
||||
* затем передаёт время остальным; при последующих сообщениях сравнивает изменение смещения для диагностики.
|
||||
* init привязывает ETCP_ID_NTP_TIME и подписку на соединения, destroy удаляет их; все вызовы — uasync. */
|
||||
#ifndef NTP_NODE_TIME_H
|
||||
#define NTP_NODE_TIME_H
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* ntp_time — асинхронные UDP NTP-запросы с DNS и периодическим повтором в uasync-потоке ядра.
|
||||
* Не меняет часы ОС: хранит local_time - ntp_time в instance->ntp.offset_us.
|
||||
* get_us/get_seconds возвращают скорректированное wall-clock время; до синхронизации — локальное.
|
||||
* init читает config и планирует первый цикл, destroy отменяет DNS/сокет/таймеры.
|
||||
* synced означает наличие коррекции (в том числе полученной от пира), reachable — результат интернет-NTP. */
|
||||
#ifndef NTP_TIME_H
|
||||
#define NTP_TIME_H
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// icmp_proxy.h — ICMP echo (ping) прокси: клиент ↔ exit через etcp_router
|
||||
/* IPv4 ICMP echo через UTUN-router: exit отправляет ping через raw socket, сопоставляет reply
|
||||
* по собственному wire id/seq и восстанавливает исходные id/seq клиента. Запросы ограничены таймаутом.
|
||||
* init/destroy и callbacks — в uasync; контекст принадлежит inst, роль берётся из tcp_proxy_server.enabled.
|
||||
* test_loopback возвращает виртуальные ответы без сетевой отправки и предназначен для тестов. */
|
||||
#ifndef ICMP_PROXY_H
|
||||
#define ICMP_PROXY_H
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// socks_proxy.h — SOCKS5 / HTTP CONNECT proxy (client side)
|
||||
/* Локальные SOCKS5 CONNECT и HTTP proxy/CONNECT: DNS, handshake и передача TCP через удалённый exit.
|
||||
* tcp_proxy_client владеет listener и списками соединений; их callbacks выполняются в uasync.
|
||||
* init_listen заимствует указатели на списки/счётчики до close_listen; закрытие listener не освобождает клиентов. */
|
||||
#ifndef SOCKS_PROXY_H
|
||||
#define SOCKS_PROXY_H
|
||||
|
||||
@@ -81,13 +83,13 @@ struct listen_ctx* socks_proxy_init_listen(struct UASYNC* ua, const char* addr_s
|
||||
struct UTUN_INSTANCE* inst, uint64_t via_node_id, int is_http);
|
||||
|
||||
// Закрыть слушающий сокет и освободить listen_ctx.
|
||||
// sock_out получает значение сокета (для последующего close).
|
||||
// Если sock_out задан, в него записывается SOCKET_INVALID: сокет уже закрыт.
|
||||
void socks_proxy_close_listen(struct UASYNC* ua, struct listen_ctx* ctx, socket_t* sock_out);
|
||||
|
||||
// Найти соединение по stream_id
|
||||
struct socks_proxy_conn* socks_proxy_find_conn(struct socks_proxy_conn* head, uint32_t stream_id);
|
||||
|
||||
// Обработать входящее ETCP сообщение (DATA/CLOSE/ERROR/FIN)
|
||||
// Обработать ответ exit: CONNECTED/DATA/WINDOW_UPDATE/CLOSE/ERROR/FIN.
|
||||
// Возвращает 1 если обработано, 0 если stream_id не найден
|
||||
int socks_proxy_handle_etcp(struct socks_proxy_conn** head, int* count,
|
||||
uint32_t stream_id, uint8_t subcmd,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// tcp_proxy_client.h — TCP прокси-клиент: стек lwIP TCP → ETCP → удалённый exit узел
|
||||
/* Клиент TCP-прокси: принимает IPv4 с отдельного TUN через lwIP либо TCP от SOCKS/HTTP listener.
|
||||
* Передаёт потоки через UTUN-router на via_node_id; proxy_flow обеспечивает окно и backpressure.
|
||||
* create/destroy и callbacks — в uasync. Владеет созданными TUN/lwIP/listener/потоками,
|
||||
* заимствует inst/ua/mappings до destroy. Без tun_name/tun_ip может работать только SOCKS/HTTP. */
|
||||
#ifndef TCP_PROXY_CLIENT_H
|
||||
#define TCP_PROXY_CLIENT_H
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// tcp_proxy_server.h — TCP прокси-сервер (exit node)
|
||||
/* Exit TCP-прокси: принимает CONNECT/DATA через UTUN-router и открывает обычный TCP к назначению.
|
||||
* Поток определяется парой peer_node_id/stream_id; proxy_flow согласует окна и half-close.
|
||||
* init учитывает tcp_proxy_server_enabled в конфиге; destroy закрывает потоки и общий UDP/ICMP-прокси.
|
||||
* Состояние принадлежит UTUN_INSTANCE, операции и callbacks выполняются в его uasync-потоке. */
|
||||
#ifndef TCP_PROXY_SERVER_H
|
||||
#define TCP_PROXY_SERVER_H
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// udp_proxy.h — UDP датаграммный прокси: клиент ↔ exit через etcp_router
|
||||
/* UDP из TUN через UTUN-router: клиент отправляет REQUEST, exit открывает сокет для кортежа адресов
|
||||
* и возвращает REPLY. Потоки exit удаляются по таймауту неактивности.
|
||||
* init/destroy и callbacks — в uasync; контекст принадлежит inst, роль берётся из tcp_proxy_server.enabled. */
|
||||
#ifndef UDP_PROXY_H
|
||||
#define UDP_PROXY_H
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ int radio_audio_vad_mode(void);
|
||||
/* Текущее состояние передачи: ручной PTT либо сработавший VAD. */
|
||||
int radio_audio_transmitting(void);
|
||||
|
||||
/* uasync-поток: принятый Opus-кадр источника (декодируем + кладём в ring). */
|
||||
/* uasync-поток: копируем Opus-кадр в jitter источника; декодирование/растяжение — на pull в RX-потоке. */
|
||||
void radio_audio_on_frame(struct UTUN_INSTANCE* inst, uint64_t group_id,
|
||||
uint64_t src_node_id, uint16_t stream_id, uint16_t seq,
|
||||
uint8_t fin, const uint8_t* opus, int len, void* arg);
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* conn_mgr_priv — внутренние состояния, wire-команды и общие операции трёх частей conn_mgr.
|
||||
* core управляет handles и попытками, indirect — согласованием посредников, monitor — оценкой/обновлением путей.
|
||||
* Все структуры принадлежат менеджеру topo-группы и используются в его uasync-потоке.
|
||||
* Сервисы подключаются через conn_mgr.h; поля ENTRY/CANDIDATE не являются внешним API. */
|
||||
#ifndef CONN_MGR_PRIV_H
|
||||
#define CONN_MGR_PRIV_H
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* route6_lib — локальная IPv6-таблица подсетей на BSD radix с longest-prefix lookup.
|
||||
* Очередь индексирует записи по node_id для удаления всех подсетей узла; TOPO_GROUP_NODE заимствован.
|
||||
* create/insert/lookup/delete/destroy — в одном uasync-потоке; маршруты удалять до освобождения узла.
|
||||
* addr — 16 сетевых байтов. Результат lookup принадлежит таблице и живёт до удаления записи/destroy. */
|
||||
#ifndef ROUTE6_LIB_H
|
||||
#define ROUTE6_LIB_H
|
||||
|
||||
@@ -13,36 +17,7 @@ extern "C" {
|
||||
#include "../lib/u_async.h"
|
||||
|
||||
|
||||
/*
|
||||
Диапазон Назначение
|
||||
::/128 Неопределенный адрес (unspecified). Используется до назначения адреса интерфейсу.
|
||||
::1/128 Адрес обратной петли (loopback), аналог 127.0.0.1 в IPv4.
|
||||
2000::/3 Глобально маршрутизируемые (Global Unicast) адреса. Основное адресное пространство Интернета.
|
||||
fc00::/7 Уникальные локальные адреса (ULA), аналог частных IPv4 (10.0.0.0/8, 192.168.0.0/16). На практике обычно используется fd00::/8.
|
||||
fe80::/10 Локальные канальные адреса (Link-Local). Автоматически назначаются интерфейсам и работают только в пределах одного сегмента сети. Не маршрутизируются.
|
||||
ff00::/8 Multicast-адреса. Используются вместо широковещания (broadcast), которого в IPv6 нет.
|
||||
100::/64 Адреса для протокола Discard-Only. Предназначены для тестирования и отладки.
|
||||
64:ff9b::/96 Префикс для трансляции IPv4↔IPv6 (NAT64).
|
||||
64:ff9b:1::/48 Расширенный префикс NAT64.
|
||||
2001:db8::/32 Зарезервирован для документации и примеров. Не используется в Интернете.
|
||||
2002::/16 6to4-адреса (устаревший механизм перехода с IPv4 на IPv6).
|
||||
2001::/32 Teredo (устаревшая технология туннелирования IPv6 через IPv4).
|
||||
::ffff:0:0/96 IPv4-mapped IPv6 addresses. Используются ОС для представления IPv4-адресов в IPv6 API.
|
||||
|
||||
Адреса узлов сети формируются по следующему принципу:
|
||||
FCxx:xxxx:xxxx:xxxx : yyyy:yyyy:yyyy:yyyy - local network: x = network id, y - node id.
|
||||
-- network id --- ---- node id ------
|
||||
|
||||
FDxx/8 - опциональные ipv6 подсети узлов /64 (если нужно)
|
||||
|
||||
В разных node_groups общие:
|
||||
- nodelists с их настройками (глобальная таблица)
|
||||
- одинаковые линки между nodes (т.к. только один линк между парой узлов)
|
||||
|
||||
- При маршрутизации используем только узлы
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// таблица маршрутизации IPv6 на radix tree + ll_queue (поиск по node_id для удаления)
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* route_connectivity — прямые UDP/TCP-пробы адресов узла для оценки достижимости и RTT.
|
||||
* probe_node запускает серии из подходящих локальных сокетов и обновляет nq->connectivity;
|
||||
* результат используется топологией, сама проба не создаёт READY-сессию группы.
|
||||
* Состояние привязано к TOPO_GROUP_NODE: отменить пробы до удаления узла/группы. Все операции — uasync. */
|
||||
#ifndef ROUTE_CONNECTIVITY_H
|
||||
#define ROUTE_CONNECTIVITY_H
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* route_lib — локальная IPv4-таблица подсетей UTUN, отсортированный массив без пересечения маршрутов.
|
||||
* create → insert/add_local_subnet → lookup → delete/destroy; все операции в одном uasync-потоке.
|
||||
* network/dest_ip/parse_subnet — host order; только is_local_subnet принимает network order.
|
||||
* TOPO_GROUP_NODE заимствован: удалить его маршруты до освобождения узла.
|
||||
* lookup возвращает элемент массива, действительный до следующего изменения таблицы. */
|
||||
#ifndef ROUTE_LIB_H
|
||||
#define ROUTE_LIB_H
|
||||
|
||||
@@ -32,7 +37,7 @@ typedef enum {
|
||||
* Структура представляет собой отдельную запись в таблице маршрутизации с детальной информацией о маршруте.
|
||||
*/
|
||||
struct ROUTE_ENTRY {
|
||||
uint32_t network; // Сетевой адрес (big-endian)
|
||||
uint32_t network; // Сетевой адрес в host order
|
||||
uint8_t prefix_length; // Длина префикса подсети
|
||||
struct TOPO_GROUP_NODE* v_node_info; // узел владелец этих маршрутов. null если - локальный маршрут.
|
||||
};
|
||||
@@ -78,7 +83,7 @@ void route_table_destroy(struct ROUTE_TABLE *table);
|
||||
* @brief Вставляет в таблицу маршрутизации все подсети для указанного узла
|
||||
* @param node узел, все маршруты которого нужно добавить
|
||||
*
|
||||
* @return true если вставка/обновление успешно
|
||||
* @return true если подсети добавлены; false при отсутствии подсетей, пересечении или ошибке выделения памяти
|
||||
*/
|
||||
bool route_insert(struct ROUTE_TABLE *table, struct TOPO_GROUP_NODE *node);
|
||||
|
||||
@@ -94,7 +99,7 @@ void route_delete(struct ROUTE_TABLE *table, struct TOPO_GROUP_NODE *node);
|
||||
* @brief Выполняет поиск маршрута для заданного IP-адреса
|
||||
*
|
||||
* @param table Указатель на таблицу маршрутизации
|
||||
* @param dest_ip Целевой IP-адрес
|
||||
* @param dest_ip Целевой IPv4-адрес в host order
|
||||
* @return найденный маршрут или NULL
|
||||
*/
|
||||
struct ROUTE_ENTRY* route_lookup(struct ROUTE_TABLE *table, uint32_t dest_ip);
|
||||
@@ -110,7 +115,7 @@ void route_table_print(const struct ROUTE_TABLE *table);
|
||||
* @brief Парсит строку подсети в сетевой адрес и длину префикса
|
||||
*
|
||||
* @param subnet_str Строка подсети (например, "192.168.1.0/24")
|
||||
* @param network Указатель для сохранения сетевого адреса
|
||||
* @param network Указатель для сохранения адреса в host order
|
||||
* @param prefix_length Указатель для сохранения длины префикса
|
||||
* @return 0 при успехе, -1 при ошибке
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// routing.h - Centralized routing module for utun
|
||||
/* routing — обмен IPv4-пакетами UTUN между локальным TUN и сервисом DATA ETCP-router.
|
||||
* create создаёт таблицу, bind регистрирует DATA после инициализации router; set_tun подключает очередь TUN.
|
||||
* route_pkt принимает [cmd:1][IPv4...] и забирает entry/dgram; все вызовы выполняются в uasync-потоке.
|
||||
* Групповые пути ведёт topo_group, пересылку через промежуточные узлы — etcp_router. */
|
||||
#ifndef ROUTING_H
|
||||
#define ROUTING_H
|
||||
|
||||
@@ -36,22 +39,20 @@ int routing_bind(struct UTUN_INSTANCE* instance);
|
||||
void routing_destroy(struct UTUN_INSTANCE* instance);
|
||||
|
||||
/**
|
||||
* @brief Register ETCP connection with routing
|
||||
* Called from pn_init() to register connection's normalizer output queue
|
||||
* @brief Исторический вызов из pn_init: сейчас только диагностический no-op, очереди не регистрирует
|
||||
* @param etcp ETCP connection
|
||||
*/
|
||||
void routing_add_conn(struct ETCP_CONN* etcp);
|
||||
|
||||
/**
|
||||
* @brief Unregister ETCP connection from routing
|
||||
* Called from pn_deinit() to unregister connection's normalizer output queue
|
||||
* @brief Исторический вызов из pn_deinit: сейчас только диагностический no-op
|
||||
* @param etcp ETCP connection
|
||||
*/
|
||||
void routing_del_conn(struct ETCP_CONN* etcp);
|
||||
|
||||
/**
|
||||
* @brief Set TUN interface for routing
|
||||
* Called from utun_instance_init() after tun_init()
|
||||
* Вызывается при подключении TUN к UTUN-сервису
|
||||
* @param instance UTUN instance with configured tun
|
||||
*/
|
||||
void routing_set_tun(struct UTUN_INSTANCE* instance);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* topo_node_sqlite — хранение подписанных снимков узлов, адресов, каналов и блоков мемберов в общей SQLite.
|
||||
* Модель/проверка подписей/registry — topo_node и member_sync; этот модуль реализует SQL-операции в uasync-потоке.
|
||||
* snapshot_put проверяет подпись и сохраняет только более свежий timestamp; node_load предпочитает snapshot.
|
||||
* db/groups заимствованы. Возвращённый TOPO_NODE без registry ref: передать registry либо уничтожить через topo_node_destroy.
|
||||
* Массивы out_ids/out_ch_ids/out_peers принадлежат вызывающему и освобождаются u_free. */
|
||||
#ifndef TOPO_NODE_SQLITE_H
|
||||
#define TOPO_NODE_SQLITE_H
|
||||
|
||||
@@ -101,8 +106,8 @@ void topo_node_sqlite_update_rtt(sqlite3* db, uint64_t node_id, uint16_t rtt);
|
||||
* @param groups нужен для выделения адресов из memory_pool
|
||||
* @return TOPO_NODE* или NULL если узел не найден/нет адресов
|
||||
*
|
||||
* Загружает pubkey, name из nodes, IPv4/UDP-адреса из node_addresses.
|
||||
* Вызывающий должен передать владение через topo_node_registry_acquire().
|
||||
* Сначала загружает и проверяет подписанный snapshot; при его отсутствии собирает сведения nodes/node_addresses.
|
||||
* Вызывающий передаёт владение через topo_node_registry_acquire() либо вызывает topo_node_destroy().
|
||||
*/
|
||||
struct TOPO_NODE* topo_node_sqlite_node_load(sqlite3* db, struct TOPO_GROUPS* groups, uint64_t node_id);
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* crc32 — табличный CRC-32 с отражённым полиномом 0xEDB88320.
|
||||
* calc для непустого блока начинает с UINT32_MAX и инвертирует результат.
|
||||
* calc_ex/update возвращают внутренний CRC без финальной инверсии: для потока начать с UINT32_MAX,
|
||||
* последовательно update и в конце инвертировать. NULL/пустой calc → UINT32_MAX, update → исходный CRC.
|
||||
* Таблица общая, без блокировки: при нескольких потоках выполнить init до их запуска. */
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
|
||||
@@ -25,4 +30,4 @@ uint32_t crc32_update(uint32_t crc, const uint8_t *data, size_t len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // CRC32_H
|
||||
#endif // CRC32_H
|
||||
@@ -1,3 +1,7 @@
|
||||
/* etcp_bbr — модель congestion control одного ETCP-линка: состояния BBR, окно и pacing rate.
|
||||
* ETCP собирает bbr_rate_sample из ACK/потерь и вызывает init/main/note_loss/tx_start в uasync-потоке.
|
||||
* Модуль не отправляет пакеты: возвращённые лимиты применяет линк/loadbalancer.
|
||||
* cwnd/inflight/delivered — байты, interval/rtt — микросекунды, pacing_rate — байты в секунду. */
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
@@ -8,178 +8,22 @@ struct ETCP_CONN;
|
||||
struct TOPO_GROUP_NODE;
|
||||
typedef void (*etcp_connect_callback_t)(void* arg, struct ETCP_CONN* conn, int type);
|
||||
|
||||
/**
|
||||
* ============================================================================
|
||||
* etcp_connect() — асинхронное подключение к удалённому узлу
|
||||
* ============================================================================
|
||||
*
|
||||
* Инициирует (или находит существующее) ETCP-соединение к узлу.
|
||||
* Вызов неблокирующий: коллбэк cb вызывается асинхронно по мере прохождения
|
||||
* фаз установки соединения.
|
||||
*
|
||||
* @param inst UTUN_INSTANCE
|
||||
* @param node узел-адресат (TOPO_GROUP_NODE). Из node->node берутся:
|
||||
* - node_id — идентификатор узла (0 = вычислить из pubkey)
|
||||
* - public_key — X25519 pubkey (32 байта)
|
||||
* - v4_addrs / v6_addrs — адреса для создания линков
|
||||
* @param cb коллбэк (etcp_connect_callback_t)
|
||||
* @param arg пользовательский аргумент, передаваемый в cb
|
||||
* @param flags битовая маска интересующих фаз: ETCP_CONNECT_EARLY(1) |
|
||||
* ETCP_CONNECT_LATE(2)
|
||||
* @return 0 при успехе, -1 при ошибке (до вызова коллбэка)
|
||||
*
|
||||
*
|
||||
* ---- Деривация node_id ----
|
||||
*
|
||||
* Если node->node->node_id == 0, он вычисляется из public_key:
|
||||
* node_id = SHA256(pubkey, 32)[0..7] & 0x7FFFFFFFFFFFFFFF
|
||||
*
|
||||
* Требования к ключу:
|
||||
* - public_key не NULL
|
||||
* - не все 32 байта нулевые
|
||||
* Иначе — возврат -1 без вызова коллбэка.
|
||||
*
|
||||
* Вычисленный node_id сохраняется обратно в node->node->node_id.
|
||||
*
|
||||
*
|
||||
* ---- Индексация соединения ----
|
||||
*
|
||||
* Сразу после etcp_connection_create() conn->peer_node_id устанавливается
|
||||
* в node_id, что позволяет etcp_conn_queue_set_ready() (при инициализации
|
||||
* первого линка) переиндексировать запись в очереди inst->connections
|
||||
* с key=0 на key=node_id.
|
||||
*
|
||||
* До переиндексации соединение находится в очереди с key=0 и доступно
|
||||
* только через connect_find() в pending_connects или по совпадению адреса.
|
||||
*
|
||||
*
|
||||
* ---- Поиск существующего соединения ----
|
||||
*
|
||||
* Перед созданием нового conn выполняется поиск:
|
||||
*
|
||||
* a. instance_find_conn(inst, node_id) — активное соединение в очереди
|
||||
* inst->connections (UDP) или inst->tcp_connections (TCP)
|
||||
* b. connect_find(inst, node_id) — контекст в inst->pending_connects
|
||||
*
|
||||
* Возможные комбинации:
|
||||
*
|
||||
* 1. conn && ctx — уже подключается
|
||||
* ├─ ctx->done (таймаут уже сработал) → cb(arg, NULL, 0) сразу
|
||||
* └─ иначе → cb добавляется в ctx->cb_list (ждёт своей фазы)
|
||||
*
|
||||
* 2. !conn && ctx — контекст есть, но conn был удалён (редкий случай)
|
||||
* → cb добавляется в ctx->cb_list
|
||||
*
|
||||
* 3. conn && !ctx — соединение рабочее, контекста нет (входящее/серверное)
|
||||
* ├─ conn->state == 0 (pending, ещё не инициализирован):
|
||||
* │ → создаётся ctx с connect_init_cb, initial_timer
|
||||
* │ → ctx добавляется в pending_connects
|
||||
* │ → ожидание инициализации в обычном порядке
|
||||
* │
|
||||
* └─ conn->state == 1 (ready, уже проинициализирован):
|
||||
* → connect_deliver(ctx, ETCP_CONNECT_LATE) сразу
|
||||
* → контекст освобождается; готовность топологии принадлежит группе
|
||||
*
|
||||
* 4. !conn && !ctx — новое подключение (основной путь)
|
||||
* → etcp_connection_create(inst, NULL)
|
||||
* → conn->peer_node_id = node_id (индексация deferred до queue_set_ready)
|
||||
* → sc_init_ctx + sc_set_peer_public_key — настройка крипто
|
||||
* → connect_create_links_v4/v6 — создание UDP + TCP линков
|
||||
* → initial_timer = uasync_set_timeout(connect_timeout_tb, ...)
|
||||
* → ctx добавляется в pending_connects
|
||||
*
|
||||
*
|
||||
* ---- Фазы доставки коллбэков ----
|
||||
*
|
||||
* connect_init_cb (вызывается при conn->initialized, первый линк отдал рукопожатие):
|
||||
*
|
||||
* Подсчитывается total_links и up_links (link_state == 3):
|
||||
*
|
||||
* ├─ total_links == 1: один линк — EARLY не нужен
|
||||
* │ → connect_deliver(ctx, ETCP_CONNECT_LATE) — сразу LATE
|
||||
* │ → ctx освобождается
|
||||
* │
|
||||
* ├─ up_links == total_links: все линки уже UP (link_state==3)
|
||||
* │ → connect_deliver(ctx, ETCP_CONNECT_LATE) — сразу LATE
|
||||
* │ → ctx освобождается
|
||||
* │
|
||||
* └─ иначе (часть линков UP, часть ещё в handshake):
|
||||
* → connect_deliver(ctx, ETCP_CONNECT_EARLY) — уведомить о доступности
|
||||
* → initial_timer отменяется
|
||||
* → запускается settle_timer = min_rtt * 8 (clamped [500ms, 2s] в 0.1ms)
|
||||
*
|
||||
* connect_settle_timeout_cb (settle-таймер):
|
||||
* ├─ Закрывает неинициализированные линки (!link->initialized)
|
||||
* ├─ Закрывает TCP-линк если !tcp_ready
|
||||
* ├─ Убирает connect_init_cb из conn->cbks
|
||||
* └─ connect_deliver(ctx, ETCP_CONNECT_LATE) → ctx освобождается
|
||||
*
|
||||
* connect_initial_timeout_cb (initial_timer):
|
||||
* ├─ ctx->done = 1
|
||||
* ├─ Закрывает TCP-линк
|
||||
* ├─ connect_deliver(ctx, 0) → cb(arg, NULL, 0) для всех
|
||||
* ├─ etcp_connection_close(conn) — закрывает соединение
|
||||
* └─ ctx освобождается
|
||||
*
|
||||
*
|
||||
* ---- Ошибки ----
|
||||
*
|
||||
* Коллбэк вызывается с type=0, conn=NULL в случаях:
|
||||
* - initial_timer истёк (ни один линк не инициализировался)
|
||||
* - все линки были закрыты до завершения handshake
|
||||
* - ошибка аллокации / крипто на этапе создания
|
||||
*
|
||||
*
|
||||
* ---- Штатное закрытие исходящих соединений ----
|
||||
*
|
||||
* Пути завершения ctx:
|
||||
*
|
||||
* 1. Таймаут установки (connect_initial_timeout_cb):
|
||||
* stcp_link_close(tcp_link) → etcp_connection_close(conn) → connect_cancel(ctx)
|
||||
*
|
||||
* 2. Settle таймаут (connect_settle_timeout_cb):
|
||||
* stcp_link_close(tcp_link) (если !tcp_ready) → connect_cancel(ctx)
|
||||
*
|
||||
* 3. Штатное закрытие через utun_instance_destroy():
|
||||
* utun_instance_destroy(inst)
|
||||
* ├── etcp_connection_close(conn) для всех conn
|
||||
* │ Фаза 1 (detach): закрыть линки, удалить из inst->connections, state=2
|
||||
* │ Фаза 2 (deferred): uasync_call_soon(ua, conn, etcp_connection_free_deferred)
|
||||
* │
|
||||
* ├── while (immediate_queue_head) uasync_poll(ua, 0)
|
||||
* │ └── etcp_connection_free_resources(conn)
|
||||
* │ ├── drain_and_free_queue(*)
|
||||
* │ ├── etcp_connect_cancel_for_conn(inst, conn)
|
||||
* │ └── u_free(etcp)
|
||||
* │
|
||||
* └── memory_pool_destroy(pkt/ack/data)
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
/* Внутренний установщик прямого ETCP-транспорта; владельцы используют node_conn_direct.h.
|
||||
* node->node_id должен находиться в node_registry: оттуда берутся ключ и IPv4/IPv6 адреса.
|
||||
* Подключение создаёт UDP/STCP-линки либо подписывает callback на текущую попытку к тому же узлу.
|
||||
* Все вызовы/callbacks — в uasync. flags — непустая маска ETCP_CONNECT_EARLY/LATE (etcp_api.h).
|
||||
* EARLY означает появление транспорта; LATE — завершение выбора линков. Они не означают READY группы.
|
||||
* При одном/полностью готовом наборе линков обе запрошенные фазы выдаются подряд;
|
||||
* иначе после EARLY ждём settle 0.5..2с и удаляем неинициализированные линки.
|
||||
* Для уже готового соединения callback вызывается внутри etcp_connect, до возврата.
|
||||
* conn в callback заимствован. type=0/conn=NULL — отказ; initial timeout закрывает соединение.
|
||||
* Возврат 0 означает принятую попытку/выданный результат; -1 — ошибка, причём некоторые
|
||||
* ошибки создания также вызывают cb(NULL,0). Обработчик должен учитывать оба способа отказа. */
|
||||
int etcp_connect(struct UTUN_INSTANCE* instance, struct TOPO_GROUP_NODE* node,
|
||||
etcp_connect_callback_t cb, void* arg, uint8_t flags);
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* etcp_connect_cancel_for_conn()
|
||||
* ============================================================================
|
||||
*
|
||||
* Аналог приватного connect_cancel(), но ищет ETCP_CONNECT ctx по совпадению
|
||||
* ctx->conn == conn (а не по указателю на ctx).
|
||||
*
|
||||
* Делает:
|
||||
* 1. Удаляет ctx из inst->pending_connects
|
||||
* 2. ctx->done = 1; ctx->conn = NULL
|
||||
* 3. uasync_cancel_timeout(initial_timer / settle_timer)
|
||||
* 4. u_free(ctx)
|
||||
*
|
||||
* НЕ закрывает ctx->tcp_link (чужая ответственность).
|
||||
*
|
||||
* Вызывается ТОЛЬКО из etcp_connection_free_resources (фаза 2 deferred cleanup).
|
||||
* НЕ вызывать из mainloop / uasync_poll callbacks — conn уже может быть в state=2.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
/* Снять таймеры/контекст по conn без уведомления callbacks. Только teardown соединения,
|
||||
* когда connect_init_cb больше не может быть вызван; транспорт освобождает вызывающий слой. */
|
||||
void etcp_connect_cancel_for_conn(struct UTUN_INSTANCE* inst, struct ETCP_CONN* conn);
|
||||
|
||||
/* Полная отмена pending-коннекта по node_id: снимает коллбэки с conn (conn остаётся
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* etcp_debug — форматирование IPv4 в host order и диагностический разбор секций ETCP_DGRAM.
|
||||
* ip_to_string возвращает строку по значению. dump_pkt_sections пишет DEBUG категории dump,
|
||||
* не меняет пакет и не проверяет его криптографию; состояние pkt/link читается в uasync-потоке. */
|
||||
#ifndef ETCP_DEBUG_H
|
||||
#define ETCP_DEBUG_H
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* etcp_dump — снимки состояния ETCP-соединений/линков, очередей и сокетов экземпляра.
|
||||
* Вызывается в uasync-потоке, пишет DEBUG категории etcp_dump; не меняет состояние и не владеет объектами.
|
||||
* conn_state выводит один conn, all_conns/sockets — соответствующие списки, all — оба списка. */
|
||||
#ifndef ETCP_DUMP_H
|
||||
#define ETCP_DUMP_H
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// etcp_loadbalancer.h - Load Balancer for ETCP Channels
|
||||
/* etcp_loadbalancer — выбор доступного линка одного ETCP_CONN с учётом cwnd, inflight и pacing/shaper.
|
||||
* select_link возвращает заимствованный готовый линк или NULL. send шифрует/отправляет пакет и учитывает shaper,
|
||||
* link_ready пробуждает packet_request_fn после снятия ограничений; все вызовы — uasync-поток соединения. */
|
||||
#ifndef ETCP_LOADBALANCER_H
|
||||
#define ETCP_LOADBALANCER_H
|
||||
|
||||
@@ -20,13 +22,13 @@ struct ETCP_LINK* etcp_loadbalancer_select_link(struct ETCP_CONN* etcp);
|
||||
|
||||
// Когда линк снова ready (timer или link_ready) - loadbalancer должен вызвать ETCP_CONN->packet_request_fn(etcp)
|
||||
|
||||
//void etcp_loadbalancer_update_after_send(struct ETCP_LINK* link, size_t pkt_size); - это надо заменить на:
|
||||
// Передать dgram с установленным link: после отправки (включая ошибку сокета) возвращает dgram в pkt_pool.
|
||||
void etcp_loadbalancer_send(struct ETCP_DGRAM* dgram);
|
||||
|
||||
// сообщаем в loadbalancer о готовности линка (вызывается из таймера, ACK, изменения лимита)
|
||||
void loadbalancer_link_ready(struct ETCP_LINK* link);
|
||||
|
||||
// проверяет все условия блокировки отправки (включая inflight_bytes)
|
||||
// Проверяет готовность shaper (burst разрешён); cwnd/inflight учитывает select_link отдельно.
|
||||
int loadbalancer_link_can_send(struct ETCP_LINK* link);
|
||||
|
||||
// Получить состояние связи ETCP: 1 - есть живой линк, 0 - все недоступны
|
||||
@@ -36,4 +38,4 @@ int etcp_loadbalancer_get_link_status(struct ETCP_CONN* etcp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ETCP_LOADBALANCER_H
|
||||
#endif // ETCP_LOADBALANCER_H
|
||||
@@ -1,3 +1,7 @@
|
||||
/* etcp_session — подтверждение эпох одного ETCP_CONN, чтобы старые DATA не попадали в новый поток.
|
||||
* HELLO/CHALLENGE/CONFIRM отправляются по инициализированным линкам, вне надёжного потока/normalizer.
|
||||
* Обработчик вызывается после проверки защиты пакета; принадлежность сессии проверяет accept_data.
|
||||
* Состояние и retry-таймер принадлежат ETCP_CONN. Все вызовы — его uasync-поток; перед teardown нужен cancel. */
|
||||
#ifndef ETCP_SESSION_H
|
||||
#define ETCP_SESSION_H
|
||||
#include <stddef.h>
|
||||
@@ -11,11 +15,16 @@ struct ETCP_CONN;
|
||||
#define ETCP_SESSION_HEADER_SIZE 17
|
||||
#define ETCP_SESSION_CONTROL_SIZE 25
|
||||
|
||||
/* Authenticated link control, independent of the reliable stream and its normalizer. */
|
||||
/* Запустить обязательное подтверждение; при таймауте неподтверждённое соединение закрывается. */
|
||||
void etcp_session_start(struct ETCP_CONN* conn);
|
||||
/* Предложить ненулевую эпоху пира для challenge; это ещё не разрешает приём DATA новой эпохи. */
|
||||
void etcp_session_observe(struct ETCP_CONN* conn, uint64_t peer_epoch);
|
||||
/* Отменить retry и сбросить candidate/cookie; подтверждённые reset_id/peer_reset_id сохраняются. */
|
||||
void etcp_session_cancel(struct ETCP_CONN* conn);
|
||||
/* 1 — control распознан (в том числе отброшен как ошибочный), 0 — не control. Буфер остаётся у вызывающего. */
|
||||
int etcp_session_receive(struct ETCP_CONN* conn, const uint8_t* data, size_t len);
|
||||
/* Записать 17-байтный заголовок code/sender/target; epochs — big-endian, cookie/body добавляет вызывающий. */
|
||||
void etcp_session_encode(uint8_t* data, uint8_t code, uint64_t sender, uint64_t target);
|
||||
/* 1 — DATA принадлежит готовой текущей сессии, 0 — ошибочная/старая. Заголовок не снимает, поток не обрабатывает. */
|
||||
int etcp_session_accept_data(struct ETCP_CONN* conn, const uint8_t* data, size_t len);
|
||||
#endif
|
||||
@@ -1,3 +1,6 @@
|
||||
/* packet_dump — текстовая сводка IPv4-пакета: адреса, транспортные поля и короткий hex-фрагмент.
|
||||
* Принимает IP-пакет без ETCP-заголовка. Результат в общем static-буфере перезаписывается каждым вызовом;
|
||||
* его не освобождать, для хранения скопировать. Модуль не потокобезопасен и сам в лог не пишет. */
|
||||
#ifndef PACKET_DUMP_H
|
||||
#define PACKET_DUMP_H
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
// pkt_normalizer.h (упрощенная версия)
|
||||
/* pkt_normalizer — упаковка кодограмм сервисов в надёжный байтовый поток ETCP и обратная сборка.
|
||||
* input принимает целые кодограммы, packer добавляет длину и делит поток под MTU;
|
||||
* unpacker читает etcp->output_queue и выдаёт целые кодограммы в output/etcp_int_recv.
|
||||
* Содержимое cmd сервисов непрозрачно для normalizer. Контекст принадлежит ETCP_CONN,
|
||||
* владеет своими очередями/частичными буферами/ожиданием backpressure; все вызовы — uasync. */
|
||||
#ifndef PKT_NORMALIZER_H
|
||||
#define PKT_NORMALIZER_H
|
||||
|
||||
@@ -11,14 +15,7 @@ extern "C" {
|
||||
#include "../lib/u_async.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
формат кодограмм: <cmd 1 byte> <data ... n bytes>
|
||||
cmd = 0 - пакет для передачи адресату (далее содержимое пакета)
|
||||
cmd = 1 - элемент роутинг-таблицы (далее один маршрут)
|
||||
cmd = 2 - запрос роутинг-таблицы (без данных)
|
||||
|
||||
|
||||
*/
|
||||
/* Формат входной кодограммы: [cmd:1][данные сервиса...]; максимальная длина — PKTNORM_MAX_DGRAM_SIZE. */
|
||||
|
||||
#define PKTNORM_MAX_DGRAM_SIZE 16384
|
||||
|
||||
@@ -78,4 +75,4 @@ void pn_unpacker_reset_state(struct PKTNORM* pn);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // PKT_NORMALIZER_H
|
||||
#endif // PKT_NORMALIZER_H
|
||||
@@ -1,4 +1,9 @@
|
||||
// secure_channel.h
|
||||
/* secure_channel — криптографические операции транспорта, без сокетов и сетевого handshake.
|
||||
* Инициализировать локальные X25519-ключи → init_ctx → set_peer_public_key → encrypt/decrypt.
|
||||
* ctx заимствует SC_MYKEYS до конца использования; состояние счётчиков и stream-объекты имеют одного владельца.
|
||||
* Пакеты: AES-128-CCM над plaintext+CRC32; выход = nonce(13)+ciphertext+tag(16).
|
||||
* Отдельные API дают обфускацию ключа, потоковый AES-CTR и Ed25519; CTR сам по себе не аутентифицирует данные.
|
||||
* Возврат SC_OK / отрицательный SC_ERR_*; caller владеет входными/выходными буферами. */
|
||||
#ifndef SECURE_CHANNEL_H
|
||||
#define SECURE_CHANNEL_H
|
||||
|
||||
@@ -66,7 +71,9 @@ sc_status_t sc_init_local_keys(struct SC_MYKEYS *mykeys, const char *public_key,
|
||||
sc_status_t sc_set_peer_public_key(sc_context_t *ctx, const uint8_t *peer_public_key, int mode);// mode: 0-bin 1-hex key format
|
||||
sc_status_t sc_compute_public_key_from_private(const uint8_t *private_key, uint8_t *public_key);
|
||||
|
||||
// Криптографические операции
|
||||
/* Выходные длины только заполняются, не задают capacity! Для encrypt выделить plaintext_len+33 байта,
|
||||
* для decrypt — ciphertext_len-33. Пустой plaintext запрещён; decrypt проверяет CCM tag и CRC.
|
||||
* Проверка повторного посещения/эпохи транспорта находится выше этого модуля. */
|
||||
sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len);
|
||||
sc_status_t sc_decrypt(sc_context_t *ctx, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *plaintext, size_t *plaintext_len);
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* socket_monitor — наблюдение за адресами интерфейсов и маршрутами ОС для ETCP-сокетов.
|
||||
* init подключает уведомления ОС к uasync экземпляра; изменения обновляют interface_addr и сетевое состояние.
|
||||
* auto_socket отдельно создаёт/удаляет сокеты. destroy отключает наблюдение до освобождения экземпляра.
|
||||
* Публичные операции и изменения ETCP_SOCKET — в потоке uasync. */
|
||||
#ifndef SOCKET_MONITOR_H
|
||||
#define SOCKET_MONITOR_H
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
// stcp.h — Streaming TCP: shared structures, constants, connection lifecycle
|
||||
/* stcp — зашифрованное фреймирование поверх TCP: handshake ключей/эпох, AES-CTR поток и CRC кадров.
|
||||
* Этот заголовок — внутренние структуры и I/O; создание исходящих/входящих соединений — client/server,
|
||||
* интеграция с ETCP_LINK — stcp_link.h. Все операции одного соединения выполняются в uasync-потоке.
|
||||
* do_close закрывает I/O и вызывает on_close; окончательное освобождение зависит от владельца conn.
|
||||
* recv_on_chunk получает заимствованный буфер только на время callback; rx_queue получает отдельную копию. */
|
||||
#ifndef STCP_H
|
||||
#define STCP_H
|
||||
|
||||
@@ -163,12 +167,12 @@ int stcp_frame_decrypt(uint8_t *data, size_t len, struct sc_stream_state *strea
|
||||
void stcp_pending_queue(struct stcp_conn *c, const uint8_t *data, size_t len);
|
||||
void stcp_pending_clear(struct stcp_conn *c);
|
||||
|
||||
// takes ownership of data (must be u_malloc'd, will be u_free'd)
|
||||
// data из u_malloc: 0 — отправлен и освобождён, 1 — принят для досылки; -1 оставляет data вызывающему.
|
||||
int stcp_try_send(struct stcp_conn *c, uint8_t *data, size_t len);
|
||||
void stcp_write_cb(socket_t sock, void *arg);
|
||||
void stcp_flush_pending(struct stcp_conn *c);
|
||||
|
||||
// unified recv: read from TCP, grow recv_buf, calls stcp_recv_try. returns 1=data, 0=wait, -1=error/closed
|
||||
// Читает TCP в recv_buf: 1 — новые байты, 0 — ждать, -1 — ошибка/закрыто. Разбор через stcp_recv_try вызывает владелец.
|
||||
int stcp_conn_read(struct stcp_conn *c);
|
||||
|
||||
// set next expected chunk: need=0+streaming=1 enters DATA stream mode
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// stcp_client.h — STCP client: connect, handshake
|
||||
/* stcp_client — асинхронные TCP connect и STCP-handshake, с опциональными SOCKS5 и REALITY.
|
||||
* connect возвращает владеющий handle или NULL; готовность DATA сообщает ready_cb, закрытие — close_cb.
|
||||
* get_conn заимствует conn из handle. destroy отменяет подключение/закрывает conn и делает handle недействительным.
|
||||
* Все API/callbacks — uasync-поток; TCP-ping использует отдельный короткий handshake и не создаёт ETCP-сессию. */
|
||||
#ifndef STCP_CLIENT_H
|
||||
#define STCP_CLIENT_H
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
// stcp_link.h — STCP link management (TCP connection via STCP protocol)
|
||||
/* stcp_link — адаптер STCP-соединения к ETCP_LINK: handshake, очереди DATA, ready/close callbacks.
|
||||
* Серверный путь создаёт входящие линки, connect запускает исходящий для заданного ETCP_LINK.
|
||||
* send копирует data в tx_queue (0 / -1); ready означает готовность STCP, не READY topo-группы.
|
||||
* close гасит callback внезапного разрыва и откладывает teardown; после close handle не использовать.
|
||||
* API и callbacks — uasync-поток. Указатели get_* заимствованы; адреса peer/local используют static-буферы. */
|
||||
#ifndef STCP_LINK_H
|
||||
#define STCP_LINK_H
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// stcp_server.h — STCP server: listen, accept, handshake
|
||||
/* stcp_server — TCP listener и входящий STCP-handshake для одного UTUN_INSTANCE.
|
||||
* create → connect_cb для готовых conn → destroy; сервер владеет listener и списком принятых соединений.
|
||||
* destroy закрывает также принятые conn и вызывает их close callbacks; все операции — uasync-поток.
|
||||
* set_reality включает TLS-камуфляж и relay неавторизованных клиентов; результат conn callback заимствован. */
|
||||
#ifndef STCP_SERVER_H
|
||||
#define STCP_SERVER_H
|
||||
|
||||
|
||||
+5
-1
@@ -1,4 +1,8 @@
|
||||
// tun_if.h - Cross-platform TUN interface management for utun
|
||||
/* Кроссплатформенный TUN: init создаёт интерфейс и очереди, close освобождает их.
|
||||
* output_queue несёт TUN → ядро, input_queue — ядро → TUN; формат очереди: префикс(1) + IP-пакет.
|
||||
* tun_write принимает тот же префикс и пропускает его при записи; tun_inject_packet принимает чистый IP.
|
||||
* Основной API — в uasync; Windows read-thread передаёт пакеты через tun_packet_handler.
|
||||
* test_mode использует очереди вместо устройства ОС. */
|
||||
#ifndef TUN_IF_H
|
||||
#define TUN_IF_H
|
||||
|
||||
|
||||
Reference in new issue
Block a user