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  	"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  // TestTCPListener tests both single and double listen to a test
    62  // listener with same address family, same listening address and
    63  // same port.
    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  // TestUDPListener tests both single and double listen to a test
   123  // listener with same address family, same listening address and
   124  // same port.
   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 // first listener
   159  	network2, address2 string // second listener
   160  	xerr               error  // expected error value, nil or other
   161  }{
   162  	// Test cases and expected results for the attempting 2nd listen on the same port
   163  	// 1st listen                2nd listen                 darwin  freebsd  linux  openbsd
   164  	// ------------------------------------------------------------------------------------
   165  	// "tcp"  ""                 "tcp"  ""                    -        -       -       -
   166  	// "tcp"  ""                 "tcp"  "0.0.0.0"             -        -       -       -
   167  	// "tcp"  "0.0.0.0"          "tcp"  ""                    -        -       -       -
   168  	// ------------------------------------------------------------------------------------
   169  	// "tcp"  ""                 "tcp"  "[::]"                -        -       -       ok
   170  	// "tcp"  "[::]"             "tcp"  ""                    -        -       -       ok
   171  	// "tcp"  "0.0.0.0"          "tcp"  "[::]"                -        -       -       ok
   172  	// "tcp"  "[::]"             "tcp"  "0.0.0.0"             -        -       -       ok
   173  	// "tcp"  "[::ffff:0.0.0.0]" "tcp"  "[::]"                -        -       -       ok
   174  	// "tcp"  "[::]"             "tcp"  "[::ffff:0.0.0.0]"    -        -       -       ok
   175  	// ------------------------------------------------------------------------------------
   176  	// "tcp4" ""                 "tcp6" ""                    ok       ok      ok      ok
   177  	// "tcp6" ""                 "tcp4" ""                    ok       ok      ok      ok
   178  	// "tcp4" "0.0.0.0"          "tcp6" "[::]"                ok       ok      ok      ok
   179  	// "tcp6" "[::]"             "tcp4" "0.0.0.0"             ok       ok      ok      ok
   180  	// ------------------------------------------------------------------------------------
   181  	// "tcp"  "127.0.0.1"        "tcp"  "[::1]"               ok       ok      ok      ok
   182  	// "tcp"  "[::1]"            "tcp"  "127.0.0.1"           ok       ok      ok      ok
   183  	// "tcp4" "127.0.0.1"        "tcp6" "[::1]"               ok       ok      ok      ok
   184  	// "tcp6" "[::1]"            "tcp4" "127.0.0.1"           ok       ok      ok      ok
   185  	//
   186  	// Platform default configurations:
   187  	// darwin, kernel version 11.3.0
   188  	//	net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
   189  	// freebsd, kernel version 8.2
   190  	//	net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
   191  	// linux, kernel version 3.0.0
   192  	//	net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
   193  	// openbsd, kernel version 5.0
   194  	//	net.inet6.ip6.v6only=1 (overriding is prohibited)
   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  // TestDualStackTCPListener tests both single and double listen
   219  // to a test listener with various address families, different
   220  // listening address and same port.
   221  //
   222  // On DragonFly BSD, we expect the kernel version of node under test
   223  // to be greater than or equal to 4.4.
   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 // first listener
   283  	network2, address2 string // second listener
   284  	xerr               error  // expected error value, nil or other
   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  // TestDualStackUDPListener tests both single and double listen
   309  // to a test listener with various address families, different
   310  // listening address and same port.
   311  //
   312  // On DragonFly BSD, we expect the kernel version of node under test
   313  // to be greater than or equal to 4.4.
   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  		// If a node under test supports both IPv6 capability
   455  		// and IPv6 IPv4-mapping capability, we can assume
   456  		// that the node listens on a wildcard address with an
   457  		// AF_INET6 socket.
   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  		// If a node under test supports both IPv6 capability
   469  		// and IPv6 IPv4-mapping capability, we can assume
   470  		// that the node listens on a wildcard address with an
   471  		// AF_INET6 socket.
   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 // see RFC 4727
   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  // TestIPv4MulticastListener tests both single and double listen to a
   528  // test listener with same address family, same group address and same
   529  // port.
   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  		// Note that multicast interface assignment by system
   551  		// is not recommended because it usually relies on
   552  		// routing stuff for finding out an appropriate
   553  		// nexthop containing both network and link layer
   554  		// adjacencies.
   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 // see RFC 4727
   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  // TestIPv6MulticastListener tests both single and double listen to a
   601  // test listener with same address family, same group address and same
   602  // port.
   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  		// Note that multicast interface assignment by system
   627  		// is not recommended because it usually relies on
   628  		// routing stuff for finding out an appropriate
   629  		// nexthop containing both network and link layer
   630  		// adjacencies.
   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 // not implemented yet
   674  	case "linux":
   675  		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
   676  			return true, nil // not implemented yet
   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  // Issue 21856.
   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  	// Let the goroutine start. We don't sleep long: if the
   713  	// goroutine doesn't start, the test will pass without really
   714  	// testing anything, which is OK.
   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