]> Cypherpunks repositories - gostls13.git/commitdiff
net: ensure that ResolveTCPAddr(addr.String()) reproduces addr
authorRuss Cox <rsc@golang.org>
Tue, 24 Sep 2013 02:40:24 +0000 (22:40 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 24 Sep 2013 02:40:24 +0000 (22:40 -0400)
And same for UDP.

Fixes #6465.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/13740048

src/pkg/net/cgo_unix.go
src/pkg/net/ip.go
src/pkg/net/ipraw_test.go
src/pkg/net/ipsock.go
src/pkg/net/ipsock_test.go
src/pkg/net/tcp_test.go
src/pkg/net/tcpsock.go
src/pkg/net/udp_test.go
src/pkg/net/udpsock.go

index 8397cd70c2ecef51eaa735ed6af3eafed912b0e8..1f366ee5c6d1596dee3d623b2b8d0969ea8e4ff6 100644 (file)
@@ -155,6 +155,9 @@ func cgoLookupCNAME(name string) (cname string, err error, completed bool) {
 }
 
 func copyIP(x IP) IP {
+       if len(x) < 16 {
+               return x.To16()
+       }
        y := make(IP, len(x))
        copy(y, x)
        return y
index f0f0d9ec6bddd0543d84f6ef8435df037ccb9767..fd6a7d4ee8bae274ea51f1d5892d07b82a6a25e9 100644 (file)
@@ -312,6 +312,15 @@ func (ip IP) String() string {
        return s
 }
 
+// ipEmptyString is like ip.String except that it returns
+// an empty string when ip is unset.
+func ipEmptyString(ip IP) string {
+       if len(ip) == 0 {
+               return ""
+       }
+       return ip.String()
+}
+
 // MarshalText implements the encoding.TextMarshaler interface.
 // The encoding is the same as returned by String.
 func (ip IP) MarshalText() ([]byte, error) {
index c8e3c846f4f4a5a89a72d68adaceff144930cc53..13c977cac4d0ccf543a7239c205d2baecd9be4a6 100644 (file)
@@ -52,8 +52,8 @@ func init() {
        }
        if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 {
                resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
-                       {"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1).To4()}, nil},
-                       {"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1).To4()}, nil},
+                       {"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+                       {"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
                        {"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil},
                }...)
        }
index a4601bad6d6f8fc367605aafd9d38d21443d4d18..8b586ef7c3e5d472b3de333cb6ce874712135c64 100644 (file)
@@ -116,11 +116,11 @@ func firstSupportedAddr(filter func(IP) IP, ips []IP, inetaddr func(IP) netaddr)
 }
 
 // ipv4only returns IPv4 addresses that we can use with the kernel's
-// IPv4 addressing modes.  It returns IPv4-mapped IPv6 addresses as
-// IPv4 addresses and returns other IPv6 address types as nils.
+// IPv4 addressing modes. If ip is an IPv4 address, ipv4only returns ip.
+// Otherwise it returns nil.
 func ipv4only(ip IP) IP {
-       if supportsIPv4 {
-               return ip.To4()
+       if supportsIPv4 && ip.To4() != nil {
+               return ip
        }
        return nil
 }
index 3deacaaa72b9751a945f4decc6ffb0579008d7f5..9ecaaec69f671b5e35f97b156014a3c60b3d3505 100644 (file)
@@ -26,7 +26,7 @@ var firstFavoriteAddrTests = []struct {
                },
                testInetaddr,
                addrList{
-                       &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+                       &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                        &TCPAddr{IP: IPv6loopback, Port: 5682},
                },
                nil,
@@ -39,7 +39,7 @@ var firstFavoriteAddrTests = []struct {
                },
                testInetaddr,
                addrList{
-                       &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+                       &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                        &TCPAddr{IP: IPv6loopback, Port: 5682},
                },
                nil,
@@ -51,7 +51,7 @@ var firstFavoriteAddrTests = []struct {
                        IPv4(192, 168, 0, 1),
                },
                testInetaddr,
-               &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+               &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                nil,
        },
        {
@@ -74,7 +74,7 @@ var firstFavoriteAddrTests = []struct {
                },
                testInetaddr,
                addrList{
-                       &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+                       &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                        &TCPAddr{IP: IPv6loopback, Port: 5682},
                },
                nil,
@@ -89,7 +89,7 @@ var firstFavoriteAddrTests = []struct {
                },
                testInetaddr,
                addrList{
-                       &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+                       &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                        &TCPAddr{IP: IPv6loopback, Port: 5682},
                },
                nil,
@@ -104,7 +104,7 @@ var firstFavoriteAddrTests = []struct {
                },
                testInetaddr,
                addrList{
-                       &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+                       &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                        &TCPAddr{IP: IPv6loopback, Port: 5682},
                },
                nil,
@@ -119,7 +119,7 @@ var firstFavoriteAddrTests = []struct {
                },
                testInetaddr,
                addrList{
-                       &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+                       &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                        &TCPAddr{IP: IPv6loopback, Port: 5682},
                },
                nil,
@@ -132,7 +132,7 @@ var firstFavoriteAddrTests = []struct {
                        IPv6loopback,
                },
                testInetaddr,
-               &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+               &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                nil,
        },
        {
@@ -142,7 +142,7 @@ var firstFavoriteAddrTests = []struct {
                        IPv4(127, 0, 0, 1),
                },
                testInetaddr,
-               &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+               &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
                nil,
        },
 
index a9c7562585cd01504619dabe31e7d668868534dd..62fd99f5c0bb2442e1423207a3041e3b19f279ce 100644 (file)
@@ -292,6 +292,8 @@ var resolveTCPAddrTests = []resolveTCPAddrTest{
        {"", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
        {"", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},         // Go 1.0 behavior
 
+       {"tcp", ":12345", &TCPAddr{Port: 12345}, nil},
+
        {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
 }
 
@@ -305,8 +307,8 @@ func init() {
        }
        if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 {
                resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
-                       {"tcp", "localhost:5", &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5}, nil},
-                       {"tcp4", "localhost:6", &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 6}, nil},
+                       {"tcp", "localhost:5", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5}, nil},
+                       {"tcp4", "localhost:6", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 6}, nil},
                        {"tcp6", "localhost:7", &TCPAddr{IP: IPv6loopback, Port: 7}, nil},
                }...)
        }
