Suppose you write this piece of Go code to do a DNS resolve using 1.1.1.1:
var resolver = &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Millisecond * time.Duration(5000),
}
return d.DialContext(ctx, "udp", "1.1.1.1:53")
},
}
func getIP(dns string) (string, error) {
addrs, err := resolver.LookupHost(context.Background(), dns)
if err != nil {
return "", err
}
return addrs[0], nil
}
This works nicely, until, the DNS name does not exist. Then you'll see this error:
lookup foobar-something.example.org on 8.8.8.8:53: no such host
How can this be? This is caused by how Dial is overwritten, but the error handling is not. To give the correct error message, you can write logic like this:
var resolver = &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
// this prints "Wanted to dial 8.8.8.8" or whatever server you configured in the OS settings
log.Printf("Wanted to dial %s", address)
d := net.Dialer{
Timeout: time.Millisecond * time.Duration(5000),
}
return d.DialContext(ctx, "udp", "1.1.1.1:53")
},
}
func getIP(dns string) (string, error) {
addrs, err := resolver.LookupHost(context.Background(), dns)
if err != nil {
if dnsErr, isDNSErr := err.(*net.DNSError); isDNSErr {
dnsErr.Server = "1.1.1.1:53"
return "", dnsErr
}
return "", err
}
return addrs[0], nil
}
Now, the error is this:
lookup foobar-something.example.org on 1.1.1.1:53: no such host