OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv6 / unicast_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 package ipv6_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/ipv6"
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         if !supportsIPv6 {
27                 t.Skip("ipv6 is not supported")
28         }
29
30         c, err := nettest.NewLocalPacketListener("udp6")
31         if err != nil {
32                 t.Fatal(err)
33         }
34         defer c.Close()
35         p := ipv6.NewPacketConn(c)
36         defer p.Close()
37
38         dst := c.LocalAddr()
39         cm := ipv6.ControlMessage{
40                 TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
41                 Src:          net.IPv6loopback,
42         }
43         cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
44         ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
45         if ifi != nil {
46                 cm.IfIndex = ifi.Index
47         }
48         wb := []byte("HELLO-R-U-THERE")
49
50         for i, toggle := range []bool{true, false, true} {
51                 if err := p.SetControlMessage(cf, toggle); err != nil {
52                         if nettest.ProtocolNotSupported(err) {
53                                 t.Logf("not supported on %s", runtime.GOOS)
54                                 continue
55                         }
56                         t.Fatal(err)
57                 }
58                 cm.HopLimit = i + 1
59                 if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
60                         t.Fatal(err)
61                 }
62                 if n, err := p.WriteTo(wb, &cm, dst); err != nil {
63                         t.Fatal(err)
64                 } else if n != len(wb) {
65                         t.Fatalf("got %v; want %v", n, len(wb))
66                 }
67                 rb := make([]byte, 128)
68                 if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
69                         t.Fatal(err)
70                 }
71                 if n, _, _, err := p.ReadFrom(rb); err != nil {
72                         t.Fatal(err)
73                 } else if !bytes.Equal(rb[:n], wb) {
74                         t.Fatalf("got %v; want %v", rb[:n], wb)
75                 }
76         }
77 }
78
79 func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
80         switch runtime.GOOS {
81         case "nacl", "plan9", "windows":
82                 t.Skipf("not supported on %s", runtime.GOOS)
83         }
84         if !supportsIPv6 {
85                 t.Skip("ipv6 is not supported")
86         }
87         if m, ok := nettest.SupportsRawIPSocket(); !ok {
88                 t.Skip(m)
89         }
90
91         c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
92         if err != nil {
93                 t.Fatal(err)
94         }
95         defer c.Close()
96         p := ipv6.NewPacketConn(c)
97         defer p.Close()
98
99         dst, err := net.ResolveIPAddr("ip6", "::1")
100         if err != nil {
101                 t.Fatal(err)
102         }
103
104         pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP)
105         cm := ipv6.ControlMessage{
106                 TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
107                 Src:          net.IPv6loopback,
108         }
109         cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
110         ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
111         if ifi != nil {
112                 cm.IfIndex = ifi.Index
113         }
114
115         var f ipv6.ICMPFilter
116         f.SetAll(true)
117         f.Accept(ipv6.ICMPTypeEchoReply)
118         if err := p.SetICMPFilter(&f); err != nil {
119                 t.Fatal(err)
120         }
121
122         var psh []byte
123         for i, toggle := range []bool{true, false, true} {
124                 if toggle {
125                         psh = nil
126                         if err := p.SetChecksum(true, 2); err != nil {
127                                 // Solaris never allows to modify
128                                 // ICMP properties.
129                                 if runtime.GOOS != "solaris" {
130                                         t.Fatal(err)
131                                 }
132                         }
133                 } else {
134                         psh = pshicmp
135                         // Some platforms never allow to disable the
136                         // kernel checksum processing.
137                         p.SetChecksum(false, -1)
138                 }
139                 wb, err := (&icmp.Message{
140                         Type: ipv6.ICMPTypeEchoRequest, Code: 0,
141                         Body: &icmp.Echo{
142                                 ID: os.Getpid() & 0xffff, Seq: i + 1,
143                                 Data: []byte("HELLO-R-U-THERE"),
144                         },
145                 }).Marshal(psh)
146                 if err != nil {
147                         t.Fatal(err)
148                 }
149                 if err := p.SetControlMessage(cf, toggle); err != nil {
150                         if nettest.ProtocolNotSupported(err) {
151                                 t.Logf("not supported on %s", runtime.GOOS)
152                                 continue
153                         }
154                         t.Fatal(err)
155                 }
156                 cm.HopLimit = i + 1
157                 if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
158                         t.Fatal(err)
159                 }
160                 if n, err := p.WriteTo(wb, &cm, dst); err != nil {
161                         t.Fatal(err)
162                 } else if n != len(wb) {
163                         t.Fatalf("got %v; want %v", n, len(wb))
164                 }
165                 rb := make([]byte, 128)
166                 if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
167                         t.Fatal(err)
168                 }
169                 if n, _, _, err := p.ReadFrom(rb); err != nil {
170                         switch runtime.GOOS {
171                         case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
172                                 t.Logf("not supported on %s", runtime.GOOS)
173                                 continue
174                         }
175                         t.Fatal(err)
176                 } else {
177                         if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil {
178                                 t.Fatal(err)
179                         } else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
180                                 t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
181                         }
182                 }
183         }
184 }