blob: 8b66b684524a349b4d1bf9a0f173beaab49715d1 [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartdd60e452011-08-08 11:38:36 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymocddd2d02014-11-10 19:55:35 -08005#include "shill/connection.h"
6
Paul Stewart9a908082011-08-31 12:18:48 -07007#include <arpa/inet.h>
8#include <linux/rtnetlink.h>
9
Ben Chan22f1fbc2014-10-17 14:18:07 -070010#include <memory>
Paul Stewartc8f4bef2011-12-13 09:45:51 -080011#include <string>
Paul Stewart9a908082011-08-31 12:18:48 -070012#include <vector>
13
Paul Stewartdd60e452011-08-08 11:38:36 -070014#include <gtest/gtest.h>
15#include <gmock/gmock.h>
16
Paul Stewartdd60e452011-08-08 11:38:36 -070017#include "shill/ipconfig.h"
Darin Petkov13e6d552012-05-09 14:22:23 +020018#include "shill/mock_connection.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070019#include "shill/mock_control.h"
Paul Stewartc8f4bef2011-12-13 09:45:51 -080020#include "shill/mock_device.h"
Paul Stewart9a908082011-08-31 12:18:48 -070021#include "shill/mock_device_info.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070022#include "shill/mock_resolver.h"
23#include "shill/mock_routing_table.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070024#include "shill/net/mock_rtnl_handler.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070025#include "shill/routing_table_entry.h"
26
Paul Stewartc8f4bef2011-12-13 09:45:51 -080027using std::string;
Paul Stewart9a908082011-08-31 12:18:48 -070028using std::vector;
Paul Stewartdd60e452011-08-08 11:38:36 -070029using testing::_;
Paul Stewarte78ec542012-06-08 18:28:50 -070030using testing::Mock;
Paul Stewartdd60e452011-08-08 11:38:36 -070031using testing::NiceMock;
32using testing::Return;
Paul Stewart4a6748d2012-07-17 14:31:36 -070033using testing::ReturnRef;
Paul Stewartdd60e452011-08-08 11:38:36 -070034using testing::StrictMock;
35using testing::Test;
36
37namespace shill {
38
39namespace {
40const char kTestDeviceName0[] = "netdev0";
41const int kTestDeviceInterfaceIndex0 = 123;
42const char kTestDeviceName1[] = "netdev1";
43const int kTestDeviceInterfaceIndex1 = 321;
44const char kIPAddress0[] = "192.168.1.1";
45const char kGatewayAddress0[] = "192.168.1.254";
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070046const char kGatewayAddress1[] = "192.168.2.254";
Paul Stewart9a908082011-08-31 12:18:48 -070047const char kBroadcastAddress0[] = "192.168.1.255";
Paul Stewartdd60e452011-08-08 11:38:36 -070048const char kNameServer0[] = "8.8.8.8";
49const char kNameServer1[] = "8.8.9.9";
Ben Chan7fab8972014-08-10 17:14:46 -070050const int32_t kPrefix0 = 24;
51const int32_t kPrefix1 = 31;
Paul Stewartdd60e452011-08-08 11:38:36 -070052const char kSearchDomain0[] = "chromium.org";
53const char kSearchDomain1[] = "google.com";
Peter Qiub25083f2014-08-25 13:22:31 -070054const char kIPv6Address[] = "2001:db8::1";
55const char kIPv6NameServer0[] = "2001:db9::1";
56const char kIPv6NameServer1[] = "2001:db9::2";
Ben Chana6bfe872012-09-26 09:48:34 -070057} // namespace
Paul Stewartdd60e452011-08-08 11:38:36 -070058
59class ConnectionTest : public Test {
60 public:
61 ConnectionTest()
Paul Stewart9a908082011-08-31 12:18:48 -070062 : device_info_(new StrictMock<MockDeviceInfo>(
63 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -070064 nullptr,
65 nullptr,
66 nullptr)),
Paul Stewart9a908082011-08-31 12:18:48 -070067 connection_(new Connection(
68 kTestDeviceInterfaceIndex0,
69 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -070070 Technology::kUnknown,
mukesh agrawal23ac6b72013-01-31 18:52:37 -080071 device_info_.get())),
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070072 ipconfig_(new IPConfig(&control_, kTestDeviceName0)),
Peter Qiub25083f2014-08-25 13:22:31 -070073 ip6config_(new IPConfig(&control_, kTestDeviceName0)),
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070074 local_address_(IPAddress::kFamilyIPv4),
75 broadcast_address_(IPAddress::kFamilyIPv4),
76 gateway_address_(IPAddress::kFamilyIPv4),
Peter Qiub25083f2014-08-25 13:22:31 -070077 default_address_(IPAddress::kFamilyIPv4),
78 local_ipv6_address_(IPAddress::kFamilyIPv6) {}
Paul Stewartdd60e452011-08-08 11:38:36 -070079
80 virtual void SetUp() {
Paul Stewartc8f4bef2011-12-13 09:45:51 -080081 ReplaceSingletons(connection_);
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070082 properties_.address = kIPAddress0;
83 properties_.subnet_prefix = kPrefix0;
84 properties_.gateway = kGatewayAddress0;
85 properties_.broadcast_address = kBroadcastAddress0;
86 properties_.dns_servers.push_back(kNameServer0);
87 properties_.dns_servers.push_back(kNameServer1);
88 properties_.domain_search.push_back(kSearchDomain0);
89 properties_.domain_search.push_back(kSearchDomain1);
90 properties_.address_family = IPAddress::kFamilyIPv4;
91 UpdateProperties();
Peter Qiub25083f2014-08-25 13:22:31 -070092 ipv6_properties_.address = kIPv6Address;
93 ipv6_properties_.dns_servers.push_back(kIPv6NameServer0);
94 ipv6_properties_.dns_servers.push_back(kIPv6NameServer1);
95 ipv6_properties_.address_family = IPAddress::kFamilyIPv6;
96 UpdateIPv6Properties();
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070097 EXPECT_TRUE(local_address_.SetAddressFromString(kIPAddress0));
98 EXPECT_TRUE(broadcast_address_.SetAddressFromString(kBroadcastAddress0));
99 EXPECT_TRUE(gateway_address_.SetAddressFromString(kGatewayAddress0));
Peter Qiub25083f2014-08-25 13:22:31 -0700100 EXPECT_TRUE(local_ipv6_address_.SetAddressFromString(kIPv6Address));
Paul Stewartdd60e452011-08-08 11:38:36 -0700101 }
102
Paul Stewart9a908082011-08-31 12:18:48 -0700103 virtual void TearDown() {
Darin Petkov13e6d552012-05-09 14:22:23 +0200104 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700105 connection_ = nullptr;
Paul Stewart9a908082011-08-31 12:18:48 -0700106 }
107
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800108 void ReplaceSingletons(ConnectionRefPtr connection) {
109 connection->resolver_ = &resolver_;
110 connection->routing_table_ = &routing_table_;
111 connection->rtnl_handler_ = &rtnl_handler_;
112 }
113
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700114 void UpdateProperties() {
Paul Stewartc5099532013-12-12 07:53:15 -0800115 ipconfig_->UpdateProperties(properties_);
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700116 }
117
Peter Qiub25083f2014-08-25 13:22:31 -0700118 void UpdateIPv6Properties() {
119 ip6config_->UpdateProperties(ipv6_properties_);
120 }
121
Paul Stewarte93b0382012-04-24 13:11:28 -0700122 bool PinHostRoute(ConnectionRefPtr connection,
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800123 const IPAddress trusted_ip,
124 const IPAddress gateway) {
125 return connection->PinHostRoute(trusted_ip, gateway);
Paul Stewarte93b0382012-04-24 13:11:28 -0700126 }
127
Paul Stewart4a6748d2012-07-17 14:31:36 -0700128 const IPAddress &GetLocalAddress(ConnectionRefPtr connection) {
129 return connection->local_;
130 }
131
132 const IPAddress &GetGatewayAddress(ConnectionRefPtr connection) {
133 return connection->gateway_;
134 }
135
136 bool GetHasBroadcastDomain(ConnectionRefPtr connection) {
137 return connection->has_broadcast_domain_;
138 }
139
Ben Chan7fab8972014-08-10 17:14:46 -0700140 uint32_t GetDefaultMetric() {
Paul Stewart05a42c22012-08-02 16:47:21 -0700141 return Connection::kDefaultMetric;
142 }
143
Ben Chan7fab8972014-08-10 17:14:46 -0700144 uint32_t GetNonDefaultMetricBase() {
Paul Stewart05a42c22012-08-02 16:47:21 -0700145 return Connection::kNonDefaultMetricBase;
146 }
147
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800148 void SetLocal(const IPAddress &local) {
149 connection_->local_ = local;
150 }
151
Paul Stewartdd60e452011-08-08 11:38:36 -0700152 protected:
Darin Petkov13e6d552012-05-09 14:22:23 +0200153 class DisconnectCallbackTarget {
154 public:
155 DisconnectCallbackTarget()
156 : callback_(base::Bind(&DisconnectCallbackTarget::CallTarget,
157 base::Unretained(this))) {}
158
159 MOCK_METHOD0(CallTarget, void());
160 const base::Closure &callback() { return callback_; }
161
162 private:
163 base::Closure callback_;
164 };
165
166 void AddDestructorExpectations() {
167 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
168 EXPECT_CALL(routing_table_, FlushRoutesWithTag(kTestDeviceInterfaceIndex0));
169 EXPECT_CALL(*device_info_.get(),
170 FlushAddresses(kTestDeviceInterfaceIndex0));
171 }
172
173 // Returns a new test connection object. The caller usually needs to call
174 // AddDestructorExpectations before destroying the object.
175 ConnectionRefPtr GetNewConnection() {
176 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
177 kTestDeviceName0,
178 Technology::kUnknown,
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800179 device_info_.get()));
Darin Petkov13e6d552012-05-09 14:22:23 +0200180 ReplaceSingletons(connection);
181 return connection;
182 }
183
Ben Chan22f1fbc2014-10-17 14:18:07 -0700184 std::unique_ptr<StrictMock<MockDeviceInfo>> device_info_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700185 ConnectionRefPtr connection_;
186 MockControl control_;
187 IPConfigRefPtr ipconfig_;
Peter Qiub25083f2014-08-25 13:22:31 -0700188 IPConfigRefPtr ip6config_;
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700189 IPConfig::Properties properties_;
Peter Qiub25083f2014-08-25 13:22:31 -0700190 IPConfig::Properties ipv6_properties_;
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700191 IPAddress local_address_;
192 IPAddress broadcast_address_;
193 IPAddress gateway_address_;
194 IPAddress default_address_;
Peter Qiub25083f2014-08-25 13:22:31 -0700195 IPAddress local_ipv6_address_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700196 StrictMock<MockResolver> resolver_;
197 StrictMock<MockRoutingTable> routing_table_;
198 StrictMock<MockRTNLHandler> rtnl_handler_;
199};
200
Darin Petkov13e6d552012-05-09 14:22:23 +0200201namespace {
Paul Stewartdd60e452011-08-08 11:38:36 -0700202
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700203MATCHER_P2(IsIPAddress, address, prefix, "") {
204 IPAddress match_address(address);
205 match_address.set_prefix(prefix);
206 return match_address.Equals(arg);
207}
208
Peter Qiub25083f2014-08-25 13:22:31 -0700209MATCHER_P(IsIPv6Address, address, "") {
210 IPAddress match_address(address);
211 return match_address.Equals(arg);
212}
213
Darin Petkov13e6d552012-05-09 14:22:23 +0200214MATCHER(IsNonNullCallback, "") {
215 return !arg.is_null();
216}
217
218} // namespace
219
220TEST_F(ConnectionTest, InitState) {
221 EXPECT_EQ(kTestDeviceInterfaceIndex0, connection_->interface_index_);
222 EXPECT_EQ(kTestDeviceName0, connection_->interface_name_);
223 EXPECT_FALSE(connection_->is_default());
224 EXPECT_FALSE(connection_->routing_request_count_);
225}
226
Paul Stewartdd60e452011-08-08 11:38:36 -0700227TEST_F(ConnectionTest, AddConfig) {
Paul Stewart05a42c22012-08-02 16:47:21 -0700228 EXPECT_CALL(*device_info_,
229 HasOtherAddress(kTestDeviceInterfaceIndex0,
230 IsIPAddress(local_address_, kPrefix0)))
231 .WillOnce(Return(false));
Paul Stewartdd60e452011-08-08 11:38:36 -0700232 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700233 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
234 IsIPAddress(local_address_, kPrefix0),
235 IsIPAddress(broadcast_address_, 0),
236 IsIPAddress(default_address_, 0)));
Paul Stewart7cfca042011-12-08 14:18:17 -0800237 EXPECT_CALL(routing_table_,
238 SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700239 IsIPAddress(gateway_address_, 0),
Paul Stewart05a42c22012-08-02 16:47:21 -0700240 GetNonDefaultMetricBase() +
Paul Stewart7cfca042011-12-08 14:18:17 -0800241 kTestDeviceInterfaceIndex0));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700242 EXPECT_CALL(routing_table_,
243 ConfigureRoutes(kTestDeviceInterfaceIndex0,
244 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700245 GetDefaultMetric()));
Paul Stewartdd60e452011-08-08 11:38:36 -0700246 connection_->UpdateFromIPConfig(ipconfig_);
Paul Stewart4a6748d2012-07-17 14:31:36 -0700247 IPAddress test_local_address(local_address_);
248 test_local_address.set_prefix(kPrefix0);
249 EXPECT_TRUE(test_local_address.Equals(GetLocalAddress(connection_)));
250 EXPECT_TRUE(gateway_address_.Equals(GetGatewayAddress(connection_)));
251 EXPECT_TRUE(GetHasBroadcastDomain(connection_));
Peter Qiub25083f2014-08-25 13:22:31 -0700252 EXPECT_FALSE(connection_->IsIPv6());
Paul Stewart4a6748d2012-07-17 14:31:36 -0700253
254 EXPECT_CALL(routing_table_,
255 CreateLinkRoute(kTestDeviceInterfaceIndex0,
256 IsIPAddress(local_address_, kPrefix0),
257 IsIPAddress(gateway_address_, 0)))
258 .WillOnce(Return(true))
259 .WillOnce(Return(false));
260 EXPECT_TRUE(connection_->CreateGatewayRoute());
261 EXPECT_FALSE(connection_->CreateGatewayRoute());
262 connection_->has_broadcast_domain_ = false;
263 EXPECT_FALSE(connection_->CreateGatewayRoute());
Paul Stewartdd60e452011-08-08 11:38:36 -0700264
265 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
Paul Stewart05a42c22012-08-02 16:47:21 -0700266 GetDefaultMetric()));
Paul Stewartdd60e452011-08-08 11:38:36 -0700267 EXPECT_CALL(resolver_, SetDNSFromLists(
268 ipconfig_->properties().dns_servers,
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800269 ipconfig_->properties().domain_search));
Paul Stewartdd60e452011-08-08 11:38:36 -0700270
Paul Stewartc681fa02012-03-02 19:40:04 -0800271 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
272 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700273 nullptr,
274 nullptr,
275 nullptr,
Paul Stewartc681fa02012-03-02 19:40:04 -0800276 kTestDeviceName0,
277 string(),
278 kTestDeviceInterfaceIndex0));
279 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
280 .WillOnce(Return(device));
281 EXPECT_CALL(*device.get(), RequestPortalDetection())
282 .WillOnce(Return(true));
Paul Stewarte78ec542012-06-08 18:28:50 -0700283 EXPECT_CALL(routing_table_, FlushCache())
284 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800285 connection_->SetIsDefault(true);
Paul Stewarte78ec542012-06-08 18:28:50 -0700286 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700287 EXPECT_TRUE(connection_->is_default());
288
Paul Stewart7cfca042011-12-08 14:18:17 -0800289 EXPECT_CALL(routing_table_,
290 SetDefaultMetric(kTestDeviceInterfaceIndex0,
Paul Stewart05a42c22012-08-02 16:47:21 -0700291 GetNonDefaultMetricBase() +
Paul Stewart7cfca042011-12-08 14:18:17 -0800292 kTestDeviceInterfaceIndex0));
Paul Stewarte78ec542012-06-08 18:28:50 -0700293 EXPECT_CALL(routing_table_, FlushCache())
294 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800295 connection_->SetIsDefault(false);
Paul Stewartdd60e452011-08-08 11:38:36 -0700296 EXPECT_FALSE(connection_->is_default());
297}
298
Peter Qiub25083f2014-08-25 13:22:31 -0700299TEST_F(ConnectionTest, AddConfigIPv6) {
300 EXPECT_CALL(*device_info_,
301 HasOtherAddress(kTestDeviceInterfaceIndex0,
302 IsIPv6Address(local_ipv6_address_)))
303 .WillOnce(Return(false));
304 EXPECT_CALL(rtnl_handler_,
305 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
306 IsIPv6Address(local_ipv6_address_),
307 _,
308 _));
309 EXPECT_CALL(routing_table_,
310 ConfigureRoutes(kTestDeviceInterfaceIndex0,
311 ip6config_,
312 GetDefaultMetric()));
313 connection_->UpdateFromIPConfig(ip6config_);
314 IPAddress test_local_address(local_ipv6_address_);
315 EXPECT_TRUE(test_local_address.Equals(GetLocalAddress(connection_)));
316 EXPECT_TRUE(connection_->IsIPv6());
317}
318
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700319TEST_F(ConnectionTest, AddConfigWithPeer) {
320 const string kPeerAddress("192.168.1.222");
321 IPAddress peer_address(IPAddress::kFamilyIPv4);
322 EXPECT_TRUE(peer_address.SetAddressFromString(kPeerAddress));
323 properties_.peer_address = kPeerAddress;
324 properties_.gateway = string();
325 UpdateProperties();
Paul Stewart05a42c22012-08-02 16:47:21 -0700326 EXPECT_CALL(*device_info_,
327 HasOtherAddress(kTestDeviceInterfaceIndex0,
328 IsIPAddress(local_address_, kPrefix0)))
329 .WillOnce(Return(false));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700330 EXPECT_CALL(rtnl_handler_,
331 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
332 IsIPAddress(local_address_, kPrefix0),
333 IsIPAddress(broadcast_address_, 0),
334 IsIPAddress(peer_address, 0)));
335 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _)).Times(0);
336 EXPECT_CALL(routing_table_,
337 ConfigureRoutes(kTestDeviceInterfaceIndex0,
338 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700339 GetDefaultMetric()));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700340 connection_->UpdateFromIPConfig(ipconfig_);
Paul Stewart4a6748d2012-07-17 14:31:36 -0700341 EXPECT_FALSE(GetHasBroadcastDomain(connection_));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700342}
343
344TEST_F(ConnectionTest, AddConfigWithBrokenNetmask) {
345 // Assign a prefix that makes the gateway unreachable.
346 properties_.subnet_prefix = kPrefix1;
347 UpdateProperties();
348
349 // Connection should override with a prefix which will allow the
350 // gateway to be reachable.
Paul Stewart05a42c22012-08-02 16:47:21 -0700351 EXPECT_CALL(*device_info_,
352 HasOtherAddress(kTestDeviceInterfaceIndex0,
353 IsIPAddress(local_address_, kPrefix0)))
354 .WillOnce(Return(false));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700355 EXPECT_CALL(rtnl_handler_,
356 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
357 IsIPAddress(local_address_, kPrefix0),
358 IsIPAddress(broadcast_address_, 0),
359 IsIPAddress(default_address_, 0)));
360 EXPECT_CALL(routing_table_,
361 SetDefaultRoute(kTestDeviceInterfaceIndex0,
362 IsIPAddress(gateway_address_, 0),
Paul Stewart05a42c22012-08-02 16:47:21 -0700363 GetNonDefaultMetricBase() +
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700364 kTestDeviceInterfaceIndex0));
365 EXPECT_CALL(routing_table_,
366 ConfigureRoutes(kTestDeviceInterfaceIndex0,
367 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700368 GetDefaultMetric()));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700369 connection_->UpdateFromIPConfig(ipconfig_);
370
371 // Assign a gateway address that violates the minimum plausible prefix
372 // the Connection can assign.
373 properties_.gateway = kGatewayAddress1;
374 UpdateProperties();
375
Paul Stewart49258292012-05-26 06:37:14 -0700376 IPAddress gateway_address1(IPAddress::kFamilyIPv4);
377 EXPECT_TRUE(gateway_address1.SetAddressFromString(kGatewayAddress1));
378 // Connection cannot override this prefix, so it will switch to a
379 // model where the peer address is set to the value of the gateway
380 // address.
Paul Stewart05a42c22012-08-02 16:47:21 -0700381 EXPECT_CALL(*device_info_,
382 HasOtherAddress(kTestDeviceInterfaceIndex0,
383 IsIPAddress(local_address_, kPrefix1)))
384 .WillOnce(Return(false));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700385 EXPECT_CALL(rtnl_handler_,
386 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
387 IsIPAddress(local_address_, kPrefix1),
388 IsIPAddress(broadcast_address_, 0),
Paul Stewart49258292012-05-26 06:37:14 -0700389 IsIPAddress(gateway_address1, 0)));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700390 EXPECT_CALL(routing_table_,
391 SetDefaultRoute(kTestDeviceInterfaceIndex0, _, _));
392 EXPECT_CALL(routing_table_,
393 ConfigureRoutes(kTestDeviceInterfaceIndex0, _, _));
394 connection_->UpdateFromIPConfig(ipconfig_);
395}
396
Paul Stewartdd60e452011-08-08 11:38:36 -0700397TEST_F(ConnectionTest, AddConfigReverse) {
398 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
Paul Stewart05a42c22012-08-02 16:47:21 -0700399 GetDefaultMetric()));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800400 vector<string> empty_list;
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800401 EXPECT_CALL(resolver_, SetDNSFromLists(empty_list, empty_list));
Paul Stewartc681fa02012-03-02 19:40:04 -0800402 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
403 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700404 nullptr,
405 nullptr,
406 nullptr,
Paul Stewartc681fa02012-03-02 19:40:04 -0800407 kTestDeviceName0,
408 string(),
409 kTestDeviceInterfaceIndex0));
410 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
411 .WillOnce(Return(device));
412 EXPECT_CALL(*device.get(), RequestPortalDetection())
413 .WillOnce(Return(true));
Paul Stewarte78ec542012-06-08 18:28:50 -0700414 EXPECT_CALL(routing_table_, FlushCache())
415 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800416 connection_->SetIsDefault(true);
Paul Stewarte78ec542012-06-08 18:28:50 -0700417 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700418
Paul Stewart05a42c22012-08-02 16:47:21 -0700419 EXPECT_CALL(*device_info_,
420 HasOtherAddress(kTestDeviceInterfaceIndex0,
421 IsIPAddress(local_address_, kPrefix0)))
422 .WillOnce(Return(false));
Paul Stewartdd60e452011-08-08 11:38:36 -0700423 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700424 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
425 IsIPAddress(local_address_, kPrefix0),
426 IsIPAddress(broadcast_address_, 0),
427 IsIPAddress(default_address_, 0)));
Paul Stewartdd60e452011-08-08 11:38:36 -0700428 EXPECT_CALL(routing_table_, SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700429 IsIPAddress(gateway_address_, 0),
Paul Stewart05a42c22012-08-02 16:47:21 -0700430 GetDefaultMetric()));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700431 EXPECT_CALL(routing_table_,
432 ConfigureRoutes(kTestDeviceInterfaceIndex0,
433 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700434 GetDefaultMetric()));
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800435 EXPECT_CALL(resolver_,
436 SetDNSFromLists(ipconfig_->properties().dns_servers,
437 ipconfig_->properties().domain_search));
Paul Stewartdd60e452011-08-08 11:38:36 -0700438
439 connection_->UpdateFromIPConfig(ipconfig_);
440}
441
Paul Stewart4d1868b2012-09-10 11:58:46 -0700442TEST_F(ConnectionTest, AddConfigWithDNSDomain) {
443 const string kDomainName("chromium.org");
444 properties_.domain_search.clear();
445 properties_.domain_name = kDomainName;
446 UpdateProperties();
447 EXPECT_CALL(*device_info_, HasOtherAddress(_, _))
448 .WillOnce(Return(false));
449 EXPECT_CALL(rtnl_handler_, AddInterfaceAddress(_, _, _, _));
450 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _));
451 EXPECT_CALL(routing_table_, ConfigureRoutes(_, _, _));
452 connection_->UpdateFromIPConfig(ipconfig_);
453
454 EXPECT_CALL(routing_table_, SetDefaultMetric(_, _));
455 vector<string> domain_search_list;
456 domain_search_list.push_back(kDomainName + ".");
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800457 EXPECT_CALL(resolver_, SetDNSFromLists(_, domain_search_list));
Paul Stewart4d1868b2012-09-10 11:58:46 -0700458 DeviceRefPtr device;
459 EXPECT_CALL(*device_info_, GetDevice(_)).WillOnce(Return(device));
460 EXPECT_CALL(routing_table_, FlushCache()).WillOnce(Return(true));
461 connection_->SetIsDefault(true);
462}
463
Paul Stewart05a42c22012-08-02 16:47:21 -0700464TEST_F(ConnectionTest, HasOtherAddress) {
465 EXPECT_CALL(*device_info_,
466 HasOtherAddress(kTestDeviceInterfaceIndex0,
467 IsIPAddress(local_address_, kPrefix0)))
468 .WillOnce(Return(true));
469 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
470 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex0));
471 EXPECT_CALL(rtnl_handler_,
472 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
473 IsIPAddress(local_address_, kPrefix0),
474 IsIPAddress(broadcast_address_, 0),
475 IsIPAddress(default_address_, 0)));
476 EXPECT_CALL(routing_table_,
477 SetDefaultRoute(kTestDeviceInterfaceIndex0,
478 IsIPAddress(gateway_address_, 0),
479 GetNonDefaultMetricBase() +
480 kTestDeviceInterfaceIndex0));
481 EXPECT_CALL(routing_table_,
482 ConfigureRoutes(kTestDeviceInterfaceIndex0,
483 ipconfig_,
484 GetDefaultMetric()));
485 connection_->UpdateFromIPConfig(ipconfig_);
486}
487
Peter Qiua89154b2014-05-23 15:45:42 -0700488TEST_F(ConnectionTest, UpdateDNSServers) {
489 const char* kDnsServers[] = {"1.1.1.1", "1.1.1.2"};
490 vector<string> dns_servers(kDnsServers, std::end(kDnsServers));
491
492 // Non-default connection.
493 connection_->is_default_ = false;
494 EXPECT_CALL(resolver_, SetDNSFromLists(_, _)).Times(0);
495 connection_->UpdateDNSServers(dns_servers);
496 Mock::VerifyAndClearExpectations(&resolver_);
497
498 // Default connection.
499 connection_->is_default_ = true;
500 EXPECT_CALL(resolver_, SetDNSFromLists(dns_servers, _));
501 connection_->UpdateDNSServers(dns_servers);
502 Mock::VerifyAndClearExpectations(&resolver_);
503}
504
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800505TEST_F(ConnectionTest, RouteRequest) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200506 ConnectionRefPtr connection = GetNewConnection();
Paul Stewartf748a362012-03-07 12:01:20 -0800507 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
508 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700509 nullptr,
510 nullptr,
511 nullptr,
Paul Stewartf748a362012-03-07 12:01:20 -0800512 kTestDeviceName0,
513 string(),
514 kTestDeviceInterfaceIndex0));
515 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
516 .WillRepeatedly(Return(device));
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800517 EXPECT_CALL(*device.get(), SetLooseRouting(true)).Times(1);
Paul Stewartf748a362012-03-07 12:01:20 -0800518 connection->RequestRouting();
519 connection->RequestRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800520
Paul Stewartf748a362012-03-07 12:01:20 -0800521 // The first release should only decrement the reference counter.
522 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800523
Paul Stewartf748a362012-03-07 12:01:20 -0800524 // Another release will re-enable reverse-path filter.
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800525 EXPECT_CALL(*device.get(), SetLooseRouting(false));
Paul Stewartf748a362012-03-07 12:01:20 -0800526 EXPECT_CALL(routing_table_, FlushCache());
527 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800528
Paul Stewartf748a362012-03-07 12:01:20 -0800529 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200530 AddDestructorExpectations();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800531}
532
Paul Stewartdd60e452011-08-08 11:38:36 -0700533TEST_F(ConnectionTest, Destructor) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200534 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex1,
535 kTestDeviceName1,
536 Technology::kUnknown,
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800537 device_info_.get()));
Darin Petkov13e6d552012-05-09 14:22:23 +0200538 connection->resolver_ = &resolver_;
539 connection->routing_table_ = &routing_table_;
540 connection->rtnl_handler_ = &rtnl_handler_;
Thieu Lefb46caf2012-03-08 11:57:15 -0800541 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex1));
Paul Stewarte93b0382012-04-24 13:11:28 -0700542 EXPECT_CALL(routing_table_, FlushRoutesWithTag(kTestDeviceInterfaceIndex1));
Paul Stewart9a908082011-08-31 12:18:48 -0700543 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex1));
Ben Chancc225ef2014-09-30 13:26:51 -0700544 connection = nullptr;
Paul Stewartdd60e452011-08-08 11:38:36 -0700545}
546
Paul Stewartf748a362012-03-07 12:01:20 -0800547TEST_F(ConnectionTest, RequestHostRoute) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200548 ConnectionRefPtr connection = GetNewConnection();
Paul Stewartf748a362012-03-07 12:01:20 -0800549 IPAddress address(IPAddress::kFamilyIPv4);
550 ASSERT_TRUE(address.SetAddressFromString(kIPAddress0));
551 size_t prefix_len = address.GetLength() * 8;
Darin Petkov13e6d552012-05-09 14:22:23 +0200552 EXPECT_CALL(routing_table_,
553 RequestRouteToHost(IsIPAddress(address, prefix_len),
554 -1,
555 kTestDeviceInterfaceIndex0,
556 IsNonNullCallback()))
Paul Stewartf748a362012-03-07 12:01:20 -0800557 .WillOnce(Return(true));
558 EXPECT_TRUE(connection->RequestHostRoute(address));
559
560 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200561 AddDestructorExpectations();
Paul Stewarte93b0382012-04-24 13:11:28 -0700562}
563
Ben Chana0163122012-09-25 15:10:52 -0700564TEST_F(ConnectionTest, BlackholeIPv6) {
565 properties_.blackhole_ipv6 = true;
566 UpdateProperties();
567 EXPECT_CALL(*device_info_, HasOtherAddress(_, _))
568 .WillOnce(Return(false));
569 EXPECT_CALL(rtnl_handler_, AddInterfaceAddress(_, _, _, _));
570 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _));
571 EXPECT_CALL(routing_table_, ConfigureRoutes(_, _, _));
572 EXPECT_CALL(routing_table_,
573 CreateBlackholeRoute(kTestDeviceInterfaceIndex0,
574 IPAddress::kFamilyIPv6,
575 Connection::kDefaultMetric))
576 .WillOnce(Return(true));
577 connection_->UpdateFromIPConfig(ipconfig_);
578}
579
Paul Stewarte93b0382012-04-24 13:11:28 -0700580TEST_F(ConnectionTest, PinHostRoute) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200581 ConnectionRefPtr connection = GetNewConnection();
Paul Stewarte93b0382012-04-24 13:11:28 -0700582
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800583 IPAddress gateway(IPAddress::kFamilyIPv4);
584 IPAddress trusted_ip(IPAddress::kFamilyIPv4);
Paul Stewarte93b0382012-04-24 13:11:28 -0700585
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800586 // Should fail because neither IP address is set.
587 EXPECT_FALSE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700588
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800589 static const char kGateway[] = "10.242.2.13";
590 ASSERT_TRUE(gateway.SetAddressFromString(kGateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700591
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800592 // Should fail because trusted IP is not set.
593 EXPECT_FALSE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700594
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800595 static const char kTrustedIP[] = "10.0.1.1";
596 ASSERT_TRUE(trusted_ip.SetAddressFromString(kTrustedIP));
597
Paul Stewarte435d342013-09-27 16:41:00 -0700598 // Should pass without calling RequestRouteToHost since if the gateway
599 // is not set, there is no work to be done.
600 EXPECT_CALL(routing_table_, RequestRouteToHost(_, _, _, _)).Times(0);
601 EXPECT_TRUE(PinHostRoute(connection, trusted_ip,
602 IPAddress(gateway.family())));
603 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800604
605 size_t prefix_len = IPAddress::GetMaxPrefixLength(trusted_ip.family());
Paul Stewarte93b0382012-04-24 13:11:28 -0700606 EXPECT_CALL(routing_table_, RequestRouteToHost(
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800607 IsIPAddress(trusted_ip, prefix_len), -1, kTestDeviceInterfaceIndex0, _))
Paul Stewarte93b0382012-04-24 13:11:28 -0700608 .WillOnce(Return(false));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800609 EXPECT_FALSE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700610
611 EXPECT_CALL(routing_table_, RequestRouteToHost(
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800612 IsIPAddress(trusted_ip, prefix_len), -1, kTestDeviceInterfaceIndex0, _))
Paul Stewarte93b0382012-04-24 13:11:28 -0700613 .WillOnce(Return(true));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800614 EXPECT_TRUE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700615
616 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200617 AddDestructorExpectations();
Paul Stewartf748a362012-03-07 12:01:20 -0800618}
619
Paul Stewart53a30382012-04-26 09:06:59 -0700620TEST_F(ConnectionTest, FixGatewayReachability) {
621 static const char kLocal[] = "10.242.2.13";
622 IPAddress local(IPAddress::kFamilyIPv4);
623 ASSERT_TRUE(local.SetAddressFromString(kLocal));
624 const int kPrefix = 24;
625 local.set_prefix(kPrefix);
626 IPAddress gateway(IPAddress::kFamilyIPv4);
627 IPAddress peer(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800628 IPAddress trusted_ip(IPAddress::kFamilyIPv4);
Paul Stewart53a30382012-04-26 09:06:59 -0700629
630 // Should fail because no gateway is set.
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800631 EXPECT_FALSE(Connection::FixGatewayReachability(
632 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700633 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700634 EXPECT_FALSE(peer.IsValid());
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800635 EXPECT_FALSE(gateway.IsValid());
Paul Stewart53a30382012-04-26 09:06:59 -0700636
637 // Should succeed because with the given prefix, this gateway is reachable.
638 static const char kReachableGateway[] = "10.242.2.14";
639 ASSERT_TRUE(gateway.SetAddressFromString(kReachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800640 IPAddress gateway_backup(gateway);
Paul Stewart49258292012-05-26 06:37:14 -0700641 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800642 EXPECT_TRUE(Connection::FixGatewayReachability(
643 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700644 // Prefix should remain unchanged.
645 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700646 // Peer should remain unchanged.
647 EXPECT_FALSE(peer.IsValid());
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800648 // Gateway should remain unchanged.
649 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700650
651 // Should succeed because we modified the prefix to match the gateway.
652 static const char kExpandableGateway[] = "10.242.3.14";
653 ASSERT_TRUE(gateway.SetAddressFromString(kExpandableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800654 gateway_backup = gateway;
Paul Stewart49258292012-05-26 06:37:14 -0700655 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800656 EXPECT_TRUE(Connection::FixGatewayReachability(
657 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700658 // Prefix should have opened up by 1 bit.
659 EXPECT_EQ(kPrefix - 1, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700660 // Peer should remain unchanged.
661 EXPECT_FALSE(peer.IsValid());
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800662 // Gateway should remain unchanged.
663 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700664
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700665 // Should change models to assuming point-to-point because we cannot
Paul Stewart49258292012-05-26 06:37:14 -0700666 // plausibly expand the prefix past 8.
Paul Stewart53a30382012-04-26 09:06:59 -0700667 local.set_prefix(kPrefix);
668 static const char kUnreachableGateway[] = "11.242.2.14";
669 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800670 gateway_backup = gateway;
Paul Stewart49258292012-05-26 06:37:14 -0700671 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800672 EXPECT_TRUE(Connection::FixGatewayReachability(
673 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700674 // Prefix should not have changed.
675 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700676 // Peer address should be set to the gateway address.
677 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800678 // Gateway should remain unchanged.
679 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700680
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700681 // Should also use point-to-point model if the netmask is set to the
682 // "all-ones" addresss, even if this address could have been made
683 // accessible by plausibly changing the prefix.
684 const int kIPv4MaxPrefix =
685 IPAddress::GetMaxPrefixLength(IPAddress::kFamilyIPv4);
686 local.set_prefix(kIPv4MaxPrefix);
687 ASSERT_TRUE(gateway.SetAddressFromString(kExpandableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800688 gateway_backup = gateway;
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700689 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800690 EXPECT_TRUE(Connection::FixGatewayReachability(
691 &local, &peer, &gateway, trusted_ip));
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700692 // Prefix should not have changed.
693 EXPECT_EQ(kIPv4MaxPrefix, local.prefix());
694 // Peer address should be set to the gateway address.
695 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800696 // Gateway should remain unchanged.
697 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700698
Paul Stewart49258292012-05-26 06:37:14 -0700699 // If this is a peer-to-peer interface and the peer matches the gateway,
700 // we should succeed.
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700701 local.set_prefix(kPrefix);
702 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800703 gateway_backup = gateway;
Paul Stewart53a30382012-04-26 09:06:59 -0700704 ASSERT_TRUE(peer.SetAddressFromString(kUnreachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800705 EXPECT_TRUE(Connection::FixGatewayReachability(
706 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700707 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700708 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800709 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700710
711 // If there is a peer specified and it does not match the gateway (even
712 // if it was reachable via netmask), we should fail.
713 ASSERT_TRUE(gateway.SetAddressFromString(kReachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800714 EXPECT_FALSE(Connection::FixGatewayReachability(
715 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700716 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700717 EXPECT_FALSE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800718
719 // If this is a peer-to-peer interface and the peer matches the gateway,
720 // but it also matches the trusted IP address, the gateway and peer address
721 // should be modified to allow routing to work correctly.
722 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
723 ASSERT_TRUE(peer.SetAddressFromString(kUnreachableGateway));
724 ASSERT_TRUE(trusted_ip.SetAddressFromString(kUnreachableGateway));
725 EXPECT_TRUE(Connection::FixGatewayReachability(
726 &local, &peer, &gateway, trusted_ip));
727 EXPECT_TRUE(peer.IsDefault());
728 EXPECT_TRUE(gateway.IsDefault());
Paul Stewart53a30382012-04-26 09:06:59 -0700729}
730
Darin Petkov13e6d552012-05-09 14:22:23 +0200731TEST_F(ConnectionTest, Binders) {
732 EXPECT_TRUE(connection_->binders_.empty());
733 DisconnectCallbackTarget target0;
734 DisconnectCallbackTarget target1;
735 DisconnectCallbackTarget target2;
736 DisconnectCallbackTarget target3;
737 Connection::Binder binder0("binder0", target0.callback());
738 Connection::Binder binder1("binder1", target1.callback());
739 Connection::Binder binder2("binder2", target2.callback());
740 Connection::Binder binder3("binder3", target3.callback());
741
742 binder0.Attach(connection_);
743 binder1.Attach(connection_);
744
745 EXPECT_CALL(target1, CallTarget()).Times(0);
746 binder1.Attach(connection_);
747
748 binder3.Attach(connection_);
749 binder2.Attach(connection_);
750
751 EXPECT_CALL(target3, CallTarget()).Times(0);
Ben Chancc225ef2014-09-30 13:26:51 -0700752 binder3.Attach(nullptr);
Darin Petkov13e6d552012-05-09 14:22:23 +0200753
754 ASSERT_EQ(3, connection_->binders_.size());
755 EXPECT_TRUE(connection_->binders_.at(0) == &binder0);
756 EXPECT_TRUE(connection_->binders_.at(1) == &binder1);
757 EXPECT_TRUE(connection_->binders_.at(2) == &binder2);
758
759 EXPECT_CALL(target0, CallTarget()).Times(1);
760 EXPECT_CALL(target1, CallTarget()).Times(1);
761 EXPECT_CALL(target2, CallTarget()).Times(1);
762 connection_->NotifyBindersOnDisconnect();
763 EXPECT_TRUE(connection_->binders_.empty());
764
765 // Should be a no-op.
766 connection_->NotifyBindersOnDisconnect();
767}
768
769TEST_F(ConnectionTest, Binder) {
770 // No connection should be bound initially.
771 Connection::Binder *binder = &connection_->lower_binder_;
772 EXPECT_EQ(connection_->interface_name(), binder->name_);
773 EXPECT_FALSE(binder->client_disconnect_callback_.is_null());
774 EXPECT_FALSE(binder->IsBound());
775
776 ConnectionRefPtr connection1 = GetNewConnection();
777 EXPECT_TRUE(connection1->binders_.empty());
778
779 // Bind lower |connection1| and check if it's bound.
780 binder->Attach(connection1);
781 EXPECT_TRUE(binder->IsBound());
782 EXPECT_EQ(connection1.get(), binder->connection().get());
783 ASSERT_FALSE(connection1->binders_.empty());
784 EXPECT_TRUE(binder == connection1->binders_.at(0));
785
786 // Unbind lower |connection1| and check if it's unbound.
Ben Chancc225ef2014-09-30 13:26:51 -0700787 binder->Attach(nullptr);
Darin Petkov13e6d552012-05-09 14:22:23 +0200788 EXPECT_FALSE(binder->IsBound());
789 EXPECT_TRUE(connection1->binders_.empty());
790
791 ConnectionRefPtr connection2 = GetNewConnection();
792
793 // Bind lower |connection1| to upper |connection2| and destroy the upper
794 // |connection2|. Make sure lower |connection1| is unbound (i.e., the
795 // disconnect callback is deregistered).
796 connection2->lower_binder_.Attach(connection1);
797 EXPECT_FALSE(connection1->binders_.empty());
798 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700799 connection2 = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200800 EXPECT_TRUE(connection1->binders_.empty());
801
802 // Bind lower |connection1| to upper |connection_| and destroy lower
803 // |connection1|. Make sure lower |connection1| is unbound from upper
804 // |connection_| and upper |connection_|'s registered disconnect callbacks are
805 // run.
806 binder->Attach(connection1);
807 DisconnectCallbackTarget target;
808 Connection::Binder test_binder("from_test", target.callback());
809 test_binder.Attach(connection_);
810 EXPECT_CALL(target, CallTarget()).Times(1);
811 ASSERT_FALSE(connection_->binders_.empty());
812 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700813 connection1 = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200814 EXPECT_FALSE(binder->IsBound());
815 EXPECT_FALSE(test_binder.IsBound());
816 EXPECT_TRUE(connection_->binders_.empty());
817
818 {
819 // Binding a connection to itself should be safe.
820 ConnectionRefPtr connection = GetNewConnection();
821
822 connection->lower_binder_.Attach(connection);
823
824 EXPECT_FALSE(connection->binders_.empty());
825
826 DisconnectCallbackTarget target;
827 Connection::Binder binder("test", target.callback());
828 binder.Attach(connection);
829
830 AddDestructorExpectations();
831 EXPECT_CALL(target, CallTarget()).Times(1);
Ben Chancc225ef2014-09-30 13:26:51 -0700832 connection = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200833 }
Darin Petkov13e6d552012-05-09 14:22:23 +0200834 {
835 // Circular binding of multiple connections should be safe.
836 ConnectionRefPtr connection_a = GetNewConnection();
837 ConnectionRefPtr connection_b = GetNewConnection();
838
839 connection_a->lower_binder_.Attach(connection_b);
840 connection_b->lower_binder_.Attach(connection_a);
841
842 EXPECT_FALSE(connection_a->binders_.empty());
843 EXPECT_FALSE(connection_b->binders_.empty());
844
845 DisconnectCallbackTarget target_a;
846 DisconnectCallbackTarget target_b;
847 Connection::Binder binder_a("test_a", target_a.callback());
848 Connection::Binder binder_b("test_b", target_b.callback());
849 binder_a.Attach(connection_a);
850 binder_b.Attach(connection_b);
851
852 AddDestructorExpectations();
853 EXPECT_CALL(target_a, CallTarget()).Times(1);
854 EXPECT_CALL(target_b, CallTarget()).Times(1);
Ben Chancc225ef2014-09-30 13:26:51 -0700855 connection_b = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200856
857 EXPECT_TRUE(connection_a->binders_.empty());
858
859 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700860 connection_a = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200861 }
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200862 {
863 // Test the weak pointer to the bound Connection. This is not a case that
864 // should occur but the weak pointer should handle it gracefully.
865 DisconnectCallbackTarget target;
866 Connection::Binder binder("test_weak", target.callback());
867 ConnectionRefPtr connection = GetNewConnection();
868 binder.Attach(connection);
869
870 // Make sure the connection doesn't notify the binder on destruction.
871 connection->binders_.clear();
872 AddDestructorExpectations();
873 EXPECT_CALL(target, CallTarget()).Times(0);
Ben Chancc225ef2014-09-30 13:26:51 -0700874 connection = nullptr;
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200875
Ben Chancc225ef2014-09-30 13:26:51 -0700876 // Ensure no crash -- the weak pointer to connection should be nullptr.
Darin Petkov5eb05422012-05-11 15:45:25 +0200877 EXPECT_FALSE(binder.connection());
Ben Chancc225ef2014-09-30 13:26:51 -0700878 binder.Attach(nullptr);
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200879 }
Darin Petkov13e6d552012-05-09 14:22:23 +0200880}
881
882TEST_F(ConnectionTest, OnRouteQueryResponse) {
883 Connection::Binder *binder = &connection_->lower_binder_;
884 ConnectionRefPtr connection = GetNewConnection();
885 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
886 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700887 nullptr,
888 nullptr,
889 nullptr,
Darin Petkov13e6d552012-05-09 14:22:23 +0200890 kTestDeviceName1,
891 string(),
892 kTestDeviceInterfaceIndex1));
893
894 // Make sure we unbind the old lower connection even if we can't lookup the
895 // lower connection device.
896 binder->Attach(connection);
897 scoped_refptr<MockDevice> null_device;
898 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
899 .WillOnce(Return(null_device));
900 connection_->OnRouteQueryResponse(
901 kTestDeviceInterfaceIndex1, RoutingTableEntry());
902 EXPECT_FALSE(binder->IsBound());
903
904 // Check for graceful handling of a device with no connection.
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800905 ConnectionRefPtr device_connection;
906 EXPECT_CALL(*device, connection())
907 .WillRepeatedly(testing::ReturnRef(device_connection));
Darin Petkov13e6d552012-05-09 14:22:23 +0200908 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
909 .WillOnce(Return(device));
910 connection_->OnRouteQueryResponse(
911 kTestDeviceInterfaceIndex1, RoutingTableEntry());
912 EXPECT_FALSE(binder->IsBound());
913
mukesh agrawalf407d592013-07-31 11:37:57 -0700914 // Create a mock connection that will be used for binding.
Paul Stewart4a6748d2012-07-17 14:31:36 -0700915 scoped_refptr<MockConnection> mock_connection(
916 new StrictMock<MockConnection>(device_info_.get()));
917 EXPECT_CALL(*device_info_.get(),
918 FlushAddresses(mock_connection->interface_index()));
919 const string kInterfaceName(kTestDeviceName0);
920 EXPECT_CALL(*mock_connection, interface_name())
921 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800922 device_connection = mock_connection.get();
923 EXPECT_CALL(*device, connection())
924 .WillRepeatedly(testing::ReturnRef(device_connection));
Darin Petkov13e6d552012-05-09 14:22:23 +0200925 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
926 .WillOnce(Return(device));
Paul Stewart4a6748d2012-07-17 14:31:36 -0700927
Ben Chana6bfe872012-09-26 09:48:34 -0700928 // Check that the binding process completes, causing its upper
Paul Stewart4a6748d2012-07-17 14:31:36 -0700929 // connection to create a gateway route.
930 EXPECT_CALL(*mock_connection, CreateGatewayRoute())
931 .WillOnce(Return(true));
Paul Stewart8596f9f2013-03-14 07:58:26 -0700932
933 // Ensure that the Device is notified of the change to the connection.
934 EXPECT_CALL(*device, OnConnectionUpdated()).Times(1);
Darin Petkov13e6d552012-05-09 14:22:23 +0200935 connection_->OnRouteQueryResponse(
936 kTestDeviceInterfaceIndex1, RoutingTableEntry());
Paul Stewart4a6748d2012-07-17 14:31:36 -0700937
938 // Check that the upper connection is bound to the lower connection.
Darin Petkov13e6d552012-05-09 14:22:23 +0200939 EXPECT_TRUE(binder->IsBound());
Paul Stewart4a6748d2012-07-17 14:31:36 -0700940 EXPECT_EQ(mock_connection.get(), binder->connection().get());
Darin Petkov13e6d552012-05-09 14:22:23 +0200941
Darin Petkov13e6d552012-05-09 14:22:23 +0200942 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700943 connection = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200944}
945
Alex Deymofddc09a2013-07-03 18:41:31 -0700946TEST_F(ConnectionTest, GetCarrierConnection) {
947 EXPECT_EQ(connection_.get(), connection_->GetCarrierConnection().get());
948
949 ConnectionRefPtr connection1 = GetNewConnection();
950 ConnectionRefPtr connection2 = GetNewConnection();
951 ConnectionRefPtr connection3 = GetNewConnection();
952
953 connection_->lower_binder_.Attach(connection1);
954 EXPECT_EQ(connection1.get(), connection_->GetCarrierConnection().get());
955
956 connection1->lower_binder_.Attach(connection2);
957 EXPECT_EQ(connection2.get(), connection_->GetCarrierConnection().get());
958
959 connection2->lower_binder_.Attach(connection3);
960 EXPECT_EQ(connection3.get(), connection_->GetCarrierConnection().get());
961
962 // Create a cycle back to |connection1|.
963 connection3->lower_binder_.Attach(connection1);
Ben Chancc225ef2014-09-30 13:26:51 -0700964 EXPECT_EQ(nullptr, connection_->GetCarrierConnection().get());
Alex Deymofddc09a2013-07-03 18:41:31 -0700965
966 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700967 connection3 = nullptr;
Alex Deymofddc09a2013-07-03 18:41:31 -0700968
969 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700970 connection2 = nullptr;
Alex Deymofddc09a2013-07-03 18:41:31 -0700971
972 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700973 connection1 = nullptr;
Alex Deymofddc09a2013-07-03 18:41:31 -0700974}
975
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800976TEST_F(ConnectionTest, GetSubnetName) {
Paul Stewart182888e2014-11-13 01:43:12 -0800977 EXPECT_EQ("", connection_->GetSubnetName());
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800978 IPAddress local("1.2.3.4");
979 local.set_prefix(24);
980 SetLocal(local);
981 EXPECT_EQ("1.2.3.0/24", connection_->GetSubnetName());
982}
983
Paul Stewartdd60e452011-08-08 11:38:36 -0700984} // namespace shill