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
) {
48 case "plan9", "windows":
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
) {
72 case "plan9", "windows":
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 func TestSimpleTCPListener(t
*testing
.T
) {
105 switch runtime
.GOOS
{
107 t
.Skipf("skipping test on %q", runtime
.GOOS
)
111 for _
, tt
:= range listenerTests
{
112 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
118 l1
, port
:= usableListenPort(t
, tt
.net
, tt
.laddr
)
119 checkFirstListener(t
, tt
.net
, tt
.laddr
+":"+port
, l1
)
120 l2
, err
:= Listen(tt
.net
, tt
.laddr
+":"+port
)
121 checkSecondListener(t
, tt
.net
, tt
.laddr
+":"+port
, err
, l2
)
126 func TestSimpleUDPListener(t
*testing
.T
) {
127 switch runtime
.GOOS
{
129 t
.Skipf("skipping test on %q", runtime
.GOOS
)
133 toudpnet
:= func(net
string) string {
145 for _
, tt
:= range listenerTests
{
146 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
152 tt
.net
= toudpnet(tt
.net
)
153 l1
, port
:= usableListenPacketPort(t
, tt
.net
, tt
.laddr
)
154 checkFirstListener(t
, tt
.net
, tt
.laddr
+":"+port
, l1
)
155 l2
, err
:= ListenPacket(tt
.net
, tt
.laddr
+":"+port
)
156 checkSecondListener(t
, tt
.net
, tt
.laddr
+":"+port
, err
, l2
)
161 var dualStackListenerTests
= []struct {
162 net1
string // first listener
164 net2
string // second listener
166 wildcard
bool // test with wildcard address
167 xerr error
// expected error value, nil or other
169 // Test cases and expected results for the attemping 2nd listen on the same port
170 // 1st listen 2nd listen darwin freebsd linux openbsd
171 // ------------------------------------------------------------------------------------
172 // "tcp" "" "tcp" "" - - - -
173 // "tcp" "" "tcp" "0.0.0.0" - - - -
174 // "tcp" "0.0.0.0" "tcp" "" - - - -
175 // ------------------------------------------------------------------------------------
176 // "tcp" "" "tcp" "[::]" - - - ok
177 // "tcp" "[::]" "tcp" "" - - - ok
178 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
179 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
180 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
181 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
182 // ------------------------------------------------------------------------------------
183 // "tcp4" "" "tcp6" "" ok ok ok ok
184 // "tcp6" "" "tcp4" "" ok ok ok ok
185 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
186 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
187 // ------------------------------------------------------------------------------------
188 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
189 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
190 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
191 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
193 // Platform default configurations:
194 // darwin, kernel version 11.3.0
195 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
196 // freebsd, kernel version 8.2
197 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
198 // linux, kernel version 3.0.0
199 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
200 // openbsd, kernel version 5.0
201 // net.inet6.ip6.v6only=1 (overriding is prohibited)
203 {net1
: "tcp", laddr1
: "", net2
: "tcp", laddr2
: "", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
204 {net1
: "tcp", laddr1
: "", net2
: "tcp", laddr2
: "0.0.0.0", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
205 {net1
: "tcp", laddr1
: "0.0.0.0", net2
: "tcp", laddr2
: "", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
207 {net1
: "tcp", laddr1
: "", net2
: "tcp", laddr2
: "[::]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
208 {net1
: "tcp", laddr1
: "[::]", net2
: "tcp", laddr2
: "", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
209 {net1
: "tcp", laddr1
: "0.0.0.0", net2
: "tcp", laddr2
: "[::]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
210 {net1
: "tcp", laddr1
: "[::]", net2
: "tcp", laddr2
: "0.0.0.0", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
211 {net1
: "tcp", laddr1
: "[::ffff:0.0.0.0]", net2
: "tcp", laddr2
: "[::]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
212 {net1
: "tcp", laddr1
: "[::]", net2
: "tcp", laddr2
: "[::ffff:0.0.0.0]", wildcard
: true, xerr
: syscall
.EADDRINUSE
},
214 {net1
: "tcp4", laddr1
: "", net2
: "tcp6", laddr2
: "", wildcard
: true},
215 {net1
: "tcp6", laddr1
: "", net2
: "tcp4", laddr2
: "", wildcard
: true},
216 {net1
: "tcp4", laddr1
: "0.0.0.0", net2
: "tcp6", laddr2
: "[::]", wildcard
: true},
217 {net1
: "tcp6", laddr1
: "[::]", net2
: "tcp4", laddr2
: "0.0.0.0", wildcard
: true},
219 {net1
: "tcp", laddr1
: "127.0.0.1", net2
: "tcp", laddr2
: "[::1]"},
220 {net1
: "tcp", laddr1
: "[::1]", net2
: "tcp", laddr2
: "127.0.0.1"},
221 {net1
: "tcp4", laddr1
: "127.0.0.1", net2
: "tcp6", laddr2
: "[::1]"},
222 {net1
: "tcp6", laddr1
: "[::1]", net2
: "tcp4", laddr2
: "127.0.0.1"},
225 // TestDualStackTCPListener tests both single and double listen
226 // to a test listener with various address families, differnet
227 // listening address and same port.
228 func TestDualStackTCPListener(t
*testing
.T
) {
229 switch runtime
.GOOS
{
231 t
.Skipf("skipping test on %q", runtime
.GOOS
)
237 for _
, tt
:= range dualStackListenerTests
{
238 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
241 switch runtime
.GOOS
{
243 if tt
.wildcard
&& differentWildcardAddr(tt
.laddr1
, tt
.laddr2
) {
247 l1
, port
:= usableListenPort(t
, tt
.net1
, tt
.laddr1
)
248 laddr
:= tt
.laddr1
+ ":" + port
249 checkFirstListener(t
, tt
.net1
, laddr
, l1
)
250 laddr
= tt
.laddr2
+ ":" + port
251 l2
, err
:= Listen(tt
.net2
, laddr
)
252 checkDualStackSecondListener(t
, tt
.net2
, laddr
, tt
.xerr
, err
, l2
)
257 // TestDualStackUDPListener tests both single and double listen
258 // to a test listener with various address families, differnet
259 // listening address and same port.
260 func TestDualStackUDPListener(t
*testing
.T
) {
261 switch runtime
.GOOS
{
263 t
.Skipf("skipping test on %q", runtime
.GOOS
)
269 toudpnet
:= func(net
string) string {
281 for _
, tt
:= range dualStackListenerTests
{
282 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
285 tt
.net1
= toudpnet(tt
.net1
)
286 tt
.net2
= toudpnet(tt
.net2
)
287 switch runtime
.GOOS
{
289 if tt
.wildcard
&& differentWildcardAddr(tt
.laddr1
, tt
.laddr2
) {
293 l1
, port
:= usableListenPacketPort(t
, tt
.net1
, tt
.laddr1
)
294 laddr
:= tt
.laddr1
+ ":" + port
295 checkFirstListener(t
, tt
.net1
, laddr
, l1
)
296 laddr
= tt
.laddr2
+ ":" + port
297 l2
, err
:= ListenPacket(tt
.net2
, laddr
)
298 checkDualStackSecondListener(t
, tt
.net2
, laddr
, tt
.xerr
, err
, l2
)
303 func usableListenPort(t
*testing
.T
, net
, laddr
string) (l Listener
, port
string) {
308 panic("usableListenPort net=" + net
)
309 case "tcp", "tcp4", "tcp6":
310 l
, err
= Listen(net
, laddr
+":0")
312 t
.Fatalf("Probe Listen(%q, %q) failed: %v", net
, laddr
, err
)
314 nladdr
= l
.(*TCPListener
).Addr().String()
316 _
, port
, err
= SplitHostPort(nladdr
)
318 t
.Fatalf("SplitHostPort failed: %v", err
)
323 func usableListenPacketPort(t
*testing
.T
, net
, laddr
string) (l PacketConn
, port
string) {
328 panic("usableListenPacketPort net=" + net
)
329 case "udp", "udp4", "udp6":
330 l
, err
= ListenPacket(net
, laddr
+":0")
332 t
.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net
, laddr
, err
)
334 nladdr
= l
.(*UDPConn
).LocalAddr().String()
336 _
, port
, err
= SplitHostPort(nladdr
)
338 t
.Fatalf("SplitHostPort failed: %v", err
)
343 func differentWildcardAddr(i
, j
string) bool {
344 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") {
347 if i
== "[::]" && j
== "[::]" {
353 func checkFirstListener(t
*testing
.T
, net
, laddr
string, l
interface{}) {
356 fd
:= l
.(*TCPListener
).fd
357 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
359 fd
:= l
.(*TCPListener
).fd
360 if fd
.family
!= syscall
.AF_INET
{
361 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
364 fd
:= l
.(*TCPListener
).fd
365 if fd
.family
!= syscall
.AF_INET6
{
366 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
369 fd
:= l
.(*UDPConn
).fd
370 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
372 fd
:= l
.(*UDPConn
).fd
373 if fd
.family
!= syscall
.AF_INET
{
374 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
377 fd
:= l
.(*UDPConn
).fd
378 if fd
.family
!= syscall
.AF_INET6
{
379 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
382 t
.Fatalf("Unexpected network: %q", net
)
386 func checkSecondListener(t
*testing
.T
, net
, laddr
string, err error
, l
interface{}) {
388 case "tcp", "tcp4", "tcp6":
390 l
.(*TCPListener
).Close()
391 t
.Fatalf("Second Listen(%q, %q) should fail", net
, laddr
)
393 case "udp", "udp4", "udp6":
396 t
.Fatalf("Second ListenPacket(%q, %q) should fail", net
, laddr
)
399 t
.Fatalf("Unexpected network: %q", net
)
403 func checkDualStackSecondListener(t
*testing
.T
, net
, laddr
string, xerr
, err error
, l
interface{}) {
405 case "tcp", "tcp4", "tcp6":
406 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
407 t
.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
409 l
.(*TCPListener
).Close()
410 case "udp", "udp4", "udp6":
411 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
412 t
.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
416 t
.Fatalf("Unexpected network: %q", net
)
420 func checkDualStackAddrFamily(t
*testing
.T
, net
, laddr
string, fd
*netFD
) {
421 switch a
:= fd
.laddr
.(type) {
423 // If a node under test supports both IPv6 capability
424 // and IPv6 IPv4-mapping capability, we can assume
425 // that the node listens on a wildcard address with an
427 if supportsIPv4map
&& fd
.laddr
.(*TCPAddr
).isWildcard() {
428 if fd
.family
!= syscall
.AF_INET6
{
429 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
432 if fd
.family
!= a
.family() {
433 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
437 // If a node under test supports both IPv6 capability
438 // and IPv6 IPv4-mapping capability, we can assume
439 // that the node listens on a wildcard address with an
441 if supportsIPv4map
&& fd
.laddr
.(*UDPAddr
).isWildcard() {
442 if fd
.family
!= syscall
.AF_INET6
{
443 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
446 if fd
.family
!= a
.family() {
447 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
451 t
.Fatalf("Unexpected protocol address type: %T", a
)
455 var prohibitionaryDialArgTests
= []struct {
459 {"tcp6", "127.0.0.1"},
460 {"tcp6", "[::ffff:127.0.0.1]"},
463 func TestProhibitionaryDialArgs(t
*testing
.T
) {
464 switch runtime
.GOOS
{
466 t
.Skipf("skipping test on %q", runtime
.GOOS
)
468 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
469 if !supportsIPv4map || testing
.Short() ||
!*testExternal
{
473 l
, port
:= usableListenPort(t
, "tcp", "[::]")
476 for _
, tt
:= range prohibitionaryDialArgTests
{
477 c
, err
:= Dial(tt
.net
, tt
.addr
+":"+port
)
480 t
.Fatalf("Dial(%q, %q) should fail", tt
.net
, tt
.addr
)
485 func TestWildWildcardListener(t
*testing
.T
) {
486 switch runtime
.GOOS
{
488 t
.Skipf("skipping test on %q", runtime
.GOOS
)
491 if testing
.Short() ||
!*testExternal
{
492 t
.Skip("skipping test to avoid external network")
496 if recover() != nil {
501 if ln
, err
:= Listen("tcp", ""); err
== nil {
504 if ln
, err
:= ListenPacket("udp", ""); err
== nil {
507 if ln
, err
:= ListenTCP("tcp", nil); err
== nil {
510 if ln
, err
:= ListenUDP("udp", nil); err
== nil {
513 if ln
, err
:= ListenIP("ip:icmp", nil); err
== nil {