// config_parser.h - Configuration parser for utun application #ifndef CONFIG_PARSER_H #define CONFIG_PARSER_H #include #include #include "../lib/platform_compat.h" #include "secure_channel.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 #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 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 }; 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; }; #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[16]; // Instance name char my_private_key_hex[MAX_KEY_LEN]; char my_public_key_hex[MAX_KEY_LEN]; uint64_t my_node_id; 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 struct sockaddr_storage msg_transport_sock; // 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) uint32_t db_sync_ttl; // TTL for unsent records in seconds (default: 86400) 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[16][16]; // category name char level[16][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 tcp_recv_buf; // SO_RCVBUF для TCP сокетов (0=default ОС) // NTP configuration ([ntp] section) int ntp_enabled; char ntp_servers[5][256]; // up to 5 NTP server hostnames int ntp_server_count; int ntp_resync_interval; // seconds, default 3600 }; 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); void free_config(struct utun_config *config); void print_config(const struct utun_config *config); int update_config_keys(const char *filename, const char *priv_key, const char *pub_key); #ifdef __cplusplus } #endif #endif