You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
326 lines
16 KiB
326 lines
16 KiB
/* utun_instance — владелец ядра и сервисов одного узла. |
|
* Ядро содержит транспорт, маршрутизатор, идентичность и общую БД. |
|
* create → core_start; UTUN и чат запускаются отдельно через service_start/stop. |
|
* Все операции жизненного цикла — в потоке переданного uasync, вне callbacks сервисов. |
|
* destroy останавливает сервисы и освобождает ядро, но не сам uasync. */ |
|
#ifndef UTUN_INSTANCE_H |
|
#define UTUN_INSTANCE_H |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
|
|
#include <stdint.h> |
|
#include <stdbool.h> |
|
#include <stdio.h> |
|
#include "../lib/memory_pool.h" |
|
#include "../lib/sqlite3.h" |
|
#include "secure_channel.h" |
|
#include "etcp_api.h" |
|
#include "config_parser.h" |
|
#include "stcp_link.h" |
|
#include "firewall.h" |
|
#include "eim_nat.h" |
|
#include "nat_transport.h" |
|
#include "media_delivery/media_delivery.h" |
|
#include "media_async/media_async.h" |
|
#include "proxy/tcp_proxy_client.h" |
|
#include "etcp_router.h" |
|
#include "proxy/tcp_proxy_server.h" |
|
#include "ntp_time.h" |
|
#include "ntp_node_time.h" |
|
|
|
#include "etcp_api.h" |
|
#include "config_parser.h" |
|
#include "topo_group.h" |
|
#include "chat/chat_setting.h" |
|
#include "chat/chat_event.h" |
|
|
|
// Forward declarations |
|
struct utun_config; |
|
struct chat_core_ctx; |
|
struct chat_sync; |
|
struct join_key_entry; /* chat_join.c */ |
|
struct dm_state; |
|
struct dm_mb_state; |
|
struct call_ctx; /* call/call.c */ |
|
struct radio_instance; /* radio/radio.c */ |
|
struct radio_headless; /* radio/radio_headless.c */ |
|
struct uasync_s; |
|
struct ROUTE_TABLE; |
|
struct ETCP_CONN; |
|
typedef void (*etcp_new_conn_fn)(struct ETCP_CONN* conn, void* arg); |
|
struct ETCP_SOCKET; |
|
struct NODE_CONN_DIRECT; |
|
struct tun_if; |
|
struct ETCP_BINDINGS; |
|
struct ETCP_ROUTER_BINDINGS; |
|
struct TOPO_GROUP; |
|
struct TOPO_GROUPS; |
|
struct control_server; |
|
|
|
struct PING_CONTEXT; |
|
struct CONN_MGR; |
|
struct ETCP_CONNECT; |
|
struct DB_SYNC; |
|
struct NAT_DETECTION; |
|
struct merkle_sync; |
|
|
|
struct NETWORK_ENTRY { |
|
uint64_t id; // 56-bit (offset 0 = index key) |
|
uint8_t pubkey[SC_PUBKEY_SIZE]; // 32 bytes binary |
|
uint8_t signing_key[SC_PRIVKEY_SIZE]; // 32 bytes binary |
|
char name[64]; |
|
}; |
|
|
|
// Queue entry for instance->connections (indexed by peer_node_id) |
|
struct conn_queue_entry { |
|
uint64_t peer_node_id; |
|
struct ETCP_CONN* conn; |
|
}; |
|
|
|
// Постоянный запрос UTUN-сервиса к пиру из конфигурации; транспортом владеет группа. |
|
struct CONFIG_CONN_HANDLE { |
|
uint64_t node_id; |
|
char name[MAX_CONN_NAME_LEN]; |
|
struct TOPO_PEER_REQUEST* request; // принадлежит этой записи; закрывается при stop/reload |
|
struct CONFIG_CONN_HANDLE* next; |
|
}; |
|
|
|
// Queue entry for instance->tcp_connections (indexed by node_id) |
|
struct tcp_conn_entry { |
|
uint64_t node_id; // index key |
|
struct stcp_link* link; // active TCP link |
|
struct ETCP_CONN* etcp_conn; // = stcp_link_get_etcp_conn(link) — for etcp_send() compat |
|
}; |
|
|
|
// Подписка на смену active mode (client_activity). Событие рассылается |
|
// подписчикам (topo_group, keepalive и т.д.) при каждом изменении активности. |
|
typedef void (*utun_activity_cbk_fn)(struct UTUN_INSTANCE* instance, int active, void* arg); |
|
struct utun_activity_cbk_entry { |
|
utun_activity_cbk_fn fn; |
|
void* arg; |
|
struct utun_activity_cbk_entry* next; |
|
}; |
|
|
|
// Подписка на смену спячки пира (keepalive-протокол). Сервер (или любой узел) |
|
// получает от мобильного пира sleep-анонс и уведомляет подписчиков: |
|
// sleeping=1 — пир ушёл в спячку (в фон), 0 — проснулся (дедлайн истёк / обычный keepalive). |
|
typedef void (*peer_sleep_cbk_fn)(struct UTUN_INSTANCE* instance, uint64_t peer_node_id, int sleeping, void* arg); |
|
struct peer_sleep_cbk_entry { |
|
peer_sleep_cbk_fn fn; |
|
void* arg; |
|
struct peer_sleep_cbk_entry* next; |
|
}; |
|
|
|
// Состояние одного узла. Вложенные модули освобождаются через их lifecycle API. |
|
struct UTUN_INSTANCE { |
|
uint8_t core_started, utun_started, chat_started; // успешный запуск ядра / UTUN / чата |
|
|
|
// Identification |
|
char name[MAX_CONN_NAME_LEN]; // Instance name from config |
|
|
|
// Конфигурация принадлежит экземпляру после успешного create. |
|
struct utun_config *config; |
|
|
|
// TUN interface |
|
struct tun_if* tun; |
|
|
|
// Заимствованный список системных маршрутов из config; нужен для stop UTUN. |
|
struct CFG_ROUTE_ENTRY* route_subnets; |
|
|
|
struct ROUTE_TABLE* rt; // таблица маршрутов подсетей |
|
struct TOPO_GROUPS* topo_groups; // Groups module for topology exchange |
|
sqlite3* topo_sqlite_db; // Shared SQLite DB (nodes/channels/peers) |
|
struct NAT_DETECTION* nat_det; // NAT detection module |
|
struct merkle_sync* msync; // Merkle tree sync module (per-instance) |
|
|
|
// Identification |
|
uint64_t node_id; |
|
|
|
struct SC_MYKEYS my_keys; |
|
|
|
uint8_t my_ed25519_pubkey[SC_PUBKEY_SIZE]; // свой Ed25519 pubkey (для подписи метрик) |
|
uint8_t my_ed25519_privkey[SC_PRIVKEY_SIZE]; // свой Ed25519 privkey (derived from X25519) |
|
|
|
uint8_t next_socket_id; // Counter for unique socket IDs (0-255) |
|
|
|
// Заимствованный цикл событий: создаёт и уничтожает вызывающий. |
|
struct UASYNC* ua; |
|
|
|
// State |
|
int running; // продолжать utun_instance_run; не флаг готовности сервисов |
|
|
|
// Connections (очередь всех подключений для instance) |
|
struct ll_queue* connections; // indexed by peer_node_id (0=pending), data=conn_queue_entry |
|
struct ll_queue* tcp_connections; // indexed by node_id, data=tcp_conn_entry [TCP-only] |
|
|
|
// Callback chain for new ETCP connections |
|
struct etcp_inst_cbk_entry* new_conn_cbks; |
|
struct etcp_link_status_cbk_entry* link_status_cbks; |
|
struct etcp_status_cbk_entry* conn_status_cbks; // instance-level: NEW/UP/DOWN/DELETE |
|
struct etcp_socket_cbk_entry* socket_cbks; // instance-level: socket ADDR/STATUS changes |
|
struct nodeinfo_cbk_entry* nodeinfo_cbks; // глобальная подписка на изменения nodeinfo |
|
void* test_user_ptr; // Generic user pointer (used by tests) |
|
|
|
struct memory_pool* data_pool;// для входных-выходных данных пакета |
|
struct memory_pool* pkt_pool; // ETCP_DGRAM и буферы сетевых пакетов |
|
struct memory_pool* ack_pool; // ACK_PACKET |
|
|
|
// Active sockets (UDP + TCP, is_tcp=1 flag) |
|
struct ETCP_SOCKET* etcp_sockets;// linked-list (UDP + TCP) |
|
struct stcp_server *stcp_servers; // TCP servers linked list (via stcp_link.c) |
|
void* socket_monitor; // SOCKET_MONITOR* (opaque, transport_layer/socket_monitor.c) |
|
void* auto_socket_state; // AUTO_SOCKET* (opaque, transport_layer/auto_socket.c) |
|
uint8_t auto_socket_enabled; // 1 = auto_sockets enabled from config |
|
|
|
// Pending one-shot pings (for callback on PONG or timeout) |
|
struct PING_CONTEXT* pending_pings; |
|
|
|
// Routing statistics |
|
uint64_t routed_packets; |
|
uint64_t dropped_packets; |
|
|
|
// ETCP API bindings (per-instance) |
|
struct ETCP_BINDINGS api_bindings; |
|
|
|
// Control server for monitoring |
|
struct control_server* control_srv; |
|
|
|
// Firewall |
|
struct firewall_ctx fw; |
|
|
|
// EIM NAT |
|
struct eim_nat_ctx nat; |
|
struct nat_transport_ctx nat_tr; |
|
|
|
// Media delivery |
|
struct media_delivery_ctx md; |
|
|
|
// Media async engine (thread-per-task for crypto/file ops) |
|
struct media_async* media_async; |
|
|
|
// Socket initialization status: 0=OK, 1=partial (some sockets failed), -1=error (none created) |
|
int socket_init_status; |
|
|
|
// TCP proxy client (optional, NULL if not enabled) |
|
struct tcp_proxy_client* tcp_proxy_client; |
|
|
|
// etcp_router bindings и seq-connections (per-instance service routing) |
|
struct ETCP_ROUTER_BINDINGS router_bindings; |
|
struct ll_queue* router_conns; |
|
uint64_t router_loop_drops; // пакеты, вернувшиеся в уже посещённый узел |
|
uint64_t router_path_errors; // некорректный или переполненный список пройденных узлов |
|
struct CONN_MGR* conn_mgr; // заимствован у UTUN-группы; NULL при остановленном UTUN |
|
struct DB_SYNC* db_sync; // Distributed DB sync (может быть NULL) |
|
|
|
// Контексты чат-сервиса; освобождаются при chat_service_stop. |
|
struct chat_core_ctx* chat_core; // каналы, сообщения и доступ к общей БД |
|
struct chat_sync* chat_sync; // join и синхронизация каналов |
|
struct join_key_entry* join_keys; // зарегистрированные ключи приглашений |
|
struct chat_join_registration* join_registrations; // ожидания KEY_REGISTER_ACK |
|
int join_stopping; // запрещает новые регистрации при teardown |
|
struct chat_invite_build_req* invite_gui_request; // текущее построение ссылки для GUI |
|
struct dm_state* dm; // личные сообщения |
|
struct dm_mb_state* dm_mailbox; // хранилище личных сообщений для получателей |
|
struct call_ctx* call; // call/call.c — P2P audio call |
|
void* call_audio; // call/call_headless.c — audio stream socket |
|
struct radio_instance* radio; // radio/radio.c — PTT walkie-talkie (frame cb + counters) |
|
struct radio_headless* radio_headless; // radio/radio_headless.c — audio stream socket |
|
struct chat_setting_state chat_settings; // текущие настройки чата |
|
chat_event_handler_fn chat_event_handler; // получатель событий чата |
|
void* headless; // контекст TCP-управления headless-чатом |
|
|
|
// E2E encryption cache — per-peer sc_context_t with derived session key |
|
#define E2E_CTX_CACHE_SIZE 8 |
|
struct { uint64_t peer_node_id; struct secure_channel ctx; uint8_t valid; } e2e_ctx_cache[E2E_CTX_CACHE_SIZE]; |
|
|
|
struct broadcast_ctx* broadcast; // Broadcast protocol instance handler (ETCP_ID_BROADCAST dispatcher) |
|
|
|
uint8_t client_type; // CLIENT_TYPE_SERVER/DESKTOP/MOBILE (from config) |
|
uint16_t keepalive_interval; // желаемый keepalive (ms), из конфига. для handshake |
|
uint8_t client_activity; // CLIENT_ACTIVITY_STANDBY/ACTIVE |
|
void* client_activity_timer; // uasync timer handle for inactivity timeout |
|
struct utun_activity_cbk_entry* activity_cbks; // подписки на смену client_activity |
|
struct peer_sleep_cbk_entry* peer_sleep_cbks; // подписки на смену спячки пира (keepalive) |
|
uint8_t standby_enabled; // 1 = standby duty-cycle активен (chatgui-android) |
|
|
|
// TCP proxy server (exit node) |
|
struct tcp_proxy_server tcp_proxy_server; |
|
struct udp_proxy_ctx* udp_proxy; |
|
struct icmp_proxy_ctx* icmp_proxy; |
|
|
|
// Networks (queue of NETWORK_ENTRY, indexed by 56-bit id) |
|
struct ll_queue* networks; |
|
|
|
// Pending background connections (etcp_connect API) |
|
struct ETCP_CONNECT* pending_connects; |
|
uint32_t etcp_connect_timeout_tb; // Initial timeout in 0.1ms units, default 20000 (2s) |
|
|
|
// NTP time synchronization |
|
struct NTP_TIME ntp; |
|
struct NTP_NODE_TIME ntp_node; |
|
|
|
// Постоянные групповые запросы UTUN к пирам из конфигурации. |
|
struct CONFIG_CONN_HANDLE* config_conn_handles; |
|
|
|
// Per-instance NCD state (replaces global statics in node_conn_direct.c) |
|
void* ncd_registry; // struct ncd_entry* linked list |
|
uint8_t ncd_control_bound; // 1 = etcp_bind(ETCP_RT_ID_NCD_CONTROL) сделан |
|
}; |
|
|
|
// Создать ядро по файлу конфигурации; NULL при ошибке. Сервисы ещё не запущены. |
|
struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char* config_file); |
|
// При успехе забирает config; при ошибке config остаётся у вызывающего. |
|
struct UTUN_INSTANCE* utun_instance_create_from_config(struct UASYNC* ua, struct utun_config* config); |
|
// Как create, но конфигурация передана строкой; строку не сохраняет. |
|
struct UTUN_INSTANCE* utun_instance_create_from_str(struct UASYNC* ua, const char* config_text); |
|
// Остановить сервисы и освободить instance. Переданный uasync остаётся у вызывающего. |
|
void utun_instance_destroy(struct UTUN_INSTANCE* instance); |
|
/* Запустить общие сетевые службы ядра. Повтор допустим; 0/-1. */ |
|
int utun_core_start(struct UTUN_INSTANCE* instance); |
|
/* Запустить UTUN-группу, TUN/NAT по конфигу и запросы к пирам. Нужен core_start; 0/-1. */ |
|
int utun_service_start(struct UTUN_INSTANCE* instance); |
|
/* Остановить UTUN, сохранив ядро и чат. Повтор допустим. */ |
|
void utun_service_stop(struct UTUN_INSTANCE* instance); |
|
/* Запустить ядро, UTUN и включённый в конфиге чат. 0/-1. */ |
|
int utun_instance_init(struct UTUN_INSTANCE *instance); |
|
/* Перечитать конфигурацию, при необходимости пересоздать экземпляр; использовать возвращённый указатель. */ |
|
struct UTUN_INSTANCE *utun_instance_reload(struct UTUN_INSTANCE *instance, struct UASYNC *ua, const char *config_file); |
|
/* Выполнять цикл событий до stop(). */ |
|
void utun_instance_run(struct UTUN_INSTANCE *instance); |
|
/* Снять running и разбудить цикл; ресурсы освобождает destroy(), а не stop(). */ |
|
void utun_instance_stop(struct UTUN_INSTANCE *instance); |
|
/* Глобальные переключатели создания TUN/топологии для тестов и встраивания. */ |
|
void utun_instance_set_tun_init_enabled(int enabled); |
|
void utun_instance_set_topo_group_enabled(int enabled); |
|
void utun_set_client_activity(struct UTUN_INSTANCE* instance, int active); |
|
void utun_add_activity_cbk(struct UTUN_INSTANCE* instance, utun_activity_cbk_fn fn, void* arg); |
|
void utun_remove_activity_cbk(struct UTUN_INSTANCE* instance, utun_activity_cbk_fn fn, void* arg); |
|
void utun_add_peer_sleep_cbk(struct UTUN_INSTANCE* instance, peer_sleep_cbk_fn fn, void* arg); |
|
void utun_remove_peer_sleep_cbk(struct UTUN_INSTANCE* instance, peer_sleep_cbk_fn fn, void* arg); |
|
void utun_fire_peer_sleep_cbk(struct UTUN_INSTANCE* instance, uint64_t peer_node_id, int sleeping); |
|
|
|
// Diagnostic function for memory leak analysis |
|
void utun_instance_diagnose_leaks(struct UTUN_INSTANCE* instance, const char* phase); |
|
|
|
/* Найти транспорт по node_id в реестрах ETCP/TCP. Указатель заимствован. |
|
* NULL — не найден; ненулевой результат не гарантирует UP или готовность группы. */ |
|
static inline struct ETCP_CONN* instance_find_conn(struct UTUN_INSTANCE* inst, uint64_t node_id) { |
|
if (inst->connections) { |
|
struct ll_entry* e = queue_find_data_by_index(inst->connections, (const uint8_t*)&node_id); |
|
if (e) return ((struct conn_queue_entry*)e->data)->conn; |
|
} |
|
if (inst->tcp_connections) { |
|
struct ll_entry* e = queue_find_data_by_index(inst->tcp_connections, (const uint8_t*)&node_id); |
|
if (e) return ((struct tcp_conn_entry*)e->data)->etcp_conn; |
|
} |
|
return NULL; |
|
} |
|
|
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif // UTUN_INSTANCE_H
|
|
|