Source file
src/net/listen_test.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "fmt"
11 "internal/testenv"
12 "os"
13 "runtime"
14 "syscall"
15 "testing"
16 "time"
17 )
18
19 func (ln *TCPListener) port() string {
20 _, port, err := SplitHostPort(ln.Addr().String())
21 if err != nil {
22 return ""
23 }
24 return port
25 }
26
27 func (c *UDPConn) port() string {
28 _, port, err := SplitHostPort(c.LocalAddr().String())
29 if err != nil {
30 return ""
31 }
32 return port
33 }
34
35 var tcpListenerTests = []struct {
36 network string
37 address string
38 }{
39 {"tcp", ""},
40 {"tcp", "0.0.0.0"},
41 {"tcp", "::ffff:0.0.0.0"},
42 {"tcp", "::"},
43
44 {"tcp", "127.0.0.1"},
45 {"tcp", "::ffff:127.0.0.1"},
46 {"tcp", "::1"},
47
48 {"tcp4", ""},
49 {"tcp4", "0.0.0.0"},
50 {"tcp4", "::ffff:0.0.0.0"},
51
52 {"tcp4", "127.0.0.1"},
53 {"tcp4", "::ffff:127.0.0.1"},
54
55 {"tcp6", ""},
56 {"tcp6", "::"},
57
58 {"tcp6", "::1"},
59 }
60
61
62
63
64 func TestTCPListener(t *testing.T) {
65 switch runtime.GOOS {
66 case "plan9":
67 t.Skipf("not supported on %s", runtime.GOOS)
68 }
69
70 for _, tt := range tcpListenerTests {
71 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
72 t.Logf("skipping %s test", tt.network+" "+tt.address)
73 continue
74 }
75
76 ln1, err := Listen(tt.network, JoinHostPort(tt.address, "0"))
77 if err != nil {
78 t.Fatal(err)
79 }
80 if err := checkFirstListener(tt.network, ln1); err != nil {
81 ln1.Close()
82 t.Fatal(err)
83 }
84 ln2, err := Listen(tt.network, JoinHostPort(tt.address, ln1.(*TCPListener).port()))
85 if err == nil {
86 ln2.Close()
87 }
88 if err := checkSecondListener(tt.network, tt.address, err); err != nil {
89 ln1.Close()
90 t.Fatal(err)
91 }
92 ln1.Close()
93 }
94 }
95
96 var udpListenerTests = []struct {
97 network string
98 address string
99 }{
100 {"udp", ""},
101 {"udp", "0.0.0.0"},
102 {"udp", "::ffff:0.0.0.0"},
103 {"udp", "::"},
104
105 {"udp", "127.0.0.1"},
106 {"udp", "::ffff:127.0.0.1"},
107 {"udp", "::1"},
108
109 {"udp4", ""},
110 {"udp4", "0.0.0.0"},
111 {"udp4", "::ffff:0.0.0.0"},
112
113 {"udp4", "127.0.0.1"},
114 {"udp4", "::ffff:127.0.0.1"},
115
116 {"udp6", ""},
117 {"udp6", "::"},
118
119 {"udp6", "::1"},
120 }
121
122
123
124
125 func TestUDPListener(t *testing.T) {
126 switch runtime.GOOS {
127 case "plan9":
128 t.Skipf("not supported on %s", runtime.GOOS)
129 }
130
131 for _, tt := range udpListenerTests {
132 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
133 t.Logf("skipping %s test", tt.network+" "+tt.address)
134 continue
135 }
136
137 c1, err := ListenPacket(tt.network, JoinHostPort(tt.address, "0"))
138 if err != nil {
139 t.Fatal(err)
140 }
141 if err := checkFirstListener(tt.network, c1); err != nil {
142 c1.Close()
143 t.Fatal(err)
144 }
145 c2, err := ListenPacket(tt.network, JoinHostPort(tt.address, c1.(*UDPConn).port()))
146 if err == nil {
147 c2.Close()
148 }
149 if err := checkSecondListener(tt.network, tt.address, err); err != nil {
150 c1.Close()
151 t.Fatal(err)
152 }
153 c1.Close()
154 }
155 }
156
157 var dualStackTCPListenerTests = []struct {
158 network1, address1 string
159 network2, address2 string
160 xerr error
161 }{
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 {"tcp", "", "tcp", "", syscall.EADDRINUSE},
197 {"tcp", "", "tcp", "0.0.0.0", syscall.EADDRINUSE},
198 {"tcp", "0.0.0.0", "tcp", "", syscall.EADDRINUSE},
199
200 {"tcp", "", "tcp", "::", syscall.EADDRINUSE},
201 {"tcp", "::", "tcp", "", syscall.EADDRINUSE},
202 {"tcp", "0.0.0.0", "tcp", "::", syscall.EADDRINUSE},
203 {"tcp", "::", "tcp", "0.0.0.0", syscall.EADDRINUSE},
204 {"tcp", "::ffff:0.0.0.0", "tcp", "::", syscall.EADDRINUSE},
205 {"tcp", "::", "tcp", "::ffff:0.0.0.0", syscall.EADDRINUSE},
206
207 {"tcp4", "", "tcp6", "", nil},
208 {"tcp6", "", "tcp4", "", nil},
209 {"tcp4", "0.0.0.0", "tcp6", "::", nil},
210 {"tcp6", "::", "tcp4", "0.0.0.0", nil},
211
212 {"tcp", "127.0.0.1", "tcp", "::1", nil},
213 {"tcp", "::1", "tcp", "127.0.0.1", nil},
214 {"tcp4", "127.0.0.1", "tcp6", "::1", nil},
215 {"tcp6", "::1", "tcp4", "127.0.0.1", nil},
216 }
217
218
219
220
221
222
223
224 func TestDualStackTCPListener(t *testing.T) {
225 switch runtime.GOOS {
226 case "plan9":
227 t.Skipf("not supported on %s", runtime.GOOS)
228 }
229 if !supportsIPv4() || !supportsIPv6() {
230 t.Skip("both IPv4 and IPv6 are required")
231 }
232
233 for _, tt := range dualStackTCPListenerTests {
234 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
235 t.Logf("skipping %s test", tt.network1+" "+tt.address1)
236 continue
237 }
238
239 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) {
240 tt.xerr = nil
241 }
242 var firstErr, secondErr error
243 for i := 0; i < 5; i++ {
244 lns, err := newDualStackListener()
245 if err != nil {
246 t.Fatal(err)
247 }
248 port := lns[0].port()
249 for _, ln := range lns {
250 ln.Close()
251 }
252 var ln1 Listener
253 ln1, firstErr = Listen(tt.network1, JoinHostPort(tt.address1, port))
254 if firstErr != nil {
255 continue
256 }
257 if err := checkFirstListener(tt.network1, ln1); err != nil {
258 ln1.Close()
259 t.Fatal(err)
260 }
261 ln2, err := Listen(tt.network2, JoinHostPort(tt.address2, ln1.(*TCPListener).port()))
262 if err == nil {
263 ln2.Close()
264 }
265 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
266 ln1.Close()
267 continue
268 }
269 ln1.Close()
270 break
271 }
272 if firstErr != nil {
273 t.Error(firstErr)
274 }
275 if secondErr != nil {
276 t.Error(secondErr)
277 }
278 }
279 }
280
281 var dualStackUDPListenerTests = []struct {
282 network1, address1 string
283 network2, address2 string
284 xerr error
285 }{
286 {"udp", "", "udp", "", syscall.EADDRINUSE},
287 {"udp", "", "udp", "0.0.0.0", syscall.EADDRINUSE},
288 {"udp", "0.0.0.0", "udp", "", syscall.EADDRINUSE},
289
290 {"udp", "", "udp", "::", syscall.EADDRINUSE},
291 {"udp", "::", "udp", "", syscall.EADDRINUSE},
292 {"udp", "0.0.0.0", "udp", "::", syscall.EADDRINUSE},
293 {"udp", "::", "udp", "0.0.0.0", syscall.EADDRINUSE},
294 {"udp", "::ffff:0.0.0.0", "udp", "::", syscall.EADDRINUSE},
295 {"udp", "::", "udp", "::ffff:0.0.0.0", syscall.EADDRINUSE},
296
297 {"udp4", "", "udp6", "", nil},
298 {"udp6", "", "udp4", "", nil},
299 {"udp4", "0.0.0.0", "udp6", "::", nil},
300 {"udp6", "::", "udp4", "0.0.0.0", nil},
301
302 {"udp", "127.0.0.1", "udp", "::1", nil},
303 {"udp", "::1", "udp", "127.0.0.1", nil},
304 {"udp4", "127.0.0.1", "udp6", "::1", nil},
305 {"udp6", "::1", "udp4", "127.0.0.1", nil},
306 }
307
308
309
310
311
312
313
314 func TestDualStackUDPListener(t *testing.T) {
315 switch runtime.GOOS {
316 case "plan9":
317 t.Skipf("not supported on %s", runtime.GOOS)
318 }
319 if !supportsIPv4() || !supportsIPv6() {
320 t.Skip("both IPv4 and IPv6 are required")
321 }
322
323 for _, tt := range dualStackUDPListenerTests {
324 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
325 t.Logf("skipping %s test", tt.network1+" "+tt.address1)
326 continue
327 }
328
329 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) {
330 tt.xerr = nil
331 }
332 var firstErr, secondErr error
333 for i := 0; i < 5; i++ {
334 cs, err := newDualStackPacketListener()
335 if err != nil {
336 t.Fatal(err)
337 }
338 port := cs[0].port()
339 for _, c := range cs {
340 c.Close()
341 }
342 var c1 PacketConn
343 c1, firstErr = ListenPacket(tt.network1, JoinHostPort(tt.address1, port))
344 if firstErr != nil {
345 continue
346 }
347 if err := checkFirstListener(tt.network1, c1); err != nil {
348 c1.Close()
349 t.Fatal(err)
350 }
351 c2, err := ListenPacket(tt.network2, JoinHostPort(tt.address2, c1.(*UDPConn).port()))
352 if err == nil {
353 c2.Close()
354 }
355 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
356 c1.Close()
357 continue
358 }
359 c1.Close()
360 break
361 }
362 if firstErr != nil {
363 t.Error(firstErr)
364 }
365 if secondErr != nil {
366 t.Error(secondErr)
367 }
368 }
369 }
370
371 func differentWildcardAddr(i, j string) bool {
372 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") {
373 return false
374 }
375 if i == "[::]" && j == "[::]" {
376 return false
377 }
378 return true
379 }
380
381 func checkFirstListener(network string, ln any) error {
382 switch network {
383 case "tcp":
384 fd := ln.(*TCPListener).fd
385 if err := checkDualStackAddrFamily(fd); err != nil {
386 return err
387 }
388 case "tcp4":
389 fd := ln.(*TCPListener).fd
390 if fd.family != syscall.AF_INET {
391 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET)
392 }
393 case "tcp6":
394 fd := ln.(*TCPListener).fd
395 if fd.family != syscall.AF_INET6 {
396 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6)
397 }
398 case "udp":
399 fd := ln.(*UDPConn).fd
400 if err := checkDualStackAddrFamily(fd); err != nil {
401 return err
402 }
403 case "udp4":
404 fd := ln.(*UDPConn).fd
405 if fd.family != syscall.AF_INET {
406 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET)
407 }
408 case "udp6":
409 fd := ln.(*UDPConn).fd
410 if fd.family != syscall.AF_INET6 {
411 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6)
412 }
413 default:
414 return UnknownNetworkError(network)
415 }
416 return nil
417 }
418
419 func checkSecondListener(network, address string, err error) error {
420 switch network {
421 case "tcp", "tcp4", "tcp6":
422 if err == nil {
423 return fmt.Errorf("%s should fail", network+" "+address)
424 }
425 case "udp", "udp4", "udp6":
426 if err == nil {
427 return fmt.Errorf("%s should fail", network+" "+address)
428 }
429 default:
430 return UnknownNetworkError(network)
431 }
432 return nil
433 }
434
435 func checkDualStackSecondListener(network, address string, err, xerr error) error {
436 switch network {
437 case "tcp", "tcp4", "tcp6":
438 if xerr == nil && err != nil || xerr != nil && err == nil {
439 return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr)
440 }
441 case "udp", "udp4", "udp6":
442 if xerr == nil && err != nil || xerr != nil && err == nil {
443 return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr)
444 }
445 default:
446 return UnknownNetworkError(network)
447 }
448 return nil
449 }
450
451 func checkDualStackAddrFamily(fd *netFD) error {
452 switch a := fd.laddr.(type) {
453 case *TCPAddr:
454
455
456
457
458 if supportsIPv4map() && fd.laddr.(*TCPAddr).isWildcard() {
459 if fd.family != syscall.AF_INET6 {
460 return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6)
461 }
462 } else {
463 if fd.family != a.family() {
464 return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family())
465 }
466 }
467 case *UDPAddr:
468
469
470
471
472 if supportsIPv4map() && fd.laddr.(*UDPAddr).isWildcard() {
473 if fd.family != syscall.AF_INET6 {
474 return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6)
475 }
476 } else {
477 if fd.family != a.family() {
478 return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family())
479 }
480 }
481 default:
482 return fmt.Errorf("unexpected protocol address type: %T", a)
483 }
484 return nil
485 }
486
487 func TestWildWildcardListener(t *testing.T) {
488 testenv.MustHaveExternalNetwork(t)
489
490 switch runtime.GOOS {
491 case "plan9":
492 t.Skipf("not supported on %s", runtime.GOOS)
493 }
494
495 defer func() {
496 if p := recover(); p != nil {
497 t.Fatalf("panicked: %v", p)
498 }
499 }()
500
501 if ln, err := Listen("tcp", ""); err == nil {
502 ln.Close()
503 }
504 if ln, err := ListenPacket("udp", ""); err == nil {
505 ln.Close()
506 }
507 if ln, err := ListenTCP("tcp", nil); err == nil {
508 ln.Close()
509 }
510 if ln, err := ListenUDP("udp", nil); err == nil {
511 ln.Close()
512 }
513 if ln, err := ListenIP("ip:icmp", nil); err == nil {
514 ln.Close()
515 }
516 }
517
518 var ipv4MulticastListenerTests = []struct {
519 net string
520 gaddr *UDPAddr
521 }{
522 {"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
523
524 {"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
525 }
526
527
528
529
530 func TestIPv4MulticastListener(t *testing.T) {
531 testenv.MustHaveExternalNetwork(t)
532
533 switch runtime.GOOS {
534 case "android", "plan9":
535 t.Skipf("not supported on %s", runtime.GOOS)
536 }
537 if !supportsIPv4() {
538 t.Skip("IPv4 is not supported")
539 }
540
541 closer := func(cs []*UDPConn) {
542 for _, c := range cs {
543 if c != nil {
544 c.Close()
545 }
546 }
547 }
548
549 for _, ifi := range []*Interface{loopbackInterface(), nil} {
550
551
552
553
554
555 if ifi == nil || !*testIPv4 {
556 continue
557 }
558 for _, tt := range ipv4MulticastListenerTests {
559 var err error
560 cs := make([]*UDPConn, 2)
561 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
562 t.Fatal(err)
563 }
564 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
565 closer(cs)
566 t.Fatal(err)
567 }
568 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
569 closer(cs)
570 t.Fatal(err)
571 }
572 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
573 closer(cs)
574 t.Fatal(err)
575 }
576 closer(cs)
577 }
578 }
579 }
580
581 var ipv6MulticastListenerTests = []struct {
582 net string
583 gaddr *UDPAddr
584 }{
585 {"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
586 {"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
587 {"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
588 {"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
589 {"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
590 {"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
591
592 {"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
593 {"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
594 {"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
595 {"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
596 {"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
597 {"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
598 }
599
600
601
602
603 func TestIPv6MulticastListener(t *testing.T) {
604 testenv.MustHaveExternalNetwork(t)
605
606 switch runtime.GOOS {
607 case "plan9":
608 t.Skipf("not supported on %s", runtime.GOOS)
609 }
610 if !supportsIPv6() {
611 t.Skip("IPv6 is not supported")
612 }
613 if os.Getuid() != 0 {
614 t.Skip("must be root")
615 }
616
617 closer := func(cs []*UDPConn) {
618 for _, c := range cs {
619 if c != nil {
620 c.Close()
621 }
622 }
623 }
624
625 for _, ifi := range []*Interface{loopbackInterface(), nil} {
626
627
628
629
630
631 if ifi == nil && !*testIPv6 {
632 continue
633 }
634 for _, tt := range ipv6MulticastListenerTests {
635 var err error
636 cs := make([]*UDPConn, 2)
637 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
638 t.Fatal(err)
639 }
640 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
641 closer(cs)
642 t.Fatal(err)
643 }
644 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
645 closer(cs)
646 t.Fatal(err)
647 }
648 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
649 closer(cs)
650 t.Fatal(err)
651 }
652 closer(cs)
653 }
654 }
655 }
656
657 func checkMulticastListener(c *UDPConn, ip IP) error {
658 if ok, err := multicastRIBContains(ip); err != nil {
659 return err
660 } else if !ok {
661 return fmt.Errorf("%s not found in multicast rib", ip.String())
662 }
663 la := c.LocalAddr()
664 if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
665 return fmt.Errorf("got %v; want a proper address with non-zero port number", la)
666 }
667 return nil
668 }
669
670 func multicastRIBContains(ip IP) (bool, error) {
671 switch runtime.GOOS {
672 case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "illumos", "windows":
673 return true, nil
674 case "linux":
675 if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
676 return true, nil
677 }
678 }
679 ift, err := Interfaces()
680 if err != nil {
681 return false, err
682 }
683 for _, ifi := range ift {
684 ifmat, err := ifi.MulticastAddrs()
685 if err != nil {
686 return false, err
687 }
688 for _, ifma := range ifmat {
689 if ifma.(*IPAddr).IP.Equal(ip) {
690 return true, nil
691 }
692 }
693 }
694 return false, nil
695 }
696
697
698 func TestClosingListener(t *testing.T) {
699 ln := newLocalListener(t, "tcp")
700 addr := ln.Addr()
701
702 go func() {
703 for {
704 c, err := ln.Accept()
705 if err != nil {
706 return
707 }
708 c.Close()
709 }
710 }()
711
712
713
714
715 time.Sleep(time.Millisecond)
716
717 ln.Close()
718
719 ln2, err := Listen("tcp", addr.String())
720 if err != nil {
721 t.Fatal(err)
722 }
723 ln2.Close()
724 }
725
726 func TestListenConfigControl(t *testing.T) {
727 switch runtime.GOOS {
728 case "plan9":
729 t.Skipf("not supported on %s", runtime.GOOS)
730 }
731
732 t.Run("StreamListen", func(t *testing.T) {
733 for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
734 if !testableNetwork(network) {
735 continue
736 }
737 ln := newLocalListener(t, network, &ListenConfig{Control: controlOnConnSetup})
738 ln.Close()
739 }
740 })
741 t.Run("PacketListen", func(t *testing.T) {
742 for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} {
743 if !testableNetwork(network) {
744 continue
745 }
746 c := newLocalPacketListener(t, network, &ListenConfig{Control: controlOnConnSetup})
747 c.Close()
748 }
749 })
750 }
751
View as plain text