Files
utun2/src/config_parser.h
T

279 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* INI-конфигурация ядра: слушающие сокеты, исходящие пиры, сети/подсети и настройки сервисов.
* parse_config читает файл, parse_config_from_buf — текст; filename задаёт источник в диагностике.
* Успех возвращает выделенную utun_config со списками; освобождение — только free_config.
* Парсер заполняет модель, запуск сетевых ресурсов выполняет utun_instance. */
#ifndef CONFIG_PARSER_H
#define CONFIG_PARSER_H
#include <stdint.h>
#include <stddef.h>
#include "../lib/platform_compat.h"
#include "../lib/debug_config.h"
#include "secure_channel.h"
#include "transport_layer/reality.h"
#include "chat/chat_setting.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_CONN_NAME_LEN 64
#define MAX_KEY_LEN 256
#define MAX_ADDR_LEN 64
struct IP {
sa_family_t family;
union {
struct in_addr v4;
struct in6_addr v6;
} addr;
};
#define CFG_SERVER_TYPE_UNKNOWN 0
#define CFG_SERVER_TYPE_PUBLIC 1
#define CFG_SERVER_TYPE_NAT 2
#define CFG_SERVER_TYPE_PRIVATE 3
#define CFG_SERVER_TYPE_LOCAL 4
/* Режимы auto_sockets: OFF — ручные [server]; SYSTEM — авто-сокеты из системных
* интерфейсов; ANDROID — авто-сокеты из [server] секций конфига (генерирует Kotlin). */
#define CFG_AUTO_SOCKETS_OFF 0
#define CFG_AUTO_SOCKETS_SYSTEM 1
#define CFG_AUTO_SOCKETS_ANDROID 2
#define CFG_IPV6_MODE_NONE 0 // normal explicit address
#define CFG_IPV6_MODE_TEMPORARY 1 // temporary IPv6 from interface
#define CFG_IPV6_MODE_PERMANENT 2 // permanent IPv6 from interface
struct CFG_SERVER {
struct CFG_SERVER* next;
char name[MAX_CONN_NAME_LEN];
struct sockaddr_storage ip; // ip:port
uint32_t netif_index;// if_nameindex, 0 - no interface specified
int so_mark;
int fib; // FreeBSD FIB (routing table), -1 = don't set
uint8_t type; // public/nat/private
uint8_t transport; // 0=udp (default), 1=tcp
uint8_t reality_enabled; // 1 = TCP-порт с REALITY-камуфляжем (только transport=1)
uint8_t socks_enabled; // 1 = UDP-сокет туннелировать через SOCKS5 (только transport=0)
uint8_t ipv6_mode; // CFG_IPV6_MODE_*
int mtu;
uint8_t only_local; // 1 = only local connections, no forwarding
};
struct CFG_CLIENT_LINK {
struct CFG_CLIENT_LINK *next; // Next link in linked list
struct CFG_SERVER* local_srv;
char server_name[MAX_CONN_NAME_LEN]; // Name of local server for this link
struct sockaddr_storage remote_addr; // ip:port
};
struct CFG_CLIENT {
char name[MAX_CONN_NAME_LEN];
char peer_public_key_hex[MAX_KEY_LEN];
int keepalive;
struct CFG_CLIENT_LINK *links; // Linked list of links
struct CFG_CLIENT *next; // Next client in linked list
uint8_t reality_enabled; // 1 = TCP-линк с REALITY-камуфляжем
struct reality_client_config reality; // short_id, server_static_pubkey, version, server_name, fingerprint
};
struct CFG_NETWORK {
struct CFG_NETWORK* next;
char name[64];
uint64_t id; // 56-bit network ID
char pubkey_hex[SC_PUBKEY_SIZE * 2 + 1]; // 64 hex chars
char signing_key_hex[SC_PRIVKEY_SIZE * 2 + 1]; // 64 hex chars
};
struct CFG_ROUTE_ENTRY {
struct CFG_ROUTE_ENTRY* next;
struct IP ip;
uint8_t netmask;
};
struct CFG_FIREWALL_RULE {
uint32_t ip; // IPv4 in host byte order for sorting
uint16_t port; // 0 means any port
uint8_t bypass; // 1 for allow=all (bypass all checks)
};
struct CFG_CONTROL_ALLOW {
uint32_t network; // IPv4 network in host byte order
uint32_t netmask; // netmask in host byte order (e.g. 0xffffff00 for /24)
};
struct CFG_ALLOWED_KEY {
uint8_t key_bin[SC_PUBKEY_SIZE]; // public key in binary (32 bytes, X25519)
struct CFG_ALLOWED_KEY *next;
};
struct CFG_NTP_SERVER {
char name[256];
struct CFG_NTP_SERVER *next;
};
/* STUN-серверы обходятся в порядке конфигурации; DNS выполняет модуль stun_nat. */
struct CFG_STUN_SERVER {
struct CFG_STUN_SERVER* next;
char host[256];
uint16_t port;
};
#define MAX_TCP_PROXY_CLIENT_MAPPINGS 32
struct tcp_proxy_client_mapping_config {
uint16_t local_port;
char remote_ip[64];
uint16_t remote_port;
};
struct global_config {
char name[MAX_CONN_NAME_LEN]; // Instance name
char my_private_key_hex[MAX_KEY_LEN];
char my_public_key_hex[MAX_KEY_LEN];
uint64_t my_node_id;
uint8_t client_type; // 0=server, 1=desktop, 2=mobile
int tun_enabled; // 1 = create TUN (default), 0 = skip TUN (run without root)
char tun_ifname[16]; // TUN interface name (e.g., "tun12")
struct IP tun_ip;
int mtu;
struct sockaddr_storage control_sock;
char control_ip[MAX_ADDR_LEN]; // Control server IP address
// Debug and logging configuration
char log_file[256]; // Path to log file (empty = stdout)
char db_path[256]; // Path to SQLite database (empty = disabled)
int db_sync_enabled; // 1 = enable distributed DB sync (default: 0)
int chatserver_enabled; // 1 = chat server mode (set by [chatserver] section presence)
uint32_t db_sync_ttl; // TTL for unsent records in seconds (default: 86400)
// UDP log target
char log_udp_ip[64];
int log_udp_port;
char debug_level[16]; // debug level: error, warn, info, debug, trace
int enable_timestamp; // enable timestamps in logs
int enable_function_names; // enable function names in logs
int enable_file_lines; // enable file:line in logs
int enable_colors; // enable ANSI colors in logs
// Per-category debug levels (loaded from [debug] section)
struct {
char category[DEBUG_CATEGORY_COUNT][16]; // category name
char level[DEBUG_CATEGORY_COUNT][16]; // level string
int count;
} debug_levels;
int tun_test_mode; // test mode: 1 = don't open real TUN, queues only
int keepalive_timeout; // keepalive timeout in ms (default: 2000)
int keepalive_interval; // keepalive interval in ms (default: 200)
int keepalive_adaptive; // 1 = adaptive period (default), 0 = fixed interval
int bbr_max_cwnd; // BBR cwnd cap in bytes (default: 100000)
// Firewall configuration
struct CFG_FIREWALL_RULE *firewall_rules;
int firewall_rule_count;
int firewall_bypass_all;
// Control server configuration ([control] section)
struct CFG_CONTROL_ALLOW *control_allows;
int control_allow_count;
// Allowed keys configuration ([allowed_keys] section)
struct CFG_ALLOWED_KEY *allowed_keys;
int allowed_keys_count;
int allowed_keys_allow_all;
// NAT configuration ([nat] section)
int nat_enabled;
char nat_tun_ifname[16];
struct IP nat_tun_ip;
uint64_t nat_via_node_id; // 0 = this node is provider; !=0 = client, use this provider
uint16_t nat_port_start;
uint16_t nat_port_end;
#define MAX_NAT_FORWARDS 64
struct {
uint8_t proto;
uint32_t internal_ip_host;
uint16_t internal_port_net;
uint16_t external_port;
} nat_forwards[MAX_NAT_FORWARDS];
int nat_forward_count;
// TCP proxy client configuration ([tcp_proxy_client] section)
int tcp_proxy_client_enabled;
char tcp_proxy_client_tun_name[16];
char tcp_proxy_client_tun_ip[64];
int tcp_proxy_client_mtu;
uint64_t tcp_proxy_client_via_node_id; // через этот узел проксируются все forward-правила
struct tcp_proxy_client_mapping_config tcp_proxy_client_mappings[MAX_TCP_PROXY_CLIENT_MAPPINGS];
int tcp_proxy_client_mapping_count;
int tcp_proxy_client_socks_enabled;
char tcp_proxy_client_socks_addr[64]; // e.g. "127.0.0.1:1080"
int tcp_proxy_client_http_proxy_enabled;
char tcp_proxy_client_http_proxy_addr[64]; // e.g. "127.0.0.1:8080"
// TCP proxy server (exit node) configuration ([tcp_proxy_server] section)
int tcp_proxy_server_enabled;
int auto_sockets; // CFG_AUTO_SOCKETS_*: OFF/SYSTEM/ANDROID (см. константы ниже)
int auto_socket_skip_no_default_route; // 1 = в авто-режиме не создавать сокеты на интерфейсах без default-маршрута
int tcp_recv_buf; // SO_RCVBUF для TCP сокетов (0=default ОС)
int tcp_proxy_server_fib; // FreeBSD SO_SETFIB, 0=не менять
int tcp_proxy_server_so_mark; // Linux SO_MARK, 0=не менять
uint32_t tcp_proxy_server_netif_index; // Linux SO_BINDTODEVICE, 0=нет
char tcp_proxy_server_bind_ip[64]; // IP для bind() перед connect()
int tcp_proxy_server_connect_timeout_ms; // таймаут connect(), мс (0 = без таймаута)
// NTP configuration ([ntp] section)
int ntp_enabled;
struct CFG_NTP_SERVER *ntp_servers; // linked list, unlimited
int ntp_server_count;
int ntp_resync_interval; // seconds, default 3600
int stun_enabled; // [stun] enabled=yes; по умолчанию выключено
struct CFG_STUN_SERVER* stun_servers;
int stun_server_count;
// Chatserver configuration ([chatserver] section)
char chatserver_join_password[128]; // пароль для входа в группу
char chatserver_allowed_groups[1024]; // "all" или hex-ID через запятую
uint64_t chatserver_storage_total_size; // bytes, общий лимит хранилища (0 = безлимит)
uint64_t chatserver_storage_unit_size; // bytes, лимит одного файла (0 = отключено)
char headless_control_bind[64]; // ip:port для headless chat CLI (пусто = отключено)
char call_audio_bind[64]; // ip:port для headless аудио-сокета звонков (пусто = отключено)
char radio_audio_bind[64]; // ip:port для headless аудио-сокета рации (пусто = отключено)
struct chat_setting_state chat_settings; // chat-настройки из [chatserver] (per-instance)
// Reality-камуфляж ([reality] section)
struct reality_config reality;
// SOCKS5-прокси для исходящих ETCP-линков ([socks] section)
int socks_enabled; // 1 = TCP/STCP-линки подключаются через SOCKS5
char socks_host[64]; // host прокси (ip или домен)
uint16_t socks_port; // порт прокси
char socks_username[64]; // пусто = no-auth
char socks_password[64];
};
struct utun_config {
struct global_config global;
struct CFG_SERVER* servers;
struct CFG_CLIENT* clients;
struct CFG_ROUTE_ENTRY* route_subnets;
struct CFG_ROUTE_ENTRY* my_subnets;
struct CFG_NETWORK* networks;
};
struct utun_config* parse_config(const char *filename);
struct utun_config* parse_config_from_buf(const char *buf, size_t len, const char *filename);
void free_config(struct utun_config *config);
void print_config(const struct utun_config *config);
void print_chatserver_invite_link(const struct utun_config *config, const struct CFG_SERVER *servers);
int update_config_keys(const char *filename, const char *priv_key, const char *pub_key);
/* Узел (по pubkey, 32 байта) присутствует в списке [client] конфига? 1=да, 0=нет. */
int config_peer_in_clients(const struct utun_config* config, const uint8_t* pubkey);
#ifdef __cplusplus
}
#endif
#endif