github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/net/platform_test.go (about) 1 // 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 5 package net 6 7 import ( 8 "internal/testenv" 9 "os" 10 "os/exec" 11 "runtime" 12 "strconv" 13 "strings" 14 "testing" 15 ) 16 17 var unixEnabledOnAIX bool 18 19 func init() { 20 if runtime.GOOS == "aix" { 21 // Unix network isn't properly working on AIX 7.2 with 22 // Technical Level < 2. 23 // The information is retrieved only once in this init() 24 // instead of everytime testableNetwork is called. 25 out, _ := exec.Command("oslevel", "-s").Output() 26 if len(out) >= len("7200-XX-ZZ-YYMM") { // AIX 7.2, Tech Level XX, Service Pack ZZ, date YYMM 27 aixVer := string(out[:4]) 28 tl, _ := strconv.Atoi(string(out[5:7])) 29 unixEnabledOnAIX = aixVer > "7200" || (aixVer == "7200" && tl >= 2) 30 } 31 } 32 } 33 34 // testableNetwork reports whether network is testable on the current 35 // platform configuration. 36 func testableNetwork(network string) bool { 37 net, _, _ := strings.Cut(network, ":") 38 switch net { 39 case "ip+nopriv": 40 case "ip", "ip4", "ip6": 41 switch runtime.GOOS { 42 case "plan9": 43 return false 44 default: 45 if os.Getuid() != 0 { 46 return false 47 } 48 } 49 case "unix", "unixgram": 50 switch runtime.GOOS { 51 case "android", "plan9", "windows": 52 return false 53 case "aix": 54 return unixEnabledOnAIX 55 } 56 // iOS does not support unix, unixgram. 57 if iOS() { 58 return false 59 } 60 case "unixpacket": 61 switch runtime.GOOS { 62 case "aix", "android", "darwin", "ios", "plan9", "windows": 63 return false 64 case "netbsd": 65 // It passes on amd64 at least. 386 fails (Issue 22927). arm is unknown. 66 if runtime.GOARCH == "386" { 67 return false 68 } 69 } 70 } 71 switch net { 72 case "tcp4", "udp4", "ip4": 73 if !supportsIPv4() { 74 return false 75 } 76 case "tcp6", "udp6", "ip6": 77 if !supportsIPv6() { 78 return false 79 } 80 } 81 return true 82 } 83 84 func iOS() bool { 85 return runtime.GOOS == "ios" 86 } 87 88 // testableAddress reports whether address of network is testable on 89 // the current platform configuration. 90 func testableAddress(network, address string) bool { 91 switch net, _, _ := strings.Cut(network, ":"); net { 92 case "unix", "unixgram", "unixpacket": 93 // Abstract unix domain sockets, a Linux-ism. 94 if address[0] == '@' && runtime.GOOS != "linux" { 95 return false 96 } 97 } 98 return true 99 } 100 101 // testableListenArgs reports whether arguments are testable on the 102 // current platform configuration. 103 func testableListenArgs(network, address, client string) bool { 104 if !testableNetwork(network) || !testableAddress(network, address) { 105 return false 106 } 107 108 var err error 109 var addr Addr 110 switch net, _, _ := strings.Cut(network, ":"); net { 111 case "tcp", "tcp4", "tcp6": 112 addr, err = ResolveTCPAddr("tcp", address) 113 case "udp", "udp4", "udp6": 114 addr, err = ResolveUDPAddr("udp", address) 115 case "ip", "ip4", "ip6": 116 addr, err = ResolveIPAddr("ip", address) 117 default: 118 return true 119 } 120 if err != nil { 121 return false 122 } 123 var ip IP 124 var wildcard bool 125 switch addr := addr.(type) { 126 case *TCPAddr: 127 ip = addr.IP 128 wildcard = addr.isWildcard() 129 case *UDPAddr: 130 ip = addr.IP 131 wildcard = addr.isWildcard() 132 case *IPAddr: 133 ip = addr.IP 134 wildcard = addr.isWildcard() 135 } 136 137 // Test wildcard IP addresses. 138 if wildcard && !testenv.HasExternalNetwork() { 139 return false 140 } 141 142 // Test functionality of IPv4 communication using AF_INET and 143 // IPv6 communication using AF_INET6 sockets. 144 if !supportsIPv4() && ip.To4() != nil { 145 return false 146 } 147 if !supportsIPv6() && ip.To16() != nil && ip.To4() == nil { 148 return false 149 } 150 cip := ParseIP(client) 151 if cip != nil { 152 if !supportsIPv4() && cip.To4() != nil { 153 return false 154 } 155 if !supportsIPv6() && cip.To16() != nil && cip.To4() == nil { 156 return false 157 } 158 } 159 160 // Test functionality of IPv4 communication using AF_INET6 161 // sockets. 162 if !supportsIPv4map() && supportsIPv4() && (network == "tcp" || network == "udp" || network == "ip") && wildcard { 163 // At this point, we prefer IPv4 when ip is nil. 164 // See favoriteAddrFamily for further information. 165 if ip.To16() != nil && ip.To4() == nil && cip.To4() != nil { // a pair of IPv6 server and IPv4 client 166 return false 167 } 168 if (ip.To4() != nil || ip == nil) && cip.To16() != nil && cip.To4() == nil { // a pair of IPv4 server and IPv6 client 169 return false 170 } 171 } 172 173 return true 174 } 175 176 func condFatalf(t *testing.T, network string, format string, args ...any) { 177 t.Helper() 178 // A few APIs like File and Read/WriteMsg{UDP,IP} are not 179 // fully implemented yet on Plan 9 and Windows. 180 switch runtime.GOOS { 181 case "windows": 182 if network == "file+net" { 183 t.Logf(format, args...) 184 return 185 } 186 case "plan9": 187 t.Logf(format, args...) 188 return 189 } 190 t.Fatalf(format, args...) 191 }