Black Lives Matter. Support the Equal Justice Initiative.

Source file src/net/listen_test.go

Documentation: net

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

View as plain text