...
Run Format

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  // +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 "nacl", "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 "nacl", "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 interface{}) 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", "nacl", "plan9":
   536  		t.Skipf("not supported on %s", runtime.GOOS)
   537  	case "solaris":
   538  		t.Skipf("not supported on solaris, see golang.org/issue/7399")
   539  	}
   540  	if !supportsIPv4() {
   541  		t.Skip("IPv4 is not supported")
   542  	}
   543  
   544  	closer := func(cs []*UDPConn) {
   545  		for _, c := range cs {
   546  			if c != nil {
   547  				c.Close()
   548  			}
   549  		}
   550  	}
   551  
   552  	for _, ifi := range []*Interface{loopbackInterface(), nil} {
   553  		// Note that multicast interface assignment by system
   554  		// is not recommended because it usually relies on
   555  		// routing stuff for finding out an appropriate
   556  		// nexthop containing both network and link layer
   557  		// adjacencies.
   558  		if ifi == nil || !*testIPv4 {
   559  			continue
   560  		}
   561  		for _, tt := range ipv4MulticastListenerTests {
   562  			var err error
   563  			cs := make([]*UDPConn, 2)
   564  			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
   565  				t.Fatal(err)
   566  			}
   567  			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
   568  				closer(cs)
   569  				t.Fatal(err)
   570  			}
   571  			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
   572  				closer(cs)
   573  				t.Fatal(err)
   574  			}
   575  			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
   576  				closer(cs)
   577  				t.Fatal(err)
   578  			}
   579  			closer(cs)
   580  		}
   581  	}
   582  }
   583  
   584  var ipv6MulticastListenerTests = []struct {
   585  	net   string
   586  	gaddr *UDPAddr // see RFC 4727
   587  }{
   588  	{"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
   589  	{"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
   590  	{"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
   591  	{"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
   592  	{"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
   593  	{"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
   594  
   595  	{"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
   596  	{"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
   597  	{"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
   598  	{"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
   599  	{"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
   600  	{"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
   601  }
   602  
   603  // TestIPv6MulticastListener tests both single and double listen to a
   604  // test listener with same address family, same group address and same
   605  // port.
   606  func TestIPv6MulticastListener(t *testing.T) {
   607  	testenv.MustHaveExternalNetwork(t)
   608  
   609  	switch runtime.GOOS {
   610  	case "plan9":
   611  		t.Skipf("not supported on %s", runtime.GOOS)
   612  	case "solaris":
   613  		t.Skipf("not supported on solaris, see issue 7399")
   614  	}
   615  	if !supportsIPv6() {
   616  		t.Skip("IPv6 is not supported")
   617  	}
   618  	if os.Getuid() != 0 {
   619  		t.Skip("must be root")
   620  	}
   621  
   622  	closer := func(cs []*UDPConn) {
   623  		for _, c := range cs {
   624  			if c != nil {
   625  				c.Close()
   626  			}
   627  		}
   628  	}
   629  
   630  	for _, ifi := range []*Interface{loopbackInterface(), nil} {
   631  		// Note that multicast interface assignment by system
   632  		// is not recommended because it usually relies on
   633  		// routing stuff for finding out an appropriate
   634  		// nexthop containing both network and link layer
   635  		// adjacencies.
   636  		if ifi == nil && !*testIPv6 {
   637  			continue
   638  		}
   639  		for _, tt := range ipv6MulticastListenerTests {
   640  			var err error
   641  			cs := make([]*UDPConn, 2)
   642  			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
   643  				t.Fatal(err)
   644  			}
   645  			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
   646  				closer(cs)
   647  				t.Fatal(err)
   648  			}
   649  			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
   650  				closer(cs)
   651  				t.Fatal(err)
   652  			}
   653  			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
   654  				closer(cs)
   655  				t.Fatal(err)
   656  			}
   657  			closer(cs)
   658  		}
   659  	}
   660  }
   661  
   662  func checkMulticastListener(c *UDPConn, ip IP) error {
   663  	if ok, err := multicastRIBContains(ip); err != nil {
   664  		return err
   665  	} else if !ok {
   666  		return fmt.Errorf("%s not found in multicast rib", ip.String())
   667  	}
   668  	la := c.LocalAddr()
   669  	if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
   670  		return fmt.Errorf("got %v; want a proper address with non-zero port number", la)
   671  	}
   672  	return nil
   673  }
   674  
   675  func multicastRIBContains(ip IP) (bool, error) {
   676  	switch runtime.GOOS {
   677  	case "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "windows":
   678  		return true, nil // not implemented yet
   679  	case "linux":
   680  		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
   681  			return true, nil // not implemented yet
   682  		}
   683  	}
   684  	ift, err := Interfaces()
   685  	if err != nil {
   686  		return false, err
   687  	}
   688  	for _, ifi := range ift {
   689  		ifmat, err := ifi.MulticastAddrs()
   690  		if err != nil {
   691  			return false, err
   692  		}
   693  		for _, ifma := range ifmat {
   694  			if ifma.(*IPAddr).IP.Equal(ip) {
   695  				return true, nil
   696  			}
   697  		}
   698  	}
   699  	return false, nil
   700  }
   701  
   702  // Issue 21856.
   703  func TestClosingListener(t *testing.T) {
   704  	ln, err := newLocalListener("tcp")
   705  	if err != nil {
   706  		t.Fatal(err)
   707  	}
   708  	addr := ln.Addr()
   709  
   710  	go func() {
   711  		for {
   712  			c, err := ln.Accept()
   713  			if err != nil {
   714  				return
   715  			}
   716  			c.Close()
   717  		}
   718  	}()
   719  
   720  	// Let the goroutine start. We don't sleep long: if the
   721  	// goroutine doesn't start, the test will pass without really
   722  	// testing anything, which is OK.
   723  	time.Sleep(time.Millisecond)
   724  
   725  	ln.Close()
   726  
   727  	ln2, err := Listen("tcp", addr.String())
   728  	if err != nil {
   729  		t.Fatal(err)
   730  	}
   731  	ln2.Close()
   732  }
   733  
   734  func TestListenConfigControl(t *testing.T) {
   735  	switch runtime.GOOS {
   736  	case "nacl", "plan9":
   737  		t.Skipf("not supported on %s", runtime.GOOS)
   738  	}
   739  
   740  	t.Run("StreamListen", func(t *testing.T) {
   741  		for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
   742  			if !testableNetwork(network) {
   743  				continue
   744  			}
   745  			ln, err := newLocalListener(network)
   746  			if err != nil {
   747  				t.Error(err)
   748  				continue
   749  			}
   750  			address := ln.Addr().String()
   751  			ln.Close()
   752  			lc := ListenConfig{Control: controlOnConnSetup}
   753  			ln, err = lc.Listen(context.Background(), network, address)
   754  			if err != nil {
   755  				t.Error(err)
   756  				continue
   757  			}
   758  			ln.Close()
   759  		}
   760  	})
   761  	t.Run("PacketListen", func(t *testing.T) {
   762  		for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} {
   763  			if !testableNetwork(network) {
   764  				continue
   765  			}
   766  			c, err := newLocalPacketListener(network)
   767  			if err != nil {
   768  				t.Error(err)
   769  				continue
   770  			}
   771  			address := c.LocalAddr().String()
   772  			c.Close()
   773  			if network == "unixgram" {
   774  				os.Remove(address)
   775  			}
   776  			lc := ListenConfig{Control: controlOnConnSetup}
   777  			c, err = lc.ListenPacket(context.Background(), network, address)
   778  			if err != nil {
   779  				t.Error(err)
   780  				continue
   781  			}
   782  			c.Close()
   783  		}
   784  	})
   785  }
   786  

View as plain text