OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv4 / unicast_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 package ipv4_test
6
7 import (
8         "bytes"
9         "net"
10         "os"
11         "runtime"
12         "testing"
13         "time"
14
15         "golang.org/x/net/icmp"
16         "golang.org/x/net/internal/iana"
17         "golang.org/x/net/internal/nettest"
18         "golang.org/x/net/ipv4"
19 )
20
21 func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
22         switch runtime.GOOS {
23         case "nacl", "plan9", "windows":
24                 t.Skipf("not supported on %s", runtime.GOOS)
25         }
26         ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
27         if ifi == nil {
28                 t.Skipf("not available on %s", runtime.GOOS)
29         }
30
31         c, err := nettest.NewLocalPacketListener("udp4")
32         if err != nil {
33                 t.Fatal(err)
34         }
35         defer c.Close()
36         p := ipv4.NewPacketConn(c)
37         defer p.Close()
38
39         dst := c.LocalAddr()
40         cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
41         wb := []byte("HELLO-R-U-THERE")
42
43         for i, toggle := range []bool{true, false, true} {
44                 if err := p.SetControlMessage(cf, toggle); err != nil {
45                         if nettest.ProtocolNotSupported(err) {
46                                 t.Logf("not supported on %s", runtime.GOOS)
47                                 continue
48                         }
49                         t.Fatal(err)
50                 }
51                 p.SetTTL(i + 1)
52                 if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
53                         t.Fatal(err)
54                 }
55                 if n, err := p.WriteTo(wb, nil, dst); err != nil {
56                         t.Fatal(err)
57                 } else if n != len(wb) {
58                         t.Fatalf("got %v; want %v", n, len(wb))
59                 }
60                 rb := make([]byte, 128)
61                 if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
62                         t.Fatal(err)
63                 }
64                 if n, _, _, err := p.ReadFrom(rb); err != nil {
65                         t.Fatal(err)
66                 } else if !bytes.Equal(rb[:n], wb) {
67                         t.Fatalf("got %v; want %v", rb[:n], wb)
68                 }
69         }
70 }
71
72 func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
73         switch runtime.GOOS {
74         case "nacl", "plan9", "windows":
75                 t.Skipf("not supported on %s", runtime.GOOS)
76         }
77         if m, ok := nettest.SupportsRawIPSocket(); !ok {
78                 t.Skip(m)
79         }
80         ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
81         if ifi == nil {
82                 t.Skipf("not available on %s", runtime.GOOS)
83         }
84
85         c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
86         if err != nil {
87                 t.Fatal(err)
88         }
89         defer c.Close()
90
91         dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
92         if err != nil {
93                 t.Fatal(err)
94         }
95         p := ipv4.NewPacketConn(c)
96         defer p.Close()
97         cf := ipv4.FlagDst | ipv4.FlagInterface
98         if runtime.GOOS != "solaris" {
99                 // Solaris never allows to modify ICMP properties.
100                 cf |= ipv4.FlagTTL
101         }
102
103         for i, toggle := range []bool{true, false, true} {
104                 wb, err := (&icmp.Message{
105                         Type: ipv4.ICMPTypeEcho, Code: 0,
106                         Body: &icmp.Echo{
107                                 ID: os.Getpid() & 0xffff, Seq: i + 1,
108                                 Data: []byte("HELLO-R-U-THERE"),
109                         },
110                 }).Marshal(nil)
111                 if err != nil {
112                         t.Fatal(err)
113                 }
114                 if err := p.SetControlMessage(cf, toggle); err != nil {
115                         if nettest.ProtocolNotSupported(err) {
116                                 t.Logf("not supported on %s", runtime.GOOS)
117                                 continue
118                         }
119                         t.Fatal(err)
120                 }
121                 p.SetTTL(i + 1)
122                 if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
123                         t.Fatal(err)
124                 }
125                 if n, err := p.WriteTo(wb, nil, dst); err != nil {
126                         t.Fatal(err)
127                 } else if n != len(wb) {
128                         t.Fatalf("got %v; want %v", n, len(wb))
129                 }
130                 rb := make([]byte, 128)
131         loop:
132                 if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
133                         t.Fatal(err)
134                 }
135                 if n, _, _, err := p.ReadFrom(rb); err != nil {
136                         switch runtime.GOOS {
137                         case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
138                                 t.Logf("not supported on %s", runtime.GOOS)
139                                 continue
140                         }
141                         t.Fatal(err)
142                 } else {
143                         m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
144                         if err != nil {
145                                 t.Fatal(err)
146                         }
147                         if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
148                                 // On Linux we must handle own sent packets.
149                                 goto loop
150                         }
151                         if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
152                                 t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
153                         }
154                 }
155         }
156 }
157
158 func TestRawConnReadWriteUnicastICMP(t *testing.T) {
159         switch runtime.GOOS {
160         case "nacl", "plan9", "windows":
161                 t.Skipf("not supported on %s", runtime.GOOS)
162         }
163         if m, ok := nettest.SupportsRawIPSocket(); !ok {
164                 t.Skip(m)
165         }
166         ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
167         if ifi == nil {
168                 t.Skipf("not available on %s", runtime.GOOS)
169         }
170
171         c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
172         if err != nil {
173                 t.Fatal(err)
174         }
175         defer c.Close()
176
177         dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
178         if err != nil {
179                 t.Fatal(err)
180         }
181         r, err := ipv4.NewRawConn(c)
182         if err != nil {
183                 t.Fatal(err)
184         }
185         defer r.Close()
186         cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
187
188         for i, toggle := range []bool{true, false, true} {
189                 wb, err := (&icmp.Message{
190                         Type: ipv4.ICMPTypeEcho, Code: 0,
191                         Body: &icmp.Echo{
192                                 ID: os.Getpid() & 0xffff, Seq: i + 1,
193                                 Data: []byte("HELLO-R-U-THERE"),
194                         },
195                 }).Marshal(nil)
196                 if err != nil {
197                         t.Fatal(err)
198                 }
199                 wh := &ipv4.Header{
200                         Version:  ipv4.Version,
201                         Len:      ipv4.HeaderLen,
202                         TOS:      i + 1,
203                         TotalLen: ipv4.HeaderLen + len(wb),
204                         TTL:      i + 1,
205                         Protocol: 1,
206                         Dst:      dst.IP,
207                 }
208                 if err := r.SetControlMessage(cf, toggle); err != nil {
209                         if nettest.ProtocolNotSupported(err) {
210                                 t.Logf("not supported on %s", runtime.GOOS)
211                                 continue
212                         }
213                         t.Fatal(err)
214                 }
215                 if err := r.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
216                         t.Fatal(err)
217                 }
218                 if err := r.WriteTo(wh, wb, nil); err != nil {
219                         t.Fatal(err)
220                 }
221                 rb := make([]byte, ipv4.HeaderLen+128)
222         loop:
223                 if err := r.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
224                         t.Fatal(err)
225                 }
226                 if _, b, _, err := r.ReadFrom(rb); err != nil {
227                         switch runtime.GOOS {
228                         case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
229                                 t.Logf("not supported on %s", runtime.GOOS)
230                                 continue
231                         }
232                         t.Fatal(err)
233                 } else {
234                         m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
235                         if err != nil {
236                                 t.Fatal(err)
237                         }
238                         if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
239                                 // On Linux we must handle own sent packets.
240                                 goto loop
241                         }
242                         if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
243                                 t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
244                         }
245                 }
246         }
247 }