OSDN Git Service

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