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