Files
elmprodvpn/selective-vpn-api/app/dnscfg/smartdns.go

103 lines
2.0 KiB
Go

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"
}