blob: c9c45e1fe39b392560b929245eaf12011b51049e [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
Paul Stewartc8f4bef2011-12-13 09:45:51 -08008#include <string>
Paul Stewart9a908082011-08-31 12:18:48 -07009#include <vector>
10
11#include <base/memory/scoped_ptr.h>
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;
32using testing::StrictMock;
33using testing::Test;
34
35namespace shill {
36
37namespace {
38const char kTestDeviceName0[] = "netdev0";
39const int kTestDeviceInterfaceIndex0 = 123;
40const char kTestDeviceName1[] = "netdev1";
41const int kTestDeviceInterfaceIndex1 = 321;
42const char kIPAddress0[] = "192.168.1.1";
43const char kGatewayAddress0[] = "192.168.1.254";
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070044const char kGatewayAddress1[] = "192.168.2.254";
Paul Stewart9a908082011-08-31 12:18:48 -070045const char kBroadcastAddress0[] = "192.168.1.255";
Paul Stewartdd60e452011-08-08 11:38:36 -070046const char kNameServer0[] = "8.8.8.8";
47const char kNameServer1[] = "8.8.9.9";
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070048const int32 kPrefix0 = 24;
49const int32 kPrefix1 = 31;
Paul Stewartdd60e452011-08-08 11:38:36 -070050const char kSearchDomain0[] = "chromium.org";
51const char kSearchDomain1[] = "google.com";
52} // namespace {}
53
54class ConnectionTest : public Test {
55 public:
56 ConnectionTest()
Paul Stewart9a908082011-08-31 12:18:48 -070057 : device_info_(new StrictMock<MockDeviceInfo>(
58 &control_,
59 static_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080060 static_cast<Metrics*>(NULL),
Paul Stewart9a908082011-08-31 12:18:48 -070061 static_cast<Manager*>(NULL))),
62 connection_(new Connection(
63 kTestDeviceInterfaceIndex0,
64 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -070065 Technology::kUnknown,
Paul Stewart9a908082011-08-31 12:18:48 -070066 device_info_.get())),
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070067 ipconfig_(new IPConfig(&control_, kTestDeviceName0)),
68 local_address_(IPAddress::kFamilyIPv4),
69 broadcast_address_(IPAddress::kFamilyIPv4),
70 gateway_address_(IPAddress::kFamilyIPv4),
71 default_address_(IPAddress::kFamilyIPv4) {}
Paul Stewartdd60e452011-08-08 11:38:36 -070072
73 virtual void SetUp() {
Paul Stewartc8f4bef2011-12-13 09:45:51 -080074 ReplaceSingletons(connection_);
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070075 properties_.address = kIPAddress0;
76 properties_.subnet_prefix = kPrefix0;
77 properties_.gateway = kGatewayAddress0;
78 properties_.broadcast_address = kBroadcastAddress0;
79 properties_.dns_servers.push_back(kNameServer0);
80 properties_.dns_servers.push_back(kNameServer1);
81 properties_.domain_search.push_back(kSearchDomain0);
82 properties_.domain_search.push_back(kSearchDomain1);
83 properties_.address_family = IPAddress::kFamilyIPv4;
84 UpdateProperties();
85 EXPECT_TRUE(local_address_.SetAddressFromString(kIPAddress0));
86 EXPECT_TRUE(broadcast_address_.SetAddressFromString(kBroadcastAddress0));
87 EXPECT_TRUE(gateway_address_.SetAddressFromString(kGatewayAddress0));
Paul Stewartdd60e452011-08-08 11:38:36 -070088 }
89
Paul Stewart9a908082011-08-31 12:18:48 -070090 virtual void TearDown() {
Darin Petkov13e6d552012-05-09 14:22:23 +020091 AddDestructorExpectations();
Paul Stewarte93b0382012-04-24 13:11:28 -070092 connection_ = NULL;
Paul Stewart9a908082011-08-31 12:18:48 -070093 }
94
Paul Stewartc8f4bef2011-12-13 09:45:51 -080095 void ReplaceSingletons(ConnectionRefPtr connection) {
96 connection->resolver_ = &resolver_;
97 connection->routing_table_ = &routing_table_;
98 connection->rtnl_handler_ = &rtnl_handler_;
99 }
100
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700101 void UpdateProperties() {
102 ipconfig_->UpdateProperties(properties_, true);
103 }
104
Paul Stewarte93b0382012-04-24 13:11:28 -0700105 bool PinHostRoute(ConnectionRefPtr connection,
106 const IPConfig::Properties &properties) {
107 return connection->PinHostRoute(properties);
108 }
109
Paul Stewartdd60e452011-08-08 11:38:36 -0700110 protected:
Darin Petkov13e6d552012-05-09 14:22:23 +0200111 class DisconnectCallbackTarget {
112 public:
113 DisconnectCallbackTarget()
114 : callback_(base::Bind(&DisconnectCallbackTarget::CallTarget,
115 base::Unretained(this))) {}
116
117 MOCK_METHOD0(CallTarget, void());
118 const base::Closure &callback() { return callback_; }
119
120 private:
121 base::Closure callback_;
122 };
123
124 void AddDestructorExpectations() {
125 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
126 EXPECT_CALL(routing_table_, FlushRoutesWithTag(kTestDeviceInterfaceIndex0));
127 EXPECT_CALL(*device_info_.get(),
128 FlushAddresses(kTestDeviceInterfaceIndex0));
129 }
130
131 // Returns a new test connection object. The caller usually needs to call
132 // AddDestructorExpectations before destroying the object.
133 ConnectionRefPtr GetNewConnection() {
134 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
135 kTestDeviceName0,
136 Technology::kUnknown,
137 device_info_.get()));
138 ReplaceSingletons(connection);
139 return connection;
140 }
141
Paul Stewart9a908082011-08-31 12:18:48 -0700142 scoped_ptr<StrictMock<MockDeviceInfo> > device_info_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700143 ConnectionRefPtr connection_;
144 MockControl control_;
145 IPConfigRefPtr ipconfig_;
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700146 IPConfig::Properties properties_;
147 IPAddress local_address_;
148 IPAddress broadcast_address_;
149 IPAddress gateway_address_;
150 IPAddress default_address_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700151 StrictMock<MockResolver> resolver_;
152 StrictMock<MockRoutingTable> routing_table_;
153 StrictMock<MockRTNLHandler> rtnl_handler_;
154};
155
Darin Petkov13e6d552012-05-09 14:22:23 +0200156namespace {
Paul Stewartdd60e452011-08-08 11:38:36 -0700157
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700158MATCHER_P2(IsIPAddress, address, prefix, "") {
159 IPAddress match_address(address);
160 match_address.set_prefix(prefix);
161 return match_address.Equals(arg);
162}
163
Darin Petkov13e6d552012-05-09 14:22:23 +0200164MATCHER(IsNonNullCallback, "") {
165 return !arg.is_null();
166}
167
168} // namespace
169
170TEST_F(ConnectionTest, InitState) {
171 EXPECT_EQ(kTestDeviceInterfaceIndex0, connection_->interface_index_);
172 EXPECT_EQ(kTestDeviceName0, connection_->interface_name_);
173 EXPECT_FALSE(connection_->is_default());
174 EXPECT_FALSE(connection_->routing_request_count_);
175}
176
Paul Stewartdd60e452011-08-08 11:38:36 -0700177TEST_F(ConnectionTest, AddConfig) {
178 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700179 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
180 IsIPAddress(local_address_, kPrefix0),
181 IsIPAddress(broadcast_address_, 0),
182 IsIPAddress(default_address_, 0)));
Paul Stewart7cfca042011-12-08 14:18:17 -0800183 EXPECT_CALL(routing_table_,
184 SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700185 IsIPAddress(gateway_address_, 0),
Paul Stewart7cfca042011-12-08 14:18:17 -0800186 Connection::kNonDefaultMetricBase +
187 kTestDeviceInterfaceIndex0));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700188 EXPECT_CALL(routing_table_,
189 ConfigureRoutes(kTestDeviceInterfaceIndex0,
190 ipconfig_,
191 Connection::kDefaultMetric));
Paul Stewartdd60e452011-08-08 11:38:36 -0700192 connection_->UpdateFromIPConfig(ipconfig_);
193
194 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
195 Connection::kDefaultMetric));
196 EXPECT_CALL(resolver_, SetDNSFromLists(
197 ipconfig_->properties().dns_servers,
198 ipconfig_->properties().domain_search));
199
Paul Stewartc681fa02012-03-02 19:40:04 -0800200 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
201 &control_,
202 reinterpret_cast<EventDispatcher *>(NULL),
203 reinterpret_cast<Metrics *>(NULL),
204 reinterpret_cast<Manager *>(NULL),
205 kTestDeviceName0,
206 string(),
207 kTestDeviceInterfaceIndex0));
208 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
209 .WillOnce(Return(device));
210 EXPECT_CALL(*device.get(), RequestPortalDetection())
211 .WillOnce(Return(true));
Paul Stewarte78ec542012-06-08 18:28:50 -0700212 EXPECT_CALL(routing_table_, FlushCache())
213 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800214 connection_->SetIsDefault(true);
Paul Stewarte78ec542012-06-08 18:28:50 -0700215 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700216 EXPECT_TRUE(connection_->is_default());
217
Paul Stewart7cfca042011-12-08 14:18:17 -0800218 EXPECT_CALL(routing_table_,
219 SetDefaultMetric(kTestDeviceInterfaceIndex0,
220 Connection::kNonDefaultMetricBase +
221 kTestDeviceInterfaceIndex0));
Paul Stewarte78ec542012-06-08 18:28:50 -0700222 EXPECT_CALL(routing_table_, FlushCache())
223 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800224 connection_->SetIsDefault(false);
Paul Stewartdd60e452011-08-08 11:38:36 -0700225 EXPECT_FALSE(connection_->is_default());
226}
227
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700228TEST_F(ConnectionTest, AddConfigWithPeer) {
229 const string kPeerAddress("192.168.1.222");
230 IPAddress peer_address(IPAddress::kFamilyIPv4);
231 EXPECT_TRUE(peer_address.SetAddressFromString(kPeerAddress));
232 properties_.peer_address = kPeerAddress;
233 properties_.gateway = string();
234 UpdateProperties();
235 EXPECT_CALL(rtnl_handler_,
236 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
237 IsIPAddress(local_address_, kPrefix0),
238 IsIPAddress(broadcast_address_, 0),
239 IsIPAddress(peer_address, 0)));
240 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _)).Times(0);
241 EXPECT_CALL(routing_table_,
242 ConfigureRoutes(kTestDeviceInterfaceIndex0,
243 ipconfig_,
244 Connection::kDefaultMetric));
245 connection_->UpdateFromIPConfig(ipconfig_);
246}
247
248TEST_F(ConnectionTest, AddConfigWithBrokenNetmask) {
249 // Assign a prefix that makes the gateway unreachable.
250 properties_.subnet_prefix = kPrefix1;
251 UpdateProperties();
252
253 // Connection should override with a prefix which will allow the
254 // gateway to be reachable.
255 EXPECT_CALL(rtnl_handler_,
256 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
257 IsIPAddress(local_address_, kPrefix0),
258 IsIPAddress(broadcast_address_, 0),
259 IsIPAddress(default_address_, 0)));
260 EXPECT_CALL(routing_table_,
261 SetDefaultRoute(kTestDeviceInterfaceIndex0,
262 IsIPAddress(gateway_address_, 0),
263 Connection::kNonDefaultMetricBase +
264 kTestDeviceInterfaceIndex0));
265 EXPECT_CALL(routing_table_,
266 ConfigureRoutes(kTestDeviceInterfaceIndex0,
267 ipconfig_,
268 Connection::kDefaultMetric));
269 connection_->UpdateFromIPConfig(ipconfig_);
270
271 // Assign a gateway address that violates the minimum plausible prefix
272 // the Connection can assign.
273 properties_.gateway = kGatewayAddress1;
274 UpdateProperties();
275
Paul Stewart49258292012-05-26 06:37:14 -0700276 IPAddress gateway_address1(IPAddress::kFamilyIPv4);
277 EXPECT_TRUE(gateway_address1.SetAddressFromString(kGatewayAddress1));
278 // Connection cannot override this prefix, so it will switch to a
279 // model where the peer address is set to the value of the gateway
280 // address.
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700281 EXPECT_CALL(rtnl_handler_,
282 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
283 IsIPAddress(local_address_, kPrefix1),
284 IsIPAddress(broadcast_address_, 0),
Paul Stewart49258292012-05-26 06:37:14 -0700285 IsIPAddress(gateway_address1, 0)));
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700286 EXPECT_CALL(routing_table_,
287 SetDefaultRoute(kTestDeviceInterfaceIndex0, _, _));
288 EXPECT_CALL(routing_table_,
289 ConfigureRoutes(kTestDeviceInterfaceIndex0, _, _));
290 connection_->UpdateFromIPConfig(ipconfig_);
291}
292
Paul Stewartdd60e452011-08-08 11:38:36 -0700293TEST_F(ConnectionTest, AddConfigReverse) {
294 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
295 Connection::kDefaultMetric));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800296 vector<string> empty_list;
Paul Stewartdd60e452011-08-08 11:38:36 -0700297 EXPECT_CALL(resolver_, SetDNSFromLists(empty_list, empty_list));
Paul Stewartc681fa02012-03-02 19:40:04 -0800298 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
299 &control_,
300 reinterpret_cast<EventDispatcher *>(NULL),
301 reinterpret_cast<Metrics *>(NULL),
302 reinterpret_cast<Manager *>(NULL),
303 kTestDeviceName0,
304 string(),
305 kTestDeviceInterfaceIndex0));
306 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
307 .WillOnce(Return(device));
308 EXPECT_CALL(*device.get(), RequestPortalDetection())
309 .WillOnce(Return(true));
Paul Stewarte78ec542012-06-08 18:28:50 -0700310 EXPECT_CALL(routing_table_, FlushCache())
311 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800312 connection_->SetIsDefault(true);
Paul Stewarte78ec542012-06-08 18:28:50 -0700313 Mock::VerifyAndClearExpectations(&routing_table_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700314
315 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700316 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
317 IsIPAddress(local_address_, kPrefix0),
318 IsIPAddress(broadcast_address_, 0),
319 IsIPAddress(default_address_, 0)));
Paul Stewartdd60e452011-08-08 11:38:36 -0700320 EXPECT_CALL(routing_table_, SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700321 IsIPAddress(gateway_address_, 0),
322 Connection::kDefaultMetric));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700323 EXPECT_CALL(routing_table_,
324 ConfigureRoutes(kTestDeviceInterfaceIndex0,
325 ipconfig_,
326 Connection::kDefaultMetric));
Paul Stewartdd60e452011-08-08 11:38:36 -0700327 EXPECT_CALL(resolver_, SetDNSFromIPConfig(ipconfig_));
328
329 connection_->UpdateFromIPConfig(ipconfig_);
330}
331
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800332TEST_F(ConnectionTest, RouteRequest) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200333 ConnectionRefPtr connection = GetNewConnection();
Paul Stewartf748a362012-03-07 12:01:20 -0800334 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
335 &control_,
336 reinterpret_cast<EventDispatcher *>(NULL),
337 reinterpret_cast<Metrics *>(NULL),
338 reinterpret_cast<Manager *>(NULL),
339 kTestDeviceName0,
340 string(),
341 kTestDeviceInterfaceIndex0));
342 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
343 .WillRepeatedly(Return(device));
344 EXPECT_CALL(*device.get(), DisableReversePathFilter()).Times(1);
345 connection->RequestRouting();
346 connection->RequestRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800347
Paul Stewartf748a362012-03-07 12:01:20 -0800348 // The first release should only decrement the reference counter.
349 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800350
Paul Stewartf748a362012-03-07 12:01:20 -0800351 // Another release will re-enable reverse-path filter.
352 EXPECT_CALL(*device.get(), EnableReversePathFilter());
353 EXPECT_CALL(routing_table_, FlushCache());
354 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800355
Paul Stewartf748a362012-03-07 12:01:20 -0800356 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200357 AddDestructorExpectations();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800358}
359
Paul Stewartdd60e452011-08-08 11:38:36 -0700360TEST_F(ConnectionTest, Destructor) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200361 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex1,
362 kTestDeviceName1,
363 Technology::kUnknown,
364 device_info_.get()));
365 connection->resolver_ = &resolver_;
366 connection->routing_table_ = &routing_table_;
367 connection->rtnl_handler_ = &rtnl_handler_;
Thieu Lefb46caf2012-03-08 11:57:15 -0800368 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex1));
Paul Stewarte93b0382012-04-24 13:11:28 -0700369 EXPECT_CALL(routing_table_, FlushRoutesWithTag(kTestDeviceInterfaceIndex1));
Paul Stewart9a908082011-08-31 12:18:48 -0700370 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex1));
Darin Petkov13e6d552012-05-09 14:22:23 +0200371 connection = NULL;
Paul Stewartdd60e452011-08-08 11:38:36 -0700372}
373
Paul Stewartf748a362012-03-07 12:01:20 -0800374TEST_F(ConnectionTest, RequestHostRoute) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200375 ConnectionRefPtr connection = GetNewConnection();
Paul Stewartf748a362012-03-07 12:01:20 -0800376 IPAddress address(IPAddress::kFamilyIPv4);
377 ASSERT_TRUE(address.SetAddressFromString(kIPAddress0));
378 size_t prefix_len = address.GetLength() * 8;
Darin Petkov13e6d552012-05-09 14:22:23 +0200379 EXPECT_CALL(routing_table_,
380 RequestRouteToHost(IsIPAddress(address, prefix_len),
381 -1,
382 kTestDeviceInterfaceIndex0,
383 IsNonNullCallback()))
Paul Stewartf748a362012-03-07 12:01:20 -0800384 .WillOnce(Return(true));
385 EXPECT_TRUE(connection->RequestHostRoute(address));
386
387 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200388 AddDestructorExpectations();
Paul Stewarte93b0382012-04-24 13:11:28 -0700389}
390
391TEST_F(ConnectionTest, PinHostRoute) {
392 static const char kGateway[] = "10.242.2.13";
393 static const char kNetwork[] = "10.242.2.1";
394
Darin Petkov13e6d552012-05-09 14:22:23 +0200395 ConnectionRefPtr connection = GetNewConnection();
Paul Stewarte93b0382012-04-24 13:11:28 -0700396
397 IPConfig::Properties props;
398 props.address_family = IPAddress::kFamilyIPv4;
399 EXPECT_FALSE(PinHostRoute(connection, props));
400
401 props.gateway = kGateway;
402 EXPECT_FALSE(PinHostRoute(connection, props));
403
404 props.gateway.clear();
405 props.trusted_ip = "xxx";
406 EXPECT_FALSE(PinHostRoute(connection, props));
407
408 props.gateway = kGateway;
409 EXPECT_FALSE(PinHostRoute(connection, props));
410
411 props.trusted_ip = kNetwork;
412 IPAddress address(IPAddress::kFamilyIPv4);
413 ASSERT_TRUE(address.SetAddressFromString(kNetwork));
414 size_t prefix_len = address.GetLength() * 8;
415 EXPECT_CALL(routing_table_, RequestRouteToHost(
Darin Petkovabf6d282012-05-08 15:49:05 +0200416 IsIPAddress(address, prefix_len), -1, kTestDeviceInterfaceIndex0, _))
Paul Stewarte93b0382012-04-24 13:11:28 -0700417 .WillOnce(Return(false));
418 EXPECT_FALSE(PinHostRoute(connection, props));
419
420 EXPECT_CALL(routing_table_, RequestRouteToHost(
Darin Petkovabf6d282012-05-08 15:49:05 +0200421 IsIPAddress(address, prefix_len), -1, kTestDeviceInterfaceIndex0, _))
Paul Stewarte93b0382012-04-24 13:11:28 -0700422 .WillOnce(Return(true));
423 EXPECT_TRUE(PinHostRoute(connection, props));
424
425 // The destructor will remove the routes and addresses.
Darin Petkov13e6d552012-05-09 14:22:23 +0200426 AddDestructorExpectations();
Paul Stewartf748a362012-03-07 12:01:20 -0800427}
428
Paul Stewart53a30382012-04-26 09:06:59 -0700429TEST_F(ConnectionTest, FixGatewayReachability) {
430 static const char kLocal[] = "10.242.2.13";
431 IPAddress local(IPAddress::kFamilyIPv4);
432 ASSERT_TRUE(local.SetAddressFromString(kLocal));
433 const int kPrefix = 24;
434 local.set_prefix(kPrefix);
435 IPAddress gateway(IPAddress::kFamilyIPv4);
436 IPAddress peer(IPAddress::kFamilyIPv4);
437
438 // Should fail because no gateway is set.
Paul Stewart49258292012-05-26 06:37:14 -0700439 EXPECT_FALSE(Connection::FixGatewayReachability(&local, &peer, gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700440 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700441 EXPECT_FALSE(peer.IsValid());
Paul Stewart53a30382012-04-26 09:06:59 -0700442
443 // Should succeed because with the given prefix, this gateway is reachable.
444 static const char kReachableGateway[] = "10.242.2.14";
445 ASSERT_TRUE(gateway.SetAddressFromString(kReachableGateway));
Paul Stewart49258292012-05-26 06:37:14 -0700446 peer = IPAddress(IPAddress::kFamilyIPv4);
447 EXPECT_TRUE(Connection::FixGatewayReachability(&local, &peer, gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700448 // Prefix should remain unchanged.
449 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700450 // Peer should remain unchanged.
451 EXPECT_FALSE(peer.IsValid());
Paul Stewart53a30382012-04-26 09:06:59 -0700452
453 // Should succeed because we modified the prefix to match the gateway.
454 static const char kExpandableGateway[] = "10.242.3.14";
455 ASSERT_TRUE(gateway.SetAddressFromString(kExpandableGateway));
Paul Stewart49258292012-05-26 06:37:14 -0700456 peer = IPAddress(IPAddress::kFamilyIPv4);
457 EXPECT_TRUE(Connection::FixGatewayReachability(&local, &peer, gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700458 // Prefix should have opened up by 1 bit.
459 EXPECT_EQ(kPrefix - 1, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700460 // Peer should remain unchanged.
461 EXPECT_FALSE(peer.IsValid());
Paul Stewart53a30382012-04-26 09:06:59 -0700462
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700463 // Should change models to assuming point-to-point because we cannot
Paul Stewart49258292012-05-26 06:37:14 -0700464 // plausibly expand the prefix past 8.
Paul Stewart53a30382012-04-26 09:06:59 -0700465 local.set_prefix(kPrefix);
466 static const char kUnreachableGateway[] = "11.242.2.14";
467 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
Paul Stewart49258292012-05-26 06:37:14 -0700468 peer = IPAddress(IPAddress::kFamilyIPv4);
469 EXPECT_TRUE(Connection::FixGatewayReachability(&local, &peer, gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700470 // Prefix should not have changed.
471 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700472 // Peer address should be set to the gateway address.
473 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700474
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700475 // Should also use point-to-point model if the netmask is set to the
476 // "all-ones" addresss, even if this address could have been made
477 // accessible by plausibly changing the prefix.
478 const int kIPv4MaxPrefix =
479 IPAddress::GetMaxPrefixLength(IPAddress::kFamilyIPv4);
480 local.set_prefix(kIPv4MaxPrefix);
481 ASSERT_TRUE(gateway.SetAddressFromString(kExpandableGateway));
482 peer = IPAddress(IPAddress::kFamilyIPv4);
483 EXPECT_TRUE(Connection::FixGatewayReachability(&local, &peer, gateway));
484 // Prefix should not have changed.
485 EXPECT_EQ(kIPv4MaxPrefix, local.prefix());
486 // Peer address should be set to the gateway address.
487 EXPECT_TRUE(peer.Equals(gateway));
488
Paul Stewart49258292012-05-26 06:37:14 -0700489 // If this is a peer-to-peer interface and the peer matches the gateway,
490 // we should succeed.
Paul Stewart2aa5d7d2012-06-21 22:16:54 -0700491 local.set_prefix(kPrefix);
492 ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700493 ASSERT_TRUE(peer.SetAddressFromString(kUnreachableGateway));
Paul Stewart49258292012-05-26 06:37:14 -0700494 EXPECT_TRUE(Connection::FixGatewayReachability(&local, &peer, gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700495 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700496 EXPECT_TRUE(peer.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700497
498 // If there is a peer specified and it does not match the gateway (even
499 // if it was reachable via netmask), we should fail.
500 ASSERT_TRUE(gateway.SetAddressFromString(kReachableGateway));
Paul Stewart49258292012-05-26 06:37:14 -0700501 EXPECT_FALSE(Connection::FixGatewayReachability(&local, &peer, gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700502 EXPECT_EQ(kPrefix, local.prefix());
Paul Stewart49258292012-05-26 06:37:14 -0700503 EXPECT_FALSE(peer.Equals(gateway));
Paul Stewart53a30382012-04-26 09:06:59 -0700504}
505
Darin Petkov13e6d552012-05-09 14:22:23 +0200506TEST_F(ConnectionTest, Binders) {
507 EXPECT_TRUE(connection_->binders_.empty());
508 DisconnectCallbackTarget target0;
509 DisconnectCallbackTarget target1;
510 DisconnectCallbackTarget target2;
511 DisconnectCallbackTarget target3;
512 Connection::Binder binder0("binder0", target0.callback());
513 Connection::Binder binder1("binder1", target1.callback());
514 Connection::Binder binder2("binder2", target2.callback());
515 Connection::Binder binder3("binder3", target3.callback());
516
517 binder0.Attach(connection_);
518 binder1.Attach(connection_);
519
520 EXPECT_CALL(target1, CallTarget()).Times(0);
521 binder1.Attach(connection_);
522
523 binder3.Attach(connection_);
524 binder2.Attach(connection_);
525
526 EXPECT_CALL(target3, CallTarget()).Times(0);
527 binder3.Attach(NULL);
528
529 ASSERT_EQ(3, connection_->binders_.size());
530 EXPECT_TRUE(connection_->binders_.at(0) == &binder0);
531 EXPECT_TRUE(connection_->binders_.at(1) == &binder1);
532 EXPECT_TRUE(connection_->binders_.at(2) == &binder2);
533
534 EXPECT_CALL(target0, CallTarget()).Times(1);
535 EXPECT_CALL(target1, CallTarget()).Times(1);
536 EXPECT_CALL(target2, CallTarget()).Times(1);
537 connection_->NotifyBindersOnDisconnect();
538 EXPECT_TRUE(connection_->binders_.empty());
539
540 // Should be a no-op.
541 connection_->NotifyBindersOnDisconnect();
542}
543
544TEST_F(ConnectionTest, Binder) {
545 // No connection should be bound initially.
546 Connection::Binder *binder = &connection_->lower_binder_;
547 EXPECT_EQ(connection_->interface_name(), binder->name_);
548 EXPECT_FALSE(binder->client_disconnect_callback_.is_null());
549 EXPECT_FALSE(binder->IsBound());
550
551 ConnectionRefPtr connection1 = GetNewConnection();
552 EXPECT_TRUE(connection1->binders_.empty());
553
554 // Bind lower |connection1| and check if it's bound.
555 binder->Attach(connection1);
556 EXPECT_TRUE(binder->IsBound());
557 EXPECT_EQ(connection1.get(), binder->connection().get());
558 ASSERT_FALSE(connection1->binders_.empty());
559 EXPECT_TRUE(binder == connection1->binders_.at(0));
560
561 // Unbind lower |connection1| and check if it's unbound.
562 binder->Attach(NULL);
563 EXPECT_FALSE(binder->IsBound());
564 EXPECT_TRUE(connection1->binders_.empty());
565
566 ConnectionRefPtr connection2 = GetNewConnection();
567
568 // Bind lower |connection1| to upper |connection2| and destroy the upper
569 // |connection2|. Make sure lower |connection1| is unbound (i.e., the
570 // disconnect callback is deregistered).
571 connection2->lower_binder_.Attach(connection1);
572 EXPECT_FALSE(connection1->binders_.empty());
573 AddDestructorExpectations();
574 connection2 = NULL;
575 EXPECT_TRUE(connection1->binders_.empty());
576
577 // Bind lower |connection1| to upper |connection_| and destroy lower
578 // |connection1|. Make sure lower |connection1| is unbound from upper
579 // |connection_| and upper |connection_|'s registered disconnect callbacks are
580 // run.
581 binder->Attach(connection1);
582 DisconnectCallbackTarget target;
583 Connection::Binder test_binder("from_test", target.callback());
584 test_binder.Attach(connection_);
585 EXPECT_CALL(target, CallTarget()).Times(1);
586 ASSERT_FALSE(connection_->binders_.empty());
587 AddDestructorExpectations();
588 connection1 = NULL;
589 EXPECT_FALSE(binder->IsBound());
590 EXPECT_FALSE(test_binder.IsBound());
591 EXPECT_TRUE(connection_->binders_.empty());
592
593 {
594 // Binding a connection to itself should be safe.
595 ConnectionRefPtr connection = GetNewConnection();
596
597 connection->lower_binder_.Attach(connection);
598
599 EXPECT_FALSE(connection->binders_.empty());
600
601 DisconnectCallbackTarget target;
602 Connection::Binder binder("test", target.callback());
603 binder.Attach(connection);
604
605 AddDestructorExpectations();
606 EXPECT_CALL(target, CallTarget()).Times(1);
607 connection = NULL;
608 }
Darin Petkov13e6d552012-05-09 14:22:23 +0200609 {
610 // Circular binding of multiple connections should be safe.
611 ConnectionRefPtr connection_a = GetNewConnection();
612 ConnectionRefPtr connection_b = GetNewConnection();
613
614 connection_a->lower_binder_.Attach(connection_b);
615 connection_b->lower_binder_.Attach(connection_a);
616
617 EXPECT_FALSE(connection_a->binders_.empty());
618 EXPECT_FALSE(connection_b->binders_.empty());
619
620 DisconnectCallbackTarget target_a;
621 DisconnectCallbackTarget target_b;
622 Connection::Binder binder_a("test_a", target_a.callback());
623 Connection::Binder binder_b("test_b", target_b.callback());
624 binder_a.Attach(connection_a);
625 binder_b.Attach(connection_b);
626
627 AddDestructorExpectations();
628 EXPECT_CALL(target_a, CallTarget()).Times(1);
629 EXPECT_CALL(target_b, CallTarget()).Times(1);
630 connection_b = NULL;
631
632 EXPECT_TRUE(connection_a->binders_.empty());
633
634 AddDestructorExpectations();
635 connection_a = NULL;
636 }
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200637 {
638 // Test the weak pointer to the bound Connection. This is not a case that
639 // should occur but the weak pointer should handle it gracefully.
640 DisconnectCallbackTarget target;
641 Connection::Binder binder("test_weak", target.callback());
642 ConnectionRefPtr connection = GetNewConnection();
643 binder.Attach(connection);
644
645 // Make sure the connection doesn't notify the binder on destruction.
646 connection->binders_.clear();
647 AddDestructorExpectations();
648 EXPECT_CALL(target, CallTarget()).Times(0);
649 connection = NULL;
650
651 // Ensure no crash -- the weak pointer to connection should be NULL.
Darin Petkov5eb05422012-05-11 15:45:25 +0200652 EXPECT_FALSE(binder.connection());
Darin Petkovef1f9fe2012-05-11 16:51:52 +0200653 binder.Attach(NULL);
654 }
Darin Petkov13e6d552012-05-09 14:22:23 +0200655}
656
657TEST_F(ConnectionTest, OnRouteQueryResponse) {
658 Connection::Binder *binder = &connection_->lower_binder_;
659 ConnectionRefPtr connection = GetNewConnection();
660 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
661 &control_,
662 reinterpret_cast<EventDispatcher *>(NULL),
663 reinterpret_cast<Metrics *>(NULL),
664 reinterpret_cast<Manager *>(NULL),
665 kTestDeviceName1,
666 string(),
667 kTestDeviceInterfaceIndex1));
668
669 // Make sure we unbind the old lower connection even if we can't lookup the
670 // lower connection device.
671 binder->Attach(connection);
672 scoped_refptr<MockDevice> null_device;
673 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
674 .WillOnce(Return(null_device));
675 connection_->OnRouteQueryResponse(
676 kTestDeviceInterfaceIndex1, RoutingTableEntry());
677 EXPECT_FALSE(binder->IsBound());
678
679 // Check for graceful handling of a device with no connection.
680 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
681 .WillOnce(Return(device));
682 connection_->OnRouteQueryResponse(
683 kTestDeviceInterfaceIndex1, RoutingTableEntry());
684 EXPECT_FALSE(binder->IsBound());
685
686 // Check that the upper connection is bound to the lower connection.
687 device->connection_ = connection;
688 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex1))
689 .WillOnce(Return(device));
690 connection_->OnRouteQueryResponse(
691 kTestDeviceInterfaceIndex1, RoutingTableEntry());
692 EXPECT_TRUE(binder->IsBound());
693 EXPECT_EQ(connection.get(), binder->connection().get());
694
695 device->connection_ = NULL;
696 AddDestructorExpectations();
697 connection = NULL;
698}
699
Paul Stewartdd60e452011-08-08 11:38:36 -0700700} // namespace shill