3
* Copyright 2004--2011, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
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.
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.
29
#include "talk/base/gunit.h"
30
#include "talk/base/network.h"
34
class NetworkTest : public testing::Test, public sigslot::has_slots<> {
36
NetworkTest() : callback_called_(false) {}
38
void OnNetworksChanged() {
39
callback_called_ = true;
42
void MergeNetworkList(BasicNetworkManager& network_manager,
43
const NetworkManager::NetworkList& list,
45
network_manager.MergeNetworkList(list, changed);
48
bool IsIgnoredNetwork(const Network& network) {
49
return BasicNetworkManager::IsIgnoredNetwork(network);
52
NetworkManager::NetworkList GetNetworks(
53
const BasicNetworkManager& network_manager, bool include_ignored) {
54
NetworkManager::NetworkList list;
55
network_manager.CreateNetworks(include_ignored, &list);
60
bool callback_called_;
63
// Test that the Network ctor works properly.
64
TEST_F(NetworkTest, TestNetworkConstruct) {
65
Network ipv4_network1("test_eth0", "Test Network Adapter 1",
66
IPAddress(0x12345600U), 24);
67
EXPECT_EQ("test_eth0", ipv4_network1.name());
68
EXPECT_EQ("Test Network Adapter 1", ipv4_network1.description());
69
EXPECT_EQ(IPAddress(0x12345600U), ipv4_network1.prefix());
70
EXPECT_EQ(24, ipv4_network1.prefix_length());
71
EXPECT_FALSE(ipv4_network1.ignored());
74
// Tests that our ignore function works properly.
75
TEST_F(NetworkTest, TestNetworkIgnore) {
76
Network ipv4_network1("test_eth0", "Test Network Adapter 1",
77
IPAddress(0x12345600U), 24);
78
Network ipv4_network2("test_eth1", "Test Network Adapter 2",
79
IPAddress(0x00010000U), 16);
80
EXPECT_FALSE(IsIgnoredNetwork(ipv4_network1));
81
EXPECT_TRUE(IsIgnoredNetwork(ipv4_network2));
84
TEST_F(NetworkTest, TestCreateNetworks) {
85
BasicNetworkManager manager;
86
NetworkManager::NetworkList result = GetNetworks(manager, true);
87
// We should be able to bind to any addresses we find.
88
NetworkManager::NetworkList::iterator it;
89
for (it = result.begin();
92
sockaddr_storage storage;
93
memset(&storage, 0, sizeof(storage));
94
IPAddress ip = (*it)->ip();
95
SocketAddress bindaddress(ip, 0);
96
bindaddress.SetScopeID((*it)->scope_id());
97
// TODO: Make this use talk_base::AsyncSocket once it supports IPv6.
98
int fd = static_cast<int>(socket(ip.family(), SOCK_STREAM, IPPROTO_TCP));
100
size_t ipsize = bindaddress.ToSockAddrStorage(&storage);
101
EXPECT_GE(ipsize, 0U);
102
int success = ::bind(fd,
103
reinterpret_cast<sockaddr*>(&storage),
104
static_cast<int>(ipsize));
105
EXPECT_EQ(0, success);
115
// Test that UpdateNetworks succeeds.
116
TEST_F(NetworkTest, TestUpdateNetworks) {
117
BasicNetworkManager manager;
118
manager.SignalNetworksChanged.connect(
119
static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
120
manager.StartUpdating();
121
Thread::Current()->ProcessMessages(0);
122
EXPECT_TRUE(callback_called_);
123
callback_called_ = false;
124
// Callback should be triggered immediately when StartUpdating
125
// is called, after network update signal is already sent.
126
manager.StartUpdating();
127
EXPECT_TRUE(manager.started());
128
Thread::Current()->ProcessMessages(0);
129
EXPECT_TRUE(callback_called_);
130
manager.StopUpdating();
131
EXPECT_TRUE(manager.started());
132
manager.StopUpdating();
133
EXPECT_FALSE(manager.started());
134
manager.StopUpdating();
135
EXPECT_FALSE(manager.started());
136
callback_called_ = false;
137
// Callback should be triggered immediately after StartUpdating is called
138
// when start_count_ is reset to 0.
139
manager.StartUpdating();
140
Thread::Current()->ProcessMessages(0);
141
EXPECT_TRUE(callback_called_);
144
// Verify that MergeNetworkList() merges network lists properly.
145
TEST_F(NetworkTest, TestBasicMergeNetworkList) {
146
Network ipv4_network1("test_eth0", "Test Network Adapter 1",
147
IPAddress(0x12345600U), 24);
148
Network ipv4_network2("test_eth1", "Test Network Adapter 2",
149
IPAddress(0x00010000U), 16);
150
ipv4_network1.AddIP(IPAddress(0x12345678));
151
ipv4_network2.AddIP(IPAddress(0x00010004));
152
BasicNetworkManager manager;
154
// Add ipv4_network1 to the list of networks.
155
NetworkManager::NetworkList list;
156
list.push_back(new Network(ipv4_network1));
158
MergeNetworkList(manager, list, &changed);
159
EXPECT_TRUE(changed);
162
manager.GetNetworks(&list);
163
EXPECT_EQ(1U, list.size());
164
EXPECT_EQ(ipv4_network1.ToString(), list[0]->ToString());
165
Network* net1 = list[0];
168
// Replace ipv4_network1 with ipv4_network2.
169
list.push_back(new Network(ipv4_network2));
170
MergeNetworkList(manager, list, &changed);
171
EXPECT_TRUE(changed);
174
manager.GetNetworks(&list);
175
EXPECT_EQ(1U, list.size());
176
EXPECT_EQ(ipv4_network2.ToString(), list[0]->ToString());
177
Network* net2 = list[0];
180
// Add Network2 back.
181
list.push_back(new Network(ipv4_network1));
182
list.push_back(new Network(ipv4_network2));
183
MergeNetworkList(manager, list, &changed);
184
EXPECT_TRUE(changed);
187
// Verify that we get previous instances of Network objects.
188
manager.GetNetworks(&list);
189
EXPECT_EQ(2U, list.size());
190
EXPECT_TRUE((net1 == list[0] && net2 == list[1]) ||
191
(net1 == list[1] && net2 == list[0]));
194
// Call MergeNetworkList() again and verify that we don't get update
196
list.push_back(new Network(ipv4_network2));
197
list.push_back(new Network(ipv4_network1));
198
MergeNetworkList(manager, list, &changed);
199
EXPECT_FALSE(changed);
202
// Verify that we get previous instances of Network objects.
203
manager.GetNetworks(&list);
204
EXPECT_EQ(2U, list.size());
205
EXPECT_TRUE((net1 == list[0] && net2 == list[1]) ||
206
(net1 == list[1] && net2 == list[0]));
210
// Sets up some test IPv6 networks and appends them to list.
211
// Four networks are added - public and link local, for two interfaces.
212
void SetupNetworks(NetworkManager::NetworkList* list) {
215
EXPECT_TRUE(IPFromString("fe80::1234:5678:abcd:ef12", &ip));
216
EXPECT_TRUE(IPFromString("fe80::", &prefix));
217
// First, fake link-locals.
218
Network ipv6_eth0_linklocalnetwork("test_eth0", "Test NetworkAdapter 1",
220
ipv6_eth0_linklocalnetwork.AddIP(ip);
221
EXPECT_TRUE(IPFromString("fe80::5678:abcd:ef12:3456", &ip));
222
Network ipv6_eth1_linklocalnetwork("test_eth1", "Test NetworkAdapter 2",
224
ipv6_eth1_linklocalnetwork.AddIP(ip);
226
EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &ip));
227
prefix = TruncateIP(ip, 64);
228
Network ipv6_eth0_publicnetwork1_ip1("test_eth0", "Test NetworkAdapter 1",
230
ipv6_eth0_publicnetwork1_ip1.AddIP(ip);
231
EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:abcd:efab:cdef", &ip));
232
prefix = TruncateIP(ip, 64);
233
Network ipv6_eth1_publicnetwork1_ip1("test_eth1", "Test NetworkAdapter 1",
235
ipv6_eth1_publicnetwork1_ip1.AddIP(ip);
236
list->push_back(new Network(ipv6_eth0_linklocalnetwork));
237
list->push_back(new Network(ipv6_eth1_linklocalnetwork));
238
list->push_back(new Network(ipv6_eth0_publicnetwork1_ip1));
239
list->push_back(new Network(ipv6_eth1_publicnetwork1_ip1));
242
// Test that the basic network merging case works.
243
TEST_F(NetworkTest, TestIPv6MergeNetworkList) {
244
BasicNetworkManager manager;
245
manager.SignalNetworksChanged.connect(
246
static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
247
NetworkManager::NetworkList original_list;
248
SetupNetworks(&original_list);
249
bool changed = false;
250
MergeNetworkList(manager, original_list, &changed);
251
EXPECT_TRUE(changed);
252
NetworkManager::NetworkList list;
253
manager.GetNetworks(&list);
254
EXPECT_EQ(original_list.size(), list.size());
255
// Verify that the original members are in the merged list.
256
for (NetworkManager::NetworkList::iterator it = original_list.begin();
257
it != original_list.end(); ++it) {
258
EXPECT_NE(list.end(), std::find(list.begin(), list.end(), *it));
262
// Tests that when two network lists that describe the same set of networks are
263
// merged, that the changed callback is not called, and that the original
264
// objects remain in the result list.
265
TEST_F(NetworkTest, TestNoChangeMerge) {
266
BasicNetworkManager manager;
267
manager.SignalNetworksChanged.connect(
268
static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
269
NetworkManager::NetworkList original_list;
270
SetupNetworks(&original_list);
271
bool changed = false;
272
MergeNetworkList(manager, original_list, &changed);
273
EXPECT_TRUE(changed);
274
// Second list that describes the same networks but with new objects.
275
NetworkManager::NetworkList second_list;
276
SetupNetworks(&second_list);
278
MergeNetworkList(manager, second_list, &changed);
279
EXPECT_FALSE(changed);
280
NetworkManager::NetworkList resulting_list;
281
manager.GetNetworks(&resulting_list);
282
EXPECT_EQ(original_list.size(), resulting_list.size());
283
// Verify that the original members are in the merged list.
284
for (NetworkManager::NetworkList::iterator it = original_list.begin();
285
it != original_list.end(); ++it) {
286
EXPECT_NE(resulting_list.end(),
287
std::find(resulting_list.begin(), resulting_list.end(), *it));
289
// Doublecheck that the new networks aren't in the list.
290
for (NetworkManager::NetworkList::iterator it = second_list.begin();
291
it != second_list.end(); ++it) {
292
EXPECT_EQ(resulting_list.end(),
293
std::find(resulting_list.begin(), resulting_list.end(), *it));
297
// Test that we can merge a network that is the same as another network but with
298
// a different IP. The original network should remain in the list, but have its
300
TEST_F(NetworkTest, MergeWithChangedIP) {
301
BasicNetworkManager manager;
302
manager.SignalNetworksChanged.connect(
303
static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
304
NetworkManager::NetworkList original_list;
305
SetupNetworks(&original_list);
306
// Make a network that we're going to change.
308
EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:faa:fee:faa", &ip));
309
IPAddress prefix = TruncateIP(ip, 64);
310
Network* network_to_change = new Network("test_eth0",
311
"Test Network Adapter 1",
313
Network* changed_network = new Network(*network_to_change);
314
network_to_change->AddIP(ip);
315
IPAddress changed_ip;
316
EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:f00:f00:f00", &changed_ip));
317
changed_network->AddIP(changed_ip);
318
original_list.push_back(network_to_change);
319
bool changed = false;
320
MergeNetworkList(manager, original_list, &changed);
321
NetworkManager::NetworkList second_list;
322
SetupNetworks(&second_list);
323
second_list.push_back(changed_network);
325
MergeNetworkList(manager, second_list, &changed);
326
EXPECT_TRUE(changed);
327
NetworkManager::NetworkList list;
328
manager.GetNetworks(&list);
329
EXPECT_EQ(original_list.size(), list.size());
330
// Make sure the original network is still in the merged list.
331
EXPECT_NE(list.end(),
332
std::find(list.begin(), list.end(), network_to_change));
333
EXPECT_EQ(changed_ip, network_to_change->GetIPs().at(0));
336
// Testing a similar case to above, but checking that a network can be updated
337
// with additional IPs (not just a replacement).
338
TEST_F(NetworkTest, TestMultipleIPMergeNetworkList) {
339
BasicNetworkManager manager;
340
manager.SignalNetworksChanged.connect(
341
static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
342
NetworkManager::NetworkList original_list;
343
SetupNetworks(&original_list);
344
bool changed = false;
345
MergeNetworkList(manager, original_list, &changed);
346
EXPECT_TRUE(changed);
350
// Add a second IP to the public network on eth0 (2401:fa00:4:1000/64).
351
EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c6", &ip));
352
prefix = TruncateIP(ip, 64);
353
Network ipv6_eth0_publicnetwork1_ip2("test_eth0", "Test NetworkAdapter 1",
355
// This is the IP that already existed in the public network on eth0.
356
EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &check_ip));
357
ipv6_eth0_publicnetwork1_ip2.AddIP(ip);
358
original_list.push_back(new Network(ipv6_eth0_publicnetwork1_ip2));
360
MergeNetworkList(manager, original_list, &changed);
361
EXPECT_TRUE(changed);
362
// There should still be four networks.
363
NetworkManager::NetworkList list;
364
manager.GetNetworks(&list);
365
EXPECT_EQ(4U, list.size());
366
// Check the gathered IPs.
368
for (NetworkManager::NetworkList::iterator it = list.begin();
369
it != list.end(); ++it) {
370
if ((*it)->ToString() == original_list[2]->ToString()) {
372
EXPECT_EQ(1, matchcount);
373
// This should be the same network object as before.
374
EXPECT_EQ((*it), original_list[2]);
375
// But with two addresses now.
376
EXPECT_EQ(2U, (*it)->GetIPs().size());
377
EXPECT_NE((*it)->GetIPs().end(),
378
std::find((*it)->GetIPs().begin(),
379
(*it)->GetIPs().end(),
381
EXPECT_NE((*it)->GetIPs().end(),
382
std::find((*it)->GetIPs().begin(),
383
(*it)->GetIPs().end(),
386
// Check the IP didn't get added anywhere it wasn't supposed to.
387
EXPECT_EQ((*it)->GetIPs().end(),
388
std::find((*it)->GetIPs().begin(),
389
(*it)->GetIPs().end(),
395
// Test that merge correctly distinguishes multiple networks on an interface.
396
TEST_F(NetworkTest, TestMultiplePublicNetworksOnOneInterfaceMerge) {
397
BasicNetworkManager manager;
398
manager.SignalNetworksChanged.connect(
399
static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
400
NetworkManager::NetworkList original_list;
401
SetupNetworks(&original_list);
402
bool changed = false;
403
MergeNetworkList(manager, original_list, &changed);
404
EXPECT_TRUE(changed);
407
// A second network for eth0.
408
EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:5bff:fee5:c3", &ip));
409
prefix = TruncateIP(ip, 64);
410
Network ipv6_eth0_publicnetwork2_ip1("test_eth0", "Test NetworkAdapter 1",
412
ipv6_eth0_publicnetwork2_ip1.AddIP(ip);
413
original_list.push_back(new Network(ipv6_eth0_publicnetwork2_ip1));
415
MergeNetworkList(manager, original_list, &changed);
416
EXPECT_TRUE(changed);
417
// There should be five networks now.
418
NetworkManager::NetworkList list;
419
manager.GetNetworks(&list);
420
EXPECT_EQ(5U, list.size());
421
// Check the resulting addresses.
422
for (NetworkManager::NetworkList::iterator it = list.begin();
423
it != list.end(); ++it) {
424
if ((*it)->prefix() == ipv6_eth0_publicnetwork2_ip1.prefix() &&
425
(*it)->name() == ipv6_eth0_publicnetwork2_ip1.name()) {
426
// Check the new network has 1 IP and that it's the correct one.
427
EXPECT_EQ(1U, (*it)->GetIPs().size());
428
EXPECT_EQ(ip, (*it)->GetIPs().at(0));
430
// Check the IP didn't get added anywhere it wasn't supposed to.
431
EXPECT_EQ((*it)->GetIPs().end(),
432
std::find((*it)->GetIPs().begin(),
433
(*it)->GetIPs().end(),
439
// Test that DumpNetworks works.
440
TEST_F(NetworkTest, TestDumpNetworks) {
441
BasicNetworkManager manager;
442
manager.DumpNetworks(true);
445
// Test that we can toggle IPv6 on and off.
446
TEST_F(NetworkTest, TestIPv6Toggle) {
447
BasicNetworkManager manager;
448
bool ipv6_found = false;
449
NetworkManager::NetworkList list;
451
// There should be at least one IPv6 network (fe80::/64 should be in there).
452
// TODO: Disabling this test on windows for the moment as the test
453
// machines don't seem to have IPv6 installed on them at all.
454
manager.set_ipv6_enabled(true);
455
list = GetNetworks(manager, true);
456
for (NetworkManager::NetworkList::iterator it = list.begin();
457
it != list.end(); ++it) {
458
if ((*it)->prefix().family() == AF_INET6) {
463
EXPECT_TRUE(ipv6_found);
466
manager.set_ipv6_enabled(false);
467
list = GetNetworks(manager, true);
468
for (NetworkManager::NetworkList::iterator it = list.begin();
469
it != list.end(); ++it) {
470
if ((*it)->prefix().family() == AF_INET6) {
475
EXPECT_FALSE(ipv6_found);
478
} // namespace talk_base