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.Logf("skipping test on %q", runtime.GOOS)
53 for _, tt := range listenerTests {
54 if tt.wildcard && (testing.Short() || !*testExternal) {
57 if tt.ipv6 && !supportsIPv6 {
60 l1, port := usableListenPort(t, tt.net, tt.laddr)
61 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
62 l2, err := Listen(tt.net, tt.laddr+":"+port)
63 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
68 // TestUDPListener tests both single and double listen to a test
69 // listener with same address family, same listening address and
71 func TestUDPListener(t *testing.T) {
73 case "plan9", "windows":
74 t.Logf("skipping test on %q", runtime.GOOS)
78 toudpnet := func(net string) string {
90 for _, tt := range listenerTests {
91 if tt.wildcard && (testing.Short() || !*testExternal) {
94 if tt.ipv6 && !supportsIPv6 {
97 tt.net = toudpnet(tt.net)
98 l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
99 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
100 l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
101 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
106 func TestSimpleTCPListener(t *testing.T) {
107 switch runtime.GOOS {
109 t.Logf("skipping test on %q", runtime.GOOS)
113 for _, tt := range listenerTests {
114 if tt.wildcard && (testing.Short() || !*testExternal) {
120 l1, port := usableListenPort(t, tt.net, tt.laddr)
121 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
122 l2, err := Listen(tt.net, tt.laddr+":"+port)
123 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
128 func TestSimpleUDPListener(t *testing.T) {
129 switch runtime.GOOS {
131 t.Logf("skipping test on %q", runtime.GOOS)
135 toudpnet := func(net string) string {
147 for _, tt := range listenerTests {
148 if tt.wildcard && (testing.Short() || !*testExternal) {
154 tt.net = toudpnet(tt.net)
155 l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
156 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
157 l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
158 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
163 var dualStackListenerTests = []struct {
164 net1 string // first listener
166 net2 string // second listener
168 wildcard bool // test with wildcard address
169 xerr error // expected error value, nil or other
171 // Test cases and expected results for the attemping 2nd listen on the same port
172 // 1st listen 2nd listen darwin freebsd linux openbsd
173 // ------------------------------------------------------------------------------------
174 // "tcp" "" "tcp" "" - - - -
175 // "tcp" "" "tcp" "0.0.0.0" - - - -
176 // "tcp" "0.0.0.0" "tcp" "" - - - -
177 // ------------------------------------------------------------------------------------
178 // "tcp" "" "tcp" "[::]" - - - ok
179 // "tcp" "[::]" "tcp" "" - - - ok
180 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
181 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
182 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
183 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
184 // ------------------------------------------------------------------------------------
185 // "tcp4" "" "tcp6" "" ok ok ok ok
186 // "tcp6" "" "tcp4" "" ok ok ok ok
187 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
188 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
189 // ------------------------------------------------------------------------------------
190 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
191 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
192 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
193 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
195 // Platform default configurations:
196 // darwin, kernel version 11.3.0
197 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
198 // freebsd, kernel version 8.2
199 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
200 // linux, kernel version 3.0.0
201 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
202 // openbsd, kernel version 5.0
203 // net.inet6.ip6.v6only=1 (overriding is prohibited)
205 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
206 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
207 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
209 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
210 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
211 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
212 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
213 {net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
214 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE},
216 {net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true},
217 {net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true},
218 {net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true},
219 {net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true},
221 {net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"},
222 {net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"},
223 {net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"},
224 {net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"},
227 // TestDualStackTCPListener tests both single and double listen
228 // to a test listener with various address families, differnet
229 // listening address and same port.
230 func TestDualStackTCPListener(t *testing.T) {
231 switch runtime.GOOS {
233 t.Logf("skipping test on %q", runtime.GOOS)
240 for _, tt := range dualStackListenerTests {
241 if tt.wildcard && (testing.Short() || !*testExternal) {
244 switch runtime.GOOS {
246 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
250 l1, port := usableListenPort(t, tt.net1, tt.laddr1)
251 laddr := tt.laddr1 + ":" + port
252 checkFirstListener(t, tt.net1, laddr, l1)
253 laddr = tt.laddr2 + ":" + port
254 l2, err := Listen(tt.net2, laddr)
255 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
260 // TestDualStackUDPListener tests both single and double listen
261 // to a test listener with various address families, differnet
262 // listening address and same port.
263 func TestDualStackUDPListener(t *testing.T) {
264 switch runtime.GOOS {
266 t.Logf("skipping test on %q", runtime.GOOS)
273 toudpnet := func(net string) string {
285 for _, tt := range dualStackListenerTests {
286 if tt.wildcard && (testing.Short() || !*testExternal) {
289 tt.net1 = toudpnet(tt.net1)
290 tt.net2 = toudpnet(tt.net2)
291 switch runtime.GOOS {
293 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
297 l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1)
298 laddr := tt.laddr1 + ":" + port
299 checkFirstListener(t, tt.net1, laddr, l1)
300 laddr = tt.laddr2 + ":" + port
301 l2, err := ListenPacket(tt.net2, laddr)
302 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
307 func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) {
312 panic("usableListenPort net=" + net)
313 case "tcp", "tcp4", "tcp6":
314 l, err = Listen(net, laddr+":0")
316 t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err)
318 nladdr = l.(*TCPListener).Addr().String()
320 _, port, err = SplitHostPort(nladdr)
322 t.Fatalf("SplitHostPort failed: %v", err)
327 func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) {
332 panic("usableListenPacketPort net=" + net)
333 case "udp", "udp4", "udp6":
334 l, err = ListenPacket(net, laddr+":0")
336 t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err)
338 nladdr = l.(*UDPConn).LocalAddr().String()
340 _, port, err = SplitHostPort(nladdr)
342 t.Fatalf("SplitHostPort failed: %v", err)
347 func differentWildcardAddr(i, j string) bool {
348 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") {
351 if i == "[::]" && j == "[::]" {
357 func checkFirstListener(t *testing.T, net, laddr string, l interface{}) {
360 fd := l.(*TCPListener).fd
361 checkDualStackAddrFamily(t, net, laddr, fd)
363 fd := l.(*TCPListener).fd
364 if fd.family != syscall.AF_INET {
365 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
368 fd := l.(*TCPListener).fd
369 if fd.family != syscall.AF_INET6 {
370 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
373 fd := l.(*UDPConn).fd
374 checkDualStackAddrFamily(t, net, laddr, fd)
376 fd := l.(*UDPConn).fd
377 if fd.family != syscall.AF_INET {
378 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
381 fd := l.(*UDPConn).fd
382 if fd.family != syscall.AF_INET6 {
383 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
386 t.Fatalf("Unexpected network: %q", net)
390 func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) {
392 case "tcp", "tcp4", "tcp6":
394 l.(*TCPListener).Close()
395 t.Fatalf("Second Listen(%q, %q) should fail", net, laddr)
397 case "udp", "udp4", "udp6":
400 t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
403 t.Fatalf("Unexpected network: %q", net)
407 func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) {
409 case "tcp", "tcp4", "tcp6":
410 if xerr == nil && err != nil || xerr != nil && err == nil {
411 t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
413 l.(*TCPListener).Close()
414 case "udp", "udp4", "udp6":
415 if xerr == nil && err != nil || xerr != nil && err == nil {
416 t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
420 t.Fatalf("Unexpected network: %q", net)
424 func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) {
425 switch a := fd.laddr.(type) {
427 // If a node under test supports both IPv6 capability
428 // and IPv6 IPv4-mapping capability, we can assume
429 // that the node listens on a wildcard address with an
431 if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
432 if fd.family != syscall.AF_INET6 {
433 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
436 if fd.family != a.family() {
437 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
441 // If a node under test supports both IPv6 capability
442 // and IPv6 IPv4-mapping capability, we can assume
443 // that the node listens on a wildcard address with an
445 if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
446 if fd.family != syscall.AF_INET6 {
447 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
450 if fd.family != a.family() {
451 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
455 t.Fatalf("Unexpected protocol address type: %T", a)
459 var prohibitionaryDialArgTests = []struct {
463 {"tcp6", "127.0.0.1"},
464 {"tcp6", "[::ffff:127.0.0.1]"},
467 func TestProhibitionaryDialArgs(t *testing.T) {
468 switch runtime.GOOS {
470 t.Logf("skipping test on %q", runtime.GOOS)
473 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
474 if !supportsIPv4map || testing.Short() || !*testExternal {
478 l, port := usableListenPort(t, "tcp", "[::]")
481 for _, tt := range prohibitionaryDialArgTests {
482 c, err := Dial(tt.net, tt.addr+":"+port)
485 t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)
490 func TestWildWildcardListener(t *testing.T) {
491 switch runtime.GOOS {
493 t.Logf("skipping test on %q", runtime.GOOS)
497 if testing.Short() || !*testExternal {
498 t.Logf("skipping test to avoid external network")
503 if recover() != nil {
508 if ln, err := Listen("tcp", ""); err == nil {
511 if ln, err := ListenPacket("udp", ""); err == nil {
514 if ln, err := ListenTCP("tcp", nil); err == nil {
517 if ln, err := ListenUDP("udp", nil); err == nil {
520 if ln, err := ListenIP("ip:icmp", nil); err == nil {