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

View as plain text