- go.mod/main.go/config.go/sample/CHANGELOG: 移除 类 frp/去中心化 frp 本体/像 frp 类比 - 保留 ExternalService 中真实的 frp_server 外部穿透服务(客观功能,非自比)
107 lines
3.6 KiB
Go
107 lines
3.6 KiB
Go
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
|
||
}
|