OSDN Git Service

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