github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv4/readwrite_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  	"bytes"
     9  	"net"
    10  	"runtime"
    11  	"strings"
    12  	"sync"
    13  	"testing"
    14  
    15  	"golang.org/x/net/internal/nettest"
    16  	"golang.org/x/net/ipv4"
    17  )
    18  
    19  func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
    20  	c, err := net.ListenPacket("udp4", "127.0.0.1:0")
    21  	if err != nil {
    22  		return nil, nil, err
    23  	}
    24  	dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
    25  	if err != nil {
    26  		c.Close()
    27  		return nil, nil, err
    28  	}
    29  	return c, dst, nil
    30  }
    31  
    32  func BenchmarkReadWriteNetUDP(b *testing.B) {
    33  	c, dst, err := benchmarkUDPListener()
    34  	if err != nil {
    35  		b.Fatal(err)
    36  	}
    37  	defer c.Close()
    38  
    39  	wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
    40  	b.ResetTimer()
    41  	for i := 0; i < b.N; i++ {
    42  		benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
    43  	}
    44  }
    45  
    46  func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
    47  	if _, err := c.WriteTo(wb, dst); err != nil {
    48  		b.Fatal(err)
    49  	}
    50  	if _, _, err := c.ReadFrom(rb); err != nil {
    51  		b.Fatal(err)
    52  	}
    53  }
    54  
    55  func BenchmarkReadWriteIPv4UDP(b *testing.B) {
    56  	c, dst, err := benchmarkUDPListener()
    57  	if err != nil {
    58  		b.Fatal(err)
    59  	}
    60  	defer c.Close()
    61  
    62  	p := ipv4.NewPacketConn(c)
    63  	defer p.Close()
    64  	cf := ipv4.FlagTTL | ipv4.FlagInterface
    65  	if err := p.SetControlMessage(cf, true); err != nil {
    66  		b.Fatal(err)
    67  	}
    68  	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
    69  
    70  	wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
    71  	b.ResetTimer()
    72  	for i := 0; i < b.N; i++ {
    73  		benchmarkReadWriteIPv4UDP(b, p, wb, rb, dst, ifi)
    74  	}
    75  }
    76  
    77  func benchmarkReadWriteIPv4UDP(b *testing.B, p *ipv4.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
    78  	cm := ipv4.ControlMessage{TTL: 1}
    79  	if ifi != nil {
    80  		cm.IfIndex = ifi.Index
    81  	}
    82  	if n, err := p.WriteTo(wb, &cm, dst); err != nil {
    83  		b.Fatal(err)
    84  	} else if n != len(wb) {
    85  		b.Fatalf("got %v; want %v", n, len(wb))
    86  	}
    87  	if _, _, _, err := p.ReadFrom(rb); err != nil {
    88  		b.Fatal(err)
    89  	}
    90  }
    91  
    92  func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
    93  	switch runtime.GOOS {
    94  	case "nacl", "plan9", "solaris", "windows":
    95  		t.Skipf("not supported on %s", runtime.GOOS)
    96  	}
    97  
    98  	c, err := net.ListenPacket("udp4", "127.0.0.1:0")
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  	defer c.Close()
   103  	p := ipv4.NewPacketConn(c)
   104  	defer p.Close()
   105  
   106  	dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  
   111  	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
   112  	cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface
   113  	wb := []byte("HELLO-R-U-THERE")
   114  
   115  	if err := p.SetControlMessage(cf, true); err != nil { // probe before test
   116  		if nettest.ProtocolNotSupported(err) {
   117  			t.Skipf("not supported on %s", runtime.GOOS)
   118  		}
   119  		t.Fatal(err)
   120  	}
   121  
   122  	var wg sync.WaitGroup
   123  	reader := func() {
   124  		defer wg.Done()
   125  		rb := make([]byte, 128)
   126  		if n, cm, _, err := p.ReadFrom(rb); err != nil {
   127  			t.Error(err)
   128  			return
   129  		} else if !bytes.Equal(rb[:n], wb) {
   130  			t.Errorf("got %v; want %v", rb[:n], wb)
   131  			return
   132  		} else {
   133  			s := cm.String()
   134  			if strings.Contains(s, ",") {
   135  				t.Errorf("should be space-separated values: %s", s)
   136  			}
   137  		}
   138  	}
   139  	writer := func(toggle bool) {
   140  		defer wg.Done()
   141  		cm := ipv4.ControlMessage{
   142  			Src: net.IPv4(127, 0, 0, 1),
   143  		}
   144  		if ifi != nil {
   145  			cm.IfIndex = ifi.Index
   146  		}
   147  		if err := p.SetControlMessage(cf, toggle); err != nil {
   148  			t.Error(err)
   149  			return
   150  		}
   151  		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
   152  			t.Error(err)
   153  			return
   154  		} else if n != len(wb) {
   155  			t.Errorf("short write: %v", n)
   156  			return
   157  		}
   158  	}
   159  
   160  	const N = 10
   161  	wg.Add(N)
   162  	for i := 0; i < N; i++ {
   163  		go reader()
   164  	}
   165  	wg.Add(2 * N)
   166  	for i := 0; i < 2*N; i++ {
   167  		go writer(i%2 != 0)
   168  	}
   169  	wg.Add(N)
   170  	for i := 0; i < N; i++ {
   171  		go reader()
   172  	}
   173  	wg.Wait()
   174  }