OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv6 / readwrite_go1_9_test.go
1 // Copyright 2017 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 // +build go1.9
6
7 package ipv6_test
8
9 import (
10         "bytes"
11         "fmt"
12         "net"
13         "runtime"
14         "strings"
15         "sync"
16         "testing"
17
18         "golang.org/x/net/internal/iana"
19         "golang.org/x/net/internal/nettest"
20         "golang.org/x/net/ipv6"
21 )
22
23 func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
24         switch runtime.GOOS {
25         case "nacl", "plan9", "windows":
26                 b.Skipf("not supported on %s", runtime.GOOS)
27         }
28
29         payload := []byte("HELLO-R-U-THERE")
30         iph := []byte{
31                 0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
32                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
33                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
34                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
35                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
36         }
37         greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
38         datagram := append(greh, append(iph, payload...)...)
39         bb := make([]byte, 128)
40         cm := ipv6.ControlMessage{
41                 TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
42                 HopLimit:     1,
43                 Src:          net.IPv6loopback,
44         }
45         if ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback); ifi != nil {
46                 cm.IfIndex = ifi.Index
47         }
48
49         b.Run("UDP", func(b *testing.B) {
50                 c, err := nettest.NewLocalPacketListener("udp6")
51                 if err != nil {
52                         b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
53                 }
54                 defer c.Close()
55                 p := ipv6.NewPacketConn(c)
56                 dst := c.LocalAddr()
57                 cf := ipv6.FlagHopLimit | ipv6.FlagInterface
58                 if err := p.SetControlMessage(cf, true); err != nil {
59                         b.Fatal(err)
60                 }
61                 wms := []ipv6.Message{
62                         {
63                                 Buffers: [][]byte{payload},
64                                 Addr:    dst,
65                                 OOB:     cm.Marshal(),
66                         },
67                 }
68                 rms := []ipv6.Message{
69                         {
70                                 Buffers: [][]byte{bb},
71                                 OOB:     ipv6.NewControlMessage(cf),
72                         },
73                 }
74                 b.Run("Net", func(b *testing.B) {
75                         for i := 0; i < b.N; i++ {
76                                 if _, err := c.WriteTo(payload, dst); err != nil {
77                                         b.Fatal(err)
78                                 }
79                                 if _, _, err := c.ReadFrom(bb); err != nil {
80                                         b.Fatal(err)
81                                 }
82                         }
83                 })
84                 b.Run("ToFrom", func(b *testing.B) {
85                         for i := 0; i < b.N; i++ {
86                                 if _, err := p.WriteTo(payload, &cm, dst); err != nil {
87                                         b.Fatal(err)
88                                 }
89                                 if _, _, _, err := p.ReadFrom(bb); err != nil {
90                                         b.Fatal(err)
91                                 }
92                         }
93                 })
94                 b.Run("Batch", func(b *testing.B) {
95                         for i := 0; i < b.N; i++ {
96                                 if _, err := p.WriteBatch(wms, 0); err != nil {
97                                         b.Fatal(err)
98                                 }
99                                 if _, err := p.ReadBatch(rms, 0); err != nil {
100                                         b.Fatal(err)
101                                 }
102                         }
103                 })
104         })
105         b.Run("IP", func(b *testing.B) {
106                 switch runtime.GOOS {
107                 case "netbsd":
108                         b.Skip("need to configure gre on netbsd")
109                 case "openbsd":
110                         b.Skip("net.inet.gre.allow=0 by default on openbsd")
111                 }
112
113                 c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolGRE), "::1")
114                 if err != nil {
115                         b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
116                 }
117                 defer c.Close()
118                 p := ipv6.NewPacketConn(c)
119                 dst := c.LocalAddr()
120                 cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
121                 if err := p.SetControlMessage(cf, true); err != nil {
122                         b.Fatal(err)
123                 }
124                 wms := []ipv6.Message{
125                         {
126                                 Buffers: [][]byte{datagram},
127                                 Addr:    dst,
128                                 OOB:     cm.Marshal(),
129                         },
130                 }
131                 rms := []ipv6.Message{
132                         {
133                                 Buffers: [][]byte{bb},
134                                 OOB:     ipv6.NewControlMessage(cf),
135                         },
136                 }
137                 b.Run("Net", func(b *testing.B) {
138                         for i := 0; i < b.N; i++ {
139                                 if _, err := c.WriteTo(datagram, dst); err != nil {
140                                         b.Fatal(err)
141                                 }
142                                 if _, _, err := c.ReadFrom(bb); err != nil {
143                                         b.Fatal(err)
144                                 }
145                         }
146                 })
147                 b.Run("ToFrom", func(b *testing.B) {
148                         for i := 0; i < b.N; i++ {
149                                 if _, err := p.WriteTo(datagram, &cm, dst); err != nil {
150                                         b.Fatal(err)
151                                 }
152                                 if _, _, _, err := p.ReadFrom(bb); err != nil {
153                                         b.Fatal(err)
154                                 }
155                         }
156                 })
157                 b.Run("Batch", func(b *testing.B) {
158                         for i := 0; i < b.N; i++ {
159                                 if _, err := p.WriteBatch(wms, 0); err != nil {
160                                         b.Fatal(err)
161                                 }
162                                 if _, err := p.ReadBatch(rms, 0); err != nil {
163                                         b.Fatal(err)
164                                 }
165                         }
166                 })
167         })
168 }
169
170 func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
171         switch runtime.GOOS {
172         case "nacl", "plan9", "windows":
173                 t.Skipf("not supported on %s", runtime.GOOS)
174         }
175
176         payload := []byte("HELLO-R-U-THERE")
177         iph := []byte{
178                 0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
179                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
180                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
181                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
182                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
183         }
184         greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
185         datagram := append(greh, append(iph, payload...)...)
186
187         t.Run("UDP", func(t *testing.T) {
188                 c, err := nettest.NewLocalPacketListener("udp6")
189                 if err != nil {
190                         t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
191                 }
192                 defer c.Close()
193                 p := ipv6.NewPacketConn(c)
194                 t.Run("ToFrom", func(t *testing.T) {
195                         testPacketConnConcurrentReadWriteUnicast(t, p, payload, c.LocalAddr(), false)
196                 })
197                 t.Run("Batch", func(t *testing.T) {
198                         testPacketConnConcurrentReadWriteUnicast(t, p, payload, c.LocalAddr(), true)
199                 })
200         })
201         t.Run("IP", func(t *testing.T) {
202                 switch runtime.GOOS {
203                 case "netbsd":
204                         t.Skip("need to configure gre on netbsd")
205                 case "openbsd":
206                         t.Skip("net.inet.gre.allow=0 by default on openbsd")
207                 }
208
209                 c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolGRE), "::1")
210                 if err != nil {
211                         t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
212                 }
213                 defer c.Close()
214                 p := ipv6.NewPacketConn(c)
215                 t.Run("ToFrom", func(t *testing.T) {
216                         testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr(), false)
217                 })
218                 t.Run("Batch", func(t *testing.T) {
219                         testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr(), true)
220                 })
221         })
222 }
223
224 func testPacketConnConcurrentReadWriteUnicast(t *testing.T, p *ipv6.PacketConn, data []byte, dst net.Addr, batch bool) {
225         ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
226         cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
227
228         if err := p.SetControlMessage(cf, true); err != nil { // probe before test
229                 if nettest.ProtocolNotSupported(err) {
230                         t.Skipf("not supported on %s", runtime.GOOS)
231                 }
232                 t.Fatal(err)
233         }
234
235         var wg sync.WaitGroup
236         reader := func() {
237                 defer wg.Done()
238                 b := make([]byte, 128)
239                 n, cm, _, err := p.ReadFrom(b)
240                 if err != nil {
241                         t.Error(err)
242                         return
243                 }
244                 if !bytes.Equal(b[:n], data) {
245                         t.Errorf("got %#v; want %#v", b[:n], data)
246                         return
247                 }
248                 s := cm.String()
249                 if strings.Contains(s, ",") {
250                         t.Errorf("should be space-separated values: %s", s)
251                         return
252                 }
253         }
254         batchReader := func() {
255                 defer wg.Done()
256                 ms := []ipv6.Message{
257                         {
258                                 Buffers: [][]byte{make([]byte, 128)},
259                                 OOB:     ipv6.NewControlMessage(cf),
260                         },
261                 }
262                 n, err := p.ReadBatch(ms, 0)
263                 if err != nil {
264                         t.Error(err)
265                         return
266                 }
267                 if n != len(ms) {
268                         t.Errorf("got %d; want %d", n, len(ms))
269                         return
270                 }
271                 var cm ipv6.ControlMessage
272                 if err := cm.Parse(ms[0].OOB[:ms[0].NN]); err != nil {
273                         t.Error(err)
274                         return
275                 }
276                 b := ms[0].Buffers[0][:ms[0].N]
277                 if !bytes.Equal(b, data) {
278                         t.Errorf("got %#v; want %#v", b, data)
279                         return
280                 }
281                 s := cm.String()
282                 if strings.Contains(s, ",") {
283                         t.Errorf("should be space-separated values: %s", s)
284                         return
285                 }
286         }
287         writer := func(toggle bool) {
288                 defer wg.Done()
289                 cm := ipv6.ControlMessage{
290                         TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
291                         HopLimit:     1,
292                         Src:          net.IPv6loopback,
293                 }
294                 if ifi != nil {
295                         cm.IfIndex = ifi.Index
296                 }
297                 if err := p.SetControlMessage(cf, toggle); err != nil {
298                         t.Error(err)
299                         return
300                 }
301                 n, err := p.WriteTo(data, &cm, dst)
302                 if err != nil {
303                         t.Error(err)
304                         return
305                 }
306                 if n != len(data) {
307                         t.Errorf("got %d; want %d", n, len(data))
308                         return
309                 }
310         }
311         batchWriter := func(toggle bool) {
312                 defer wg.Done()
313                 cm := ipv6.ControlMessage{
314                         TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
315                         HopLimit:     1,
316                         Src:          net.IPv6loopback,
317                 }
318                 if ifi != nil {
319                         cm.IfIndex = ifi.Index
320                 }
321                 if err := p.SetControlMessage(cf, toggle); err != nil {
322                         t.Error(err)
323                         return
324                 }
325                 ms := []ipv6.Message{
326                         {
327                                 Buffers: [][]byte{data},
328                                 OOB:     cm.Marshal(),
329                                 Addr:    dst,
330                         },
331                 }
332                 n, err := p.WriteBatch(ms, 0)
333                 if err != nil {
334                         t.Error(err)
335                         return
336                 }
337                 if n != len(ms) {
338                         t.Errorf("got %d; want %d", n, len(ms))
339                         return
340                 }
341                 if ms[0].N != len(data) {
342                         t.Errorf("got %d; want %d", ms[0].N, len(data))
343                         return
344                 }
345         }
346
347         const N = 10
348         wg.Add(N)
349         for i := 0; i < N; i++ {
350                 if batch {
351                         go batchReader()
352                 } else {
353                         go reader()
354                 }
355         }
356         wg.Add(2 * N)
357         for i := 0; i < 2*N; i++ {
358                 if batch {
359                         go batchWriter(i%2 != 0)
360                 } else {
361                         go writer(i%2 != 0)
362                 }
363         }
364         wg.Add(N)
365         for i := 0; i < N; i++ {
366                 if batch {
367                         go batchReader()
368                 } else {
369                         go reader()
370                 }
371         }
372         wg.Wait()
373 }