package config import ( "fmt" "os" "regexp" "gopkg.in/yaml.v3" ) // 域名匹配规则类型 const ( MatchTypeRegexp = "regexp" MatchTypeSuffix = "suffix" MatchTypeKeyword = "keyword" ) // DNS协议类型 const ( DNSProtocolUDP = "udp" DNSProtocolTCP = "tcp" DNSProtocolDoT = "dot" // DNS over TLS DNSProtocolDoH = "doh" // DNS over HTTPS DNSProtocolDoQ = "doq" // DNS over QUIC ) // 默认配置值 const ( DefaultPort = 443 DefaultDNSProtocol = DNSProtocolUDP DefaultDNSServer = "8.8.8.8:53" DefaultDNSTimeout = 5 DefaultConnectTimeout = 10 DefaultReadTimeout = 30 DefaultWriteTimeout = 5 DefaultIdleTimeout = 60 DefaultLifeTime = 300 DefaultLogLevel = "info" DefaultMaxConns = 1000 DefaultMinFragSize = 10 DefaultMaxFragSize = 100 DefaultMinDelay = 10 DefaultMaxDelay = 30 ) // 超时配置 type TimeoutConfig struct { Connect int `yaml:"connect"` // 连接超时(秒) Read int `yaml:"read"` // 读取超时(秒) Write int `yaml:"write"` // 写入超时(秒) Idle int `yaml:"idle"` // 空闲超时(秒) LifeTime int `yaml:"lifetime"` // 连接最大生命周期(秒) } // TLS分片配置 type FragmentConfig struct { Enabled bool `yaml:"enabled"` // 是否启用TLS分片 MinSize int `yaml:"min_size"` // 最小分片大小(字节) MaxSize int `yaml:"max_size"` // 最大分片大小(字节) DelayMin int `yaml:"delay_min"` // 分片之间的最小延迟(毫秒) DelayMax int `yaml:"delay_max"` // 分片之间的最大延迟(毫秒) Validate bool `yaml:"validate"` // 是否验证TLS记录完整性 } // DNS解析器配置 type DNSResolverConfig struct { Protocol string `yaml:"protocol"` // udp, tcp, dot, doh, doq Server string `yaml:"server"` // 服务器地址,如 8.8.8.8:53, 1.1.1.1:853 Timeout int `yaml:"timeout"` // 超时时间(秒) } // 域名匹配规则 type DomainRule struct { Type string `yaml:"type"` // regexp, suffix, keyword Value string `yaml:"value"` // 匹配值 // 编译后的正则表达式(仅当Type为regexp时使用) compiledRegexp *regexp.Regexp } // 代理规则 type ProxyRule struct { Domains []DomainRule `yaml:"domains"` Port int `yaml:"port"` // 目标端口,默认为443 Fragment FragmentConfig `yaml:"fragment"` } // 配置结构 type Config struct { Listen string `yaml:"listen"` Rules []ProxyRule `yaml:"rules"` DefaultPort int `yaml:"default_port"` // 默认目标端口,如果规则中未指定 DNS DNSResolverConfig `yaml:"dns"` // DNS解析器配置 Timeout TimeoutConfig `yaml:"timeout"` // 超时配置 LogLevel string `yaml:"log_level"` // 日志级别:debug, info, warn, error MaxConns int `yaml:"max_conns"` // 最大并发连接数 } // 加载配置文件 func LoadConfig(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("读取配置文件失败: %w", err) } var cfg Config if err := yaml.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("解析配置文件失败: %w", err) } // 设置默认值 setDefaultValues(&cfg) // 编译正则表达式 if err := compileRegexps(&cfg); err != nil { return nil, err } return &cfg, nil } // 设置默认值 func setDefaultValues(cfg *Config) { // 设置默认端口 if cfg.DefaultPort == 0 { cfg.DefaultPort = DefaultPort } // 设置默认DNS配置 if cfg.DNS.Protocol == "" { cfg.DNS.Protocol = DefaultDNSProtocol } if cfg.DNS.Server == "" { cfg.DNS.Server = DefaultDNSServer } if cfg.DNS.Timeout == 0 { cfg.DNS.Timeout = DefaultDNSTimeout } // 设置默认超时配置 if cfg.Timeout.Connect == 0 { cfg.Timeout.Connect = DefaultConnectTimeout } if cfg.Timeout.Read == 0 { cfg.Timeout.Read = DefaultReadTimeout } if cfg.Timeout.Write == 0 { cfg.Timeout.Write = DefaultWriteTimeout } if cfg.Timeout.Idle == 0 { cfg.Timeout.Idle = DefaultIdleTimeout } if cfg.Timeout.LifeTime == 0 { cfg.Timeout.LifeTime = DefaultLifeTime } // 设置默认日志级别 if cfg.LogLevel == "" { cfg.LogLevel = DefaultLogLevel } // 设置默认最大连接数 if cfg.MaxConns == 0 { cfg.MaxConns = DefaultMaxConns } // 设置规则默认值 for i := range cfg.Rules { // 如果规则中未指定端口,使用默认端口 if cfg.Rules[i].Port == 0 { cfg.Rules[i].Port = cfg.DefaultPort } // 设置TLS分片配置的默认值 if cfg.Rules[i].Fragment.Enabled { setFragmentDefaults(&cfg.Rules[i].Fragment) } } } // 设置分片默认值 func setFragmentDefaults(frag *FragmentConfig) { // 设置默认的分片大小范围 if frag.MinSize <= 0 { frag.MinSize = DefaultMinFragSize } if frag.MaxSize <= 0 { frag.MaxSize = DefaultMaxFragSize } if frag.MinSize > frag.MaxSize { frag.MinSize = frag.MaxSize } // 设置默认的分片延迟范围 if frag.DelayMin <= 0 { frag.DelayMin = DefaultMinDelay } if frag.DelayMax <= 0 { frag.DelayMax = DefaultMaxDelay } if frag.DelayMin > frag.DelayMax { frag.DelayMin = frag.DelayMax } } // 编译正则表达式 func compileRegexps(cfg *Config) error { for i := range cfg.Rules { for j := range cfg.Rules[i].Domains { if cfg.Rules[i].Domains[j].Type == MatchTypeRegexp { re, err := regexp.Compile(cfg.Rules[i].Domains[j].Value) if err != nil { return fmt.Errorf("编译正则表达式失败 '%s': %w", cfg.Rules[i].Domains[j].Value, err) } cfg.Rules[i].Domains[j].compiledRegexp = re } } } return nil } // 检查域名是否匹配规则 func (r *DomainRule) Match(domain string) bool { switch r.Type { case MatchTypeRegexp: return r.compiledRegexp.MatchString(domain) case MatchTypeSuffix: return len(domain) >= len(r.Value) && domain[len(domain)-len(r.Value):] == r.Value case MatchTypeKeyword: return contains(domain, r.Value) default: return false } } // 辅助函数:检查字符串是否包含子串 func contains(s, substr string) bool { for i := 0; i <= len(s)-len(substr); i++ { if s[i:i+len(substr)] == substr { return true } } return false }