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

     1  // Copyright 2012 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 ipv4_test
     6  
     7  import (
     8  	"net"
     9  	"runtime"
    10  	"testing"
    11  
    12  	"golang.org/x/net/internal/nettest"
    13  	"golang.org/x/net/ipv4"
    14  )
    15  
    16  var packetConnMulticastSocketOptionTests = []struct {
    17  	net, proto, addr string
    18  	grp, src         net.Addr
    19  }{
    20  	{"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727
    21  	{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil},  // see RFC 4727
    22  
    23  	{"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
    24  	{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}},  // see RFC 5771
    25  }
    26  
    27  func TestPacketConnMulticastSocketOptions(t *testing.T) {
    28  	switch runtime.GOOS {
    29  	case "nacl", "plan9", "solaris":
    30  		t.Skipf("not supported on %s", runtime.GOOS)
    31  	}
    32  	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
    33  	if ifi == nil {
    34  		t.Skipf("not available on %s", runtime.GOOS)
    35  	}
    36  
    37  	m, ok := nettest.SupportsRawIPSocket()
    38  	for _, tt := range packetConnMulticastSocketOptionTests {
    39  		if tt.net == "ip4" && !ok {
    40  			t.Log(m)
    41  			continue
    42  		}
    43  		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
    44  		if err != nil {
    45  			t.Fatal(err)
    46  		}
    47  		defer c.Close()
    48  		p := ipv4.NewPacketConn(c)
    49  		defer p.Close()
    50  
    51  		if tt.src == nil {
    52  			testMulticastSocketOptions(t, p, ifi, tt.grp)
    53  		} else {
    54  			testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
    55  		}
    56  	}
    57  }
    58  
    59  var rawConnMulticastSocketOptionTests = []struct {
    60  	grp, src net.Addr
    61  }{
    62  	{&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
    63  
    64  	{&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
    65  }
    66  
    67  func TestRawConnMulticastSocketOptions(t *testing.T) {
    68  	switch runtime.GOOS {
    69  	case "nacl", "plan9", "solaris":
    70  		t.Skipf("not supported on %s", runtime.GOOS)
    71  	}
    72  	if m, ok := nettest.SupportsRawIPSocket(); !ok {
    73  		t.Skip(m)
    74  	}
    75  	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
    76  	if ifi == nil {
    77  		t.Skipf("not available on %s", runtime.GOOS)
    78  	}
    79  
    80  	for _, tt := range rawConnMulticastSocketOptionTests {
    81  		c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
    82  		if err != nil {
    83  			t.Fatal(err)
    84  		}
    85  		defer c.Close()
    86  		r, err := ipv4.NewRawConn(c)
    87  		if err != nil {
    88  			t.Fatal(err)
    89  		}
    90  		defer r.Close()
    91  
    92  		if tt.src == nil {
    93  			testMulticastSocketOptions(t, r, ifi, tt.grp)
    94  		} else {
    95  			testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src)
    96  		}
    97  	}
    98  }
    99  
   100  type testIPv4MulticastConn interface {
   101  	MulticastTTL() (int, error)
   102  	SetMulticastTTL(ttl int) error
   103  	MulticastLoopback() (bool, error)
   104  	SetMulticastLoopback(bool) error
   105  	JoinGroup(*net.Interface, net.Addr) error
   106  	LeaveGroup(*net.Interface, net.Addr) error
   107  	JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
   108  	LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
   109  	ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
   110  	IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
   111  }
   112  
   113  func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) {
   114  	const ttl = 255
   115  	if err := c.SetMulticastTTL(ttl); err != nil {
   116  		t.Error(err)
   117  		return
   118  	}
   119  	if v, err := c.MulticastTTL(); err != nil {
   120  		t.Error(err)
   121  		return
   122  	} else if v != ttl {
   123  		t.Errorf("got %v; want %v", v, ttl)
   124  		return
   125  	}
   126  
   127  	for _, toggle := range []bool{true, false} {
   128  		if err := c.SetMulticastLoopback(toggle); err != nil {
   129  			t.Error(err)
   130  			return
   131  		}
   132  		if v, err := c.MulticastLoopback(); err != nil {
   133  			t.Error(err)
   134  			return
   135  		} else if v != toggle {
   136  			t.Errorf("got %v; want %v", v, toggle)
   137  			return
   138  		}
   139  	}
   140  
   141  	if err := c.JoinGroup(ifi, grp); err != nil {
   142  		t.Error(err)
   143  		return
   144  	}
   145  	if err := c.LeaveGroup(ifi, grp); err != nil {
   146  		t.Error(err)
   147  		return
   148  	}
   149  }
   150  
   151  func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) {
   152  	// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
   153  	if err := c.JoinGroup(ifi, grp); err != nil {
   154  		t.Error(err)
   155  		return
   156  	}
   157  	if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
   158  		switch runtime.GOOS {
   159  		case "freebsd", "linux":
   160  		default: // platforms that don't support IGMPv2/3 fail here
   161  			t.Logf("not supported on %s", runtime.GOOS)
   162  			return
   163  		}
   164  		t.Error(err)
   165  		return
   166  	}
   167  	if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
   168  		t.Error(err)
   169  		return
   170  	}
   171  	if err := c.LeaveGroup(ifi, grp); err != nil {
   172  		t.Error(err)
   173  		return
   174  	}
   175  
   176  	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
   177  	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
   178  		t.Error(err)
   179  		return
   180  	}
   181  	if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
   182  		t.Error(err)
   183  		return
   184  	}
   185  
   186  	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
   187  	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
   188  		t.Error(err)
   189  		return
   190  	}
   191  	if err := c.LeaveGroup(ifi, grp); err != nil {
   192  		t.Error(err)
   193  		return
   194  	}
   195  }