Commit fa90f9b9 authored by Russ Cox's avatar Russ Cox

net: there are no invalid domain names anymore

The Go resolver reports invalid domain name for '!!!.local',
but that is allowed by multicast DNS. In general we can't predict
what future relaxations might come along, and libc resolvers
do not distinguish 'no such host' from 'invalid name', so stop
making that distinction here too. Always use 'no such host'.

Fixes #12421.

Change-Id: I8f22604767ec9e270434e483da52b337833bad71
Reviewed-on: https://go-review.googlesource.com/31468
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent 157ce90a
...@@ -316,7 +316,12 @@ func (conf *resolverConfig) releaseSema() { ...@@ -316,7 +316,12 @@ func (conf *resolverConfig) releaseSema() {
func lookup(ctx context.Context, name string, qtype uint16) (cname string, rrs []dnsRR, err error) { func lookup(ctx context.Context, name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
if !isDomainName(name) { if !isDomainName(name) {
return "", nil, &DNSError{Err: "invalid domain name", Name: name} // We used to use "invalid domain name" as the error,
// but that is a detail of the specific lookup mechanism.
// Other lookups might allow broader name syntax
// (for example Multicast DNS allows UTF-8; see RFC 6762).
// For consistency with libc resolvers, report no such host.
return "", nil, &DNSError{Err: errNoSuchHost.Error(), Name: name}
} }
resolvConf.tryUpdate("/etc/resolv.conf") resolvConf.tryUpdate("/etc/resolv.conf")
resolvConf.mu.RLock() resolvConf.mu.RLock()
...@@ -469,7 +474,8 @@ func goLookupIPOrder(ctx context.Context, name string, order hostLookupOrder) (a ...@@ -469,7 +474,8 @@ func goLookupIPOrder(ctx context.Context, name string, order hostLookupOrder) (a
} }
} }
if !isDomainName(name) { if !isDomainName(name) {
return nil, &DNSError{Err: "invalid domain name", Name: name} // See comment in func lookup above about use of errNoSuchHost.
return nil, &DNSError{Err: errNoSuchHost.Error(), Name: name}
} }
resolvConf.tryUpdate("/etc/resolv.conf") resolvConf.tryUpdate("/etc/resolv.conf")
resolvConf.mu.RLock() resolvConf.mu.RLock()
......
...@@ -717,3 +717,20 @@ func TestLookupProtocol_Minimal(t *testing.T) { ...@@ -717,3 +717,20 @@ func TestLookupProtocol_Minimal(t *testing.T) {
} }
} }
func TestLookupNonLDH(t *testing.T) {
if runtime.GOOS == "nacl" {
t.Skip("skip on nacl")
}
// "LDH" stands for letters, digits, and hyphens and is the usual
// description of standard DNS names.
// This test is checking that other kinds of names are reported
// as not found, not reported as invalid names.
addrs, err := LookupHost("!!!.###.bogus..domain.")
if err == nil {
t.Fatalf("lookup succeeded: %v", addrs)
}
if !strings.HasSuffix(err.Error(), errNoSuchHost.Error()) {
t.Fatalf("lookup error = %v, want %v", err, errNoSuchHost)
}
}
...@@ -12,10 +12,20 @@ import ( ...@@ -12,10 +12,20 @@ import (
"unsafe" "unsafe"
) )
const _WSAHOST_NOT_FOUND = syscall.Errno(11001)
func winError(call string, err error) error {
switch err {
case _WSAHOST_NOT_FOUND:
return errNoSuchHost
}
return os.NewSyscallError(call, err)
}
func getprotobyname(name string) (proto int, err error) { func getprotobyname(name string) (proto int, err error) {
p, err := syscall.GetProtoByName(name) p, err := syscall.GetProtoByName(name)
if err != nil { if err != nil {
return 0, os.NewSyscallError("getprotobyname", err) return 0, winError("getprotobyname", err)
} }
return int(p.Proto), nil return int(p.Proto), nil
} }
...@@ -85,7 +95,7 @@ func (r *Resolver) lookupIP(ctx context.Context, name string) ([]IPAddr, error) ...@@ -85,7 +95,7 @@ func (r *Resolver) lookupIP(ctx context.Context, name string) ([]IPAddr, error)
var result *syscall.AddrinfoW var result *syscall.AddrinfoW
e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result) e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result)
if e != nil { if e != nil {
ch <- ret{err: &DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: name}} ch <- ret{err: &DNSError{Err: winError("getaddrinfow", e).Error(), Name: name}}
} }
defer syscall.FreeAddrInfoW(result) defer syscall.FreeAddrInfoW(result)
addrs := make([]IPAddr, 0, 5) addrs := make([]IPAddr, 0, 5)
...@@ -151,7 +161,7 @@ func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int ...@@ -151,7 +161,7 @@ func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int
if port, err := lookupPortMap(network, service); err == nil { if port, err := lookupPortMap(network, service); err == nil {
return port, nil return port, nil
} }
return 0, &DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: network + "/" + service} return 0, &DNSError{Err: winError("getaddrinfow", e).Error(), Name: network + "/" + service}
} }
defer syscall.FreeAddrInfoW(result) defer syscall.FreeAddrInfoW(result)
if result == nil { if result == nil {
...@@ -181,7 +191,7 @@ func (*Resolver) lookupCNAME(ctx context.Context, name string) (string, error) { ...@@ -181,7 +191,7 @@ func (*Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
return absDomainName([]byte(name)), nil return absDomainName([]byte(name)), nil
} }
if e != nil { if e != nil {
return "", &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name} return "", &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
} }
defer syscall.DnsRecordListFree(r, 1) defer syscall.DnsRecordListFree(r, 1)
...@@ -203,7 +213,7 @@ func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (st ...@@ -203,7 +213,7 @@ func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (st
var r *syscall.DNSRecord var r *syscall.DNSRecord
e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil) e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil)
if e != nil { if e != nil {
return "", nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: target} return "", nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: target}
} }
defer syscall.DnsRecordListFree(r, 1) defer syscall.DnsRecordListFree(r, 1)
...@@ -223,7 +233,7 @@ func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) { ...@@ -223,7 +233,7 @@ func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
var r *syscall.DNSRecord var r *syscall.DNSRecord
e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &r, nil) e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &r, nil)
if e != nil { if e != nil {
return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name} return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
} }
defer syscall.DnsRecordListFree(r, 1) defer syscall.DnsRecordListFree(r, 1)
...@@ -243,7 +253,7 @@ func (*Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) { ...@@ -243,7 +253,7 @@ func (*Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
var r *syscall.DNSRecord var r *syscall.DNSRecord
e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil) e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil)
if e != nil { if e != nil {
return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name} return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
} }
defer syscall.DnsRecordListFree(r, 1) defer syscall.DnsRecordListFree(r, 1)
...@@ -262,7 +272,7 @@ func (*Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) { ...@@ -262,7 +272,7 @@ func (*Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) {
var r *syscall.DNSRecord var r *syscall.DNSRecord
e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil) e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil)
if e != nil { if e != nil {
return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name} return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
} }
defer syscall.DnsRecordListFree(r, 1) defer syscall.DnsRecordListFree(r, 1)
...@@ -288,7 +298,7 @@ func (*Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) ...@@ -288,7 +298,7 @@ func (*Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error)
var r *syscall.DNSRecord var r *syscall.DNSRecord
e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &r, nil) e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &r, nil)
if e != nil { if e != nil {
return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: addr} return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: addr}
} }
defer syscall.DnsRecordListFree(r, 1) defer syscall.DnsRecordListFree(r, 1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment