blob: 567d18de448cb8a959b80c989fd2dc7db52ffecd [file] [log] [blame]
Mikio Hara518331d2011-06-03 14:35:42 -04001// Copyright 2011 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
5package net
6
7import (
Mikio Haracd81db82013-02-25 23:05:40 +09008 "reflect"
Mikio Harabed884e2015-01-26 18:04:44 +09009 "runtime"
Mikio Hara518331d2011-06-03 14:35:42 -040010 "testing"
11)
12
Mikio Haracd81db82013-02-25 23:05:40 +090013// loopbackInterface returns an available logical network interface
14// for loopback tests. It returns nil if no suitable interface is
15// found.
Mikio Hara0ad88a42013-02-22 01:19:04 +090016func loopbackInterface() *Interface {
17 ift, err := Interfaces()
18 if err != nil {
19 return nil
20 }
21 for _, ifi := range ift {
22 if ifi.Flags&FlagLoopback != 0 && ifi.Flags&FlagUp != 0 {
23 return &ifi
24 }
25 }
26 return nil
27}
28
Mikio Haraaa0dda72013-03-23 09:57:40 +090029// ipv6LinkLocalUnicastAddr returns an IPv6 link-local unicast address
30// on the given network interface for tests. It returns "" if no
31// suitable address is found.
32func ipv6LinkLocalUnicastAddr(ifi *Interface) string {
33 if ifi == nil {
34 return ""
35 }
36 ifat, err := ifi.Addrs()
37 if err != nil {
38 return ""
39 }
40 for _, ifa := range ifat {
mattnea22a082015-01-19 16:56:04 +090041 if ifa, ok := ifa.(*IPNet); ok {
Mikio Haraaa0dda72013-03-23 09:57:40 +090042 if ifa.IP.To4() == nil && ifa.IP.IsLinkLocalUnicast() {
43 return ifa.IP.String()
44 }
45 }
46 }
47 return ""
48}
49
Mikio Hara14082fa2015-03-23 06:43:43 +090050type routeStats struct {
51 loop int // # of active loopback interfaces
52 other int // # of active other interfaces
53
54 uni4, uni6 int // # of active connected unicast, anycast routes
55 multi4, multi6 int // # of active connected multicast route clones
56}
57
Mikio Hara518331d2011-06-03 14:35:42 -040058func TestInterfaces(t *testing.T) {
59 ift, err := Interfaces()
60 if err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +090061 t.Fatal(err)
Mikio Hara518331d2011-06-03 14:35:42 -040062 }
Mikio Hara14082fa2015-03-23 06:43:43 +090063 var stats routeStats
Mikio Hara518331d2011-06-03 14:35:42 -040064 for _, ifi := range ift {
65 ifxi, err := InterfaceByIndex(ifi.Index)
66 if err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +090067 t.Fatal(err)
Mikio Hara518331d2011-06-03 14:35:42 -040068 }
Mikio Haracd81db82013-02-25 23:05:40 +090069 if !reflect.DeepEqual(ifxi, &ifi) {
Mikio Harabed884e2015-01-26 18:04:44 +090070 t.Errorf("got %v; want %v", ifxi, ifi)
Mikio Hara518331d2011-06-03 14:35:42 -040071 }
72 ifxn, err := InterfaceByName(ifi.Name)
73 if err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +090074 t.Fatal(err)
Mikio Hara518331d2011-06-03 14:35:42 -040075 }
Mikio Haracd81db82013-02-25 23:05:40 +090076 if !reflect.DeepEqual(ifxn, &ifi) {
Mikio Harabed884e2015-01-26 18:04:44 +090077 t.Errorf("got %v; want %v", ifxn, ifi)
Mikio Hara518331d2011-06-03 14:35:42 -040078 }
Mikio Hara3a112a82012-07-22 01:49:58 +090079 t.Logf("%q: flags %q, ifindex %v, mtu %v", ifi.Name, ifi.Flags.String(), ifi.Index, ifi.MTU)
Mikio Harabed884e2015-01-26 18:04:44 +090080 t.Logf("hardware address %q", ifi.HardwareAddr.String())
Mikio Hara14082fa2015-03-23 06:43:43 +090081 if ifi.Flags&FlagUp != 0 {
82 if ifi.Flags&FlagLoopback != 0 {
83 stats.loop++
84 } else {
85 stats.other++
86 }
Mikio Harabed884e2015-01-26 18:04:44 +090087 }
88 n4, n6 := testInterfaceAddrs(t, &ifi)
Mikio Hara14082fa2015-03-23 06:43:43 +090089 stats.uni4 += n4
90 stats.uni6 += n6
Mikio Harabed884e2015-01-26 18:04:44 +090091 n4, n6 = testInterfaceMulticastAddrs(t, &ifi)
Mikio Hara14082fa2015-03-23 06:43:43 +090092 stats.multi4 += n4
93 stats.multi6 += n6
Mikio Harabed884e2015-01-26 18:04:44 +090094 }
95 switch runtime.GOOS {
96 case "nacl", "plan9", "solaris":
97 default:
Mikio Hara14082fa2015-03-23 06:43:43 +090098 // Test the existence of connected unicast routes for
99 // IPv4.
100 if supportsIPv4 && stats.loop+stats.other > 0 && stats.uni4 == 0 {
101 t.Errorf("num IPv4 unicast routes = 0; want >0; summary: %+v", stats)
Mikio Harabed884e2015-01-26 18:04:44 +0900102 }
Mikio Hara14082fa2015-03-23 06:43:43 +0900103 // Test the existence of connected unicast routes for
104 // IPv6. We can assume the existence of ::1/128 when
105 // at least one looopback interface is installed.
106 if supportsIPv6 && stats.loop > 0 && stats.uni6 == 0 {
107 t.Errorf("num IPv6 unicast routes = 0; want >0; summary: %+v", stats)
Mikio Harabed884e2015-01-26 18:04:44 +0900108 }
109 }
110 switch runtime.GOOS {
111 case "dragonfly", "nacl", "netbsd", "openbsd", "plan9", "solaris":
112 default:
Mikio Hara14082fa2015-03-23 06:43:43 +0900113 // Test the existence of connected multicast route
114 // clones for IPv4. Unlike IPv6, IPv4 multicast
115 // capability is not a mandatory feature, and so this
116 // test is disabled.
117 //if supportsIPv4 && stats.loop > 0 && stats.uni4 > 1 && stats.multi4 == 0 {
118 // t.Errorf("num IPv4 multicast route clones = 0; want >0; summary: %+v", stats)
Mikio Harabed884e2015-01-26 18:04:44 +0900119 //}
Mikio Hara14082fa2015-03-23 06:43:43 +0900120 // Test the existence of connected multicast route
121 // clones for IPv6. Some platform never uses loopback
122 // interface as the nexthop for multicast routing.
123 // We can assume the existence of connected multicast
124 // route clones when at least two connected unicast
125 // routes, ::1/128 and other, are installed.
126 if supportsIPv6 && stats.loop > 0 && stats.uni6 > 1 && stats.multi6 == 0 {
127 t.Errorf("num IPv6 multicast route clones = 0; want >0; summary: %+v", stats)
Mikio Harabed884e2015-01-26 18:04:44 +0900128 }
Mikio Hara518331d2011-06-03 14:35:42 -0400129 }
130}
131
132func TestInterfaceAddrs(t *testing.T) {
Mikio Harabed884e2015-01-26 18:04:44 +0900133 ift, err := Interfaces()
Mikio Hara83610562011-12-21 21:39:00 +0900134 if err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +0900135 t.Fatal(err)
Mikio Hara83610562011-12-21 21:39:00 +0900136 }
Mikio Hara14082fa2015-03-23 06:43:43 +0900137 var stats routeStats
Mikio Harabed884e2015-01-26 18:04:44 +0900138 for _, ifi := range ift {
Mikio Hara14082fa2015-03-23 06:43:43 +0900139 if ifi.Flags&FlagUp != 0 {
140 if ifi.Flags&FlagLoopback != 0 {
141 stats.loop++
142 } else {
143 stats.other++
144 }
Mikio Hara83610562011-12-21 21:39:00 +0900145 }
146 }
Mikio Harabed884e2015-01-26 18:04:44 +0900147 ifat, err := InterfaceAddrs()
148 if err != nil {
149 t.Fatal(err)
150 }
Mikio Hara14082fa2015-03-23 06:43:43 +0900151 stats.uni4, stats.uni6 = testAddrs(t, ifat)
152 // Test the existence of connected unicast routes for IPv4.
153 if supportsIPv4 && stats.loop+stats.other > 0 && stats.uni4 == 0 {
154 t.Errorf("num IPv4 unicast routes = 0; want >0; summary: %+v", stats)
Mikio Harabed884e2015-01-26 18:04:44 +0900155 }
Mikio Hara14082fa2015-03-23 06:43:43 +0900156 // Test the existence of connected unicast routes for IPv6.
157 // We can assume the existence of ::1/128 when at least one
158 // looopback interface is installed.
159 if supportsIPv6 && stats.loop > 0 && stats.uni6 == 0 {
160 t.Errorf("num IPv6 unicast routes = 0; want >0; summary: %+v", stats)
Mikio Harabed884e2015-01-26 18:04:44 +0900161 }
Mikio Hara83610562011-12-21 21:39:00 +0900162}
163
Mikio Harabed884e2015-01-26 18:04:44 +0900164func testInterfaceAddrs(t *testing.T, ifi *Interface) (naf4, naf6 int) {
165 ifat, err := ifi.Addrs()
166 if err != nil {
167 t.Fatal(err)
168 }
169 return testAddrs(t, ifat)
170}
171
172func testInterfaceMulticastAddrs(t *testing.T, ifi *Interface) (nmaf4, nmaf6 int) {
173 ifmat, err := ifi.MulticastAddrs()
174 if err != nil {
175 t.Fatal(err)
176 }
177 return testMulticastAddrs(t, ifmat)
178}
179
180func testAddrs(t *testing.T, ifat []Addr) (naf4, naf6 int) {
181 for _, ifa := range ifat {
182 switch ifa := ifa.(type) {
183 case *IPNet:
184 if ifa == nil || ifa.IP == nil || ifa.IP.IsUnspecified() || ifa.IP.IsMulticast() || ifa.Mask == nil {
185 t.Errorf("unexpected value: %#v", ifa)
186 continue
187 }
188 prefixLen, maxPrefixLen := ifa.Mask.Size()
189 if ifa.IP.To4() != nil {
190 if 0 >= prefixLen || prefixLen > 8*IPv4len || maxPrefixLen != 8*IPv4len {
191 t.Errorf("unexpected prefix length: %v/%v", prefixLen, maxPrefixLen)
192 continue
193 }
194 naf4++
195 } else if ifa.IP.To16() != nil {
196 if 0 >= prefixLen || prefixLen > 8*IPv6len || maxPrefixLen != 8*IPv6len {
197 t.Errorf("unexpected prefix length: %v/%v", prefixLen, maxPrefixLen)
198 continue
199 }
200 naf6++
201 }
202 t.Logf("interface address %q", ifa.String())
203 default:
204 t.Errorf("unexpected type: %T", ifa)
205 }
206 }
207 return
208}
209
210func testMulticastAddrs(t *testing.T, ifmat []Addr) (nmaf4, nmaf6 int) {
Mikio Hara83610562011-12-21 21:39:00 +0900211 for _, ifma := range ifmat {
Mikio Haraaa0dda72013-03-23 09:57:40 +0900212 switch ifma := ifma.(type) {
Mikio Hara83610562011-12-21 21:39:00 +0900213 case *IPAddr:
Mikio Harabed884e2015-01-26 18:04:44 +0900214 if ifma == nil || ifma.IP == nil || ifma.IP.IsUnspecified() || !ifma.IP.IsMulticast() {
215 t.Errorf("unexpected value: %#v", ifma)
216 continue
Mikio Hara12e73972013-01-23 07:11:22 +0900217 }
Mikio Harabed884e2015-01-26 18:04:44 +0900218 if ifma.IP.To4() != nil {
219 nmaf4++
220 } else if ifma.IP.To16() != nil {
221 nmaf6++
222 }
223 t.Logf("joined group address %q", ifma.String())
Mikio Hara83610562011-12-21 21:39:00 +0900224 default:
Mikio Harabed884e2015-01-26 18:04:44 +0900225 t.Errorf("unexpected type: %T", ifma)
Mikio Hara83610562011-12-21 21:39:00 +0900226 }
Mikio Hara518331d2011-06-03 14:35:42 -0400227 }
Mikio Harabed884e2015-01-26 18:04:44 +0900228 return
Mikio Hara518331d2011-06-03 14:35:42 -0400229}
Mikio Hara0ad88a42013-02-22 01:19:04 +0900230
231func BenchmarkInterfaces(b *testing.B) {
Mikio Haraef549302015-05-14 09:25:24 +0900232 testHookUninstaller.Do(uninstallTestHooks)
Mikio Hara29d1f3b2015-03-01 12:27:01 +0900233
Mikio Hara0ad88a42013-02-22 01:19:04 +0900234 for i := 0; i < b.N; i++ {
235 if _, err := Interfaces(); err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +0900236 b.Fatal(err)
Mikio Hara0ad88a42013-02-22 01:19:04 +0900237 }
238 }
239}
240
241func BenchmarkInterfaceByIndex(b *testing.B) {
Mikio Haraef549302015-05-14 09:25:24 +0900242 testHookUninstaller.Do(uninstallTestHooks)
Mikio Hara29d1f3b2015-03-01 12:27:01 +0900243
Mikio Hara0ad88a42013-02-22 01:19:04 +0900244 ifi := loopbackInterface()
245 if ifi == nil {
Mikio Haracd81db82013-02-25 23:05:40 +0900246 b.Skip("loopback interface not found")
Mikio Hara0ad88a42013-02-22 01:19:04 +0900247 }
248 for i := 0; i < b.N; i++ {
249 if _, err := InterfaceByIndex(ifi.Index); err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +0900250 b.Fatal(err)
Mikio Hara0ad88a42013-02-22 01:19:04 +0900251 }
252 }
253}
254
255func BenchmarkInterfaceByName(b *testing.B) {
Mikio Haraef549302015-05-14 09:25:24 +0900256 testHookUninstaller.Do(uninstallTestHooks)
Mikio Hara29d1f3b2015-03-01 12:27:01 +0900257
Mikio Hara0ad88a42013-02-22 01:19:04 +0900258 ifi := loopbackInterface()
259 if ifi == nil {
Mikio Haracd81db82013-02-25 23:05:40 +0900260 b.Skip("loopback interface not found")
Mikio Hara0ad88a42013-02-22 01:19:04 +0900261 }
262 for i := 0; i < b.N; i++ {
263 if _, err := InterfaceByName(ifi.Name); err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +0900264 b.Fatal(err)
Mikio Hara0ad88a42013-02-22 01:19:04 +0900265 }
266 }
267}
268
269func BenchmarkInterfaceAddrs(b *testing.B) {
Mikio Haraef549302015-05-14 09:25:24 +0900270 testHookUninstaller.Do(uninstallTestHooks)
Mikio Hara29d1f3b2015-03-01 12:27:01 +0900271
Mikio Hara0ad88a42013-02-22 01:19:04 +0900272 for i := 0; i < b.N; i++ {
273 if _, err := InterfaceAddrs(); err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +0900274 b.Fatal(err)
Mikio Hara0ad88a42013-02-22 01:19:04 +0900275 }
276 }
277}
278
279func BenchmarkInterfacesAndAddrs(b *testing.B) {
Mikio Haraef549302015-05-14 09:25:24 +0900280 testHookUninstaller.Do(uninstallTestHooks)
Mikio Hara29d1f3b2015-03-01 12:27:01 +0900281
Mikio Hara0ad88a42013-02-22 01:19:04 +0900282 ifi := loopbackInterface()
283 if ifi == nil {
Mikio Haracd81db82013-02-25 23:05:40 +0900284 b.Skip("loopback interface not found")
Mikio Hara0ad88a42013-02-22 01:19:04 +0900285 }
286 for i := 0; i < b.N; i++ {
287 if _, err := ifi.Addrs(); err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +0900288 b.Fatal(err)
Mikio Hara0ad88a42013-02-22 01:19:04 +0900289 }
290 }
291}
292
293func BenchmarkInterfacesAndMulticastAddrs(b *testing.B) {
Mikio Haraef549302015-05-14 09:25:24 +0900294 testHookUninstaller.Do(uninstallTestHooks)
Mikio Hara29d1f3b2015-03-01 12:27:01 +0900295
Mikio Hara0ad88a42013-02-22 01:19:04 +0900296 ifi := loopbackInterface()
297 if ifi == nil {
Mikio Haracd81db82013-02-25 23:05:40 +0900298 b.Skip("loopback interface not found")
Mikio Hara0ad88a42013-02-22 01:19:04 +0900299 }
300 for i := 0; i < b.N; i++ {
301 if _, err := ifi.MulticastAddrs(); err != nil {
Mikio Harabed884e2015-01-26 18:04:44 +0900302 b.Fatal(err)
Mikio Hara0ad88a42013-02-22 01:19:04 +0900303 }
304 }
305}