github.com/c12o16h1/go/src@v0.0.0-20200114212001-5a151c0f00ed/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 "github.com/c12o16h1/go/src/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 ss := strings.Split(network, ":") 38 switch ss[0] { 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 runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { 58 return false 59 } 60 case "unixpacket": 61 switch runtime.GOOS { 62 case "aix", "android", "darwin", "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 ss[0] { 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 // testableAddress reports whether address of network is testable on 85 // the current platform configuration. 86 func testableAddress(network, address string) bool { 87 switch ss := strings.Split(network, ":"); ss[0] { 88 case "unix", "unixgram", "unixpacket": 89 // Abstract unix domain sockets, a Linux-ism. 90 if address[0] == '@' && runtime.GOOS != "linux" { 91 return false 92 } 93 } 94 return true 95 } 96 97 // testableListenArgs reports whether arguments are testable on the 98 // current platform configuration. 99 func testableListenArgs(network, address, client string) bool { 100 if !testableNetwork(network) || !testableAddress(network, address) { 101 return false 102 } 103 104 var err error 105 var addr Addr 106 switch ss := strings.Split(network, ":"); ss[0] { 107 case "tcp", "tcp4", "tcp6": 108 addr, err = ResolveTCPAddr("tcp", address) 109 case "udp", "udp4", "udp6": 110 addr, err = ResolveUDPAddr("udp", address) 111 case "ip", "ip4", "ip6": 112 addr, err = ResolveIPAddr("ip", address) 113 default: 114 return true 115 } 116 if err != nil { 117 return false 118 } 119 var ip IP 120 var wildcard bool 121 switch addr := addr.(type) { 122 case *TCPAddr: 123 ip = addr.IP 124 wildcard = addr.isWildcard() 125 case *UDPAddr: 126 ip = addr.IP 127 wildcard = addr.isWildcard() 128 case *IPAddr: 129 ip = addr.IP 130 wildcard = addr.isWildcard() 131 } 132 133 // Test wildcard IP addresses. 134 if wildcard && !testenv.HasExternalNetwork() { 135 return false 136 } 137 138 // Test functionality of IPv4 communication using AF_INET and 139 // IPv6 communication using AF_INET6 sockets. 140 if !supportsIPv4() && ip.To4() != nil { 141 return false 142 } 143 if !supportsIPv6() && ip.To16() != nil && ip.To4() == nil { 144 return false 145 } 146 cip := ParseIP(client) 147 if cip != nil { 148 if !supportsIPv4() && cip.To4() != nil { 149 return false 150 } 151 if !supportsIPv6() && cip.To16() != nil && cip.To4() == nil { 152 return false 153 } 154 } 155 156 // Test functionality of IPv4 communication using AF_INET6 157 // sockets. 158 if !supportsIPv4map() && supportsIPv4() && (network == "tcp" || network == "udp" || network == "ip") && wildcard { 159 // At this point, we prefer IPv4 when ip is nil. 160 // See favoriteAddrFamily for further information. 161 if ip.To16() != nil && ip.To4() == nil && cip.To4() != nil { // a pair of IPv6 server and IPv4 client 162 return false 163 } 164 if (ip.To4() != nil || ip == nil) && cip.To16() != nil && cip.To4() == nil { // a pair of IPv4 server and IPv6 client 165 return false 166 } 167 } 168 169 return true 170 } 171 172 func condFatalf(t *testing.T, network string, format string, args ...interface{}) { 173 t.Helper() 174 // A few APIs like File and Read/WriteMsg{UDP,IP} are not 175 // fully implemented yet on Plan 9 and Windows. 176 switch runtime.GOOS { 177 case "windows": 178 if network == "file+net" { 179 t.Logf(format, args...) 180 return 181 } 182 case "plan9": 183 t.Logf(format, args...) 184 return 185 } 186 t.Fatalf(format, args...) 187 }