52 lines
1.2 KiB
Go
52 lines
1.2 KiB
Go
//go:build !windows
|
|
|
|
package client
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// probeDNS parses /etc/resolv.conf for nameserver and search/domain lines.
|
|
// This works on Linux, macOS (without full mDNSResponder), and most BSDs.
|
|
func probeDNS() *DNSConfig {
|
|
cfg := &DNSConfig{}
|
|
|
|
data, err := os.ReadFile("/etc/resolv.conf")
|
|
if err != nil {
|
|
// On macOS, scutil --dns is the authoritative source but resolv.conf
|
|
// is usually symlinked to a managed copy — try it anyway.
|
|
return cfg
|
|
}
|
|
|
|
seenSrv := map[string]bool{}
|
|
seenSch := map[string]bool{}
|
|
|
|
for _, line := range strings.Split(string(data), "\n") {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") {
|
|
continue
|
|
}
|
|
fields := strings.Fields(line)
|
|
if len(fields) < 2 {
|
|
continue
|
|
}
|
|
switch fields[0] {
|
|
case "nameserver":
|
|
addr := fields[1]
|
|
if addr != "127.0.0.1" && addr != "::1" && !seenSrv[addr] {
|
|
seenSrv[addr] = true
|
|
cfg.Servers = append(cfg.Servers, addr)
|
|
}
|
|
case "search", "domain":
|
|
for _, d := range fields[1:] {
|
|
if !seenSch[d] {
|
|
seenSch[d] = true
|
|
cfg.SearchDomains = append(cfg.SearchDomains, d)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return cfg
|
|
}
|