@@ -319,7 +321,17 @@ func TestResolveTCPAddr(t *testing.T) {
                        t.Fatalf("ResolveTCPAddr(%q, %q) failed: %v", tt.net, tt.litAddrOrName, err)
                }
                if !reflect.DeepEqual(addr, tt.addr) {
-                       t.Fatalf("got %#v; expected %#v", addr, tt.addr)
+                       t.Fatalf("ResolveTCPAddr(%q, %q) = %#v, want %#v", tt.net, tt.litAddrOrName, addr, tt.addr)
+               }
+               if err == nil {
+                       str := addr.String()
+                       addr1, err := ResolveTCPAddr(tt.net, str)
+                       if err != nil {
+                               t.Fatalf("ResolveTCPAddr(%q, %q) [from %q]: %v", tt.net, str, tt.litAddrOrName, err)
+                       }
+                       if !reflect.DeepEqual(addr1, addr) {
+                               t.Fatalf("ResolveTCPAddr(%q, %q) [from %q] = %#v, want %#v", tt.net, str, tt.litAddrOrName, addr1, addr)
+                       }
                }
        }
 }
index 8614c74595e2bb0b2dd5fa21729dcc5c55c3fe70..f3dfbd23d3498e43103927f812076ae0157ce264 100644 (file)
@@ -18,10 +18,11 @@ func (a *TCPAddr) String() string {
        if a == nil {
                return "<nil>"
        }
+       ip := ipEmptyString(a.IP)
        if a.Zone != "" {
-               return JoinHostPort(a.IP.String()+"%"+a.Zone, itoa(a.Port))
+               return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
        }
-       return JoinHostPort(a.IP.String(), itoa(a.Port))
+       return JoinHostPort(ip, itoa(a.Port))
 }
 
 func (a *TCPAddr) toAddr() Addr {
index fc73a79059c7ad92c2065d7a5e96eaf13c36926c..6f4d2152c3cd54ccd12c6530baf40165a326b451 100644 (file)
@@ -5,60 +5,31 @@
 package net
 
 import (
-       "fmt"
        "reflect"
        "runtime"
+       "strings"
        "testing"
 )
 
-type resolveUDPAddrTest struct {
-       net           string
-       litAddrOrName string
-       addr          *UDPAddr
-       err           error
-}
-
-var resolveUDPAddrTests = []resolveUDPAddrTest{
-       {"udp", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
-       {"udp4", "127.0.0.1:65535", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
-
-       {"udp", "[::1]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1}, nil},
-       {"udp6", "[::1]:65534", &UDPAddr{IP: ParseIP("::1"), Port: 65534}, nil},
-
-       {"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
-       {"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
-
-       {"", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
-       {"", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil},         // Go 1.0 behavior
-
-       {"sip", "127.0.0.1:0", nil, UnknownNetworkError("sip")},
-}
-
-func init() {
-       if ifi := loopbackInterface(); ifi != nil {
-               index := fmt.Sprintf("%v", ifi.Index)
-               resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{
-                       {"udp6", "[fe80::1%" + ifi.Name + "]:3", &UDPAddr{IP: ParseIP("fe80::1"), Port: 3, Zone: zoneToString(ifi.Index)}, nil},
-                       {"udp6", "[fe80::1%" + index + "]:4", &UDPAddr{IP: ParseIP("fe80::1"), Port: 4, Zone: index}, nil},
-               }...)
-       }
-       if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 {
-               resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{
-                       {"udp", "localhost:5", &UDPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5}, nil},
-                       {"udp4", "localhost:6", &UDPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 6}, nil},
-                       {"udp6", "localhost:7", &UDPAddr{IP: IPv6loopback, Port: 7}, nil},
-               }...)
-       }
-}
-
 func TestResolveUDPAddr(t *testing.T) {
-       for _, tt := range resolveUDPAddrTests {
-               addr, err := ResolveUDPAddr(tt.net, tt.litAddrOrName)
+       for _, tt := range resolveTCPAddrTests {
+               net := strings.Replace(tt.net, "tcp", "udp", -1)
+               addr, err := ResolveUDPAddr(net, tt.litAddrOrName)
                if err != tt.err {
-                       t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", tt.net, tt.litAddrOrName, err)
+                       t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, tt.litAddrOrName, err)
+               }
+               if !reflect.DeepEqual(addr, (*UDPAddr)(tt.addr)) {
+                       t.Fatalf("ResolveUDPAddr(%q, %q) = %#v, want %#v", net, tt.litAddrOrName, addr, tt.addr)
                }
-               if !reflect.DeepEqual(addr, tt.addr) {
-                       t.Fatalf("got %#v; expected %#v", addr, tt.addr)
+               if err == nil {
+                       str := addr.String()
+                       addr1, err := ResolveUDPAddr(net, str)
+                       if err != nil {
+                               t.Fatalf("ResolveUDPAddr(%q, %q) [from %q]: %v", net, str, tt.litAddrOrName, err)
+                       }
+                       if !reflect.DeepEqual(addr1, addr) {
+                               t.Fatalf("ResolveUDPAddr(%q, %q) [from %q] = %#v, want %#v", net, str, tt.litAddrOrName, addr1, addr)
+                       }
                }
        }
 }
index edbb93be3c8c612eedd36dc6714241d920a01a9e..0dd0dbd711444b6a07cc26c9916be58df88845d3 100644 (file)
@@ -22,10 +22,11 @@ func (a *UDPAddr) String() string {
        if a == nil {
                return "<nil>"
        }
+       ip := ipEmptyString(a.IP)
        if a.Zone != "" {
-               return JoinHostPort(a.IP.String()+"%"+a.Zone, itoa(a.Port))
+               return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
        }
-       return JoinHostPort(a.IP.String(), itoa(a.Port))
+       return JoinHostPort(ip, itoa(a.Port))
 }
 
 func (a *UDPAddr) toAddr() Addr {