platform: modularize api/gui, add docs-tests-web foundation, and refresh root config
This commit is contained in:
150
selective-vpn-api/app/resolver/dns_config.go
Normal file
150
selective-vpn-api/app/resolver/dns_config.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DNSConfig struct {
|
||||
Default []string
|
||||
Meta []string
|
||||
SmartDNS string
|
||||
Mode string
|
||||
}
|
||||
|
||||
type DNSConfigDeps struct {
|
||||
ActivePool []string
|
||||
IsSmartDNSForced bool
|
||||
SmartDNSAddr string
|
||||
SmartDNSForcedMode string
|
||||
ResolveFallbackPool func() []string
|
||||
MergeDNSUpstreamPools func(primary, fallback []string) []string
|
||||
NormalizeDNSUpstream func(raw string, defaultPort string) string
|
||||
NormalizeSmartDNSAddr func(raw string) string
|
||||
NormalizeDNSResolverMode func(raw string) string
|
||||
}
|
||||
|
||||
func LoadDNSConfig(path string, base DNSConfig, deps DNSConfigDeps, logf func(string, ...any)) DNSConfig {
|
||||
cfg := DNSConfig{
|
||||
Default: append([]string(nil), base.Default...),
|
||||
Meta: append([]string(nil), base.Meta...),
|
||||
SmartDNS: strings.TrimSpace(base.SmartDNS),
|
||||
Mode: strings.TrimSpace(base.Mode),
|
||||
}
|
||||
if cfg.Mode == "" {
|
||||
cfg.Mode = "direct"
|
||||
}
|
||||
if len(deps.ActivePool) > 0 {
|
||||
cfg.Default = append([]string(nil), deps.ActivePool...)
|
||||
cfg.Meta = append([]string(nil), deps.ActivePool...)
|
||||
}
|
||||
|
||||
if deps.IsSmartDNSForced {
|
||||
addr := strings.TrimSpace(deps.SmartDNSAddr)
|
||||
if deps.NormalizeSmartDNSAddr != nil {
|
||||
if n := deps.NormalizeSmartDNSAddr(addr); n != "" {
|
||||
addr = n
|
||||
}
|
||||
}
|
||||
if addr == "" {
|
||||
addr = cfg.SmartDNS
|
||||
}
|
||||
cfg.Default = []string{addr}
|
||||
cfg.Meta = []string{addr}
|
||||
cfg.SmartDNS = addr
|
||||
if strings.TrimSpace(deps.SmartDNSForcedMode) != "" {
|
||||
cfg.Mode = deps.SmartDNSForcedMode
|
||||
} else {
|
||||
cfg.Mode = "smartdns"
|
||||
}
|
||||
if logf != nil {
|
||||
logf("dns-config: SmartDNS forced (%s), ignore %s", addr, path)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if logf != nil {
|
||||
logf("dns-config: can't read %s: %v", path, err)
|
||||
}
|
||||
fallback := []string(nil)
|
||||
if deps.ResolveFallbackPool != nil {
|
||||
fallback = deps.ResolveFallbackPool()
|
||||
}
|
||||
if deps.MergeDNSUpstreamPools != nil {
|
||||
cfg.Default = deps.MergeDNSUpstreamPools(cfg.Default, fallback)
|
||||
cfg.Meta = deps.MergeDNSUpstreamPools(cfg.Meta, fallback)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
var def, meta []string
|
||||
lines := strings.Split(string(data), "\n")
|
||||
for _, ln := range lines {
|
||||
s := strings.TrimSpace(ln)
|
||||
if s == "" || strings.HasPrefix(s, "#") {
|
||||
continue
|
||||
}
|
||||
parts := strings.Fields(s)
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
}
|
||||
key := strings.ToLower(parts[0])
|
||||
vals := parts[1:]
|
||||
switch key {
|
||||
case "default":
|
||||
for _, v := range vals {
|
||||
if deps.NormalizeDNSUpstream != nil {
|
||||
if n := deps.NormalizeDNSUpstream(v, "53"); n != "" {
|
||||
def = append(def, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
case "meta":
|
||||
for _, v := range vals {
|
||||
if deps.NormalizeDNSUpstream != nil {
|
||||
if n := deps.NormalizeDNSUpstream(v, "53"); n != "" {
|
||||
meta = append(meta, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
case "smartdns":
|
||||
if len(vals) > 0 && deps.NormalizeSmartDNSAddr != nil {
|
||||
if n := deps.NormalizeSmartDNSAddr(vals[0]); n != "" {
|
||||
cfg.SmartDNS = n
|
||||
}
|
||||
}
|
||||
case "mode":
|
||||
if len(vals) > 0 {
|
||||
rawMode := vals[0]
|
||||
if deps.NormalizeDNSResolverMode != nil {
|
||||
cfg.Mode = deps.NormalizeDNSResolverMode(rawMode)
|
||||
} else {
|
||||
cfg.Mode = strings.ToLower(strings.TrimSpace(rawMode))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(deps.ActivePool) == 0 {
|
||||
if len(def) > 0 {
|
||||
cfg.Default = def
|
||||
}
|
||||
if len(meta) > 0 {
|
||||
cfg.Meta = meta
|
||||
}
|
||||
}
|
||||
|
||||
fallback := []string(nil)
|
||||
if deps.ResolveFallbackPool != nil {
|
||||
fallback = deps.ResolveFallbackPool()
|
||||
}
|
||||
if deps.MergeDNSUpstreamPools != nil {
|
||||
cfg.Default = deps.MergeDNSUpstreamPools(cfg.Default, fallback)
|
||||
cfg.Meta = deps.MergeDNSUpstreamPools(cfg.Meta, fallback)
|
||||
}
|
||||
if logf != nil {
|
||||
logf("dns-config: accept %s: mode=%s smartdns=%s default=%v; meta=%v", path, cfg.Mode, cfg.SmartDNS, cfg.Default, cfg.Meta)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
Reference in New Issue
Block a user