OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv6 / readwrite_go1_8_test.go
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 // +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                 b.Run("Net", func(b *testing.B) {
62                         for i := 0; i < b.N; i++ {
63                                 if _, err := c.WriteTo(payload, dst); err != nil {
64                                         b.Fatal(err)
65                                 }
66                                 if _, _, err := c.ReadFrom(bb); err != nil {
67                                         b.Fatal(err)
68                                 }
69                         }
70                 })
71                 b.Run("ToFrom", func(b *testing.B) {
72                         for i := 0; i < b.N; i++ {
73                                 if _, err := p.WriteTo(payload, &cm, dst); err != nil {
74                                         b.Fatal(err)
75                                 }
76                                 if _, _, _, err := p.ReadFrom(bb); err != nil {
77                                         b.Fatal(err)
78                                 }
79                         }
80                 })
81         })
82         b.Run("IP", func(b *testing.B) {
83                 switch runtime.GOOS {
84                 case "netbsd":
85                         b.Skip("need to configure gre on netbsd")
86                 case "openbsd":
87                         b.Skip("net.inet.gre.allow=0 by default on openbsd")
88                 }
89
90                 c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolGRE), "::1")
91                 if err != nil {
92                         b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
93                 }
94                 defer c.Close()
95                 p := ipv6.NewPacketConn(c)
96                 dst := c.LocalAddr()
97                 cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
98                 if err := p.SetControlMessage(cf, true); err != nil {
99                         b.Fatal(err)
100                 }
101                 b.Run("Net", func(b *testing.B) {
102                         for i := 0; i < b.N; i++ {
103                                 if _, err := c.WriteTo(datagram, dst); err != nil {
104                                         b.Fatal(err)
105                                 }
106                                 if _, _, err := c.ReadFrom(bb); err != nil {
107                                         b.Fatal(err)
108                                 }
109                         }
110                 })
111                 b.Run("ToFrom", func(b *testing.B) {
112                         for i := 0; i < b.N; i++ {
113                                 if _, err := p.WriteTo(datagram, &cm, dst); err != nil {
114                                         b.Fatal(err)
115                                 }
116                                 if _, _, _, err := p.ReadFrom(bb); err != nil {
117                                         b.Fatal(err)
118                                 }
119                         }
120                 })
121         })
122 }
123
124 func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
125         switch runtime.GOOS {
126         case "nacl", "plan9", "windows":
127                 t.Skipf("not supported on %s", runtime.GOOS)
128         }
129
130         payload := []byte("HELLO-R-U-THERE")
131         iph := []byte{
132                 0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
133                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
134                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
135                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
136                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
137         }
138         greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
139         datagram := append(greh, append(iph, payload...)...)
140
141         t.Run("UDP", func(t *testing.T) {
142                 c, err := nettest.NewLocalPacketListener("udp6")
143                 if err != nil {
144                         t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
145                 }
146                 defer c.Close()
147                 p := ipv6.NewPacketConn(c)
148                 t.Run("ToFrom", func(t *testing.T) {
149                         testPacketConnConcurrentReadWriteUnicast(t, p, payload, c.LocalAddr())
150                 })
151         })
152         t.Run("IP", func(t *testing.T) {
153                 switch runtime.GOOS {
154                 case "netbsd":
155                         t.Skip("need to configure gre on netbsd")
156                 case "openbsd":
157                         t.Skip("net.inet.gre.allow=0 by default on openbsd")
158                 }
159
160                 c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolGRE), "::1")
161                 if err != nil {
162                         t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
163                 }
164                 defer c.Close()
165                 p := ipv6.NewPacketConn(c)
166                 t.Run("ToFrom", func(t *testing.T) {
167                         testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr())
168                 })
169         })
170 }
171
172 func testPacketConnConcurrentReadWriteUnicast(t *testing.T, p *ipv6.PacketConn, data []byte, dst net.Addr) {
173         ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
174         cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
175
176         if err := p.SetControlMessage(cf, true); err != nil { // probe before test
177                 if nettest.ProtocolNotSupported(err) {
178                         t.Skipf("not supported on %s", runtime.GOOS)
179                 }
180                 t.Fatal(err)
181         }
182
183         var wg sync.WaitGroup
184         reader := func() {
185                 defer wg.Done()
186                 b := make([]byte, 128)
187                 n, cm, _, err := p.ReadFrom(b)
188                 if err != nil {
189                         t.Error(err)
190                         return
191                 }
192                 if !bytes.Equal(b[:n], data) {
193                         t.Errorf("got %#v; want %#v", b[:n], data)
194                         return
195                 }
196                 s := cm.String()
197                 if strings.Contains(s, ",") {
198                         t.Errorf("should be space-separated values: %s", s)
199                         return
200                 }
201         }
202         writer := func(toggle bool) {
203                 defer wg.Done()
204                 cm := ipv6.ControlMessage{
205                         TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
206                         HopLimit:     1,
207                         Src:          net.IPv6loopback,
208                 }
209                 if ifi != nil {
210                         cm.IfIndex = ifi.Index
211                 }
212                 if err := p.SetControlMessage(cf, toggle); err != nil {
213                         t.Error(err)
214                         return
215                 }
216                 n, err := p.WriteTo(data, &cm, dst)
217                 if err != nil {
218                         t.Error(err)
219                         return
220                 }
221                 if n != len(data) {
222                         t.Errorf("got %d; want %d", n, len(data))
223                         return
224                 }
225         }
226
227         const N = 10
228         wg.Add(N)
229         for i := 0; i < N; i++ {
230                 go reader()
231         }
232         wg.Add(2 * N)
233         for i := 0; i < 2*N; i++ {
234                 go writer(i%2 != 0)
235
236         }
237         wg.Add(N)
238         for i := 0; i < N; i++ {
239                 go reader()
240         }
241         wg.Wait()
242 }