OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / route / message_test.go
1 // Copyright 2016 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 darwin dragonfly freebsd netbsd openbsd
6
7 package route
8
9 import (
10         "os"
11         "syscall"
12         "testing"
13         "time"
14 )
15
16 func TestFetchAndParseRIB(t *testing.T) {
17         for _, typ := range []RIBType{sysNET_RT_DUMP, sysNET_RT_IFLIST} {
18                 var lastErr error
19                 var ms []Message
20                 for _, af := range []int{sysAF_UNSPEC, sysAF_INET, sysAF_INET6} {
21                         rs, err := fetchAndParseRIB(af, typ)
22                         if err != nil {
23                                 lastErr = err
24                                 continue
25                         }
26                         ms = append(ms, rs...)
27                 }
28                 if len(ms) == 0 && lastErr != nil {
29                         t.Error(typ, lastErr)
30                         continue
31                 }
32                 ss, err := msgs(ms).validate()
33                 if err != nil {
34                         t.Error(typ, err)
35                         continue
36                 }
37                 for _, s := range ss {
38                         t.Log(typ, s)
39                 }
40         }
41 }
42
43 var (
44         rtmonSock int
45         rtmonErr  error
46 )
47
48 func init() {
49         // We need to keep rtmonSock alive to avoid treading on
50         // recycled socket descriptors.
51         rtmonSock, rtmonErr = syscall.Socket(sysAF_ROUTE, sysSOCK_RAW, sysAF_UNSPEC)
52 }
53
54 // TestMonitorAndParseRIB leaks a worker goroutine and a socket
55 // descriptor but that's intentional.
56 func TestMonitorAndParseRIB(t *testing.T) {
57         if testing.Short() || os.Getuid() != 0 {
58                 t.Skip("must be root")
59         }
60
61         if rtmonErr != nil {
62                 t.Fatal(rtmonErr)
63         }
64
65         // We suppose that using an IPv4 link-local address and the
66         // dot1Q ID for Token Ring and FDDI doesn't harm anyone.
67         pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
68         if err := pv.configure(1002); err != nil {
69                 t.Skip(err)
70         }
71         if err := pv.setup(); err != nil {
72                 t.Skip(err)
73         }
74         pv.teardown()
75
76         go func() {
77                 b := make([]byte, os.Getpagesize())
78                 for {
79                         // There's no easy way to unblock this read
80                         // call because the routing message exchange
81                         // over routing socket is a connectionless
82                         // message-oriented protocol, no control plane
83                         // for signaling connectivity, and we cannot
84                         // use the net package of standard library due
85                         // to the lack of support for routing socket
86                         // and circular dependency.
87                         n, err := syscall.Read(rtmonSock, b)
88                         if err != nil {
89                                 return
90                         }
91                         ms, err := ParseRIB(0, b[:n])
92                         if err != nil {
93                                 t.Error(err)
94                                 return
95                         }
96                         ss, err := msgs(ms).validate()
97                         if err != nil {
98                                 t.Error(err)
99                                 return
100                         }
101                         for _, s := range ss {
102                                 t.Log(s)
103                         }
104                 }
105         }()
106
107         for _, vid := range []int{1002, 1003, 1004, 1005} {
108                 pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
109                 if err := pv.configure(vid); err != nil {
110                         t.Fatal(err)
111                 }
112                 if err := pv.setup(); err != nil {
113                         t.Fatal(err)
114                 }
115                 time.Sleep(200 * time.Millisecond)
116                 if err := pv.teardown(); err != nil {
117                         t.Fatal(err)
118                 }
119                 time.Sleep(200 * time.Millisecond)
120         }
121 }
122
123 func TestParseRIBWithFuzz(t *testing.T) {
124         for _, fuzz := range []string{
125                 "0\x00\x05\x050000000000000000" +
126                         "00000000000000000000" +
127                         "00000000000000000000" +
128                         "00000000000000000000" +
129                         "0000000000000\x02000000" +
130                         "00000000",
131                 "\x02\x00\x05\f0000000000000000" +
132                         "0\x0200000000000000",
133                 "\x02\x00\x05\x100000000000000\x1200" +
134                         "0\x00\xff\x00",
135                 "\x02\x00\x05\f0000000000000000" +
136                         "0\x12000\x00\x02\x0000",
137                 "\x00\x00\x00\x01\x00",
138                 "00000",
139         } {
140                 for typ := RIBType(0); typ < 256; typ++ {
141                         ParseRIB(typ, []byte(fuzz))
142                 }
143         }
144 }
145
146 func TestRouteMessage(t *testing.T) {
147         s, err := syscall.Socket(sysAF_ROUTE, sysSOCK_RAW, sysAF_UNSPEC)
148         if err != nil {
149                 t.Fatal(err)
150         }
151         defer syscall.Close(s)
152
153         var ms []RouteMessage
154         for _, af := range []int{sysAF_INET, sysAF_INET6} {
155                 if _, err := fetchAndParseRIB(af, sysNET_RT_DUMP); err != nil {
156                         t.Log(err)
157                         continue
158                 }
159                 switch af {
160                 case sysAF_INET:
161                         ms = append(ms, []RouteMessage{
162                                 {
163                                         Type: sysRTM_GET,
164                                         Addrs: []Addr{
165                                                 &Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
166                                                 nil,
167                                                 nil,
168                                                 nil,
169                                                 &LinkAddr{},
170                                                 &Inet4Addr{},
171                                                 nil,
172                                                 &Inet4Addr{},
173                                         },
174                                 },
175                                 {
176                                         Type: sysRTM_GET,
177                                         Addrs: []Addr{
178                                                 &Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
179                                         },
180                                 },
181                         }...)
182                 case sysAF_INET6:
183                         ms = append(ms, []RouteMessage{
184                                 {
185                                         Type: sysRTM_GET,
186                                         Addrs: []Addr{
187                                                 &Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
188                                                 nil,
189                                                 nil,
190                                                 nil,
191                                                 &LinkAddr{},
192                                                 &Inet6Addr{},
193                                                 nil,
194                                                 &Inet6Addr{},
195                                         },
196                                 },
197                                 {
198                                         Type: sysRTM_GET,
199                                         Addrs: []Addr{
200                                                 &Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
201                                         },
202                                 },
203                         }...)
204                 }
205         }
206         for i, m := range ms {
207                 m.ID = uintptr(os.Getpid())
208                 m.Seq = i + 1
209                 wb, err := m.Marshal()
210                 if err != nil {
211                         t.Fatalf("%v: %v", m, err)
212                 }
213                 if _, err := syscall.Write(s, wb); err != nil {
214                         t.Fatalf("%v: %v", m, err)
215                 }
216                 rb := make([]byte, os.Getpagesize())
217                 n, err := syscall.Read(s, rb)
218                 if err != nil {
219                         t.Fatalf("%v: %v", m, err)
220                 }
221                 rms, err := ParseRIB(0, rb[:n])
222                 if err != nil {
223                         t.Fatalf("%v: %v", m, err)
224                 }
225                 for _, rm := range rms {
226                         err := rm.(*RouteMessage).Err
227                         if err != nil {
228                                 t.Errorf("%v: %v", m, err)
229                         }
230                 }
231                 ss, err := msgs(rms).validate()
232                 if err != nil {
233                         t.Fatalf("%v: %v", m, err)
234                 }
235                 for _, s := range ss {
236                         t.Log(s)
237                 }
238         }
239 }