diff --git a/net/dnsconfig_unix.go b/net/dnsconfig_unix.go index 6073fdb..9df3cec 100644 --- a/net/dnsconfig_unix.go +++ b/net/dnsconfig_unix.go @@ -8,18 +8,57 @@ package net -var defaultNS = []string{"127.0.0.1", "::1"} +import ( + "fmt" + "os/exec" + "strings" + "sync" + "time" +) + +var ( + logOnce sync.Once +) + +func getDefaultNS() []string { + var servers []string + for _, prop := range []string{"net.dns", "net.dns1", "net.dns2", "net.dns3", "net.dns4"} { + cmd := exec.Command("getprop", prop) + if cmd.Run() == nil { + outputBytes, err := cmd.Output() + if err != nil { + continue + } + + output := strings.Trim(string(outputBytes), "\n") + if ParseIP(output) != nil { + servers = append(servers, output) + } + } + } + + if servers == nil { + servers = []string{"8.8.8.8", "8.8.4.4", "4.2.2.1"} + } + + logOnce.Do(func() { + fmt.Println("Using the following DNS servers", servers) + }) + + return servers +} type dnsConfig struct { - servers []string // servers to use - search []string // suffixes to append to local name - ndots int // number of dots in name to trigger absolute lookup - timeout int // seconds before giving up on packet - attempts int // lost packets before giving up on server - rotate bool // round robin among servers - unknownOpt bool // anything unknown was encountered - lookup []string // OpenBSD top-level database "lookup" order - err error // any error that occurs during open of resolv.conf + servers []string // servers to use + search []string // suffixes to append to local name + ndots int // number of dots in name to trigger absolute lookup + timeout int // seconds before giving up on packet + attempts int // lost packets before giving up on server + rotate bool // round robin among servers + unknownOpt bool // anything unknown was encountered + lookup []string // OpenBSD top-level database "lookup" order + err error // any error that occurs during open of resolv.conf + mtime time.Time // time of resolv.conf modification } // See resolv.conf(5) on a Linux machine. @@ -33,11 +72,20 @@ func dnsReadConfig(filename string) *dnsConfig { } file, err := open(filename) if err != nil { - conf.servers = defaultNS + conf.servers = getDefaultNS() + conf.mtime = time.Now() conf.err = err return conf } defer file.close() + if fi, err := file.file.Stat(); err == nil { + conf.mtime = fi.ModTime() + } else { + conf.mtime = time.Now() + conf.servers = getDefaultNS() + conf.err = err + return conf + } for line, ok := file.readLine(); ok; line, ok = file.readLine() { if len(line) > 0 && (line[0] == ';' || line[0] == '#') { // comment. @@ -51,7 +99,7 @@ func dnsReadConfig(filename string) *dnsConfig { case "nameserver": // add one name server if len(f) > 1 && len(conf.servers) < 3 { // small, but the standard limit // One more check: make sure server name is - // just an IP address. Otherwise we need DNS + // just an IP address. Otherwise we need DNS // to look it up. if parseIPv4(f[1]) != nil { conf.servers = append(conf.servers, f[1]) @@ -110,7 +158,7 @@ func dnsReadConfig(filename string) *dnsConfig { } } if len(conf.servers) == 0 { - conf.servers = defaultNS + conf.servers = getDefaultNS() } return conf } @@ -118,3 +166,4 @@ func dnsReadConfig(filename string) *dnsConfig { func hasPrefix(s, prefix string) bool { return len(s) >= len(prefix) && s[:len(prefix)] == prefix } +