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, differnet
170 // listening address and same port.
171 func TestDualStackTCPListener(t
*testing
.T
) {
172 switch runtime
.GOOS
{
174 t
.Skipf("skipping test on %q", runtime
.GOOS
)
177 t
.Skip("ipv6 is not supported")
180 for _
, tt
:= range dualStackListenerTests
{
181 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
184 switch runtime
.GOOS
{
186 if tt
.wildcard
&& differentWildcardAddr(tt
.laddr1
, tt
.laddr2
) {
190 l1
, port
:= usableListenPort(t
, tt
.net1
, tt
.laddr1
)
191 laddr
:= tt
.laddr1
+ ":" + port
192 checkFirstListener(t
, tt
.net1
, laddr
, l1
)
193 laddr
= tt
.laddr2
+ ":" + port
194 l2
, err
:= Listen(tt
.net2
, laddr
)
195 checkDualStackSecondListener(t
, tt
.net2
, laddr
, tt
.xerr
, err
, l2
)
200 // TestDualStackUDPListener tests both single and double listen
201 // to a test listener with various address families, differnet
202 // listening address and same port.
203 func TestDualStackUDPListener(t
*testing
.T
) {
204 switch runtime
.GOOS
{
206 t
.Skipf("skipping test on %q", runtime
.GOOS
)
209 t
.Skip("ipv6 is not supported")
212 toudpnet
:= func(net
string) string {
224 for _
, tt
:= range dualStackListenerTests
{
225 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
228 tt
.net1
= toudpnet(tt
.net1
)
229 tt
.net2
= toudpnet(tt
.net2
)
230 switch runtime
.GOOS
{
232 if tt
.wildcard
&& differentWildcardAddr(tt
.laddr1
, tt
.laddr2
) {
236 l1
, port
:= usableListenPacketPort(t
, tt
.net1
, tt
.laddr1
)
237 laddr
:= tt
.laddr1
+ ":" + port
238 checkFirstListener(t
, tt
.net1
, laddr
, l1
)
239 laddr
= tt
.laddr2
+ ":" + port
240 l2
, err
:= ListenPacket(tt
.net2
, laddr
)
241 checkDualStackSecondListener(t
, tt
.net2
, laddr
, tt
.xerr
, err
, l2
)
246 func usableListenPort(t
*testing
.T
, net
, laddr
string) (l Listener
, port
string) {
251 panic("usableListenPort net=" + net
)
252 case "tcp", "tcp4", "tcp6":
253 l
, err
= Listen(net
, laddr
+":0")
255 t
.Fatalf("Probe Listen(%q, %q) failed: %v", net
, laddr
, err
)
257 nladdr
= l
.(*TCPListener
).Addr().String()
259 _
, port
, err
= SplitHostPort(nladdr
)
261 t
.Fatalf("SplitHostPort failed: %v", err
)
266 func usableListenPacketPort(t
*testing
.T
, net
, laddr
string) (l PacketConn
, port
string) {
271 panic("usableListenPacketPort net=" + net
)
272 case "udp", "udp4", "udp6":
273 l
, err
= ListenPacket(net
, laddr
+":0")
275 t
.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net
, laddr
, err
)
277 nladdr
= l
.(*UDPConn
).LocalAddr().String()
279 _
, port
, err
= SplitHostPort(nladdr
)
281 t
.Fatalf("SplitHostPort failed: %v", err
)
286 func differentWildcardAddr(i
, j
string) bool {
287 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") {
290 if i
== "[::]" && j
== "[::]" {
296 func checkFirstListener(t
*testing
.T
, net
, laddr
string, l
interface{}) {
299 fd
:= l
.(*TCPListener
).fd
300 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
302 fd
:= l
.(*TCPListener
).fd
303 if fd
.family
!= syscall
.AF_INET
{
304 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
307 fd
:= l
.(*TCPListener
).fd
308 if fd
.family
!= syscall
.AF_INET6
{
309 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
312 fd
:= l
.(*UDPConn
).fd
313 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
315 fd
:= l
.(*UDPConn
).fd
316 if fd
.family
!= syscall
.AF_INET
{
317 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
320 fd
:= l
.(*UDPConn
).fd
321 if fd
.family
!= syscall
.AF_INET6
{
322 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
325 t
.Fatalf("Unexpected network: %q", net
)
329 func checkSecondListener(t
*testing
.T
, net
, laddr
string, err error
, l
interface{}) {
331 case "tcp", "tcp4", "tcp6":
333 l
.(*TCPListener
).Close()
334 t
.Fatalf("Second Listen(%q, %q) should fail", net
, laddr
)
336 case "udp", "udp4", "udp6":
339 t
.Fatalf("Second ListenPacket(%q, %q) should fail", net
, laddr
)
342 t
.Fatalf("Unexpected network: %q", net
)
346 func checkDualStackSecondListener(t
*testing
.T
, net
, laddr
string, xerr
, err error
, l
interface{}) {
348 case "tcp", "tcp4", "tcp6":
349 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
350 t
.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
353 l
.(*TCPListener
).Close()
355 case "udp", "udp4", "udp6":
356 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
357 t
.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
363 t
.Fatalf("Unexpected network: %q", net
)
367 func checkDualStackAddrFamily(t
*testing
.T
, net
, laddr
string, fd
*netFD
) {
368 switch a
:= fd
.laddr
.(type) {
370 // If a node under test supports both IPv6 capability
371 // and IPv6 IPv4-mapping capability, we can assume
372 // that the node listens on a wildcard address with an
374 if supportsIPv4map
&& fd
.laddr
.(*TCPAddr
).isWildcard() {
375 if fd
.family
!= syscall
.AF_INET6
{
376 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
379 if fd
.family
!= a
.family() {
380 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
384 // If a node under test supports both IPv6 capability
385 // and IPv6 IPv4-mapping capability, we can assume
386 // that the node listens on a wildcard address with an
388 if supportsIPv4map
&& fd
.laddr
.(*UDPAddr
).isWildcard() {
389 if fd
.family
!= syscall
.AF_INET6
{
390 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
393 if fd
.family
!= a
.family() {
394 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
398 t
.Fatalf("Unexpected protocol address type: %T", a
)
402 var prohibitionaryDialArgTests
= []struct {
406 {"tcp6", "127.0.0.1"},
407 {"tcp6", "[::ffff:127.0.0.1]"},
410 func TestProhibitionaryDialArgs(t
*testing
.T
) {
411 switch runtime
.GOOS
{
413 t
.Skipf("skipping test on %q", runtime
.GOOS
)
415 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
416 if !supportsIPv4map || testing
.Short() ||
!*testExternal
{
420 l
, port
:= usableListenPort(t
, "tcp", "[::]")
423 for _
, tt
:= range prohibitionaryDialArgTests
{
424 c
, err
:= Dial(tt
.net
, tt
.addr
+":"+port
)
427 t
.Fatalf("Dial(%q, %q) should fail", tt
.net
, tt
.addr
)
432 func TestWildWildcardListener(t
*testing
.T
) {
433 switch runtime
.GOOS
{
435 t
.Skipf("skipping test on %q", runtime
.GOOS
)
438 if testing
.Short() ||
!*testExternal
{
439 t
.Skip("skipping test to avoid external network")
443 if p
:= recover(); p
!= nil {
444 t
.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p
)
448 if ln
, err
:= Listen("tcp", ""); err
== nil {
451 if ln
, err
:= ListenPacket("udp", ""); err
== nil {
454 if ln
, err
:= ListenTCP("tcp", nil); err
== nil {
457 if ln
, err
:= ListenUDP("udp", nil); err
== nil {
460 if ln
, err
:= ListenIP("ip:icmp", nil); err
== nil {