package dnscfg import ( "net" "os" "strings" ) func ResolveDefaultSmartDNSAddr(addrEnvValue string, configPaths []string, fallback string) string { if v := strings.TrimSpace(addrEnvValue); v != "" { if addr := NormalizeSmartDNSAddr(v); addr != "" { return addr } } for _, path := range configPaths { if addr := SmartDNSAddrFromConfig(path); addr != "" { return addr } } return strings.TrimSpace(fallback) } func SmartDNSAddrFromConfig(path string) string { data, err := os.ReadFile(path) if err != nil { return "" } for _, ln := range strings.Split(string(data), "\n") { s := strings.TrimSpace(ln) if s == "" || strings.HasPrefix(s, "#") { continue } if !strings.HasPrefix(strings.ToLower(s), "bind ") { continue } parts := strings.Fields(s) if len(parts) < 2 { continue } if addr := NormalizeSmartDNSAddr(parts[1]); addr != "" { return addr } } return "" } func NormalizeDNSUpstream(raw string, defaultPort string) string { s := strings.TrimSpace(raw) if s == "" { return "" } s = strings.TrimPrefix(s, "udp://") s = strings.TrimPrefix(s, "tcp://") if strings.Contains(s, "#") { parts := strings.SplitN(s, "#", 2) host := strings.Trim(strings.TrimSpace(parts[0]), "[]") port := strings.TrimSpace(parts[1]) if host == "" { return "" } if port == "" { port = defaultPort } return host + "#" + port } if host, port, err := net.SplitHostPort(s); err == nil { host = strings.Trim(strings.TrimSpace(host), "[]") port = strings.TrimSpace(port) if host == "" { return "" } if port == "" { port = defaultPort } return host + "#" + port } if strings.Count(s, ":") == 1 { parts := strings.SplitN(s, ":", 2) host := strings.TrimSpace(parts[0]) port := strings.TrimSpace(parts[1]) if host != "" && port != "" { return host + "#" + port } } return s } func NormalizeSmartDNSAddr(raw string) string { s := NormalizeDNSUpstream(raw, "6053") if s == "" { return "" } if strings.Contains(s, "#") { return s } return s + "#6053" }