blob: 146b7853f5b6ddb3712d0f07681ae8e367a28c8a [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004--2011, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "talk/base/network.h"
29
30#include <vector>
31#if defined(POSIX)
32#include <sys/types.h>
33#ifndef ANDROID
34#include <ifaddrs.h>
35#else
36#include "talk/base/ifaddrs-android.h"
37#endif
38#endif
39#include "talk/base/gunit.h"
40
41namespace talk_base {
42
43class NetworkTest : public testing::Test, public sigslot::has_slots<> {
44 public:
45 NetworkTest() : callback_called_(false) {}
46
47 void OnNetworksChanged() {
48 callback_called_ = true;
49 }
50
51 void MergeNetworkList(BasicNetworkManager& network_manager,
52 const NetworkManager::NetworkList& list,
53 bool* changed ) {
54 network_manager.MergeNetworkList(list, changed);
55 }
56
57 bool IsIgnoredNetwork(const Network& network) {
58 return BasicNetworkManager::IsIgnoredNetwork(network);
59 }
60
61 NetworkManager::NetworkList GetNetworks(
62 const BasicNetworkManager& network_manager, bool include_ignored) {
63 NetworkManager::NetworkList list;
64 network_manager.CreateNetworks(include_ignored, &list);
65 return list;
66 }
67
68#if defined(POSIX)
69 // Separated from CreateNetworks for tests.
70 static void CallConvertIfAddrs(const BasicNetworkManager& network_manager,
71 struct ifaddrs* interfaces,
72 bool include_ignored,
73 NetworkManager::NetworkList* networks) {
74 network_manager.ConvertIfAddrs(interfaces, include_ignored, networks);
75 }
76#endif // defined(POSIX)
77
78 protected:
79 bool callback_called_;
80};
81
82// Test that the Network ctor works properly.
83TEST_F(NetworkTest, TestNetworkConstruct) {
84 Network ipv4_network1("test_eth0", "Test Network Adapter 1",
85 IPAddress(0x12345600U), 24);
86 EXPECT_EQ("test_eth0", ipv4_network1.name());
87 EXPECT_EQ("Test Network Adapter 1", ipv4_network1.description());
88 EXPECT_EQ(IPAddress(0x12345600U), ipv4_network1.prefix());
89 EXPECT_EQ(24, ipv4_network1.prefix_length());
90 EXPECT_FALSE(ipv4_network1.ignored());
91}
92
93// Tests that our ignore function works properly.
94TEST_F(NetworkTest, TestNetworkIgnore) {
95 Network ipv4_network1("test_eth0", "Test Network Adapter 1",
96 IPAddress(0x12345600U), 24);
97 Network ipv4_network2("test_eth1", "Test Network Adapter 2",
98 IPAddress(0x00010000U), 16);
99 EXPECT_FALSE(IsIgnoredNetwork(ipv4_network1));
100 EXPECT_TRUE(IsIgnoredNetwork(ipv4_network2));
101}
102
103TEST_F(NetworkTest, TestCreateNetworks) {
104 BasicNetworkManager manager;
105 NetworkManager::NetworkList result = GetNetworks(manager, true);
106 // We should be able to bind to any addresses we find.
107 NetworkManager::NetworkList::iterator it;
108 for (it = result.begin();
109 it != result.end();
110 ++it) {
111 sockaddr_storage storage;
112 memset(&storage, 0, sizeof(storage));
113 IPAddress ip = (*it)->ip();
114 SocketAddress bindaddress(ip, 0);
115 bindaddress.SetScopeID((*it)->scope_id());
116 // TODO: Make this use talk_base::AsyncSocket once it supports IPv6.
117 int fd = static_cast<int>(socket(ip.family(), SOCK_STREAM, IPPROTO_TCP));
118 if (fd > 0) {
119 size_t ipsize = bindaddress.ToSockAddrStorage(&storage);
120 EXPECT_GE(ipsize, 0U);
121 int success = ::bind(fd,
122 reinterpret_cast<sockaddr*>(&storage),
123 static_cast<int>(ipsize));
124 EXPECT_EQ(0, success);
125#ifdef WIN32
126 closesocket(fd);
127#else
128 close(fd);
129#endif
130 }
131 }
132}
133
134// Test that UpdateNetworks succeeds.
135TEST_F(NetworkTest, TestUpdateNetworks) {
136 BasicNetworkManager manager;
137 manager.SignalNetworksChanged.connect(
138 static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
139 manager.StartUpdating();
140 Thread::Current()->ProcessMessages(0);
141 EXPECT_TRUE(callback_called_);
142 callback_called_ = false;
143 // Callback should be triggered immediately when StartUpdating
144 // is called, after network update signal is already sent.
145 manager.StartUpdating();
146 EXPECT_TRUE(manager.started());
147 Thread::Current()->ProcessMessages(0);
148 EXPECT_TRUE(callback_called_);
149 manager.StopUpdating();
150 EXPECT_TRUE(manager.started());
151 manager.StopUpdating();
152 EXPECT_FALSE(manager.started());
153 manager.StopUpdating();
154 EXPECT_FALSE(manager.started());
155 callback_called_ = false;
156 // Callback should be triggered immediately after StartUpdating is called
157 // when start_count_ is reset to 0.
158 manager.StartUpdating();
159 Thread::Current()->ProcessMessages(0);
160 EXPECT_TRUE(callback_called_);
161}
162
163// Verify that MergeNetworkList() merges network lists properly.
164TEST_F(NetworkTest, TestBasicMergeNetworkList) {
165 Network ipv4_network1("test_eth0", "Test Network Adapter 1",
166 IPAddress(0x12345600U), 24);
167 Network ipv4_network2("test_eth1", "Test Network Adapter 2",
168 IPAddress(0x00010000U), 16);
169 ipv4_network1.AddIP(IPAddress(0x12345678));
170 ipv4_network2.AddIP(IPAddress(0x00010004));
171 BasicNetworkManager manager;
172
173 // Add ipv4_network1 to the list of networks.
174 NetworkManager::NetworkList list;
175 list.push_back(new Network(ipv4_network1));
176 bool changed;
177 MergeNetworkList(manager, list, &changed);
178 EXPECT_TRUE(changed);
179 list.clear();
180
181 manager.GetNetworks(&list);
182 EXPECT_EQ(1U, list.size());
183 EXPECT_EQ(ipv4_network1.ToString(), list[0]->ToString());
184 Network* net1 = list[0];
185 list.clear();
186
187 // Replace ipv4_network1 with ipv4_network2.
188 list.push_back(new Network(ipv4_network2));
189 MergeNetworkList(manager, list, &changed);
190 EXPECT_TRUE(changed);
191 list.clear();
192
193 manager.GetNetworks(&list);
194 EXPECT_EQ(1U, list.size());
195 EXPECT_EQ(ipv4_network2.ToString(), list[0]->ToString());
196 Network* net2 = list[0];
197 list.clear();
198
199 // Add Network2 back.
200 list.push_back(new Network(ipv4_network1));
201 list.push_back(new Network(ipv4_network2));
202 MergeNetworkList(manager, list, &changed);
203 EXPECT_TRUE(changed);
204 list.clear();
205
206 // Verify that we get previous instances of Network objects.
207 manager.GetNetworks(&list);
208 EXPECT_EQ(2U, list.size());
209 EXPECT_TRUE((net1 == list[0] && net2 == list[1]) ||
210 (net1 == list[1] && net2 == list[0]));
211 list.clear();
212
213 // Call MergeNetworkList() again and verify that we don't get update
214 // notification.
215 list.push_back(new Network(ipv4_network2));
216 list.push_back(new Network(ipv4_network1));
217 MergeNetworkList(manager, list, &changed);
218 EXPECT_FALSE(changed);
219 list.clear();
220
221 // Verify that we get previous instances of Network objects.
222 manager.GetNetworks(&list);
223 EXPECT_EQ(2U, list.size());
224 EXPECT_TRUE((net1 == list[0] && net2 == list[1]) ||
225 (net1 == list[1] && net2 == list[0]));
226 list.clear();
227}
228
229// Sets up some test IPv6 networks and appends them to list.
230// Four networks are added - public and link local, for two interfaces.
231void SetupNetworks(NetworkManager::NetworkList* list) {
232 IPAddress ip;
233 IPAddress prefix;
234 EXPECT_TRUE(IPFromString("fe80::1234:5678:abcd:ef12", &ip));
235 EXPECT_TRUE(IPFromString("fe80::", &prefix));
236 // First, fake link-locals.
237 Network ipv6_eth0_linklocalnetwork("test_eth0", "Test NetworkAdapter 1",
238 prefix, 64);
239 ipv6_eth0_linklocalnetwork.AddIP(ip);
240 EXPECT_TRUE(IPFromString("fe80::5678:abcd:ef12:3456", &ip));
241 Network ipv6_eth1_linklocalnetwork("test_eth1", "Test NetworkAdapter 2",
242 prefix, 64);
243 ipv6_eth1_linklocalnetwork.AddIP(ip);
244 // Public networks:
245 EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &ip));
246 prefix = TruncateIP(ip, 64);
247 Network ipv6_eth0_publicnetwork1_ip1("test_eth0", "Test NetworkAdapter 1",
248 prefix, 64);
249 ipv6_eth0_publicnetwork1_ip1.AddIP(ip);
250 EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:abcd:efab:cdef", &ip));
251 prefix = TruncateIP(ip, 64);
252 Network ipv6_eth1_publicnetwork1_ip1("test_eth1", "Test NetworkAdapter 1",
253 prefix, 64);
254 ipv6_eth1_publicnetwork1_ip1.AddIP(ip);
255 list->push_back(new Network(ipv6_eth0_linklocalnetwork));
256 list->push_back(new Network(ipv6_eth1_linklocalnetwork));
257 list->push_back(new Network(ipv6_eth0_publicnetwork1_ip1));
258 list->push_back(new Network(ipv6_eth1_publicnetwork1_ip1));
259}
260
261// Test that the basic network merging case works.
262TEST_F(NetworkTest, TestIPv6MergeNetworkList) {
263 BasicNetworkManager manager;
264 manager.SignalNetworksChanged.connect(
265 static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
266 NetworkManager::NetworkList original_list;
267 SetupNetworks(&original_list);
268 bool changed = false;
269 MergeNetworkList(manager, original_list, &changed);
270 EXPECT_TRUE(changed);
271 NetworkManager::NetworkList list;
272 manager.GetNetworks(&list);
273 EXPECT_EQ(original_list.size(), list.size());
274 // Verify that the original members are in the merged list.
275 for (NetworkManager::NetworkList::iterator it = original_list.begin();
276 it != original_list.end(); ++it) {
277 EXPECT_NE(list.end(), std::find(list.begin(), list.end(), *it));
278 }
279}
280
281// Tests that when two network lists that describe the same set of networks are
282// merged, that the changed callback is not called, and that the original
283// objects remain in the result list.
284TEST_F(NetworkTest, TestNoChangeMerge) {
285 BasicNetworkManager manager;
286 manager.SignalNetworksChanged.connect(
287 static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
288 NetworkManager::NetworkList original_list;
289 SetupNetworks(&original_list);
290 bool changed = false;
291 MergeNetworkList(manager, original_list, &changed);
292 EXPECT_TRUE(changed);
293 // Second list that describes the same networks but with new objects.
294 NetworkManager::NetworkList second_list;
295 SetupNetworks(&second_list);
296 changed = false;
297 MergeNetworkList(manager, second_list, &changed);
298 EXPECT_FALSE(changed);
299 NetworkManager::NetworkList resulting_list;
300 manager.GetNetworks(&resulting_list);
301 EXPECT_EQ(original_list.size(), resulting_list.size());
302 // Verify that the original members are in the merged list.
303 for (NetworkManager::NetworkList::iterator it = original_list.begin();
304 it != original_list.end(); ++it) {
305 EXPECT_NE(resulting_list.end(),
306 std::find(resulting_list.begin(), resulting_list.end(), *it));
307 }
308 // Doublecheck that the new networks aren't in the list.
309 for (NetworkManager::NetworkList::iterator it = second_list.begin();
310 it != second_list.end(); ++it) {
311 EXPECT_EQ(resulting_list.end(),
312 std::find(resulting_list.begin(), resulting_list.end(), *it));
313 }
314}
315
316// Test that we can merge a network that is the same as another network but with
317// a different IP. The original network should remain in the list, but have its
318// IP changed.
319TEST_F(NetworkTest, MergeWithChangedIP) {
320 BasicNetworkManager manager;
321 manager.SignalNetworksChanged.connect(
322 static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
323 NetworkManager::NetworkList original_list;
324 SetupNetworks(&original_list);
325 // Make a network that we're going to change.
326 IPAddress ip;
327 EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:faa:fee:faa", &ip));
328 IPAddress prefix = TruncateIP(ip, 64);
329 Network* network_to_change = new Network("test_eth0",
330 "Test Network Adapter 1",
331 prefix, 64);
332 Network* changed_network = new Network(*network_to_change);
333 network_to_change->AddIP(ip);
334 IPAddress changed_ip;
335 EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:f00:f00:f00", &changed_ip));
336 changed_network->AddIP(changed_ip);
337 original_list.push_back(network_to_change);
338 bool changed = false;
339 MergeNetworkList(manager, original_list, &changed);
340 NetworkManager::NetworkList second_list;
341 SetupNetworks(&second_list);
342 second_list.push_back(changed_network);
343 changed = false;
344 MergeNetworkList(manager, second_list, &changed);
345 EXPECT_TRUE(changed);
346 NetworkManager::NetworkList list;
347 manager.GetNetworks(&list);
348 EXPECT_EQ(original_list.size(), list.size());
349 // Make sure the original network is still in the merged list.
350 EXPECT_NE(list.end(),
351 std::find(list.begin(), list.end(), network_to_change));
352 EXPECT_EQ(changed_ip, network_to_change->GetIPs().at(0));
353}
354
355// Testing a similar case to above, but checking that a network can be updated
356// with additional IPs (not just a replacement).
357TEST_F(NetworkTest, TestMultipleIPMergeNetworkList) {
358 BasicNetworkManager manager;
359 manager.SignalNetworksChanged.connect(
360 static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
361 NetworkManager::NetworkList original_list;
362 SetupNetworks(&original_list);
363 bool changed = false;
364 MergeNetworkList(manager, original_list, &changed);
365 EXPECT_TRUE(changed);
366 IPAddress ip;
367 IPAddress check_ip;
368 IPAddress prefix;
369 // Add a second IP to the public network on eth0 (2401:fa00:4:1000/64).
370 EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c6", &ip));
371 prefix = TruncateIP(ip, 64);
372 Network ipv6_eth0_publicnetwork1_ip2("test_eth0", "Test NetworkAdapter 1",
373 prefix, 64);
374 // This is the IP that already existed in the public network on eth0.
375 EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &check_ip));
376 ipv6_eth0_publicnetwork1_ip2.AddIP(ip);
377 original_list.push_back(new Network(ipv6_eth0_publicnetwork1_ip2));
378 changed = false;
379 MergeNetworkList(manager, original_list, &changed);
380 EXPECT_TRUE(changed);
381 // There should still be four networks.
382 NetworkManager::NetworkList list;
383 manager.GetNetworks(&list);
384 EXPECT_EQ(4U, list.size());
385 // Check the gathered IPs.
386 int matchcount = 0;
387 for (NetworkManager::NetworkList::iterator it = list.begin();
388 it != list.end(); ++it) {
389 if ((*it)->ToString() == original_list[2]->ToString()) {
390 ++matchcount;
391 EXPECT_EQ(1, matchcount);
392 // This should be the same network object as before.
393 EXPECT_EQ((*it), original_list[2]);
394 // But with two addresses now.
395 EXPECT_EQ(2U, (*it)->GetIPs().size());
396 EXPECT_NE((*it)->GetIPs().end(),
397 std::find((*it)->GetIPs().begin(),
398 (*it)->GetIPs().end(),
399 check_ip));
400 EXPECT_NE((*it)->GetIPs().end(),
401 std::find((*it)->GetIPs().begin(),
402 (*it)->GetIPs().end(),
403 ip));
404 } else {
405 // Check the IP didn't get added anywhere it wasn't supposed to.
406 EXPECT_EQ((*it)->GetIPs().end(),
407 std::find((*it)->GetIPs().begin(),
408 (*it)->GetIPs().end(),
409 ip));
410 }
411 }
412}
413
414// Test that merge correctly distinguishes multiple networks on an interface.
415TEST_F(NetworkTest, TestMultiplePublicNetworksOnOneInterfaceMerge) {
416 BasicNetworkManager manager;
417 manager.SignalNetworksChanged.connect(
418 static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
419 NetworkManager::NetworkList original_list;
420 SetupNetworks(&original_list);
421 bool changed = false;
422 MergeNetworkList(manager, original_list, &changed);
423 EXPECT_TRUE(changed);
424 IPAddress ip;
425 IPAddress prefix;
426 // A second network for eth0.
427 EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:5bff:fee5:c3", &ip));
428 prefix = TruncateIP(ip, 64);
429 Network ipv6_eth0_publicnetwork2_ip1("test_eth0", "Test NetworkAdapter 1",
430 prefix, 64);
431 ipv6_eth0_publicnetwork2_ip1.AddIP(ip);
432 original_list.push_back(new Network(ipv6_eth0_publicnetwork2_ip1));
433 changed = false;
434 MergeNetworkList(manager, original_list, &changed);
435 EXPECT_TRUE(changed);
436 // There should be five networks now.
437 NetworkManager::NetworkList list;
438 manager.GetNetworks(&list);
439 EXPECT_EQ(5U, list.size());
440 // Check the resulting addresses.
441 for (NetworkManager::NetworkList::iterator it = list.begin();
442 it != list.end(); ++it) {
443 if ((*it)->prefix() == ipv6_eth0_publicnetwork2_ip1.prefix() &&
444 (*it)->name() == ipv6_eth0_publicnetwork2_ip1.name()) {
445 // Check the new network has 1 IP and that it's the correct one.
446 EXPECT_EQ(1U, (*it)->GetIPs().size());
447 EXPECT_EQ(ip, (*it)->GetIPs().at(0));
448 } else {
449 // Check the IP didn't get added anywhere it wasn't supposed to.
450 EXPECT_EQ((*it)->GetIPs().end(),
451 std::find((*it)->GetIPs().begin(),
452 (*it)->GetIPs().end(),
453 ip));
454 }
455 }
456}
457
458// Test that DumpNetworks works.
459TEST_F(NetworkTest, TestDumpNetworks) {
460 BasicNetworkManager manager;
461 manager.DumpNetworks(true);
462}
463
464// Test that we can toggle IPv6 on and off.
465TEST_F(NetworkTest, TestIPv6Toggle) {
466 BasicNetworkManager manager;
467 bool ipv6_found = false;
468 NetworkManager::NetworkList list;
469#ifndef WIN32
470 // There should be at least one IPv6 network (fe80::/64 should be in there).
471 // TODO: Disabling this test on windows for the moment as the test
472 // machines don't seem to have IPv6 installed on them at all.
473 manager.set_ipv6_enabled(true);
474 list = GetNetworks(manager, true);
475 for (NetworkManager::NetworkList::iterator it = list.begin();
476 it != list.end(); ++it) {
477 if ((*it)->prefix().family() == AF_INET6) {
478 ipv6_found = true;
479 break;
480 }
481 }
482 EXPECT_TRUE(ipv6_found);
483#endif
484 ipv6_found = false;
485 manager.set_ipv6_enabled(false);
486 list = GetNetworks(manager, true);
487 for (NetworkManager::NetworkList::iterator it = list.begin();
488 it != list.end(); ++it) {
489 if ((*it)->prefix().family() == AF_INET6) {
490 ipv6_found = true;
491 break;
492 }
493 }
494 EXPECT_FALSE(ipv6_found);
495}
496
497#if defined(POSIX)
498// Verify that we correctly handle interfaces with no address.
499TEST_F(NetworkTest, TestConvertIfAddrsNoAddress) {
500 ifaddrs list;
501 memset(&list, 0, sizeof(list));
502 list.ifa_name = const_cast<char*>("test_iface");
503
504 NetworkManager::NetworkList result;
505 BasicNetworkManager manager;
506 CallConvertIfAddrs(manager, &list, true, &result);
507 EXPECT_TRUE(result.empty());
508}
509#endif // defined(POSIX)
510
511
512} // namespace talk_base