github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv6/multicastsockopt_test.go (about)

     1  // Copyright 2013 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  package ipv6_test
     6  
     7  import (
     8  	"net"
     9  	"runtime"
    10  	"testing"
    11  
    12  	"golang.org/x/net/internal/nettest"
    13  	"golang.org/x/net/ipv6"
    14  )
    15  
    16  var packetConnMulticastSocketOptionTests = []struct {
    17  	net, proto, addr string
    18  	grp, src         net.Addr
    19  }{
    20  	{"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
    21  	{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::115")}, nil}, // see RFC 4727
    22  
    23  	{"udp6", "", "[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
    24  	{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff30::8000:2")}, &net.IPAddr{IP: net.IPv6loopback}},        // see RFC 5771
    25  }
    26  
    27  func TestPacketConnMulticastSocketOptions(t *testing.T) {
    28  	switch runtime.GOOS {
    29  	case "nacl", "plan9", "solaris", "windows":
    30  		t.Skipf("not supported on %s", runtime.GOOS)
    31  	}
    32  	if !supportsIPv6 {
    33  		t.Skip("ipv6 is not supported")
    34  	}
    35  	ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
    36  	if ifi == nil {
    37  		t.Skipf("not available on %s", runtime.GOOS)
    38  	}
    39  
    40  	m, ok := nettest.SupportsRawIPSocket()
    41  	for _, tt := range packetConnMulticastSocketOptionTests {
    42  		if tt.net == "ip6" && !ok {
    43  			t.Log(m)
    44  			continue
    45  		}
    46  		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
    47  		if err != nil {
    48  			t.Fatal(err)
    49  		}
    50  		defer c.Close()
    51  		p := ipv6.NewPacketConn(c)
    52  		defer p.Close()
    53  
    54  		if tt.src == nil {
    55  			testMulticastSocketOptions(t, p, ifi, tt.grp)
    56  		} else {
    57  			testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
    58  		}
    59  	}
    60  }
    61  
    62  type testIPv6MulticastConn interface {
    63  	MulticastHopLimit() (int, error)
    64  	SetMulticastHopLimit(ttl int) error
    65  	MulticastLoopback() (bool, error)
    66  	SetMulticastLoopback(bool) error
    67  	JoinGroup(*net.Interface, net.Addr) error
    68  	LeaveGroup(*net.Interface, net.Addr) error
    69  	JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
    70  	LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
    71  	ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
    72  	IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
    73  }
    74  
    75  func testMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp net.Addr) {
    76  	const hoplim = 255
    77  	if err := c.SetMulticastHopLimit(hoplim); err != nil {
    78  		t.Error(err)
    79  		return
    80  	}
    81  	if v, err := c.MulticastHopLimit(); err != nil {
    82  		t.Error(err)
    83  		return
    84  	} else if v != hoplim {
    85  		t.Errorf("got %v; want %v", v, hoplim)
    86  		return
    87  	}
    88  
    89  	for _, toggle := range []bool{true, false} {
    90  		if err := c.SetMulticastLoopback(toggle); err != nil {
    91  			t.Error(err)
    92  			return
    93  		}
    94  		if v, err := c.MulticastLoopback(); err != nil {
    95  			t.Error(err)
    96  			return
    97  		} else if v != toggle {
    98  			t.Errorf("got %v; want %v", v, toggle)
    99  			return
   100  		}
   101  	}
   102  
   103  	if err := c.JoinGroup(ifi, grp); err != nil {
   104  		t.Error(err)
   105  		return
   106  	}
   107  	if err := c.LeaveGroup(ifi, grp); err != nil {
   108  		t.Error(err)
   109  		return
   110  	}
   111  }
   112  
   113  func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp, src net.Addr) {
   114  	// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
   115  	if err := c.JoinGroup(ifi, grp); err != nil {
   116  		t.Error(err)
   117  		return
   118  	}
   119  	if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
   120  		switch runtime.GOOS {
   121  		case "freebsd", "linux":
   122  		default: // platforms that don't support MLDv2 fail here
   123  			t.Logf("not supported on %s", runtime.GOOS)
   124  			return
   125  		}
   126  		t.Error(err)
   127  		return
   128  	}
   129  	if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
   130  		t.Error(err)
   131  		return
   132  	}
   133  	if err := c.LeaveGroup(ifi, grp); err != nil {
   134  		t.Error(err)
   135  		return
   136  	}
   137  
   138  	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
   139  	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
   140  		t.Error(err)
   141  		return
   142  	}
   143  	if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
   144  		t.Error(err)
   145  		return
   146  	}
   147  
   148  	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
   149  	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
   150  		t.Error(err)
   151  		return
   152  	}
   153  	if err := c.LeaveGroup(ifi, grp); err != nil {
   154  		t.Error(err)
   155  		return
   156  	}
   157  }