1 // Copyright 2011 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.
15 var listenerTests
= []struct {
18 ipv6
bool // test with underlying AF_INET6 socket
19 wildcard
bool // test with wildcard address
21 {net
: "tcp", laddr
: "", wildcard
: true},
22 {net
: "tcp", laddr
: "0.0.0.0", wildcard
: true},
23 {net
: "tcp", laddr
: "[::ffff:0.0.0.0]", wildcard
: true},
24 {net
: "tcp", laddr
: "[::]", ipv6
: true, wildcard
: true},
26 {net
: "tcp", laddr
: "127.0.0.1"},
27 {net
: "tcp", laddr
: "[::ffff:127.0.0.1]"},
28 {net
: "tcp", laddr
: "[::1]", ipv6
: true},
30 {net
: "tcp4", laddr
: "", wildcard
: true},
31 {net
: "tcp4", laddr
: "0.0.0.0", wildcard
: true},
32 {net
: "tcp4", laddr
: "[::ffff:0.0.0.0]", wildcard
: true},
34 {net
: "tcp4", laddr
: "127.0.0.1"},
35 {net
: "tcp4", laddr
: "[::ffff:127.0.0.1]"},
37 {net
: "tcp6", laddr
: "", ipv6
: true, wildcard
: true},
38 {net
: "tcp6", laddr
: "[::]", ipv6
: true, wildcard
: true},
40 {net
: "tcp6", laddr
: "[::1]", ipv6
: true},
43 // TestTCPListener tests both single and double listen to a test
44 // listener with same address family, same listening address and
46 func TestTCPListener(t
*testing
.T
) {
49 t
.Skipf("skipping test on %q", runtime
.GOOS
)
52 for _
, tt
:= range listenerTests
{
53 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
56 if tt
.ipv6
&& !supportsIPv6
{
59 l1
, port
:= usableListenPort(t
, tt
.net
, tt
.laddr
)
60 checkFirstListener(t
, tt
.net
, tt
.laddr
+":"+port
, l1
)
61 l2
, err
:= Listen(tt
.net
, tt
.laddr
+":"+port
)
62 checkSecondListener(t
, tt
.net
, tt
.laddr
+":"+port
, err
, l2
)
67 // TestUDPListener tests both single and double listen to a test
68 // listener with same address family, same listening address and
70 func TestUDPListener(t
*testing
.T
) {
73 t
.Skipf("skipping test on %q", runtime
.GOOS
)
76 toudpnet
:= func(net
string) string {
88 for _
, tt
:= range listenerTests
{
89 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
92 if tt
.ipv6
&& !supportsIPv6
{
95 tt
.net
= toudpnet(tt
.net
)
96 l1
, port
:= usableListenPacketPort(t
, tt
.net
, tt
.laddr
)
97 checkFirstListener(t
, tt
.net
, tt
.laddr
+":"+port
, l1
)
98 l2
, err
:= ListenPacket(tt
.net
, tt
.laddr
+":"+port
)
99 checkSecondListener(t
, tt
.net
, tt
.laddr
+":"+port
, err
, l2
)
104 var dualStackListenerTests
= []struct {
105 net1
string // first listener
107 net2
string // second listener
109 wildcard
bool // test with wildcard address
110 xerr error
// expected error value, nil or other
112 // Test cases and expected results for the attemping 2nd listen on the same port
113 // 1st listen 2nd listen darwin freebsd linux openbsd
114 // ------------------------------------------------------------------------------------
115 // "tcp" "" "tcp" "" - - - -
116 // "tcp" "" "tcp" "0.0.0.0" - - - -
117 // "tcp" "0.0.0.0" "tcp" "" - - - -
118 // ------------------------------------------------------------------------------------
119 // "tcp" "" "tcp" "[::]" - - - ok
120 // "tcp" "[::]" "tcp" "" - - - ok
121 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
122 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
123 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
124 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
125 // ------------------------------------------------------------------------------------
126 // "tcp4" "" "tcp6" "" ok ok ok ok
127 // "tcp6" "" "tcp4" "" ok ok ok ok
128 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
129 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
130 // ------------------------------------------------------------------------------------
131 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
132 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
133 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
134 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
136 // Platform default configurations:
137 // darwin, kernel version 11.3.0
138 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
139 // freebsd, kernel version 8.2
140 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
141 // linux, kernel version 3.0.0
142 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
143 // openbsd, kernel version 5.0
144 // net.inet6.ip6.v6only=1 (overriding is prohibited)
146 {net1
: "tcp", laddr1
: "", net2
: "tcp", laddr2
: "", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
147 {net1
: "tcp", laddr1
: "", net2
: "tcp", laddr2
: "0.0.0.0", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
148 {net1
: "tcp", laddr1
: "0.0.0.0", net2
: "tcp", laddr2
: "", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
150 {net1
: "tcp", laddr1
: "", net2
: "tcp", laddr2
: "[::]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
151 {net1
: "tcp", laddr1
: "[::]", net2
: "tcp", laddr2
: "", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
152 {net1
: "tcp", laddr1
: "0.0.0.0", net2
: "tcp", laddr2
: "[::]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
153 {net1
: "tcp", laddr1
: "[::]", net2
: "tcp", laddr2
: "0.0.0.0", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
154 {net1
: "tcp", laddr1
: "[::ffff:0.0.0.0]", net2
: "tcp", laddr2
: "[::]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
155 {net1
: "tcp", laddr1
: "[::]", net2
: "tcp", laddr2
: "[::ffff:0.0.0.0]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
157 {net1
: "tcp4", laddr1
: "", net2
: "tcp6", laddr2
: "", wildcard
: true},
158 {net1
: "tcp6", laddr1
: "", net2
: "tcp4", laddr2
: "", wildcard
: true},
159 {net1
: "tcp4", laddr1
: "0.0.0.0", net2
: "tcp6", laddr2
: "[::]", wildcard
: true},
160 {net1
: "tcp6", laddr1
: "[::]", net2
: "tcp4", laddr2
: "0.0.0.0", wildcard
: true},
162 {net1
: "tcp", laddr1
: "127.0.0.1", net2
: "tcp", laddr2
: "[::1]"},
163 {net1
: "tcp", laddr1
: "[::1]", net2
: "tcp", laddr2
: "127.0.0.1"},
164 {net1
: "tcp4", laddr1
: "127.0.0.1", net2
: "tcp6", laddr2
: "[::1]"},
165 {net1
: "tcp6", laddr1
: "[::1]", net2
: "tcp4", laddr2
: "127.0.0.1"},
168 // TestDualStackTCPListener tests both single and double listen
169 // to a test listener with various address families, different
170 // listening address and same port.
171 func TestDualStackTCPListener(t
*testing
.T
) {
173 t
.Skip("skipping in -short mode, see issue 5001")
175 switch runtime
.GOOS
{
177 t
.Skipf("skipping test on %q", runtime
.GOOS
)
180 t
.Skip("ipv6 is not supported")
183 for _
, tt
:= range dualStackListenerTests
{
184 if tt
.wildcard
&& !*testExternal
{
187 switch runtime
.GOOS
{
189 if tt
.wildcard
&& differentWildcardAddr(tt
.laddr1
, tt
.laddr2
) {
193 l1
, port
:= usableListenPort(t
, tt
.net1
, tt
.laddr1
)
194 laddr
:= tt
.laddr1
+ ":" + port
195 checkFirstListener(t
, tt
.net1
, laddr
, l1
)
196 laddr
= tt
.laddr2
+ ":" + port
197 l2
, err
:= Listen(tt
.net2
, laddr
)
198 checkDualStackSecondListener(t
, tt
.net2
, laddr
, tt
.xerr
, err
, l2
)
203 // TestDualStackUDPListener tests both single and double listen
204 // to a test listener with various address families, differnet
205 // listening address and same port.
206 func TestDualStackUDPListener(t
*testing
.T
) {
208 t
.Skip("skipping in -short mode, see issue 5001")
210 switch runtime
.GOOS
{
212 t
.Skipf("skipping test on %q", runtime
.GOOS
)
215 t
.Skip("ipv6 is not supported")
218 toudpnet
:= func(net
string) string {
230 for _
, tt
:= range dualStackListenerTests
{
231 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
234 tt
.net1
= toudpnet(tt
.net1
)
235 tt
.net2
= toudpnet(tt
.net2
)
236 switch runtime
.GOOS
{
238 if tt
.wildcard
&& differentWildcardAddr(tt
.laddr1
, tt
.laddr2
) {
242 l1
, port
:= usableListenPacketPort(t
, tt
.net1
, tt
.laddr1
)
243 laddr
:= tt
.laddr1
+ ":" + port
244 checkFirstListener(t
, tt
.net1
, laddr
, l1
)
245 laddr
= tt
.laddr2
+ ":" + port
246 l2
, err
:= ListenPacket(tt
.net2
, laddr
)
247 checkDualStackSecondListener(t
, tt
.net2
, laddr
, tt
.xerr
, err
, l2
)
252 func usableListenPort(t
*testing
.T
, net
, laddr
string) (l Listener
, port
string) {
257 panic("usableListenPort net=" + net
)
258 case "tcp", "tcp4", "tcp6":
259 l
, err
= Listen(net
, laddr
+":0")
261 t
.Fatalf("Probe Listen(%q, %q) failed: %v", net
, laddr
, err
)
263 nladdr
= l
.(*TCPListener
).Addr().String()
265 _
, port
, err
= SplitHostPort(nladdr
)
267 t
.Fatalf("SplitHostPort failed: %v", err
)
272 func usableListenPacketPort(t
*testing
.T
, net
, laddr
string) (l PacketConn
, port
string) {
277 panic("usableListenPacketPort net=" + net
)
278 case "udp", "udp4", "udp6":
279 l
, err
= ListenPacket(net
, laddr
+":0")
281 t
.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net
, laddr
, err
)
283 nladdr
= l
.(*UDPConn
).LocalAddr().String()
285 _
, port
, err
= SplitHostPort(nladdr
)
287 t
.Fatalf("SplitHostPort failed: %v", err
)
292 func differentWildcardAddr(i
, j
string) bool {
293 if (i
== "" || i
== "0.0.0.0" || i
== "::ffff:0.0.0.0") && (j
== "" || j
== "0.0.0.0" || j
== "::ffff:0.0.0.0") {
296 if i
== "[::]" && j
== "[::]" {
302 func checkFirstListener(t
*testing
.T
, net
, laddr
string, l
interface{}) {
305 fd
:= l
.(*TCPListener
).fd
306 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
308 fd
:= l
.(*TCPListener
).fd
309 if fd
.family
!= syscall
.AF_INET
{
310 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
313 fd
:= l
.(*TCPListener
).fd
314 if fd
.family
!= syscall
.AF_INET6
{
315 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
318 fd
:= l
.(*UDPConn
).fd
319 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
321 fd
:= l
.(*UDPConn
).fd
322 if fd
.family
!= syscall
.AF_INET
{
323 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
326 fd
:= l
.(*UDPConn
).fd
327 if fd
.family
!= syscall
.AF_INET6
{
328 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
331 t
.Fatalf("Unexpected network: %q", net
)
335 func checkSecondListener(t
*testing
.T
, net
, laddr
string, err error
, l
interface{}) {
337 case "tcp", "tcp4", "tcp6":
339 l
.(*TCPListener
).Close()
340 t
.Fatalf("Second Listen(%q, %q) should fail", net
, laddr
)
342 case "udp", "udp4", "udp6":
345 t
.Fatalf("Second ListenPacket(%q, %q) should fail", net
, laddr
)
348 t
.Fatalf("Unexpected network: %q", net
)
352 func checkDualStackSecondListener(t
*testing
.T
, net
, laddr
string, xerr
, err error
, l
interface{}) {
354 case "tcp", "tcp4", "tcp6":
355 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
356 t
.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
359 l
.(*TCPListener
).Close()
361 case "udp", "udp4", "udp6":
362 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
363 t
.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
369 t
.Fatalf("Unexpected network: %q", net
)
373 func checkDualStackAddrFamily(t
*testing
.T
, net
, laddr
string, fd
*netFD
) {
374 switch a
:= fd
.laddr
.(type) {
376 // If a node under test supports both IPv6 capability
377 // and IPv6 IPv4-mapping capability, we can assume
378 // that the node listens on a wildcard address with an
380 if supportsIPv4map
&& fd
.laddr
.(*TCPAddr
).isWildcard() {
381 if fd
.family
!= syscall
.AF_INET6
{
382 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
385 if fd
.family
!= a
.family() {
386 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
390 // If a node under test supports both IPv6 capability
391 // and IPv6 IPv4-mapping capability, we can assume
392 // that the node listens on a wildcard address with an
394 if supportsIPv4map
&& fd
.laddr
.(*UDPAddr
).isWildcard() {
395 if fd
.family
!= syscall
.AF_INET6
{
396 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
399 if fd
.family
!= a
.family() {
400 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
404 t
.Fatalf("Unexpected protocol address type: %T", a
)
408 var prohibitionaryDialArgTests
= []struct {
412 {"tcp6", "127.0.0.1"},
413 {"tcp6", "[::ffff:127.0.0.1]"},
416 func TestProhibitionaryDialArgs(t
*testing
.T
) {
417 switch runtime
.GOOS
{
419 t
.Skipf("skipping test on %q", runtime
.GOOS
)
421 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
422 if !supportsIPv4map || testing
.Short() ||
!*testExternal
{
426 l
, port
:= usableListenPort(t
, "tcp", "[::]")
429 for _
, tt
:= range prohibitionaryDialArgTests
{
430 c
, err
:= Dial(tt
.net
, tt
.addr
+":"+port
)
433 t
.Fatalf("Dial(%q, %q) should fail", tt
.net
, tt
.addr
)
438 func TestWildWildcardListener(t
*testing
.T
) {
439 switch runtime
.GOOS
{
441 t
.Skipf("skipping test on %q", runtime
.GOOS
)
444 if testing
.Short() ||
!*testExternal
{
445 t
.Skip("skipping test to avoid external network")
449 if p
:= recover(); p
!= nil {
450 t
.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p
)
454 if ln
, err
:= Listen("tcp", ""); err
== nil {
457 if ln
, err
:= ListenPacket("udp", ""); err
== nil {
460 if ln
, err
:= ListenTCP("tcp", nil); err
== nil {
463 if ln
, err
:= ListenUDP("udp", nil); err
== nil {
466 if ln
, err
:= ListenIP("ip:icmp", nil); err
== nil {