}
func copyIP(x IP) IP {
+ if len(x) < 16 {
+ return x.To16()
+ }
y := make(IP, len(x))
copy(y, x)
return y
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) {
}
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},
}...)
}
}
// 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
}
},
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,
},
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,
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,
},
{
},
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,
},
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,
},
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,
},
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,
IPv6loopback,
},
testInetaddr,
- &TCPAddr{IP: IPv4(127, 0, 0, 1).To4(), Port: 5682},
+ &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
nil,
},
{
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,
},
{"", "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")},
}
}
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},
}...)
}
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)
+ }
}
}
}
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 {
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)
+ }
}
}
}
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 {