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
) {
207 switch runtime
.GOOS
{
209 t
.Skipf("skipping test on %q", runtime
.GOOS
)
212 t
.Skip("ipv6 is not supported")
215 toudpnet
:= func(net
string) string {
227 for _
, tt
:= range dualStackListenerTests
{
228 if tt
.wildcard
&& (testing
.Short() ||
!*testExternal
) {
231 tt
.net1
= toudpnet(tt
.net1
)
232 tt
.net2
= toudpnet(tt
.net2
)
233 switch runtime
.GOOS
{
235 if tt
.wildcard
&& differentWildcardAddr(tt
.laddr1
, tt
.laddr2
) {
239 l1
, port
:= usableListenPacketPort(t
, tt
.net1
, tt
.laddr1
)
240 laddr
:= tt
.laddr1
+ ":" + port
241 checkFirstListener(t
, tt
.net1
, laddr
, l1
)
242 laddr
= tt
.laddr2
+ ":" + port
243 l2
, err
:= ListenPacket(tt
.net2
, laddr
)
244 checkDualStackSecondListener(t
, tt
.net2
, laddr
, tt
.xerr
, err
, l2
)
249 func usableListenPort(t
*testing
.T
, net
, laddr
string) (l Listener
, port
string) {
254 panic("usableListenPort net=" + net
)
255 case "tcp", "tcp4", "tcp6":
256 l
, err
= Listen(net
, laddr
+":0")
258 t
.Fatalf("Probe Listen(%q, %q) failed: %v", net
, laddr
, err
)
260 nladdr
= l
.(*TCPListener
).Addr().String()
262 _
, port
, err
= SplitHostPort(nladdr
)
264 t
.Fatalf("SplitHostPort failed: %v", err
)
269 func usableListenPacketPort(t
*testing
.T
, net
, laddr
string) (l PacketConn
, port
string) {
274 panic("usableListenPacketPort net=" + net
)
275 case "udp", "udp4", "udp6":
276 l
, err
= ListenPacket(net
, laddr
+":0")
278 t
.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net
, laddr
, err
)
280 nladdr
= l
.(*UDPConn
).LocalAddr().String()
282 _
, port
, err
= SplitHostPort(nladdr
)
284 t
.Fatalf("SplitHostPort failed: %v", err
)
289 func differentWildcardAddr(i
, j
string) bool {
290 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") {
293 if i
== "[::]" && j
== "[::]" {
299 func checkFirstListener(t
*testing
.T
, net
, laddr
string, l
interface{}) {
302 fd
:= l
.(*TCPListener
).fd
303 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
305 fd
:= l
.(*TCPListener
).fd
306 if fd
.family
!= syscall
.AF_INET
{
307 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
310 fd
:= l
.(*TCPListener
).fd
311 if fd
.family
!= syscall
.AF_INET6
{
312 t
.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
315 fd
:= l
.(*UDPConn
).fd
316 checkDualStackAddrFamily(t
, net
, laddr
, fd
)
318 fd
:= l
.(*UDPConn
).fd
319 if fd
.family
!= syscall
.AF_INET
{
320 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET
)
323 fd
:= l
.(*UDPConn
).fd
324 if fd
.family
!= syscall
.AF_INET6
{
325 t
.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
328 t
.Fatalf("Unexpected network: %q", net
)
332 func checkSecondListener(t
*testing
.T
, net
, laddr
string, err error
, l
interface{}) {
334 case "tcp", "tcp4", "tcp6":
336 l
.(*TCPListener
).Close()
337 t
.Fatalf("Second Listen(%q, %q) should fail", net
, laddr
)
339 case "udp", "udp4", "udp6":
342 t
.Fatalf("Second ListenPacket(%q, %q) should fail", net
, laddr
)
345 t
.Fatalf("Unexpected network: %q", net
)
349 func checkDualStackSecondListener(t
*testing
.T
, net
, laddr
string, xerr
, err error
, l
interface{}) {
351 case "tcp", "tcp4", "tcp6":
352 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
353 t
.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
356 l
.(*TCPListener
).Close()
358 case "udp", "udp4", "udp6":
359 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
360 t
.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net
, laddr
, err
, xerr
)
366 t
.Fatalf("Unexpected network: %q", net
)
370 func checkDualStackAddrFamily(t
*testing
.T
, net
, laddr
string, fd
*netFD
) {
371 switch a
:= fd
.laddr
.(type) {
373 // If a node under test supports both IPv6 capability
374 // and IPv6 IPv4-mapping capability, we can assume
375 // that the node listens on a wildcard address with an
377 if supportsIPv4map
&& fd
.laddr
.(*TCPAddr
).isWildcard() {
378 if fd
.family
!= syscall
.AF_INET6
{
379 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
382 if fd
.family
!= a
.family() {
383 t
.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
387 // If a node under test supports both IPv6 capability
388 // and IPv6 IPv4-mapping capability, we can assume
389 // that the node listens on a wildcard address with an
391 if supportsIPv4map
&& fd
.laddr
.(*UDPAddr
).isWildcard() {
392 if fd
.family
!= syscall
.AF_INET6
{
393 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, syscall
.AF_INET6
)
396 if fd
.family
!= a
.family() {
397 t
.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net
, laddr
, fd
.family
, a
.family())
401 t
.Fatalf("Unexpected protocol address type: %T", a
)
405 var prohibitionaryDialArgTests
= []struct {
409 {"tcp6", "127.0.0.1"},
410 {"tcp6", "[::ffff:127.0.0.1]"},
413 func TestProhibitionaryDialArgs(t
*testing
.T
) {
414 switch runtime
.GOOS
{
416 t
.Skipf("skipping test on %q", runtime
.GOOS
)
418 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
419 if !supportsIPv4map || testing
.Short() ||
!*testExternal
{
423 l
, port
:= usableListenPort(t
, "tcp", "[::]")
426 for _
, tt
:= range prohibitionaryDialArgTests
{
427 c
, err
:= Dial(tt
.net
, tt
.addr
+":"+port
)
430 t
.Fatalf("Dial(%q, %q) should fail", tt
.net
, tt
.addr
)
435 func TestWildWildcardListener(t
*testing
.T
) {
436 switch runtime
.GOOS
{
438 t
.Skipf("skipping test on %q", runtime
.GOOS
)
441 if testing
.Short() ||
!*testExternal
{
442 t
.Skip("skipping test to avoid external network")
446 if p
:= recover(); p
!= nil {
447 t
.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p
)
451 if ln
, err
:= Listen("tcp", ""); err
== nil {
454 if ln
, err
:= ListenPacket("udp", ""); err
== nil {
457 if ln
, err
:= ListenTCP("tcp", nil); err
== nil {
460 if ln
, err
:= ListenUDP("udp", nil); err
== nil {
463 if ln
, err
:= ListenIP("ip:icmp", nil); err
== nil {