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.
13 var listenerTests = []struct {
16 ipv6 bool // test with underlying AF_INET6 socket
17 wildcard bool // test with wildcard address
19 {net: "tcp", laddr: "", wildcard: true},
20 {net: "tcp", laddr: "0.0.0.0", wildcard: true},
21 {net: "tcp", laddr: "[::ffff:0.0.0.0]", wildcard: true},
22 {net: "tcp", laddr: "[::]", ipv6: true, wildcard: true},
24 {net: "tcp", laddr: "127.0.0.1"},
25 {net: "tcp", laddr: "[::ffff:127.0.0.1]"},
26 {net: "tcp", laddr: "[::1]", ipv6: true},
28 {net: "tcp4", laddr: "", wildcard: true},
29 {net: "tcp4", laddr: "0.0.0.0", wildcard: true},
30 {net: "tcp4", laddr: "[::ffff:0.0.0.0]", wildcard: true},
32 {net: "tcp4", laddr: "127.0.0.1"},
33 {net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
35 {net: "tcp6", laddr: "", ipv6: true, wildcard: true},
36 {net: "tcp6", laddr: "[::]", ipv6: true, wildcard: true},
38 {net: "tcp6", laddr: "[::1]", ipv6: true},
41 // TestTCPListener tests both single and double listen to a test
42 // listener with same address family, same listening address and
44 func TestTCPListener(t *testing.T) {
46 case "plan9", "windows":
47 t.Logf("skipping test on %q", runtime.GOOS)
51 for _, tt := range listenerTests {
52 if tt.wildcard && (testing.Short() || !*testExternal) {
55 if tt.ipv6 && !supportsIPv6 {
58 l1, port := usableListenPort(t, tt.net, tt.laddr)
59 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
60 l2, err := Listen(tt.net, tt.laddr+":"+port)
61 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
62 fd := l1.(*TCPListener).fd
65 testIPv4UnicastSocketOptions(t, fd)
66 case syscall.AF_INET6:
67 testIPv6UnicastSocketOptions(t, fd)
73 // TestUDPListener tests both single and double listen to a test
74 // listener with same address family, same listening address and
76 func TestUDPListener(t *testing.T) {
78 case "plan9", "windows":
79 t.Logf("skipping test on %q", runtime.GOOS)
83 toudpnet := func(net string) string {
95 for _, tt := range listenerTests {
96 if tt.wildcard && (testing.Short() || !*testExternal) {
99 if tt.ipv6 && !supportsIPv6 {
102 tt.net = toudpnet(tt.net)
103 l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
104 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
105 l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
106 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
107 fd := l1.(*UDPConn).fd
109 case syscall.AF_INET:
110 testIPv4UnicastSocketOptions(t, fd)
111 case syscall.AF_INET6:
112 testIPv6UnicastSocketOptions(t, fd)
118 func TestSimpleTCPListener(t *testing.T) {
119 switch runtime.GOOS {
121 t.Logf("skipping test on %q", runtime.GOOS)
125 for _, tt := range listenerTests {
126 if tt.wildcard && (testing.Short() || !*testExternal) {
132 l1, port := usableListenPort(t, tt.net, tt.laddr)
133 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
134 l2, err := Listen(tt.net, tt.laddr+":"+port)
135 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
140 func TestSimpleUDPListener(t *testing.T) {
141 switch runtime.GOOS {
143 t.Logf("skipping test on %q", runtime.GOOS)
147 toudpnet := func(net string) string {
159 for _, tt := range listenerTests {
160 if tt.wildcard && (testing.Short() || !*testExternal) {
166 tt.net = toudpnet(tt.net)
167 l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
168 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
169 l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
170 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
175 var dualStackListenerTests = []struct {
176 net1 string // first listener
178 net2 string // second listener
180 wildcard bool // test with wildcard address
181 xerr error // expected error value, nil or other
183 // Test cases and expected results for the attemping 2nd listen on the same port
184 // 1st listen 2nd listen darwin freebsd linux openbsd
185 // ------------------------------------------------------------------------------------
186 // "tcp" "" "tcp" "" - - - -
187 // "tcp" "" "tcp" "0.0.0.0" - - - -
188 // "tcp" "0.0.0.0" "tcp" "" - - - -
189 // ------------------------------------------------------------------------------------
190 // "tcp" "" "tcp" "[::]" - - - ok
191 // "tcp" "[::]" "tcp" "" - - - ok
192 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
193 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
194 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
195 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
196 // ------------------------------------------------------------------------------------
197 // "tcp4" "" "tcp6" "" ok ok ok ok
198 // "tcp6" "" "tcp4" "" ok ok ok ok
199 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
200 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
201 // ------------------------------------------------------------------------------------
202 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
203 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
204 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
205 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
207 // Platform default configurations:
208 // darwin, kernel version 11.3.0
209 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
210 // freebsd, kernel version 8.2
211 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
212 // linux, kernel version 3.0.0
213 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
214 // openbsd, kernel version 5.0
215 // net.inet6.ip6.v6only=1 (overriding is prohibited)
217 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
218 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
219 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
221 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
222 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
223 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
224 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
225 {net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
226 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE},
228 {net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true},
229 {net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true},
230 {net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true},
231 {net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true},
233 {net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"},
234 {net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"},
235 {net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"},
236 {net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"},
239 // TestDualStackTCPListener tests both single and double listen
240 // to a test listener with various address families, differnet
241 // listening address and same port.
242 func TestDualStackTCPListener(t *testing.T) {
243 switch runtime.GOOS {
245 t.Logf("skipping test on %q", runtime.GOOS)
252 for _, tt := range dualStackListenerTests {
253 if tt.wildcard && (testing.Short() || !*testExternal) {
256 switch runtime.GOOS {
258 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
262 l1, port := usableListenPort(t, tt.net1, tt.laddr1)
263 laddr := tt.laddr1 + ":" + port
264 checkFirstListener(t, tt.net1, laddr, l1)
265 laddr = tt.laddr2 + ":" + port
266 l2, err := Listen(tt.net2, laddr)
267 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
272 // TestDualStackUDPListener tests both single and double listen
273 // to a test listener with various address families, differnet
274 // listening address and same port.
275 func TestDualStackUDPListener(t *testing.T) {
276 switch runtime.GOOS {
278 t.Logf("skipping test on %q", runtime.GOOS)
285 toudpnet := func(net string) string {
297 for _, tt := range dualStackListenerTests {
298 if tt.wildcard && (testing.Short() || !*testExternal) {
301 tt.net1 = toudpnet(tt.net1)
302 tt.net2 = toudpnet(tt.net2)
303 switch runtime.GOOS {
305 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
309 l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1)
310 laddr := tt.laddr1 + ":" + port
311 checkFirstListener(t, tt.net1, laddr, l1)
312 laddr = tt.laddr2 + ":" + port
313 l2, err := ListenPacket(tt.net2, laddr)
314 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
319 func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) {
324 panic("usableListenPort net=" + net)
325 case "tcp", "tcp4", "tcp6":
326 l, err = Listen(net, laddr+":0")
328 t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err)
330 nladdr = l.(*TCPListener).Addr().String()
332 _, port, err = SplitHostPort(nladdr)
334 t.Fatalf("SplitHostPort failed: %v", err)
339 func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) {
344 panic("usableListenPacketPort net=" + net)
345 case "udp", "udp4", "udp6":
346 l, err = ListenPacket(net, laddr+":0")
348 t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err)
350 nladdr = l.(*UDPConn).LocalAddr().String()
352 _, port, err = SplitHostPort(nladdr)
354 t.Fatalf("SplitHostPort failed: %v", err)
359 func differentWildcardAddr(i, j string) bool {
360 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") {
363 if i == "[::]" && j == "[::]" {
369 func checkFirstListener(t *testing.T, net, laddr string, l interface{}) {
372 fd := l.(*TCPListener).fd
373 checkDualStackAddrFamily(t, net, laddr, fd)
375 fd := l.(*TCPListener).fd
376 if fd.family != syscall.AF_INET {
377 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
380 fd := l.(*TCPListener).fd
381 if fd.family != syscall.AF_INET6 {
382 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
385 fd := l.(*UDPConn).fd
386 checkDualStackAddrFamily(t, net, laddr, fd)
388 fd := l.(*UDPConn).fd
389 if fd.family != syscall.AF_INET {
390 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
393 fd := l.(*UDPConn).fd
394 if fd.family != syscall.AF_INET6 {
395 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
398 t.Fatalf("Unexpected network: %q", net)
402 func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) {
404 case "tcp", "tcp4", "tcp6":
406 l.(*TCPListener).Close()
407 t.Fatalf("Second Listen(%q, %q) should fail", net, laddr)
409 case "udp", "udp4", "udp6":
412 t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
415 t.Fatalf("Unexpected network: %q", net)
419 func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) {
421 case "tcp", "tcp4", "tcp6":
422 if xerr == nil && err != nil || xerr != nil && err == nil {
423 t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
425 l.(*TCPListener).Close()
426 case "udp", "udp4", "udp6":
427 if xerr == nil && err != nil || xerr != nil && err == nil {
428 t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
432 t.Fatalf("Unexpected network: %q", net)
436 func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) {
437 switch a := fd.laddr.(type) {
439 // If a node under test supports both IPv6 capability
440 // and IPv6 IPv4-mapping capability, we can assume
441 // that the node listens on a wildcard address with an
443 if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
444 if fd.family != syscall.AF_INET6 {
445 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
448 if fd.family != a.family() {
449 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
453 // If a node under test supports both IPv6 capability
454 // and IPv6 IPv4-mapping capability, we can assume
455 // that the node listens on a wildcard address with an
457 if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
458 if fd.family != syscall.AF_INET6 {
459 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
462 if fd.family != a.family() {
463 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
467 t.Fatalf("Unexpected protocol address type: %T", a)
471 func testIPv4UnicastSocketOptions(t *testing.T, fd *netFD) {
472 _, err := ipv4TOS(fd)
474 t.Fatalf("ipv4TOS failed: %v", err)
476 err = setIPv4TOS(fd, 1)
478 t.Fatalf("setIPv4TOS failed: %v", err)
482 t.Fatalf("ipv4TTL failed: %v", err)
484 err = setIPv4TTL(fd, 1)
486 t.Fatalf("setIPv4TTL failed: %v", err)
490 func testIPv6UnicastSocketOptions(t *testing.T, fd *netFD) {
491 _, err := ipv6TrafficClass(fd)
493 t.Fatalf("ipv6TrafficClass failed: %v", err)
495 err = setIPv6TrafficClass(fd, 1)
497 t.Fatalf("setIPv6TrafficClass failed: %v", err)
499 _, err = ipv6HopLimit(fd)
501 t.Fatalf("ipv6HopLimit failed: %v", err)
503 err = setIPv6HopLimit(fd, 1)
505 t.Fatalf("setIPv6HopLimit failed: %v", err)
509 var prohibitionaryDialArgTests = []struct {
513 {"tcp6", "127.0.0.1"},
514 {"tcp6", "[::ffff:127.0.0.1]"},
517 func TestProhibitionaryDialArgs(t *testing.T) {
518 switch runtime.GOOS {
520 t.Logf("skipping test on %q", runtime.GOOS)
523 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
524 if !supportsIPv4map || testing.Short() || !*testExternal {
528 l, port := usableListenPort(t, "tcp", "[::]")
531 for _, tt := range prohibitionaryDialArgTests {
532 c, err := Dial(tt.net, tt.addr+":"+port)
535 t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)