1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package net
import (
"os"
"runtime"
"strings"
"testing"
)
// testableNetwork reports whether network is testable on the current
// platform configuration.
func testableNetwork(network string) bool {
ss := strings.Split(network, ":")
switch ss[0] {
case "ip+nopriv":
switch runtime.GOOS {
case "nacl":
return false
}
case "ip", "ip4", "ip6":
switch runtime.GOOS {
case "nacl", "plan9":
return false
default:
if os.Getuid() != 0 {
return false
}
}
case "unix", "unixgram":
switch runtime.GOOS {
case "nacl", "plan9", "windows":
return false
}
// iOS does not support unix, unixgram.
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
return false
}
case "unixpacket":
switch runtime.GOOS {
case "android", "darwin", "nacl", "plan9", "windows":
fallthrough
case "freebsd": // FreeBSD 8 and below don't support unixpacket
return false
}
}
switch ss[0] {
case "tcp4", "udp4", "ip4":
if !supportsIPv4 {
return false
}
case "tcp6", "udp6", "ip6":
if !supportsIPv6 {
return false
}
}
return true
}
// testableAddress reports whether address of network is testable on
// the current platform configuration.
func testableAddress(network, address string) bool {
switch ss := strings.Split(network, ":"); ss[0] {
case "unix", "unixgram", "unixpacket":
// Abstract unix domain sockets, a Linux-ism.
if address[0] == '@' && runtime.GOOS != "linux" {
return false
}
}
return true
}
// testableListenArgs reports whether arguments are testable on the
// current platform configuration.
func testableListenArgs(network, address, client string) bool {
if !testableNetwork(network) || !testableAddress(network, address) {
return false
}
var err error
var addr Addr
switch ss := strings.Split(network, ":"); ss[0] {
case "tcp", "tcp4", "tcp6":
addr, err = ResolveTCPAddr("tcp", address)
case "udp", "udp4", "udp6":
addr, err = ResolveUDPAddr("udp", address)
case "ip", "ip4", "ip6":
addr, err = ResolveIPAddr("ip", address)
default:
return true
}
if err != nil {
return false
}
var ip IP
var wildcard bool
switch addr := addr.(type) {
case *TCPAddr:
ip = addr.IP
wildcard = addr.isWildcard()
case *UDPAddr:
ip = addr.IP
wildcard = addr.isWildcard()
case *IPAddr:
ip = addr.IP
wildcard = addr.isWildcard()
}
// Test wildcard IP addresses.
if wildcard && (testing.Short() || !*testExternal) {
return false
}
// Test functionality of IPv4 communication using AF_INET and
// IPv6 communication using AF_INET6 sockets.
if !supportsIPv4 && ip.To4() != nil {
return false
}
if !supportsIPv6 && ip.To16() != nil && ip.To4() == nil {
return false
}
cip := ParseIP(client)
if cip != nil {
if !supportsIPv4 && cip.To4() != nil {
return false
}
if !supportsIPv6 && cip.To16() != nil && cip.To4() == nil {
return false
}
}
// Test functionality of IPv4 communication using AF_INET6
// sockets.
if !supportsIPv4map && (network == "tcp" || network == "udp" || network == "ip") && wildcard {
// At this point, we prefer IPv4 when ip is nil.
// See favoriteAddrFamily for further information.
if ip.To16() != nil && ip.To4() == nil && cip.To4() != nil { // a pair of IPv6 server and IPv4 client
return false
}
if (ip.To4() != nil || ip == nil) && cip.To16() != nil && cip.To4() == nil { // a pair of IPv4 server and IPv6 client
return false
}
}
return true
}
var condFatalf = func() func(*testing.T, string, ...interface{}) {
// A few APIs, File, Read/WriteMsg{UDP,IP}, are not
// implemented yet on both Plan 9 and Windows.
switch runtime.GOOS {
case "plan9", "windows":
return (*testing.T).Logf
}
return (*testing.T).Fatalf
}()
|