]> Cypherpunks repositories - gostls13.git/commitdiff
net: avoid memory copy calling absDomainName
authorAndy Pan <panjf2000@gmail.com>
Thu, 24 Jun 2021 04:50:14 +0000 (12:50 +0800)
committerDamien Neil <dneil@google.com>
Mon, 16 Aug 2021 21:38:38 +0000 (21:38 +0000)
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>

src/net/cgo_unix.go
src/net/dnsclient.go
src/net/hosts.go
src/net/hosts_test.go
src/net/lookup_plan9.go
src/net/lookup_windows.go
src/net/lookup_windows_test.go
src/net/parse.go

index 2ea86e074fb9436fa55f9a6884a828b4cd16ad24..5bf6fd84bc2aca1c4fd49e12417367d44f0ce0f7 100644 (file)
@@ -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) {
index 1bbe39650bbac2f7ec755d8de90c2ccae3845632..3c1a12995a8033e044f74a19c1bb29da30f375a2 100644 (file)
@@ -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
-               }
-       }
-       if hasDots && b[len(b)-1] != '.' {
-               b = append(b, '.')
+func absDomainName(s string) string {
+       if bytealg.IndexByteString(s, '.') != -1 && s[len(s)-1] != '.' {
+               s += "."
        }
-       return string(b)
+       return s
 }
 
 // An SRV represents a single DNS SRV record.
index 5c560f3756ed1a2ec58ef9b08345f8a96530c3ba..e604031920b1fe55a495679f64b740683161fdfd 100644 (file)
@@ -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
index 19c43999f9291ca77a13053c92b7efedc1c8e95e..72919140e9c79f032b493e2642b863c3b026755b 100644 (file)
@@ -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)
index 75c18b33ac06f0eca362200a8909b45bf3ab23c3..d43a03b778d477a3327dfd00f96667a6f56b9507 100644 (file)
@@ -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
 }
index bb34a081336930dee36c8a6d17e67ded263f9058..27e5f86910e0fcff75b14b80731b4bebb46d21d4 100644 (file)
@@ -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
 }
index aa95501d023930d114970e828296e9d10b531d9e..f726ef0f3475b064d59be85972f5cde95a7a9010 100644 (file)
@@ -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
 }
index 6c230ab63fa0c7906a5c80b95f0e2443be5d139f..0d7cce12e624a22020af04544dc85a01e135936d 100644 (file)
@@ -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 {