]> Cypherpunks repositories - gostls13.git/commitdiff
net: store IPv4 returned from cgo resolver as 4-byte slice net.IP
authorZeke Lu <lvzecai@gmail.com>
Thu, 27 Oct 2022 01:43:16 +0000 (01:43 +0000)
committerGopher Robot <gobot@golang.org>
Wed, 2 Nov 2022 18:42:50 +0000 (18:42 +0000)
net.IP states that a 16-byte slice can still be an IPv4 address.
But after netip.Addr is introduced, it requires extra care to keep
it as an IPv4 address when converting it to a netip.Addr using
netip.AddrFromSlice.

To address this issue, let's change the cgo resolver to return
4-byte net.IP for IPv4. The change will save us 12 bytes too.

Please note that the go resolver already return IPv4 as 4-byte
slice.

The test TestResolverLookupIP has been modified to cover this
behavior. So no new test is added.

Fixes #53554.

Change-Id: I0dc2a59ad785c0c67a7bc22433105529f055997f
GitHub-Last-Rev: bd7bb2f17bd8e07ea5b39e4a24512ed35d316bb8
GitHub-Pull-Request: golang/go#53638
Reviewed-on: https://go-review.googlesource.com/c/go/+/415580
Auto-Submit: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>

src/net/cgo_unix.go
src/net/ip.go
src/net/lookup_test.go
src/net/lookup_windows.go

index 81f492f4eff3c58b855d09737c4f82ce40c6fb88..a94472733815f0d20ea82ef7c247bd993c3beae6 100644 (file)
@@ -327,12 +327,3 @@ func cgoSockaddr(ip IP, zone string) (*_C_struct_sockaddr, _C_socklen_t) {
        }
        return nil, 0
 }
-
-func copyIP(x IP) IP {
-       if len(x) < 16 {
-               return x.To16()
-       }
-       y := make(IP, len(x))
-       copy(y, x)
-       return y
-}
index 54c52881cf4d4fe94eb0ba7395f241e3fd302dec..d9f3da702127342f0029ae4b06867443e8f99237 100644 (file)
@@ -757,3 +757,9 @@ func ParseCIDR(s string) (IP, *IPNet, error) {
        m := CIDRMask(n, 8*iplen)
        return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
 }
+
+func copyIP(x IP) IP {
+       y := make(IP, len(x))
+       copy(y, x)
+       return y
+}
index ed9f93f3fe8990184aee2ad1dd475ad1dfe41b9b..38618c7dd74b7fdcf120ddbd8534ac5ffbcaaf6a 100644 (file)
@@ -10,6 +10,7 @@ import (
        "context"
        "fmt"
        "internal/testenv"
+       "net/netip"
        "reflect"
        "runtime"
        "sort"
@@ -1289,18 +1290,16 @@ func TestResolverLookupIP(t *testing.T) {
                                                t.Fatalf("DefaultResolver.LookupIP(%q, %q): failed with unexpected error: %v", network, host, err)
                                        }
 
-                                       var v4Addrs []IP
-                                       var v6Addrs []IP
+                                       var v4Addrs []netip.Addr
+                                       var v6Addrs []netip.Addr
                                        for _, ip := range ips {
-                                               switch {
-                                               case ip.To4() != nil:
-                                                       // We need to skip the test below because To16 will
-                                                       // convent an IPv4 address to an IPv4-mapped IPv6
-                                                       // address.
-                                                       v4Addrs = append(v4Addrs, ip)
-                                               case ip.To16() != nil:
-                                                       v6Addrs = append(v6Addrs, ip)
-                                               default:
+                                               if addr, ok := netip.AddrFromSlice(ip); ok {
+                                                       if addr.Is4() {
+                                                               v4Addrs = append(v4Addrs, addr)
+                                                       } else {
+                                                               v6Addrs = append(v6Addrs, addr)
+                                                       }
+                                               } else {
                                                        t.Fatalf("IP=%q is neither IPv4 nor IPv6", ip)
                                                }
                                        }
@@ -1322,7 +1321,7 @@ func TestResolverLookupIP(t *testing.T) {
                                                t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv4 addresses: %v", network, host, v4Addrs)
                                        }
                                        if network == "ip4" && len(v6Addrs) > 0 {
-                                               t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv6 addresses: %v", network, host, v6Addrs)
+                                               t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv6 or IPv4-mapped IPv6 addresses: %v", network, host, v6Addrs)
                                        }
                                })
                        }
index 9ff39c74a4e2083ca79adb81e136a52b87887910..d73c6062c9310faba188d20f976a7d578924b899 100644 (file)
@@ -134,11 +134,11 @@ func (r *Resolver) lookupIP(ctx context.Context, network, name string) ([]IPAddr
                        switch result.Family {
                        case syscall.AF_INET:
                                a := (*syscall.RawSockaddrInet4)(addr).Addr
-                               addrs = append(addrs, IPAddr{IP: IPv4(a[0], a[1], a[2], a[3])})
+                               addrs = append(addrs, IPAddr{IP: copyIP(a[:])})
                        case syscall.AF_INET6:
                                a := (*syscall.RawSockaddrInet6)(addr).Addr
                                zone := zoneCache.name(int((*syscall.RawSockaddrInet6)(addr).Scope_id))
-                               addrs = append(addrs, IPAddr{IP: IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]}, Zone: zone})
+                               addrs = append(addrs, IPAddr{IP: copyIP(a[:]), Zone: zone})
                        default:
                                return nil, &DNSError{Err: syscall.EWINDOWS.Error(), Name: name}
                        }