Source file src/net/listen_test.go

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

View as plain text