package main import ( "encoding/json" "fmt" "os" "path/filepath" "strings" "github.com/BurntSushi/toml" ) // Config 是 meshray-core 独立运行的配置文件结构。 // 支持 TOML(默认)与 JSON 两种格式,按文件扩展名自动选择解码器。 // // TOML 示例: // // network_id = "net1" // listen_port = 51820 // mtu = 1420 // private_key = "" # 留空则自动生成并写入 private_key_file // private_key_file = "key.txt" // interface = "10.0.0.1/24" # 本机隧道 IP // mode = "enhanced" # enhanced=经 9 层传输接管;native=裸 WG 直连 // // [[peers]] // public_key = "<对端公钥 base64>" // endpoint = "203.0.113.2:51820" # 增强模式经 9 层拨号对端;留空则仅作为接收方 // allowed_ips = ["10.0.0.2/32"] // // [ice] // stun = ["stun:stun.l.google.com:19302"] // turn = ["turn:your.turn:3478"] // // # 传输层级策略:auto=9 层自动降级(默认);manual=仅用下方 layers 指定的层 // layer_strategy = "auto" // layers = ["Direct-UDP"] # 仅 manual 生效;单元素=强制固定层;多元素=自定义降级顺序 type Config struct { NetworkID string `json:"network_id" toml:"network_id"` ListenPort int `json:"listen_port" toml:"listen_port"` MTU int `json:"mtu" toml:"mtu"` PrivateKey string `json:"private_key" toml:"private_key"` PrivateKeyFile string `json:"private_key_file" toml:"private_key_file"` InterfaceIP string `json:"interface" toml:"interface"` Mode string `json:"mode" toml:"mode"` Peers []PeerConf `json:"peers" toml:"peers"` ICE ICEConf `json:"ice" toml:"ice"` // LayerStrategy 传输层级策略: // "auto"(默认)= 按 DefaultLayerOrder 自动 9 层降级; // "manual" = 仅使用 Layers 指定的层(手动),不再自动探测其它层。 LayerStrategy string `json:"layer_strategy" toml:"layer_strategy"` // Layers 手动层级列表(仅 layer_strategy=manual 生效)。 // 单元素(如 ["TURN-TCP"])= 强制固定该层、禁用降级; // 多元素(如 ["Direct-UDP","TURN-TCP"])= 按列表顺序自定义降级链。 Layers []string `json:"layers" toml:"layers"` } // PeerConf 对端配置 type PeerConf struct { PublicKey string `json:"public_key" toml:"public_key"` Endpoint string `json:"endpoint" toml:"endpoint"` AllowedIPs []string `json:"allowed_ips" toml:"allowed_ips"` } // ICEConf STUN/TURN 服务器(增强模式打洞/中继用) type ICEConf struct { STUN []string `json:"stun" toml:"stun"` TURN []string `json:"turn" toml:"turn"` } // loadConfig 读取并解析配置文件:按扩展名自动选择 TOML 或 JSON 解码器。 // 默认且推荐 TOML;旧 .json 配置仍可继续使用。 func loadConfig(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, err } cfg := &Config{} // 按扩展名选择解码器:先剥离可能的 .sample 模板后缀,再判扩展名, // 避免 "meshray-core.toml.sample" 被误判为 JSON。 lower := strings.ToLower(path) lower = strings.TrimSuffix(lower, ".sample") ext := filepath.Ext(lower) switch ext { case ".toml", ".conf": // TOML:默认配置格式 if err := toml.Unmarshal(data, cfg); err != nil { return nil, fmt.Errorf("解析 TOML 配置 %s 失败: %w", path, err) } default: // JSON:兼容旧配置 if err := json.Unmarshal(data, cfg); err != nil { return nil, fmt.Errorf("解析 JSON 配置 %s 失败: %w", path, err) } } if cfg.MTU == 0 { cfg.MTU = 1420 } if cfg.Mode == "" { cfg.Mode = "enhanced" } return cfg, nil }