阅读量:
Android 端 DNS 查询错误
下面这段代码在 Android 端执行会抛错:
package main
import (
"log"
"net"
)
func main() {
ip, err := net.LookupIP("baidu.com")
if err != nil {
return
}
log.Println(ip)
}
错误信息:read udp [::1]:46548->[::1]:53: read: connection refused
通过分析后发现错误原因是 Go 在 linux 环境下是默认通过 /etc/resolve.conf 文件获取的系统 DNS 服务器地址,但是在 Android 端没有这个文件,会导致 Go 获取不到本机 DNS 服务器,然后 Go 就会使用默认设置的本机 DNS 服务器地址。
相关代码:
// net/dnsclient_unix.go
func getSystemDNSConfig() *dnsConfig {
resolvConf.tryUpdate("/etc/resolv.conf")
return resolvConf.dnsConfig.Load()
}
// net/dnsconfig_unix.go
// See resolv.conf(5) on a Linux machine.
func dnsReadConfig(filename string) *dnsConfig {
...
file, err := open(filename)
if err != nil {
conf.servers = defaultNS
conf.search = dnsDefaultSearch()
conf.err = err
return conf
}
...
}
为了解决这个问题,需要自行设置 DNS 服务器地址。可通过修改全局变量 net.DefaultResolver
实现效果:
&net.Resolver{
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
dial := net.Dialer{}
var dns []string
for _, server := range custom.DNSServers {
if _, _, err := net.SplitHostPort(server); err != nil {
dns = append(dns, net.JoinHostPort(server, defaultDNSPort))
} else {
dns = append(dns, server)
}
}
return dial.DialContext(ctx, network, dns[rand.Intn(len(dns))])
},
}