github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/ipv4/unicastsockopt_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  	"github.com/Andyfoo/golang/x/net/internal/iana"
    13  	"github.com/Andyfoo/golang/x/net/ipv4"
    14  	"github.com/Andyfoo/golang/x/net/nettest"
    15  )
    16  
    17  func TestConnUnicastSocketOptions(t *testing.T) {
    18  	switch runtime.GOOS {
    19  	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
    20  		t.Skipf("not supported on %s", runtime.GOOS)
    21  	}
    22  	if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
    23  		t.Skipf("not available on %s", runtime.GOOS)
    24  	}
    25  
    26  	ln, err := net.Listen("tcp4", "127.0.0.1:0")
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  	defer ln.Close()
    31  
    32  	errc := make(chan error, 1)
    33  	go func() {
    34  		c, err := ln.Accept()
    35  		if err != nil {
    36  			errc <- err
    37  			return
    38  		}
    39  		errc <- c.Close()
    40  	}()
    41  
    42  	c, err := net.Dial("tcp4", ln.Addr().String())
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	defer c.Close()
    47  
    48  	testUnicastSocketOptions(t, ipv4.NewConn(c))
    49  
    50  	if err := <-errc; err != nil {
    51  		t.Errorf("server: %v", err)
    52  	}
    53  }
    54  
    55  var packetConnUnicastSocketOptionTests = []struct {
    56  	net, proto, addr string
    57  }{
    58  	{"udp4", "", "127.0.0.1:0"},
    59  	{"ip4", ":icmp", "127.0.0.1"},
    60  }
    61  
    62  func TestPacketConnUnicastSocketOptions(t *testing.T) {
    63  	switch runtime.GOOS {
    64  	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
    65  		t.Skipf("not supported on %s", runtime.GOOS)
    66  	}
    67  	if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
    68  		t.Skipf("not available on %s", runtime.GOOS)
    69  	}
    70  
    71  	ok := nettest.SupportsRawSocket()
    72  	for _, tt := range packetConnUnicastSocketOptionTests {
    73  		if tt.net == "ip4" && !ok {
    74  			t.Logf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
    75  			continue
    76  		}
    77  		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
    78  		if err != nil {
    79  			t.Fatal(err)
    80  		}
    81  		defer c.Close()
    82  
    83  		testUnicastSocketOptions(t, ipv4.NewPacketConn(c))
    84  	}
    85  }
    86  
    87  func TestRawConnUnicastSocketOptions(t *testing.T) {
    88  	switch runtime.GOOS {
    89  	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
    90  		t.Skipf("not supported on %s", runtime.GOOS)
    91  	}
    92  	if !nettest.SupportsRawSocket() {
    93  		t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
    94  	}
    95  	if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
    96  		t.Skipf("not available on %s", runtime.GOOS)
    97  	}
    98  
    99  	c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	defer c.Close()
   104  
   105  	r, err := ipv4.NewRawConn(c)
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  
   110  	testUnicastSocketOptions(t, r)
   111  }
   112  
   113  type testIPv4UnicastConn interface {
   114  	TOS() (int, error)
   115  	SetTOS(int) error
   116  	TTL() (int, error)
   117  	SetTTL(int) error
   118  }
   119  
   120  func testUnicastSocketOptions(t *testing.T, c testIPv4UnicastConn) {
   121  	t.Helper()
   122  
   123  	tos := iana.DiffServCS0 | iana.NotECNTransport
   124  	switch runtime.GOOS {
   125  	case "windows":
   126  		// IP_TOS option is supported on Windows 8 and beyond.
   127  		t.Skipf("not supported on %s", runtime.GOOS)
   128  	}
   129  
   130  	if err := c.SetTOS(tos); err != nil {
   131  		t.Fatal(err)
   132  	}
   133  	if v, err := c.TOS(); err != nil {
   134  		t.Fatal(err)
   135  	} else if v != tos {
   136  		t.Fatalf("got %v; want %v", v, tos)
   137  	}
   138  	const ttl = 255
   139  	if err := c.SetTTL(ttl); err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	if v, err := c.TTL(); err != nil {
   143  		t.Fatal(err)
   144  	} else if v != ttl {
   145  		t.Fatalf("got %v; want %v", v, ttl)
   146  	}
   147  }