blob: 75e40a02f898531e199e3ea17fb4704bb04d25db [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
Paul Stewart9a908082011-08-31 12:18:48 -07005#include <arpa/inet.h>
6#include <linux/rtnetlink.h>
7
Ben Chan22f1fbc2014-10-17 14:18:07 -07008#include <memory>
Paul Stewartc8f4bef2011-12-13 09:45:51 -08009#include <string>
Paul Stewart9a908082011-08-31 12:18:48 -070010#include <vector>
11
Paul Stewartdd60e452011-08-08 11:38:36 -070012#include <gtest/gtest.h>
13#include <gmock/gmock.h>
14
15#include "shill/connection.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070016#include "shill/ipconfig.h"
Darin Petkov13e6d552012-05-09 14:22:23 +020017#include "shill/mock_connection.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070018#include "shill/mock_control.h"
Paul Stewartc8f4bef2011-12-13 09:45:51 -080019#include "shill/mock_device.h"
Paul Stewart9a908082011-08-31 12:18:48 -070020#include "shill/mock_device_info.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070021#include "shill/mock_resolver.h"
22#include "shill/mock_routing_table.h"
23#include "shill/mock_rtnl_handler.h"
24#include "shill/routing_table_entry.h"
25
Paul Stewartc8f4bef2011-12-13 09:45:51 -080026using std::string;
Paul Stewart9a908082011-08-31 12:18:48 -070027using std::vector;
Paul Stewartdd60e452011-08-08 11:38:36 -070028using testing::_;
Paul Stewarte78ec542012-06-08 18:28:50 -070029using testing::Mock;
Paul Stewartdd60e452011-08-08 11:38:36 -070030using testing::NiceMock;
31using testing::Return;
Paul Stewart4a6748d2012-07-17 14:31:36 -070032using testing::ReturnRef;
Paul Stewartdd60e452011-08-08 11:38:36 -070033using testing::StrictMock;
34using testing::Test;
35
36namespace shill {
37
38namespace {
39const char kTestDeviceName0[] = "netdev0";
40const int kTestDeviceInterfaceIndex0 = 123;
41const char kTestDeviceName1[] = "netdev1";
42const int kTestDeviceInterfaceIndex1 = 321;
43const char kIPAddress0[] = "192.168.1.1";
44const char kGatewayAddress0[] = "192.168.1.254";
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070045const char kGatewayAddress1[] = "192.168.2.254";
Paul Stewart9a908082011-08-31 12:18:48 -070046const char kBroadcastAddress0[] = "192.168.1.255";
Paul Stewartdd60e452011-08-08 11:38:36 -070047const char kNameServer0[] = "8.8.8.8";
48const char kNameServer1[] = "8.8.9.9";
Ben Chan7fab8972014-08-10 17:14:46 -070049const int32_t kPrefix0 = 24;
50const int32_t kPrefix1 = 31;
Paul Stewartdd60e452011-08-08 11:38:36 -070051const char kSearchDomain0[] = "chromium.org";
52const char kSearchDomain1[] = "google.com";
Peter Qiub25083f2014-08-25 13:22:31 -070053const char kIPv6Address[] = "2001:db8::1";
54const char kIPv6NameServer0[] = "2001:db9::1";
55const char kIPv6NameServer1[] = "2001:db9::2";
Ben Chana6bfe872012-09-26 09:48:34 -070056} // namespace
Paul Stewartdd60e452011-08-08 11:38:36 -070057
58class ConnectionTest : public Test {
59 public:
60 ConnectionTest()
Paul Stewart9a908082011-08-31 12:18:48 -070061 : device_info_(new StrictMock<MockDeviceInfo>(
62 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -070063 nullptr,
64 nullptr,
65 nullptr)),
Paul Stewart9a908082011-08-31 12:18:48 -070066 connection_(new Connection(
67 kTestDeviceInterfaceIndex0,
68 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -070069 Technology::kUnknown,
mukesh agrawal23ac6b72013-01-31 18:52:37 -080070 device_info_.get())),
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070071 ipconfig_(new IPConfig(&control_, kTestDeviceName0)),
Peter Qiub25083f2014-08-25 13:22:31 -070072 ip6config_(new IPConfig(&control_, kTestDeviceName0)),
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070073 local_address_(IPAddress::kFamilyIPv4),
74 broadcast_address_(IPAddress::kFamilyIPv4),
75 gateway_address_(IPAddress::kFamilyIPv4),
Peter Qiub25083f2014-08-25 13:22:31 -070076 default_address_(IPAddress::kFamilyIPv4),
77 local_ipv6_address_(IPAddress::kFamilyIPv6) {}
Paul Stewartdd60e452011-08-08 11:38:36 -070078
79 virtual void SetUp() {
Paul Stewartc8f4bef2011-12-13 09:45:51 -080080 ReplaceSingletons(connection_);
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070081 properties_.address = kIPAddress0;
82 properties_.subnet_prefix = kPrefix0;
83 properties_.gateway = kGatewayAddress0;
84 properties_.broadcast_address = kBroadcastAddress0;
85 properties_.dns_servers.push_back(kNameServer0);
86 properties_.dns_servers.push_back(kNameServer1);
87 properties_.domain_search.push_back(kSearchDomain0);
88 properties_.domain_search.push_back(kSearchDomain1);
89 properties_.address_family = IPAddress::kFamilyIPv4;
90 UpdateProperties();
Peter Qiub25083f2014-08-25 13:22:31 -070091 ipv6_properties_.address = kIPv6Address;
92 ipv6_properties_.dns_servers.push_back(kIPv6NameServer0);
93 ipv6_properties_.dns_servers.push_back(kIPv6NameServer1);
94 ipv6_properties_.address_family = IPAddress::kFamilyIPv6;
95 UpdateIPv6Properties();
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070096 EXPECT_TRUE(local_address_.SetAddressFromString(kIPAddress0));
97 EXPECT_TRUE(broadcast_address_.SetAddressFromString(kBroadcastAddress0));
98 EXPECT_TRUE(gateway_address_.SetAddressFromString(kGatewayAddress0));
Peter Qiub25083f2014-08-25 13:22:31 -070099 EXPECT_TRUE(local_ipv6_address_.SetAddressFromString(kIPv6Address));
Paul Stewartdd60e452011-08-08 11:38:36 -0700100 }
101
Paul Stewart9a908082011-08-31 12:18:48 -0700102 virtual void TearDown() {
Darin Petkov13e6d552012-05-09 14:22:23 +0200103 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700104 connection_ = nullptr;
Paul Stewart9a908082011-08-31 12:18:48 -0700105 }
106
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800107 void ReplaceSingletons(ConnectionRefPtr connection) {
108 connection->resolver_ = &resolver_;
109 connection->routing_table_ = &routing_table_;
110 connection->rtnl_handler_ = &rtnl_handler_;
111 }
112
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700113 void UpdateProperties() {
Paul Stewartc5099532013-12-12 07:53:15 -0800114 ipconfig_->UpdateProperties(properties_);
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700115 }
116
Peter Qiub25083f2014-08-25 13:22:31 -0700117 void UpdateIPv6Properties() {
118 ip6config_->UpdateProperties(ipv6_properties_);
119 }
120
Paul Stewarte93b0382012-04-24 13:11:28 -0700121 bool PinHostRoute(ConnectionRefPtr connection,
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800122 const IPAddress trusted_ip,
123 const IPAddress gateway) {
124 return connection->PinHostRoute(trusted_ip, gateway);
Paul Stewarte93b0382012-04-24 13:11:28 -0700125 }
126
Paul Stewart4a6748d2012-07-17 14:31:36 -0700127 const IPAddress &GetLocalAddress(ConnectionRefPtr connection) {
128 return connection->local_;
129 }
130
131 const IPAddress &GetGatewayAddress(ConnectionRefPtr connection) {
132 return connection->gateway_;
133 }
134
135 bool GetHasBroadcastDomain(ConnectionRefPtr connection) {
136 return connection->has_broadcast_domain_;
137 }
138
Ben Chan7fab8972014-08-10 17:14:46 -0700139 uint32_t GetDefaultMetric() {
Paul Stewart05a42c22012-08-02 16:47:21 -0700140 return Connection::kDefaultMetric;
141 }
142
Ben Chan7fab8972014-08-10 17:14:46 -0700143 uint32_t GetNonDefaultMetricBase() {
Paul Stewart05a42c22012-08-02 16:47:21 -0700144 return Connection::kNonDefaultMetricBase;
145 }
146
Paul Stewartdd60e452011-08-08 11:38:36 -0700147 protected:
Darin Petkov13e6d552012-05-09 14:22:23 +0200148 class DisconnectCallbackTarget {
149 public:
150 DisconnectCallbackTarget()
151 : callback_(base::Bind(&DisconnectCallbackTarget::CallTarget,
152 base::Unretained(this))) {}
153
154 MOCK_METHOD0(CallTarget, void());
155 const base::Closure &callback() { return callback_; }
156
157 private:
158 base::Closure callback_;
159 };
160
161 void AddDestructorExpectations() {
162 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
163 EXPECT_CALL(routing_table_, FlushRoutesWithTag(kTestDeviceInterfaceIndex0));
164 EXPECT_CALL(*device_info_.get(),
165 FlushAddresses(kTestDeviceInterfaceIndex0));
166 }
167
168 // Returns a new test connection object. The caller usually needs to call
169 // AddDestructorExpectations before destroying the object.
170 ConnectionRefPtr GetNewConnection() {
171 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
172 kTestDeviceName0,
173 Technology::kUnknown,
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800174 device_info_.get()));
Darin Petkov13e6d552012-05-09 14:22:23 +0200175 ReplaceSingletons(connection);
176 return connection;
177 }
178
Ben Chan22f1fbc2014-10-17 14:18:07 -0700179 std::unique_ptr<StrictMock<MockDeviceInfo>> device_info_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700180 ConnectionRefPtr connection_;
181 MockControl control_;
182 IPConfigRefPtr ipconfig_;
Peter Qiub25083f2014-08-25 13:22:31 -0700183 IPConfigRefPtr ip6config_;
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700184 IPConfig::Properties properties_;
Peter Qiub25083f2014-08-25 13:22:31 -0700185 IPConfig::Properties ipv6_properties_;
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700186 IPAddress local_address_;
187 IPAddress broadcast_address_;
188 IPAddress gateway_address_;
189 IPAddress default_address_;
Peter Qiub25083f2014-08-25 13:22:31 -0700190 IPAddress local_ipv6_address_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700191 StrictMock<MockResolver> resolver_;
192 StrictMock<MockRoutingTable> routing_table_;
193 StrictMock<MockRTNLHandler> rtnl_handler_;
194};
195
Darin Petkov13e6d552012-05-09 14:22:23 +0200196namespace {
Paul Stewartdd60e452011-08-08 11:38:36 -0700197
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700198MATCHER_P2(IsIPAddress, address, prefix, "") {
199 IPAddress match_address(address);
200 match_address.set_prefix(prefix);
201 return match_address.Equals(arg);
202}
203
Peter Qiub25083f2014-08-25 13:22:31 -0700204MATCHER_P(IsIPv6Address, address, "") {
205 IPAddress match_address(address);
206 return match_address.Equals(arg);
207}
208
Darin Petkov13e6d552012-05-09 14:22:23 +0200209MATCHER(IsNonNullCallback, "") {
210 return !arg.is_null();
211}
212
213} // namespace
214
215TEST_F(ConnectionTest, InitState) {
216 EXPECT_EQ(kTestDeviceInterfaceIndex0, connection_->interface_index_);
217 EXPECT_EQ(kTestDeviceName0, connection_->interface_name_);
218 EXPECT_FALSE(connection_->is_default());
219 EXPECT_FALSE(connection_->routing_request_count_);
220}
221
Paul Stewartdd60e452011-08-08 11:38:36 -0700222TEST_F(ConnectionTest, AddConfig) {
Paul Stewart05a42c22012-08-02 16:47:21 -0700223 EXPECT_CALL(*device_info_,
224 HasOtherAddress(kTestDeviceInterfaceIndex0,
225 IsIPAddress(local_address_, kPrefix0)))
226 .WillOnce(Return(false));
Paul Stewartdd60e452011-08-08 11:38:36 -0700227 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700228 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
229 IsIPAddress(local_address_, kPrefix0),
230 IsIPAddress(broadcast_address_, 0),
231 IsIPAddress(default_address_, 0)));
Paul Stewart7cfca042011-12-08 14:18:17 -0800232 EXPECT_CALL(routing_table_,
233 SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700234 IsIPAddress(gateway_address_, 0),
Paul Stewart05a42c22012-08-02 16:47:21 -0700235 GetNonDefaultMetricBase() +
Paul Stewart7cfca042011-12-08 14:18:17 -0800236 kTestDeviceInterfaceIndex0));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700237 EXPECT_CALL(routing_table_,
238 ConfigureRoutes(kTestDeviceInterfaceIndex0,
239 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700240 GetDefaultMetric()));
Paul Stewartdd60e452011-08-08 11:38:36 -0700241 connection_->UpdateFromIPConfig(ipconfig_);
Paul Stewart4a6748d2012-07-17 14:31:36 -0700242 IPAddress test_local_address(local_address_);
243 test_local_address.set_prefix(kPrefix0);
244 EXPECT_TRUE(test_local_address.Equals(GetLocalAddress(connection_)));
245 EXPECT_TRUE(gateway_address_.Equals(GetGatewayAddress(connection_)));
246 EXPECT_TRUE(GetHasBroadcastDomain(connection_));
Peter Qiub25083f2014-08-25 13:22:31 -0700247 EXPECT_FALSE(connection_->IsIPv6());
Paul Stewart4a6748d2012-07-17 14:31:36 -0700248
249 EXPECT_CALL(routing_table_,
250 CreateLinkRoute(kTestDeviceInterfaceIndex0,
251 IsIPAddress(local_address_, kPrefix0),
252 IsIPAddress(gateway_address_, 0)))
253 .WillOnce(Return(true))
254 .WillOnce(Return(false));
255 EXPECT_TRUE(connection_->CreateGatewayRoute());
256 EXPECT_FALSE(connection_->CreateGatewayRoute());
257 connection_->has_broadcast_domain_ = false;
258 EXPECT_FALSE(connection_->CreateGatewayRoute());
Paul Stewartdd60e452011-08-08 11:38:36 -0700259
260 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
Paul Stewart05a42c22012-08-02 16:47:21 -0700261 GetDefaultMetric()));
Paul Stewartdd60e452011-08-08 11:38:36 -0700262 EXPECT_CALL(resolver_, SetDNSFromLists(
263 ipconfig_->properties().dns_servers,
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800264 ipconfig_->properties().domain_search));
Paul Stewartdd60e452011-08-08 11:38:36 -0700265
Paul Stewartc681fa02012-03-02 19:40:04 -0800266 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
267 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700268 nullptr,
269 nullptr,
270 nullptr,
Paul Stewartc681fa02012-03-02 19:40:04 -0800271 kTestDeviceName0,
272 string(),
273 kTestDeviceInterfaceIndex0));
274 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
275 .WillOnce(Return(device));
276 EXPECT_CALL(*device.get(), RequestPortalDetection())
277 .WillOnce(Return(true));
Paul Stewarte78ec542012-06-08 18:28:50 -0700278 EXPECT_CALL(routing_table_, FlushCache())
279 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800280 connection_->SetIsDefault(true);
Paul Stewarte78ec542012-06-08 18:28:50 -0700281 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700282 EXPECT_TRUE(connection_->is_default());
283
Paul Stewart7cfca042011-12-08 14:18:17 -0800284 EXPECT_CALL(routing_table_,
285 SetDefaultMetric(kTestDeviceInterfaceIndex0,
Paul Stewart05a42c22012-08-02 16:47:21 -0700286 GetNonDefaultMetricBase() +
Paul Stewart7cfca042011-12-08 14:18:17 -0800287 kTestDeviceInterfaceIndex0));
Paul Stewarte78ec542012-06-08 18:28:50 -0700288 EXPECT_CALL(routing_table_, FlushCache())
289 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800290 connection_->SetIsDefault(false);
Paul Stewartdd60e452011-08-08 11:38:36 -0700291 EXPECT_FALSE(connection_->is_default());
292}
293
Peter Qiub25083f2014-08-25 13:22:31 -0700294TEST_F(ConnectionTest, AddConfigIPv6) {
295 EXPECT_CALL(*device_info_,
296 HasOtherAddress(kTestDeviceInterfaceIndex0,
297 IsIPv6Address(local_ipv6_address_)))
298 .WillOnce(Return(false));
299 EXPECT_CALL(rtnl_handler_,
300 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
301 IsIPv6Address(local_ipv6_address_),
302 _,
303 _));
304 EXPECT_CALL(routing_table_,
305 ConfigureRoutes(kTestDeviceInterfaceIndex0,
306 ip6config_,
307 GetDefaultMetric()));
308 connection_->UpdateFromIPConfig(ip6config_);
309 IPAddress test_local_address(local_ipv6_address_);
310 EXPECT_TRUE(test_local_address.Equals(GetLocalAddress(connection_)));
311 EXPECT_TRUE(connection_->IsIPv6());
312}
313
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700314TEST_F(ConnectionTest, AddConfigWithPeer) {
315 const string kPeerAddress("192.168.1.222");
316 IPAddress peer_address(IPAddress::kFamilyIPv4);
317 EXPECT_TRUE(peer_address.SetAddressFromString(kPeerAddress));
318 properties_.peer_address = kPeerAddress;
319 properties_.gateway = string();
320 UpdateProperties();
Paul Stewart05a42c22012-08-02 16:47:21 -0700321 EXPECT_CALL(*device_info_,
322 HasOtherAddress(kTestDeviceInterfaceIndex0,
323 IsIPAddress(local_address_, kPrefix0)))
324 .WillOnce(Return(false));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700325 EXPECT_CALL(rtnl_handler_,
326 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
327 IsIPAddress(local_address_, kPrefix0),
328 IsIPAddress(broadcast_address_, 0),
329 IsIPAddress(peer_address, 0)));
330 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _)).Times(0);
331 EXPECT_CALL(routing_table_,
332 ConfigureRoutes(kTestDeviceInterfaceIndex0,
333 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700334 GetDefaultMetric()));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700335 connection_->UpdateFromIPConfig(ipconfig_);
Paul Stewart4a6748d2012-07-17 14:31:36 -0700336 EXPECT_FALSE(GetHasBroadcastDomain(connection_));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700337}
338
339TEST_F(ConnectionTest, AddConfigWithBrokenNetmask) {
340 // Assign a prefix that makes the gateway unreachable.
341 properties_.subnet_prefix = kPrefix1;
342 UpdateProperties();
343
344 // Connection should override with a prefix which will allow the
345 // gateway to be reachable.
Paul Stewart05a42c22012-08-02 16:47:21 -0700346 EXPECT_CALL(*device_info_,
347 HasOtherAddress(kTestDeviceInterfaceIndex0,
348 IsIPAddress(local_address_, kPrefix0)))
349 .WillOnce(Return(false));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700350 EXPECT_CALL(rtnl_handler_,
351 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
352 IsIPAddress(local_address_, kPrefix0),
353 IsIPAddress(broadcast_address_, 0),
354 IsIPAddress(default_address_, 0)));
355 EXPECT_CALL(routing_table_,
356 SetDefaultRoute(kTestDeviceInterfaceIndex0,
357 IsIPAddress(gateway_address_, 0),
Paul Stewart05a42c22012-08-02 16:47:21 -0700358 GetNonDefaultMetricBase() +
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700359 kTestDeviceInterfaceIndex0));
360 EXPECT_CALL(routing_table_,
361 ConfigureRoutes(kTestDeviceInterfaceIndex0,
362 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700363 GetDefaultMetric()));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700364 connection_->UpdateFromIPConfig(ipconfig_);
365
366 // Assign a gateway address that violates the minimum plausible prefix
367 // the Connection can assign.
368 properties_.gateway = kGatewayAddress1;
369 UpdateProperties();
370
Paul Stewart49258292012-05-26 06:37:14 -0700371 IPAddress gateway_address1(IPAddress::kFamilyIPv4);
372 EXPECT_TRUE(gateway_address1.SetAddressFromString(kGatewayAddress1));
373 // Connection cannot override this prefix, so it will switch to a
374 // model where the peer address is set to the value of the gateway
375 // address.
Paul Stewart05a42c22012-08-02 16:47:21 -0700376 EXPECT_CALL(*device_info_,
377 HasOtherAddress(kTestDeviceInterfaceIndex0,
378 IsIPAddress(local_address_, kPrefix1)))
379 .WillOnce(Return(false));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700380 EXPECT_CALL(rtnl_handler_,
381 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
382 IsIPAddress(local_address_, kPrefix1),
383 IsIPAddress(broadcast_address_, 0),
Paul Stewart49258292012-05-26 06:37:14 -0700384 IsIPAddress(gateway_address1, 0)));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700385 EXPECT_CALL(routing_table_,
386 SetDefaultRoute(kTestDeviceInterfaceIndex0, _, _));
387 EXPECT_CALL(routing_table_,
388 ConfigureRoutes(kTestDeviceInterfaceIndex0, _, _));
389 connection_->UpdateFromIPConfig(ipconfig_);
390}
391
Paul Stewartdd60e452011-08-08 11:38:36 -0700392TEST_F(ConnectionTest, AddConfigReverse) {
393 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
Paul Stewart05a42c22012-08-02 16:47:21 -0700394 GetDefaultMetric()));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800395 vector<string> empty_list;
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800396 EXPECT_CALL(resolver_, SetDNSFromLists(empty_list, empty_list));
Paul Stewartc681fa02012-03-02 19:40:04 -0800397 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
398 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700399 nullptr,
400 nullptr,
401 nullptr,
Paul Stewartc681fa02012-03-02 19:40:04 -0800402 kTestDeviceName0,
403 string(),
404 kTestDeviceInterfaceIndex0));
405 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
406 .WillOnce(Return(device));
407 EXPECT_CALL(*device.get(), RequestPortalDetection())
408 .WillOnce(Return(true));
Paul Stewarte78ec542012-06-08 18:28:50 -0700409 EXPECT_CALL(routing_table_, FlushCache())
410 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800411 connection_->SetIsDefault(true);
Paul Stewarte78ec542012-06-08 18:28:50 -0700412 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700413
Paul Stewart05a42c22012-08-02 16:47:21 -0700414 EXPECT_CALL(*device_info_,
415 HasOtherAddress(kTestDeviceInterfaceIndex0,
416 IsIPAddress(local_address_, kPrefix0)))
417 .WillOnce(Return(false));
Paul Stewartdd60e452011-08-08 11:38:36 -0700418 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700419 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
420 IsIPAddress(local_address_, kPrefix0),
421 IsIPAddress(broadcast_address_, 0),
422 IsIPAddress(default_address_, 0)));
Paul Stewartdd60e452011-08-08 11:38:36 -0700423 EXPECT_CALL(routing_table_, SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700424 IsIPAddress(gateway_address_, 0),
Paul Stewart05a42c22012-08-02 16:47:21 -0700425 GetDefaultMetric()));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700426 EXPECT_CALL(routing_table_,
427 ConfigureRoutes(kTestDeviceInterfaceIndex0,
428 ipconfig_,
Paul Stewart05a42c22012-08-02 16:47:21 -0700429 GetDefaultMetric()));
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800430 EXPECT_CALL(resolver_,
431 SetDNSFromLists(ipconfig_->properties().dns_servers,
432 ipconfig_->properties().domain_search));
Paul Stewartdd60e452011-08-08 11:38:36 -0700433
434 connection_->UpdateFromIPConfig(ipconfig_);
435}
436
Paul Stewart4d1868b2012-09-10 11:58:46 -0700437TEST_F(ConnectionTest, AddConfigWithDNSDomain) {
438 const string kDomainName("chromium.org");
439 properties_.domain_search.clear();
440 properties_.domain_name = kDomainName;
441 UpdateProperties();
442 EXPECT_CALL(*device_info_, HasOtherAddress(_, _))
443 .WillOnce(Return(false));
444 EXPECT_CALL(rtnl_handler_, AddInterfaceAddress(_, _, _, _));
445 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _));
446 EXPECT_CALL(routing_table_, ConfigureRoutes(_, _, _));
447 connection_->UpdateFromIPConfig(ipconfig_);
448
449 EXPECT_CALL(routing_table_, SetDefaultMetric(_, _));
450 vector<string> domain_search_list;
451 domain_search_list.push_back(kDomainName + ".");
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800452 EXPECT_CALL(resolver_, SetDNSFromLists(_, domain_search_list));
Paul Stewart4d1868b2012-09-10 11:58:46 -0700453 DeviceRefPtr device;
454 EXPECT_CALL(*device_info_, GetDevice(_)).WillOnce(Return(device));
455 EXPECT_CALL(routing_table_, FlushCache()).WillOnce(Return(true));
456 connection_->SetIsDefault(true);
457}
458
Paul Stewart05a42c22012-08-02 16:47:21 -0700459TEST_F(ConnectionTest, HasOtherAddress) {
460 EXPECT_CALL(*device_info_,
461 HasOtherAddress(kTestDeviceInterfaceIndex0,
462 IsIPAddress(local_address_, kPrefix0)))
463 .WillOnce(Return(true));
464 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
465 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex0));
466 EXPECT_CALL(rtnl_handler_,
467 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
468 IsIPAddress(local_address_, kPrefix0),
469 IsIPAddress(broadcast_address_, 0),
470 IsIPAddress(default_address_, 0)));
471 EXPECT_CALL(routing_table_,
472 SetDefaultRoute(kTestDeviceInterfaceIndex0,
473 IsIPAddress(gateway_address_, 0),
474 GetNonDefaultMetricBase() +
475 kTestDeviceInterfaceIndex0));
476 EXPECT_CALL(routing_table_,
477 ConfigureRoutes(kTestDeviceInterfaceIndex0,
478 ipconfig_,
479 GetDefaultMetric()));
480 connection_->UpdateFromIPConfig(ipconfig_);
481}
482
Peter Qiua89154b2014-05-23 15:45:42 -0700483TEST_F(ConnectionTest, UpdateDNSServers) {
484 const char* kDnsServers[] = {"1.1.1.1", "1.1.1.2"};
485 vector<string> dns_servers(kDnsServers, std::end(kDnsServers));
486
487 // Non-default connection.
488 connection_->is_default_ = false;
489 EXPECT_CALL(resolver_, SetDNSFromLists(_, _)).Times(0);
490 connection_->UpdateDNSServers(dns_servers);
491 Mock::VerifyAndClearExpectations(&resolver_);
492
493 // Default connection.
494 connection_->is_default_ = true;
495 EXPECT_CALL(resolver_, SetDNSFromLists(dns_servers, _));
496 connection_->UpdateDNSServers(dns_servers);
497 Mock::VerifyAndClearExpectations(&resolver_);
498}
499
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800500TEST_F(ConnectionTest, RouteRequest) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200501 ConnectionRefPtr connection = GetNewConnection();
Paul Stewartf748a362012-03-07 12:01:20 -0800502 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
503 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700504 nullptr,
505 nullptr,
506 nullptr,
Paul Stewartf748a362012-03-07 12:01:20 -0800507 kTestDeviceName0,
508 string(),
509 kTestDeviceInterfaceIndex0));
510 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
511 .WillRepeatedly(Return(device));
512 EXPECT_CALL(*device.get(), DisableReversePathFilter()).Times(1);
513 connection->RequestRouting();
514 connection->RequestRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800515
Paul Stewartf748a362012-03-07 12:01:20 -0800516 // The first release should only decrement the reference counter.
517 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800518
Paul Stewartf748a362012-03-07 12:01:20 -0800519 // Another release will re-enable reverse-path filter.
520 EXPECT_CALL(*device.get(), EnableReversePathFilter());
521 EXPECT_CALL(routing_table_, FlushCache());
522 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800523
Paul Stewartf748a362012-03-07 12:01:20 -0800524 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200525 AddDestructorExpectations();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800526}
527
Paul Stewartdd60e452011-08-08 11:38:36 -0700528TEST_F(ConnectionTest, Destructor) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200529 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex1,
530 kTestDeviceName1,
531 Technology::kUnknown,
mukesh agrawal23ac6b72013-01-31 18:52:37 -0800532 device_info_.get()));
Darin Petkov13e6d552012-05-09 14:22:23 +0200533 connection->resolver_ = &resolver_;
534 connection->routing_table_ = &routing_table_;
535 connection->rtnl_handler_ = &rtnl_handler_;
Thieu Lefb46caf2012-03-08 11:57:15 -0800536 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex1));
Paul Stewarte93b0382012-04-24 13:11:28 -0700537 EXPECT_CALL(routing_table_, FlushRoutesWithTag(kTestDeviceInterfaceIndex1));
Paul Stewart9a908082011-08-31 12:18:48 -0700538 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex1));
Ben Chancc225ef2014-09-30 13:26:51 -0700539 connection = nullptr;
Paul Stewartdd60e452011-08-08 11:38:36 -0700540}
541
Paul Stewartf748a362012-03-07 12:01:20 -0800542TEST_F(ConnectionTest, RequestHostRoute) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200543 ConnectionRefPtr connection = GetNewConnection();
Paul Stewartf748a362012-03-07 12:01:20 -0800544 IPAddress address(IPAddress::kFamilyIPv4);
545 ASSERT_TRUE(address.SetAddressFromString(kIPAddress0));
546 size_t prefix_len = address.GetLength() * 8;
Darin Petkov13e6d552012-05-09 14:22:23 +0200547 EXPECT_CALL(routing_table_,
548 RequestRouteToHost(IsIPAddress(address, prefix_len),
549 -1,
550 kTestDeviceInterfaceIndex0,
551 IsNonNullCallback()))
Paul Stewartf748a362012-03-07 12:01:20 -0800552 .WillOnce(Return(true));
553 EXPECT_TRUE(connection->RequestHostRoute(address));
554
555 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200556 AddDestructorExpectations();
Paul Stewarte93b0382012-04-24 13:11:28 -0700557}
558
Ben Chana0163122012-09-25 15:10:52 -0700559TEST_F(ConnectionTest, BlackholeIPv6) {
560 properties_.blackhole_ipv6 = true;
561 UpdateProperties();
562 EXPECT_CALL(*device_info_, HasOtherAddress(_, _))
563 .WillOnce(Return(false));
564 EXPECT_CALL(rtnl_handler_, AddInterfaceAddress(_, _, _, _));
565 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _));
566 EXPECT_CALL(routing_table_, ConfigureRoutes(_, _, _));
567 EXPECT_CALL(routing_table_,
568 CreateBlackholeRoute(kTestDeviceInterfaceIndex0,
569 IPAddress::kFamilyIPv6,
570 Connection::kDefaultMetric))
571 .WillOnce(Return(true));
572 connection_->UpdateFromIPConfig(ipconfig_);
573}
574
Paul Stewarte93b0382012-04-24 13:11:28 -0700575TEST_F(ConnectionTest, PinHostRoute) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200576 ConnectionRefPtr connection = GetNewConnection();
Paul Stewarte93b0382012-04-24 13:11:28 -0700577
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800578 IPAddress gateway(IPAddress::kFamilyIPv4);
579 IPAddress trusted_ip(IPAddress::kFamilyIPv4);
Paul Stewarte93b0382012-04-24 13:11:28 -0700580
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800581 // Should fail because neither IP address is set.
582 EXPECT_FALSE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700583
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800584 static const char kGateway[] = "10.242.2.13";
585 ASSERT_TRUE(gateway.SetAddressFromString(kGateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700586
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800587 // Should fail because trusted IP is not set.
588 EXPECT_FALSE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700589
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800590 static const char kTrustedIP[] = "10.0.1.1";
591 ASSERT_TRUE(trusted_ip.SetAddressFromString(kTrustedIP));
592
Paul Stewarte435d342013-09-27 16:41:00 -0700593 // Should pass without calling RequestRouteToHost since if the gateway
594 // is not set, there is no work to be done.
595 EXPECT_CALL(routing_table_, RequestRouteToHost(_, _, _, _)).Times(0);
596 EXPECT_TRUE(PinHostRoute(connection, trusted_ip,
597 IPAddress(gateway.family())));
598 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800599
600 size_t prefix_len = IPAddress::GetMaxPrefixLength(trusted_ip.family());
Paul Stewarte93b0382012-04-24 13:11:28 -0700601 EXPECT_CALL(routing_table_, RequestRouteToHost(
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800602 IsIPAddress(trusted_ip, prefix_len), -1, kTestDeviceInterfaceIndex0, _))
Paul Stewarte93b0382012-04-24 13:11:28 -0700603 .WillOnce(Return(false));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800604 EXPECT_FALSE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700605
606 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(true));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800609 EXPECT_TRUE(PinHostRoute(connection, trusted_ip, gateway));
Paul Stewarte93b0382012-04-24 13:11:28 -0700610
611 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200612 AddDestructorExpectations();
Paul Stewartf748a362012-03-07 12:01:20 -0800613}
614
Paul Stewart53a30382012-04-26 09:06:59 -0700615TEST_F(ConnectionTest, FixGatewayReachability) {
616 static const char kLocal[] = "10.242.2.13";
617 IPAddress local(IPAddress::kFamilyIPv4);
618 ASSERT_TRUE(local.SetAddressFromString(kLocal));
619 const int kPrefix = 24;
620 local.set_prefix(kPrefix);
621 IPAddress gateway(IPAddress::kFamilyIPv4);
622 IPAddress peer(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800623 IPAddress trusted_ip(IPAddress::kFamilyIPv4);
Paul Stewart53a30382012-04-26 09:06:59 -0700624
625 // Should fail because no gateway is set.
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800626 EXPECT_FALSE(Connection::FixGatewayReachability(
627 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700628 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700629 EXPECT_FALSE(peer.IsValid());
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800630 EXPECT_FALSE(gateway.IsValid());
Paul Stewart53a30382012-04-26 09:06:59 -0700631
632 // Should succeed because with the given prefix, this gateway is reachable.
633 static const char kReachableGateway[] = "10.242.2.14";
634 ASSERT_TRUE(gateway.SetAddressFromString(kReachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800635 IPAddress gateway_backup(gateway);
Paul Stewart49258292012-05-26 06:37:14 -0700636 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800637 EXPECT_TRUE(Connection::FixGatewayReachability(
638 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700639 // Prefix should remain unchanged.
640 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700641 // Peer should remain unchanged.
642 EXPECT_FALSE(peer.IsValid());
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800643 // Gateway should remain unchanged.
644 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700645
646 // Should succeed because we modified the prefix to match the gateway.
647 static const char kExpandableGateway[] = "10.242.3.14";
648 ASSERT_TRUE(gateway.SetAddressFromString(kExpandableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800649 gateway_backup = gateway;
Paul Stewart49258292012-05-26 06:37:14 -0700650 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800651 EXPECT_TRUE(Connection::FixGatewayReachability(
652 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700653 // Prefix should have opened up by 1 bit.
654 EXPECT_EQ(kPrefix - 1, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700655 // Peer should remain unchanged.
656 EXPECT_FALSE(peer.IsValid());
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800657 // Gateway should remain unchanged.
658 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700659
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700660 // Should change models to assuming point-to-point because we cannot
Paul Stewart49258292012-05-26 06:37:14 -0700661 // plausibly expand the prefix past 8.
Paul Stewart53a30382012-04-26 09:06:59 -0700662 local.set_prefix(kPrefix);
663 static const char kUnreachableGateway[] = "11.242.2.14";
664 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800665 gateway_backup = gateway;
Paul Stewart49258292012-05-26 06:37:14 -0700666 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800667 EXPECT_TRUE(Connection::FixGatewayReachability(
668 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700669 // Prefix should not have changed.
670 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700671 // Peer address should be set to the gateway address.
672 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800673 // Gateway should remain unchanged.
674 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700675
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700676 // Should also use point-to-point model if the netmask is set to the
677 // "all-ones" addresss, even if this address could have been made
678 // accessible by plausibly changing the prefix.
679 const int kIPv4MaxPrefix =
680 IPAddress::GetMaxPrefixLength(IPAddress::kFamilyIPv4);
681 local.set_prefix(kIPv4MaxPrefix);
682 ASSERT_TRUE(gateway.SetAddressFromString(kExpandableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800683 gateway_backup = gateway;
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700684 peer = IPAddress(IPAddress::kFamilyIPv4);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800685 EXPECT_TRUE(Connection::FixGatewayReachability(
686 &local, &peer, &gateway, trusted_ip));
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700687 // Prefix should not have changed.
688 EXPECT_EQ(kIPv4MaxPrefix, local.prefix());
689 // Peer address should be set to the gateway address.
690 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800691 // Gateway should remain unchanged.
692 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700693
Paul Stewart49258292012-05-26 06:37:14 -0700694 // If this is a peer-to-peer interface and the peer matches the gateway,
695 // we should succeed.
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700696 local.set_prefix(kPrefix);
697 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800698 gateway_backup = gateway;
Paul Stewart53a30382012-04-26 09:06:59 -0700699 ASSERT_TRUE(peer.SetAddressFromString(kUnreachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800700 EXPECT_TRUE(Connection::FixGatewayReachability(
701 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700702 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700703 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800704 EXPECT_TRUE(gateway_backup.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700705
706 // If there is a peer specified and it does not match the gateway (even
707 // if it was reachable via netmask), we should fail.
708 ASSERT_TRUE(gateway.SetAddressFromString(kReachableGateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800709 EXPECT_FALSE(Connection::FixGatewayReachability(
710 &local, &peer, &gateway, trusted_ip));
Paul Stewart53a30382012-04-26 09:06:59 -0700711 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700712 EXPECT_FALSE(peer.Equals(gateway));
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800713
714 // If this is a peer-to-peer interface and the peer matches the gateway,
715 // but it also matches the trusted IP address, the gateway and peer address
716 // should be modified to allow routing to work correctly.
717 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
718 ASSERT_TRUE(peer.SetAddressFromString(kUnreachableGateway));
719 ASSERT_TRUE(trusted_ip.SetAddressFromString(kUnreachableGateway));
720 EXPECT_TRUE(Connection::FixGatewayReachability(
721 &local, &peer, &gateway, trusted_ip));
722 EXPECT_TRUE(peer.IsDefault());
723 EXPECT_TRUE(gateway.IsDefault());
Paul Stewart53a30382012-04-26 09:06:59 -0700724}
725
Darin Petkov13e6d552012-05-09 14:22:23 +0200726TEST_F(ConnectionTest, Binders) {
727 EXPECT_TRUE(connection_->binders_.empty());
728 DisconnectCallbackTarget target0;
729 DisconnectCallbackTarget target1;
730 DisconnectCallbackTarget target2;
731 DisconnectCallbackTarget target3;
732 Connection::Binder binder0("binder0", target0.callback());
733 Connection::Binder binder1("binder1", target1.callback());
734 Connection::Binder binder2("binder2", target2.callback());
735 Connection::Binder binder3("binder3", target3.callback());
736
737 binder0.Attach(connection_);
738 binder1.Attach(connection_);
739
740 EXPECT_CALL(target1, CallTarget()).Times(0);
741 binder1.Attach(connection_);
742
743 binder3.Attach(connection_);
744 binder2.Attach(connection_);
745
746 EXPECT_CALL(target3, CallTarget()).Times(0);
Ben Chancc225ef2014-09-30 13:26:51 -0700747 binder3.Attach(nullptr);
Darin Petkov13e6d552012-05-09 14:22:23 +0200748
749 ASSERT_EQ(3, connection_->binders_.size());
750 EXPECT_TRUE(connection_->binders_.at(0) == &binder0);
751 EXPECT_TRUE(connection_->binders_.at(1) == &binder1);
752 EXPECT_TRUE(connection_->binders_.at(2) == &binder2);
753
754 EXPECT_CALL(target0, CallTarget()).Times(1);
755 EXPECT_CALL(target1, CallTarget()).Times(1);
756 EXPECT_CALL(target2, CallTarget()).Times(1);
757 connection_->NotifyBindersOnDisconnect();
758 EXPECT_TRUE(connection_->binders_.empty());
759
760 // Should be a no-op.
761 connection_->NotifyBindersOnDisconnect();
762}
763
764TEST_F(ConnectionTest, Binder) {
765 // No connection should be bound initially.
766 Connection::Binder *binder = &connection_->lower_binder_;
767 EXPECT_EQ(connection_->interface_name(), binder->name_);
768 EXPECT_FALSE(binder->client_disconnect_callback_.is_null());
769 EXPECT_FALSE(binder->IsBound());
770
771 ConnectionRefPtr connection1 = GetNewConnection();
772 EXPECT_TRUE(connection1->binders_.empty());
773
774 // Bind lower |connection1| and check if it's bound.
775 binder->Attach(connection1);
776 EXPECT_TRUE(binder->IsBound());
777 EXPECT_EQ(connection1.get(), binder->connection().get());
778 ASSERT_FALSE(connection1->binders_.empty());
779 EXPECT_TRUE(binder == connection1->binders_.at(0));
780
781 // Unbind lower |connection1| and check if it's unbound.
Ben Chancc225ef2014-09-30 13:26:51 -0700782 binder->Attach(nullptr);
Darin Petkov13e6d552012-05-09 14:22:23 +0200783 EXPECT_FALSE(binder->IsBound());
784 EXPECT_TRUE(connection1->binders_.empty());
785
786 ConnectionRefPtr connection2 = GetNewConnection();
787
788 // Bind lower |connection1| to upper |connection2| and destroy the upper
789 // |connection2|. Make sure lower |connection1| is unbound (i.e., the
790 // disconnect callback is deregistered).
791 connection2->lower_binder_.Attach(connection1);
792 EXPECT_FALSE(connection1->binders_.empty());
793 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700794 connection2 = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200795 EXPECT_TRUE(connection1->binders_.empty());
796
797 // Bind lower |connection1| to upper |connection_| and destroy lower
798 // |connection1|. Make sure lower |connection1| is unbound from upper
799 // |connection_| and upper |connection_|'s registered disconnect callbacks are
800 // run.
801 binder->Attach(connection1);
802 DisconnectCallbackTarget target;
803 Connection::Binder test_binder("from_test", target.callback());
804 test_binder.Attach(connection_);
805 EXPECT_CALL(target, CallTarget()).Times(1);
806 ASSERT_FALSE(connection_->binders_.empty());
807 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700808 connection1 = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200809 EXPECT_FALSE(binder->IsBound());
810 EXPECT_FALSE(test_binder.IsBound());
811 EXPECT_TRUE(connection_->binders_.empty());
812
813 {
814 // Binding a connection to itself should be safe.
815 ConnectionRefPtr connection = GetNewConnection();
816
817 connection->lower_binder_.Attach(connection);
818
819 EXPECT_FALSE(connection->binders_.empty());
820
821 DisconnectCallbackTarget target;
822 Connection::Binder binder("test", target.callback());
823 binder.Attach(connection);
824
825 AddDestructorExpectations();
826 EXPECT_CALL(target, CallTarget()).Times(1);
Ben Chancc225ef2014-09-30 13:26:51 -0700827 connection = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200828 }
Darin Petkov13e6d552012-05-09 14:22:23 +0200829 {
830 // Circular binding of multiple connections should be safe.
831 ConnectionRefPtr connection_a = GetNewConnection();
832 ConnectionRefPtr connection_b = GetNewConnection();
833
834 connection_a->lower_binder_.Attach(connection_b);
835 connection_b->lower_binder_.Attach(connection_a);
836
837 EXPECT_FALSE(connection_a->binders_.empty());
838 EXPECT_FALSE(connection_b->binders_.empty());
839
840 DisconnectCallbackTarget target_a;
841 DisconnectCallbackTarget target_b;
842 Connection::Binder binder_a("test_a", target_a.callback());
843 Connection::Binder binder_b("test_b", target_b.callback());
844 binder_a.Attach(connection_a);
845 binder_b.Attach(connection_b);
846
847 AddDestructorExpectations();
848 EXPECT_CALL(target_a, CallTarget()).Times(1);
849 EXPECT_CALL(target_b, CallTarget()).Times(1);
Ben Chancc225ef2014-09-30 13:26:51 -0700850 connection_b = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200851
852 EXPECT_TRUE(connection_a->binders_.empty());
853
854 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700855 connection_a = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200856 }
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200857 {
858 // Test the weak pointer to the bound Connection. This is not a case that
859 // should occur but the weak pointer should handle it gracefully.
860 DisconnectCallbackTarget target;
861 Connection::Binder binder("test_weak", target.callback());
862 ConnectionRefPtr connection = GetNewConnection();
863 binder.Attach(connection);
864
865 // Make sure the connection doesn't notify the binder on destruction.
866 connection->binders_.clear();
867 AddDestructorExpectations();
868 EXPECT_CALL(target, CallTarget()).Times(0);
Ben Chancc225ef2014-09-30 13:26:51 -0700869 connection = nullptr;
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200870
Ben Chancc225ef2014-09-30 13:26:51 -0700871 // Ensure no crash -- the weak pointer to connection should be nullptr.
Darin Petkov5eb05422012-05-11 15:45:25 +0200872 EXPECT_FALSE(binder.connection());
Ben Chancc225ef2014-09-30 13:26:51 -0700873 binder.Attach(nullptr);
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200874 }
Darin Petkov13e6d552012-05-09 14:22:23 +0200875}
876
877TEST_F(ConnectionTest, OnRouteQueryResponse) {
878 Connection::Binder *binder = &connection_->lower_binder_;
879 ConnectionRefPtr connection = GetNewConnection();
880 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
881 &control_,
Ben Chancc225ef2014-09-30 13:26:51 -0700882 nullptr,
883 nullptr,
884 nullptr,
Darin Petkov13e6d552012-05-09 14:22:23 +0200885 kTestDeviceName1,
886 string(),
887 kTestDeviceInterfaceIndex1));
888
889 // Make sure we unbind the old lower connection even if we can't lookup the
890 // lower connection device.
891 binder->Attach(connection);
892 scoped_refptr<MockDevice> null_device;
893 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
894 .WillOnce(Return(null_device));
895 connection_->OnRouteQueryResponse(
896 kTestDeviceInterfaceIndex1, RoutingTableEntry());
897 EXPECT_FALSE(binder->IsBound());
898
899 // Check for graceful handling of a device with no connection.
900 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
901 .WillOnce(Return(device));
902 connection_->OnRouteQueryResponse(
903 kTestDeviceInterfaceIndex1, RoutingTableEntry());
904 EXPECT_FALSE(binder->IsBound());
905
mukesh agrawalf407d592013-07-31 11:37:57 -0700906 // Create a mock connection that will be used for binding.
Paul Stewart4a6748d2012-07-17 14:31:36 -0700907 scoped_refptr<MockConnection> mock_connection(
908 new StrictMock<MockConnection>(device_info_.get()));
909 EXPECT_CALL(*device_info_.get(),
910 FlushAddresses(mock_connection->interface_index()));
911 const string kInterfaceName(kTestDeviceName0);
912 EXPECT_CALL(*mock_connection, interface_name())
913 .WillRepeatedly(ReturnRef(kInterfaceName));
914 device->connection_ = mock_connection;
Darin Petkov13e6d552012-05-09 14:22:23 +0200915 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
916 .WillOnce(Return(device));
Paul Stewart4a6748d2012-07-17 14:31:36 -0700917
Ben Chana6bfe872012-09-26 09:48:34 -0700918 // Check that the binding process completes, causing its upper
Paul Stewart4a6748d2012-07-17 14:31:36 -0700919 // connection to create a gateway route.
920 EXPECT_CALL(*mock_connection, CreateGatewayRoute())
921 .WillOnce(Return(true));
Paul Stewart8596f9f2013-03-14 07:58:26 -0700922
923 // Ensure that the Device is notified of the change to the connection.
924 EXPECT_CALL(*device, OnConnectionUpdated()).Times(1);
Darin Petkov13e6d552012-05-09 14:22:23 +0200925 connection_->OnRouteQueryResponse(
926 kTestDeviceInterfaceIndex1, RoutingTableEntry());
Paul Stewart4a6748d2012-07-17 14:31:36 -0700927
928 // Check that the upper connection is bound to the lower connection.
Darin Petkov13e6d552012-05-09 14:22:23 +0200929 EXPECT_TRUE(binder->IsBound());
Paul Stewart4a6748d2012-07-17 14:31:36 -0700930 EXPECT_EQ(mock_connection.get(), binder->connection().get());
Darin Petkov13e6d552012-05-09 14:22:23 +0200931
Ben Chancc225ef2014-09-30 13:26:51 -0700932 device->connection_ = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200933 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700934 connection = nullptr;
Darin Petkov13e6d552012-05-09 14:22:23 +0200935}
936
Alex Deymofddc09a2013-07-03 18:41:31 -0700937TEST_F(ConnectionTest, GetCarrierConnection) {
938 EXPECT_EQ(connection_.get(), connection_->GetCarrierConnection().get());
939
940 ConnectionRefPtr connection1 = GetNewConnection();
941 ConnectionRefPtr connection2 = GetNewConnection();
942 ConnectionRefPtr connection3 = GetNewConnection();
943
944 connection_->lower_binder_.Attach(connection1);
945 EXPECT_EQ(connection1.get(), connection_->GetCarrierConnection().get());
946
947 connection1->lower_binder_.Attach(connection2);
948 EXPECT_EQ(connection2.get(), connection_->GetCarrierConnection().get());
949
950 connection2->lower_binder_.Attach(connection3);
951 EXPECT_EQ(connection3.get(), connection_->GetCarrierConnection().get());
952
953 // Create a cycle back to |connection1|.
954 connection3->lower_binder_.Attach(connection1);
Ben Chancc225ef2014-09-30 13:26:51 -0700955 EXPECT_EQ(nullptr, connection_->GetCarrierConnection().get());
Alex Deymofddc09a2013-07-03 18:41:31 -0700956
957 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700958 connection3 = nullptr;
Alex Deymofddc09a2013-07-03 18:41:31 -0700959
960 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700961 connection2 = nullptr;
Alex Deymofddc09a2013-07-03 18:41:31 -0700962
963 AddDestructorExpectations();
Ben Chancc225ef2014-09-30 13:26:51 -0700964 connection1 = nullptr;
Alex Deymofddc09a2013-07-03 18:41:31 -0700965}
966
Paul Stewartdd60e452011-08-08 11:38:36 -0700967} // namespace shill