mirror of
https://github.com/golang/go
synced 2024-11-23 05:00:07 -07:00
net: set IsNotFound on windows and plan9 DNS queries
Change-Id: I2a12acb3e4f31dd561d49f47a3b1ae3ac47ab894
GitHub-Last-Rev: 4733964f69
GitHub-Pull-Request: golang/go#63542
Reviewed-on: https://go-review.googlesource.com/c/go/+/534937
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
Run-TryBot: Mateusz Poliwczak <mpoliwczak34@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
This commit is contained in:
parent
3839447ac3
commit
95974b379f
@ -106,6 +106,22 @@ func queryDNS(ctx context.Context, addr string, typ string) (res []string, err e
|
||||
return query(ctx, netdir+"/dns", addr+" "+typ, 1024)
|
||||
}
|
||||
|
||||
func handlePlan9DNSError(err error, name string) error {
|
||||
if stringsHasSuffix(err.Error(), "dns: name does not exist") ||
|
||||
stringsHasSuffix(err.Error(), "dns: resource does not exist; negrcode 0") ||
|
||||
stringsHasSuffix(err.Error(), "dns: resource does not exist; negrcode") {
|
||||
return &DNSError{
|
||||
Err: errNoSuchHost.Error(),
|
||||
Name: name,
|
||||
IsNotFound: true,
|
||||
}
|
||||
}
|
||||
return &DNSError{
|
||||
Err: err.Error(),
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// toLower returns a lower-case version of in. Restricting us to
|
||||
// ASCII is sufficient to handle the IP protocol names and allow
|
||||
// us to not depend on the strings and unicode packages.
|
||||
@ -153,12 +169,10 @@ func (*Resolver) lookupHost(ctx context.Context, host string) (addrs []string, e
|
||||
// host names in local network (e.g. from /lib/ndb/local)
|
||||
lines, err := queryCS(ctx, "net", host, "1")
|
||||
if err != nil {
|
||||
dnsError := &DNSError{Err: err.Error(), Name: host}
|
||||
if stringsHasSuffix(err.Error(), "dns failure") {
|
||||
dnsError.Err = errNoSuchHost.Error()
|
||||
dnsError.IsNotFound = true
|
||||
return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
|
||||
}
|
||||
return nil, dnsError
|
||||
return nil, handlePlan9DNSError(err, host)
|
||||
}
|
||||
loop:
|
||||
for _, line := range lines {
|
||||
@ -252,10 +266,9 @@ func (r *Resolver) lookupCNAME(ctx context.Context, name string) (cname string,
|
||||
lines, err := queryDNS(ctx, name, "cname")
|
||||
if err != nil {
|
||||
if stringsHasSuffix(err.Error(), "dns failure") || stringsHasSuffix(err.Error(), "resource does not exist; negrcode 0") {
|
||||
cname = name + "."
|
||||
err = nil
|
||||
return absDomainName(name), nil
|
||||
}
|
||||
return
|
||||
return "", handlePlan9DNSError(err, cname)
|
||||
}
|
||||
if len(lines) > 0 {
|
||||
if f := getFields(lines[0]); len(f) >= 3 {
|
||||
@ -277,7 +290,7 @@ func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (
|
||||
}
|
||||
lines, err := queryDNS(ctx, target, "srv")
|
||||
if err != nil {
|
||||
return
|
||||
return "", nil, handlePlan9DNSError(err, name)
|
||||
}
|
||||
for _, line := range lines {
|
||||
f := getFields(line)
|
||||
@ -303,7 +316,7 @@ func (r *Resolver) lookupMX(ctx context.Context, name string) (mx []*MX, err err
|
||||
}
|
||||
lines, err := queryDNS(ctx, name, "mx")
|
||||
if err != nil {
|
||||
return
|
||||
return nil, handlePlan9DNSError(err, name)
|
||||
}
|
||||
for _, line := range lines {
|
||||
f := getFields(line)
|
||||
@ -324,7 +337,7 @@ func (r *Resolver) lookupNS(ctx context.Context, name string) (ns []*NS, err err
|
||||
}
|
||||
lines, err := queryDNS(ctx, name, "ns")
|
||||
if err != nil {
|
||||
return
|
||||
return nil, handlePlan9DNSError(err, name)
|
||||
}
|
||||
for _, line := range lines {
|
||||
f := getFields(line)
|
||||
@ -342,7 +355,7 @@ func (r *Resolver) lookupTXT(ctx context.Context, name string) (txt []string, er
|
||||
}
|
||||
lines, err := queryDNS(ctx, name, "txt")
|
||||
if err != nil {
|
||||
return
|
||||
return nil, handlePlan9DNSError(err, name)
|
||||
}
|
||||
for _, line := range lines {
|
||||
if i := bytealg.IndexByteString(line, '\t'); i >= 0 {
|
||||
@ -362,7 +375,7 @@ func (r *Resolver) lookupAddr(ctx context.Context, addr string) (name []string,
|
||||
}
|
||||
lines, err := queryDNS(ctx, arpa, "ptr")
|
||||
if err != nil {
|
||||
return
|
||||
return nil, handlePlan9DNSError(err, addr)
|
||||
}
|
||||
for _, line := range lines {
|
||||
f := getFields(line)
|
||||
|
@ -1524,3 +1524,125 @@ func allResolvers(t *testing.T, f func(t *testing.T)) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestLookupNoSuchHost(t *testing.T) {
|
||||
mustHaveExternalNetwork(t)
|
||||
|
||||
const testNXDOMAIN = "invalid.invalid."
|
||||
const testNODATA = "_ldap._tcp.google.com."
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
query func() error
|
||||
}{
|
||||
{
|
||||
name: "LookupCNAME NXDOMAIN",
|
||||
query: func() error {
|
||||
_, err := LookupCNAME(testNXDOMAIN)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupHost NXDOMAIN",
|
||||
query: func() error {
|
||||
_, err := LookupHost(testNXDOMAIN)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupHost NODATA",
|
||||
query: func() error {
|
||||
_, err := LookupHost(testNODATA)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupMX NXDOMAIN",
|
||||
query: func() error {
|
||||
_, err := LookupMX(testNXDOMAIN)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupMX NODATA",
|
||||
query: func() error {
|
||||
_, err := LookupMX(testNODATA)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupNS NXDOMAIN",
|
||||
query: func() error {
|
||||
_, err := LookupNS(testNXDOMAIN)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupNS NODATA",
|
||||
query: func() error {
|
||||
_, err := LookupNS(testNODATA)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupSRV NXDOMAIN",
|
||||
query: func() error {
|
||||
_, _, err := LookupSRV("unknown", "tcp", testNXDOMAIN)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupTXT NXDOMAIN",
|
||||
query: func() error {
|
||||
_, err := LookupTXT(testNXDOMAIN)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LookupTXT NODATA",
|
||||
query: func() error {
|
||||
_, err := LookupTXT(testNODATA)
|
||||
return err
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, v := range tests {
|
||||
t.Run(v.name, func(t *testing.T) {
|
||||
allResolvers(t, func(t *testing.T) {
|
||||
attempts := 0
|
||||
for {
|
||||
err := v.query()
|
||||
if err == nil {
|
||||
t.Errorf("unexpected success")
|
||||
return
|
||||
}
|
||||
if dnsErr, ok := err.(*DNSError); ok {
|
||||
succeeded := true
|
||||
if !dnsErr.IsNotFound {
|
||||
succeeded = false
|
||||
t.Log("IsNotFound is set to false")
|
||||
}
|
||||
if dnsErr.Err != errNoSuchHost.Error() {
|
||||
succeeded = false
|
||||
t.Logf("error message is not equal to: %v", errNoSuchHost.Error())
|
||||
}
|
||||
if succeeded {
|
||||
return
|
||||
}
|
||||
}
|
||||
testenv.SkipFlakyNet(t)
|
||||
if attempts < len(backoffDuration) {
|
||||
dur := backoffDuration[attempts]
|
||||
t.Logf("backoff %v after failure %v\n", dur, err)
|
||||
time.Sleep(dur)
|
||||
attempts++
|
||||
continue
|
||||
}
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,9 @@ import (
|
||||
const cgoAvailable = true
|
||||
|
||||
const (
|
||||
_DNS_ERROR_RCODE_NAME_ERROR = syscall.Errno(9003)
|
||||
_DNS_INFO_NO_RECORDS = syscall.Errno(9501)
|
||||
|
||||
_WSAHOST_NOT_FOUND = syscall.Errno(11001)
|
||||
_WSATRY_AGAIN = syscall.Errno(11002)
|
||||
_WSATYPE_NOT_FOUND = syscall.Errno(10109)
|
||||
@ -27,7 +30,7 @@ const (
|
||||
|
||||
func winError(call string, err error) error {
|
||||
switch err {
|
||||
case _WSAHOST_NOT_FOUND:
|
||||
case _WSAHOST_NOT_FOUND, _DNS_ERROR_RCODE_NAME_ERROR, _DNS_INFO_NO_RECORDS:
|
||||
return errNoSuchHost
|
||||
}
|
||||
return os.NewSyscallError(call, err)
|
||||
@ -271,7 +274,8 @@ func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error)
|
||||
return absDomainName(name), nil
|
||||
}
|
||||
if e != nil {
|
||||
return "", &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
|
||||
err := winError("dnsquery", e)
|
||||
return "", &DNSError{Err: err.Error(), Name: name, IsNotFound: err == errNoSuchHost}
|
||||
}
|
||||
defer syscall.DnsRecordListFree(rec, 1)
|
||||
|
||||
@ -296,7 +300,8 @@ func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (
|
||||
var rec *syscall.DNSRecord
|
||||
e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &rec, nil)
|
||||
if e != nil {
|
||||
return "", nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: target}
|
||||
err := winError("dnsquery", e)
|
||||
return "", nil, &DNSError{Err: err.Error(), Name: name, IsNotFound: err == errNoSuchHost}
|
||||
}
|
||||
defer syscall.DnsRecordListFree(rec, 1)
|
||||
|
||||
@ -319,7 +324,8 @@ func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
|
||||
var rec *syscall.DNSRecord
|
||||
e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &rec, nil)
|
||||
if e != nil {
|
||||
return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
|
||||
err := winError("dnsquery", e)
|
||||
return nil, &DNSError{Err: err.Error(), Name: name, IsNotFound: err == errNoSuchHost}
|
||||
}
|
||||
defer syscall.DnsRecordListFree(rec, 1)
|
||||
|
||||
@ -342,7 +348,8 @@ func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
|
||||
var rec *syscall.DNSRecord
|
||||
e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &rec, nil)
|
||||
if e != nil {
|
||||
return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
|
||||
err := winError("dnsquery", e)
|
||||
return nil, &DNSError{Err: err.Error(), Name: name, IsNotFound: err == errNoSuchHost}
|
||||
}
|
||||
defer syscall.DnsRecordListFree(rec, 1)
|
||||
|
||||
@ -364,7 +371,8 @@ func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error)
|
||||
var rec *syscall.DNSRecord
|
||||
e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &rec, nil)
|
||||
if e != nil {
|
||||
return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
|
||||
err := winError("dnsquery", e)
|
||||
return nil, &DNSError{Err: err.Error(), Name: name, IsNotFound: err == errNoSuchHost}
|
||||
}
|
||||
defer syscall.DnsRecordListFree(rec, 1)
|
||||
|
||||
@ -395,7 +403,8 @@ func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error
|
||||
var rec *syscall.DNSRecord
|
||||
e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &rec, nil)
|
||||
if e != nil {
|
||||
return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: addr}
|
||||
err := winError("dnsquery", e)
|
||||
return nil, &DNSError{Err: err.Error(), Name: addr, IsNotFound: err == errNoSuchHost}
|
||||
}
|
||||
defer syscall.DnsRecordListFree(rec, 1)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user