mirror of
https://github.com/golang/go
synced 2024-11-02 11:50:30 +00:00
net: avoid memory copy calling absDomainName
Change-Id: I8ea9bec8bc33e29b8c265fbca40871bc23667144 Reviewed-on: https://go-review.googlesource.com/c/go/+/330470 Reviewed-by: Damien Neil <dneil@google.com> Trust: Damien Neil <dneil@google.com> Trust: Michael Knyszek <mknyszek@google.com> Run-TryBot: Damien Neil <dneil@google.com> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
6406227d71
commit
c04a32e59a
8 changed files with 43 additions and 38 deletions
|
@ -323,7 +323,7 @@ func cgoLookupAddrPTR(addr string, sa *C.struct_sockaddr, salen C.socklen_t) (na
|
|||
break
|
||||
}
|
||||
}
|
||||
return []string{absDomainName(b)}, nil
|
||||
return []string{absDomainName(string(b))}, nil
|
||||
}
|
||||
|
||||
func cgoReverseLookup(result chan<- reverseLookupResult, addr string, sa *C.struct_sockaddr, salen C.socklen_t) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package net
|
||||
|
||||
import (
|
||||
"internal/bytealg"
|
||||
"internal/itoa"
|
||||
"sort"
|
||||
|
||||
|
@ -136,18 +137,11 @@ func isDomainName(s string) bool {
|
|||
// It's hard to tell so we settle on the heuristic that names without dots
|
||||
// (like "localhost" or "myhost") do not get trailing dots, but any other
|
||||
// names do.
|
||||
func absDomainName(b []byte) string {
|
||||
hasDots := false
|
||||
for _, x := range b {
|
||||
if x == '.' {
|
||||
hasDots = true
|
||||
break
|
||||
}
|
||||
func absDomainName(s string) string {
|
||||
if bytealg.IndexByteString(s, '.') != -1 && s[len(s)-1] != '.' {
|
||||
s += "."
|
||||
}
|
||||
if hasDots && b[len(b)-1] != '.' {
|
||||
b = append(b, '.')
|
||||
}
|
||||
return string(b)
|
||||
return s
|
||||
}
|
||||
|
||||
// An SRV represents a single DNS SRV record.
|
||||
|
|
|
@ -82,10 +82,10 @@ func readHosts() {
|
|||
continue
|
||||
}
|
||||
for i := 1; i < len(f); i++ {
|
||||
name := absDomainName([]byte(f[i]))
|
||||
name := absDomainName(f[i])
|
||||
h := []byte(f[i])
|
||||
lowerASCIIBytes(h)
|
||||
key := absDomainName(h)
|
||||
key := absDomainName(string(h))
|
||||
hs[key] = append(hs[key], addr)
|
||||
is[addr] = append(is[addr], name)
|
||||
}
|
||||
|
@ -106,11 +106,12 @@ func lookupStaticHost(host string) []string {
|
|||
defer hosts.Unlock()
|
||||
readHosts()
|
||||
if len(hosts.byName) != 0 {
|
||||
// TODO(jbd,bradfitz): avoid this alloc if host is already all lowercase?
|
||||
// or linear scan the byName map if it's small enough?
|
||||
lowerHost := []byte(host)
|
||||
lowerASCIIBytes(lowerHost)
|
||||
if ips, ok := hosts.byName[absDomainName(lowerHost)]; ok {
|
||||
if hasUpperCase(host) {
|
||||
lowerHost := []byte(host)
|
||||
lowerASCIIBytes(lowerHost)
|
||||
host = string(lowerHost)
|
||||
}
|
||||
if ips, ok := hosts.byName[absDomainName(host)]; ok {
|
||||
ipsCp := make([]string, len(ips))
|
||||
copy(ipsCp, ips)
|
||||
return ipsCp
|
||||
|
|
|
@ -70,7 +70,7 @@ func TestLookupStaticHost(t *testing.T) {
|
|||
}
|
||||
|
||||
func testStaticHost(t *testing.T, hostsPath string, ent staticHostEntry) {
|
||||
ins := []string{ent.in, absDomainName([]byte(ent.in)), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
|
||||
ins := []string{ent.in, absDomainName(ent.in), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
|
||||
for _, in := range ins {
|
||||
addrs := lookupStaticHost(in)
|
||||
if !reflect.DeepEqual(addrs, ent.out) {
|
||||
|
@ -141,7 +141,7 @@ func TestLookupStaticAddr(t *testing.T) {
|
|||
func testStaticAddr(t *testing.T, hostsPath string, ent staticHostEntry) {
|
||||
hosts := lookupStaticAddr(ent.in)
|
||||
for i := range ent.out {
|
||||
ent.out[i] = absDomainName([]byte(ent.out[i]))
|
||||
ent.out[i] = absDomainName(ent.out[i])
|
||||
}
|
||||
if !reflect.DeepEqual(hosts, ent.out) {
|
||||
t.Errorf("%s, lookupStaticAddr(%s) = %v; want %v", hostsPath, ent.in, hosts, ent.out)
|
||||
|
|
|
@ -262,8 +262,8 @@ func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (cn
|
|||
if !(portOk && priorityOk && weightOk) {
|
||||
continue
|
||||
}
|
||||
addrs = append(addrs, &SRV{absDomainName([]byte(f[5])), uint16(port), uint16(priority), uint16(weight)})
|
||||
cname = absDomainName([]byte(f[0]))
|
||||
addrs = append(addrs, &SRV{absDomainName(f[5]), uint16(port), uint16(priority), uint16(weight)})
|
||||
cname = absDomainName(f[0])
|
||||
}
|
||||
byPriorityWeight(addrs).sort()
|
||||
return
|
||||
|
@ -280,7 +280,7 @@ func (*Resolver) lookupMX(ctx context.Context, name string) (mx []*MX, err error
|
|||
continue
|
||||
}
|
||||
if pref, _, ok := dtoi(f[2]); ok {
|
||||
mx = append(mx, &MX{absDomainName([]byte(f[3])), uint16(pref)})
|
||||
mx = append(mx, &MX{absDomainName(f[3]), uint16(pref)})
|
||||
}
|
||||
}
|
||||
byPref(mx).sort()
|
||||
|
@ -297,7 +297,7 @@ func (*Resolver) lookupNS(ctx context.Context, name string) (ns []*NS, err error
|
|||
if len(f) < 3 {
|
||||
continue
|
||||
}
|
||||
ns = append(ns, &NS{absDomainName([]byte(f[2]))})
|
||||
ns = append(ns, &NS{absDomainName(f[2])})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ func (*Resolver) lookupAddr(ctx context.Context, addr string) (name []string, er
|
|||
if len(f) < 3 {
|
||||
continue
|
||||
}
|
||||
name = append(name, absDomainName([]byte(f[2])))
|
||||
name = append(name, absDomainName(f[2]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ func (*Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
|
|||
// windows returns DNS_INFO_NO_RECORDS if there are no CNAME-s
|
||||
if errno, ok := e.(syscall.Errno); ok && errno == syscall.DNS_INFO_NO_RECORDS {
|
||||
// if there are no aliases, the canonical name is the input name
|
||||
return absDomainName([]byte(name)), nil
|
||||
return absDomainName(name), nil
|
||||
}
|
||||
if e != nil {
|
||||
return "", &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
|
||||
|
@ -235,7 +235,7 @@ func (*Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
|
|||
|
||||
resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), r)
|
||||
cname := windows.UTF16PtrToString(resolved)
|
||||
return absDomainName([]byte(cname)), nil
|
||||
return absDomainName(cname), nil
|
||||
}
|
||||
|
||||
func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
|
||||
|
@ -258,10 +258,10 @@ func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (st
|
|||
srvs := make([]*SRV, 0, 10)
|
||||
for _, p := range validRecs(r, syscall.DNS_TYPE_SRV, target) {
|
||||
v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
|
||||
srvs = append(srvs, &SRV{absDomainName([]byte(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]))), v.Port, v.Priority, v.Weight})
|
||||
srvs = append(srvs, &SRV{absDomainName(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:])), v.Port, v.Priority, v.Weight})
|
||||
}
|
||||
byPriorityWeight(srvs).sort()
|
||||
return absDomainName([]byte(target)), srvs, nil
|
||||
return absDomainName(target), srvs, nil
|
||||
}
|
||||
|
||||
func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
|
||||
|
@ -278,7 +278,7 @@ func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
|
|||
mxs := make([]*MX, 0, 10)
|
||||
for _, p := range validRecs(r, syscall.DNS_TYPE_MX, name) {
|
||||
v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
|
||||
mxs = append(mxs, &MX{absDomainName([]byte(windows.UTF16PtrToString(v.NameExchange))), v.Preference})
|
||||
mxs = append(mxs, &MX{absDomainName(windows.UTF16PtrToString(v.NameExchange)), v.Preference})
|
||||
}
|
||||
byPref(mxs).sort()
|
||||
return mxs, nil
|
||||
|
@ -298,7 +298,7 @@ func (*Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
|
|||
nss := make([]*NS, 0, 10)
|
||||
for _, p := range validRecs(r, syscall.DNS_TYPE_NS, name) {
|
||||
v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
|
||||
nss = append(nss, &NS{absDomainName([]byte(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:])))})
|
||||
nss = append(nss, &NS{absDomainName(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))})
|
||||
}
|
||||
return nss, nil
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ func (*Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error)
|
|||
ptrs := make([]string, 0, 10)
|
||||
for _, p := range validRecs(r, syscall.DNS_TYPE_PTR, arpa) {
|
||||
v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
|
||||
ptrs = append(ptrs, absDomainName([]byte(windows.UTF16PtrToString(v.Host))))
|
||||
ptrs = append(ptrs, absDomainName(windows.UTF16PtrToString(v.Host)))
|
||||
}
|
||||
return ptrs, nil
|
||||
}
|
||||
|
|
|
@ -220,14 +220,14 @@ func nslookupMX(name string) (mx []*MX, err error) {
|
|||
rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+mail exchanger\s*=\s*([0-9]+)\s*([a-z0-9.\-]+)$`)
|
||||
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
|
||||
pref, _, _ := dtoi(ans[2])
|
||||
mx = append(mx, &MX{absDomainName([]byte(ans[3])), uint16(pref)})
|
||||
mx = append(mx, &MX{absDomainName(ans[3]), uint16(pref)})
|
||||
}
|
||||
// windows nslookup syntax
|
||||
// gmail.com MX preference = 30, mail exchanger = alt3.gmail-smtp-in.l.google.com
|
||||
rx = regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+MX preference\s*=\s*([0-9]+)\s*,\s*mail exchanger\s*=\s*([a-z0-9.\-]+)$`)
|
||||
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
|
||||
pref, _, _ := dtoi(ans[2])
|
||||
mx = append(mx, &MX{absDomainName([]byte(ans[3])), uint16(pref)})
|
||||
mx = append(mx, &MX{absDomainName(ans[3]), uint16(pref)})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ func nslookupNS(name string) (ns []*NS, err error) {
|
|||
// golang.org nameserver = ns1.google.com.
|
||||
rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+nameserver\s*=\s*([a-z0-9.\-]+)$`)
|
||||
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
|
||||
ns = append(ns, &NS{absDomainName([]byte(ans[2]))})
|
||||
ns = append(ns, &NS{absDomainName(ans[2])})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ func nslookupCNAME(name string) (cname string, err error) {
|
|||
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
|
||||
last = ans[2]
|
||||
}
|
||||
return absDomainName([]byte(last)), nil
|
||||
return absDomainName(last), nil
|
||||
}
|
||||
|
||||
func nslookupTXT(name string) (txt []string, err error) {
|
||||
|
@ -299,7 +299,7 @@ func lookupPTR(name string) (ptr []string, err error) {
|
|||
ptr = make([]string, 0, 10)
|
||||
rx := regexp.MustCompile(`(?m)^Pinging\s+([a-zA-Z0-9.\-]+)\s+\[.*$`)
|
||||
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
|
||||
ptr = append(ptr, absDomainName([]byte(ans[1])))
|
||||
ptr = append(ptr, absDomainName(ans[1]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -208,6 +208,16 @@ func last(s string, b byte) int {
|
|||
return i
|
||||
}
|
||||
|
||||
// hasUpperCase tells whether the given string contains at least one upper-case.
|
||||
func hasUpperCase(s string) bool {
|
||||
for i := range s {
|
||||
if 'A' <= s[i] && s[i] <= 'Z' {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// lowerASCIIBytes makes x ASCII lowercase in-place.
|
||||
func lowerASCIIBytes(x []byte) {
|
||||
for i, b := range x {
|
||||
|
|
Loading…
Reference in a new issue