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