1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/device.h"
18
19 #include <errno.h>
20 #include <netinet/in.h>
21 #include <linux/if.h> // NOLINT - Needs definitions from netinet/in.h
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/param.h>
25 #include <time.h>
26 #include <unistd.h>
27
28 #include <algorithm>
29 #include <set>
30 #include <string>
31 #include <vector>
32
33 #include <base/bind.h>
34 #include <base/files/file_util.h>
35 #include <base/memory/ref_counted.h>
36 #include <base/stl_util.h>
37 #include <base/strings/stringprintf.h>
38 #include <base/strings/string_number_conversions.h>
39 #include <base/strings/string_util.h>
40 #if defined(__ANDROID__)
41 #include <dbus/service_constants.h>
42 #else
43 #include <chromeos/dbus/service_constants.h>
44 #endif // __ANDROID__
45
46 #include "shill/async_connection.h"
47 #include "shill/connection.h"
48 #include "shill/connection_tester.h"
49 #include "shill/control_interface.h"
50 #include "shill/dhcp/dhcp_config.h"
51 #include "shill/dhcp/dhcp_provider.h"
52 #include "shill/dhcp_properties.h"
53 #include "shill/error.h"
54 #include "shill/event_dispatcher.h"
55 #include "shill/geolocation_info.h"
56 #include "shill/http_proxy.h"
57 #include "shill/icmp.h"
58 #include "shill/ip_address_store.h"
59 #include "shill/link_monitor.h"
60 #include "shill/logging.h"
61 #include "shill/manager.h"
62 #include "shill/metrics.h"
63 #include "shill/net/ip_address.h"
64 #include "shill/net/ndisc.h"
65 #include "shill/net/rtnl_handler.h"
66 #include "shill/property_accessor.h"
67 #include "shill/refptr_types.h"
68 #include "shill/service.h"
69 #include "shill/socket_info_reader.h"
70 #include "shill/store_interface.h"
71 #include "shill/technology.h"
72 #include "shill/tethering.h"
73 #include "shill/traffic_monitor.h"
74
75 using base::Bind;
76 using base::Callback;
77 using base::FilePath;
78 using base::StringPrintf;
79 using std::set;
80 using std::string;
81 using std::vector;
82
83 namespace shill {
84
85 namespace Logging {
86 static auto kModuleLogScope = ScopeLogger::kDevice;
ObjectID(Device * d)87 static string ObjectID(Device* d) { return d->GetRpcIdentifier(); }
88 }
89
90 // static
91 const char Device::kIPFlagTemplate[] = "/proc/sys/net/%s/conf/%s/%s";
92 // static
93 const char Device::kIPFlagVersion4[] = "ipv4";
94 // static
95 const char Device::kIPFlagVersion6[] = "ipv6";
96 // static
97 const char Device::kIPFlagDisableIPv6[] = "disable_ipv6";
98 // static
99 const char Device::kIPFlagUseTempAddr[] = "use_tempaddr";
100 // static
101 const char Device::kIPFlagUseTempAddrUsedAndDefault[] = "2";
102 // static
103 const char Device::kIPFlagReversePathFilter[] = "rp_filter";
104 // static
105 const char Device::kIPFlagReversePathFilterEnabled[] = "1";
106 // static
107 const char Device::kIPFlagReversePathFilterLooseMode[] = "2";
108 // static
109 const char Device::kIPFlagArpAnnounce[] = "arp_announce";
110 // static
111 const char Device::kIPFlagArpAnnounceDefault[] = "0";
112 // static
113 const char Device::kIPFlagArpAnnounceBestLocal[] = "2";
114 // static
115 const char Device::kIPFlagArpIgnore[] = "arp_ignore";
116 // static
117 const char Device::kIPFlagArpIgnoreDefault[] = "0";
118 // static
119 const char Device::kIPFlagArpIgnoreLocalOnly[] = "1";
120 // static
121 const char Device::kStoragePowered[] = "Powered";
122 // static
123 const char Device::kStorageReceiveByteCount[] = "ReceiveByteCount";
124 // static
125 const char Device::kStorageTransmitByteCount[] = "TransmitByteCount";
126 // static
127 const char Device::kFallbackDnsTestHostname[] = "www.gstatic.com";
128 // static
129 const char* Device::kFallbackDnsServers[] = {
130 "8.8.8.8",
131 "8.8.4.4"
132 };
133
134 // static
135 const int Device::kDNSTimeoutMilliseconds = 5000;
136 const int Device::kLinkUnreliableThresholdSeconds = 60 * 60;
137 const size_t Device::kHardwareAddressLength = 6U;
138
Device(ControlInterface * control_interface,EventDispatcher * dispatcher,Metrics * metrics,Manager * manager,const string & link_name,const string & address,int interface_index,Technology::Identifier technology)139 Device::Device(ControlInterface* control_interface,
140 EventDispatcher* dispatcher,
141 Metrics* metrics,
142 Manager* manager,
143 const string& link_name,
144 const string& address,
145 int interface_index,
146 Technology::Identifier technology)
147 : enabled_(false),
148 enabled_persistent_(true),
149 enabled_pending_(enabled_),
150 reconnect_(true),
151 hardware_address_(address),
152 interface_index_(interface_index),
153 running_(false),
154 link_name_(link_name),
155 unique_id_(link_name),
156 control_interface_(control_interface),
157 dispatcher_(dispatcher),
158 metrics_(metrics),
159 manager_(manager),
160 weak_ptr_factory_(this),
161 adaptor_(control_interface->CreateDeviceAdaptor(this)),
162 portal_detector_callback_(Bind(&Device::PortalDetectorCallback,
163 weak_ptr_factory_.GetWeakPtr())),
164 technology_(technology),
165 portal_attempts_to_online_(0),
166 receive_byte_offset_(0),
167 transmit_byte_offset_(0),
168 dhcp_provider_(DHCPProvider::GetInstance()),
169 rtnl_handler_(RTNLHandler::GetInstance()),
170 time_(Time::GetInstance()),
171 last_link_monitor_failed_time_(0),
172 connection_tester_callback_(Bind(&Device::ConnectionTesterCallback,
173 weak_ptr_factory_.GetWeakPtr())),
174 is_loose_routing_(false),
175 is_multi_homed_(false),
176 connection_diagnostics_callback_(
177 Bind(&Device::ConnectionDiagnosticsCallback,
178 weak_ptr_factory_.GetWeakPtr())) {
179 store_.RegisterConstString(kAddressProperty, &hardware_address_);
180
181 // kBgscanMethodProperty: Registered in WiFi
182 // kBgscanShortIntervalProperty: Registered in WiFi
183 // kBgscanSignalThresholdProperty: Registered in WiFi
184
185 // kCellularAllowRoamingProperty: Registered in Cellular
186 // kCarrierProperty: Registered in Cellular
187 // kEsnProperty: Registered in Cellular
188 // kHomeProviderProperty: Registered in Cellular
189 // kImeiProperty: Registered in Cellular
190 // kIccidProperty: Registered in Cellular
191 // kImsiProperty: Registered in Cellular
192 // kManufacturerProperty: Registered in Cellular
193 // kMdnProperty: Registered in Cellular
194 // kMeidProperty: Registered in Cellular
195 // kMinProperty: Registered in Cellular
196 // kModelIDProperty: Registered in Cellular
197 // kFirmwareRevisionProperty: Registered in Cellular
198 // kHardwareRevisionProperty: Registered in Cellular
199 // kPRLVersionProperty: Registered in Cellular
200 // kSIMLockStatusProperty: Registered in Cellular
201 // kFoundNetworksProperty: Registered in Cellular
202 // kDBusObjectProperty: Register in Cellular
203
204 store_.RegisterConstString(kInterfaceProperty, &link_name_);
205 HelpRegisterConstDerivedRpcIdentifier(
206 kSelectedServiceProperty, &Device::GetSelectedServiceRpcIdentifier);
207 HelpRegisterConstDerivedRpcIdentifiers(kIPConfigsProperty,
208 &Device::AvailableIPConfigs);
209 store_.RegisterConstString(kNameProperty, &link_name_);
210 store_.RegisterConstBool(kPoweredProperty, &enabled_);
211 HelpRegisterConstDerivedString(kTypeProperty,
212 &Device::GetTechnologyString);
213 HelpRegisterConstDerivedUint64(kLinkMonitorResponseTimeProperty,
214 &Device::GetLinkMonitorResponseTime);
215
216 // TODO(cmasone): Chrome doesn't use this...does anyone?
217 // store_.RegisterConstBool(kReconnectProperty, &reconnect_);
218
219 // TODO(cmasone): Figure out what shill concept maps to flimflam's "Network".
220 // known_properties_.push_back(kNetworksProperty);
221
222 // kRoamThresholdProperty: Registered in WiFi
223 // kScanningProperty: Registered in WiFi, Cellular
224 // kScanIntervalProperty: Registered in WiFi, Cellular
225 // kWakeOnWiFiFeaturesEnabledProperty: Registered in WiFi
226
227 if (manager_ && manager_->device_info()) { // Unit tests may not have these.
228 manager_->device_info()->GetByteCounts(
229 interface_index_, &receive_byte_offset_, &transmit_byte_offset_);
230 HelpRegisterConstDerivedUint64(kReceiveByteCountProperty,
231 &Device::GetReceiveByteCountProperty);
232 HelpRegisterConstDerivedUint64(kTransmitByteCountProperty,
233 &Device::GetTransmitByteCountProperty);
234 }
235
236 LOG(INFO) << "Device created: " << link_name_
237 << " index " << interface_index_;
238 }
239
~Device()240 Device::~Device() {
241 LOG(INFO) << "Device destructed: " << link_name_
242 << " index " << interface_index_;
243 }
244
Initialize()245 void Device::Initialize() {
246 SLOG(this, 2) << "Initialized";
247 DisableArpFiltering();
248 EnableReversePathFilter();
249 }
250
LinkEvent(unsigned flags,unsigned change)251 void Device::LinkEvent(unsigned flags, unsigned change) {
252 SLOG(this, 2) << "Device " << link_name_
253 << std::showbase << std::hex
254 << " flags " << flags << " changed " << change
255 << std::dec << std::noshowbase;
256 }
257
Scan(ScanType scan_type,Error * error,const string & reason)258 void Device::Scan(ScanType scan_type, Error* error, const string& reason) {
259 SLOG(this, 2) << __func__ << " [Device] on " << link_name() << " from "
260 << reason;
261 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
262 "Device doesn't support scan.");
263 }
264
SetSchedScan(bool enable,Error * error)265 void Device::SetSchedScan(bool enable, Error* error) {
266 SLOG(this, 2) << __func__ << " [Device] on " << link_name();
267 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
268 "Device doesn't support scheduled scan.");
269 }
270
RegisterOnNetwork(const std::string &,Error * error,const ResultCallback &)271 void Device::RegisterOnNetwork(const std::string& /*network_id*/, Error* error,
272 const ResultCallback& /*callback*/) {
273 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
274 "Device doesn't support network registration.");
275 }
276
RequirePIN(const string &,bool,Error * error,const ResultCallback &)277 void Device::RequirePIN(
278 const string& /*pin*/, bool /*require*/,
279 Error* error, const ResultCallback& /*callback*/) {
280 SLOG(this, 2) << __func__;
281 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
282 "Device doesn't support RequirePIN.");
283 }
284
EnterPIN(const string &,Error * error,const ResultCallback &)285 void Device::EnterPIN(const string& /*pin*/,
286 Error* error, const ResultCallback& /*callback*/) {
287 SLOG(this, 2) << __func__;
288 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
289 "Device doesn't support EnterPIN.");
290 }
291
UnblockPIN(const string &,const string &,Error * error,const ResultCallback &)292 void Device::UnblockPIN(const string& /*unblock_code*/,
293 const string& /*pin*/,
294 Error* error, const ResultCallback& /*callback*/) {
295 SLOG(this, 2) << __func__;
296 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
297 "Device doesn't support UnblockPIN.");
298 }
299
ChangePIN(const string &,const string &,Error * error,const ResultCallback &)300 void Device::ChangePIN(const string& /*old_pin*/,
301 const string& /*new_pin*/,
302 Error* error, const ResultCallback& /*callback*/) {
303 SLOG(this, 2) << __func__;
304 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
305 "Device doesn't support ChangePIN.");
306 }
307
Reset(Error * error,const ResultCallback &)308 void Device::Reset(Error* error, const ResultCallback& /*callback*/) {
309 SLOG(this, 2) << __func__;
310 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
311 "Device doesn't support Reset.");
312 }
313
SetCarrier(const string &,Error * error,const ResultCallback &)314 void Device::SetCarrier(const string& /*carrier*/,
315 Error* error, const ResultCallback& /*callback*/) {
316 SLOG(this, 2) << __func__;
317 Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
318 "Device doesn't support SetCarrier.");
319 }
320
IsIPv6Allowed() const321 bool Device::IsIPv6Allowed() const {
322 return true;
323 }
324
DisableIPv6()325 void Device::DisableIPv6() {
326 SLOG(this, 2) << __func__;
327 SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "1");
328 }
329
EnableIPv6()330 void Device::EnableIPv6() {
331 SLOG(this, 2) << __func__;
332 if (!IsIPv6Allowed()) {
333 LOG(INFO) << "Skip enabling IPv6 on " << link_name_
334 << " as it is not allowed.";
335 return;
336 }
337 SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "0");
338 }
339
EnableIPv6Privacy()340 void Device::EnableIPv6Privacy() {
341 SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagUseTempAddr,
342 kIPFlagUseTempAddrUsedAndDefault);
343 }
344
SetLooseRouting(bool is_loose_routing)345 void Device::SetLooseRouting(bool is_loose_routing) {
346 if (is_loose_routing == is_loose_routing_) {
347 return;
348 }
349 is_loose_routing_ = is_loose_routing;
350 if (is_multi_homed_) {
351 // Nothing to do: loose routing is already enabled, and should remain so.
352 return;
353 }
354 if (is_loose_routing) {
355 DisableReversePathFilter();
356 } else {
357 EnableReversePathFilter();
358 }
359 }
360
DisableReversePathFilter()361 void Device::DisableReversePathFilter() {
362 // TODO(pstew): Current kernel doesn't offer reverse-path filtering flag
363 // for IPv6. crbug.com/207193
364 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter,
365 kIPFlagReversePathFilterLooseMode);
366 }
367
EnableReversePathFilter()368 void Device::EnableReversePathFilter() {
369 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter,
370 kIPFlagReversePathFilterEnabled);
371 }
372
SetIsMultiHomed(bool is_multi_homed)373 void Device::SetIsMultiHomed(bool is_multi_homed) {
374 if (is_multi_homed == is_multi_homed_) {
375 return;
376 }
377 LOG(INFO) << "Device " << FriendlyName() << " multi-home state is now "
378 << is_multi_homed;
379 is_multi_homed_ = is_multi_homed;
380 if (is_multi_homed) {
381 EnableArpFiltering();
382 if (!is_loose_routing_) {
383 DisableReversePathFilter();
384 }
385 } else {
386 DisableArpFiltering();
387 if (!is_loose_routing_) {
388 EnableReversePathFilter();
389 }
390 }
391 }
392
DisableArpFiltering()393 void Device::DisableArpFiltering() {
394 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce,
395 kIPFlagArpAnnounceDefault);
396 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore, kIPFlagArpIgnoreDefault);
397 }
398
EnableArpFiltering()399 void Device::EnableArpFiltering() {
400 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce,
401 kIPFlagArpAnnounceBestLocal);
402 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore,
403 kIPFlagArpIgnoreLocalOnly);
404 }
405
IsConnected() const406 bool Device::IsConnected() const {
407 if (selected_service_)
408 return selected_service_->IsConnected();
409 return false;
410 }
411
IsConnectedToService(const ServiceRefPtr & service) const412 bool Device::IsConnectedToService(const ServiceRefPtr& service) const {
413 return service == selected_service_ && IsConnected();
414 }
415
IsConnectedViaTether() const416 bool Device::IsConnectedViaTether() const {
417 if (!ipconfig_.get())
418 return false;
419
420 ByteArray vendor_encapsulated_options =
421 ipconfig_->properties().vendor_encapsulated_options;
422 size_t android_vendor_encapsulated_options_len =
423 strlen(Tethering::kAndroidVendorEncapsulatedOptions);
424
425 return (vendor_encapsulated_options.size() ==
426 android_vendor_encapsulated_options_len) &&
427 !memcmp(&vendor_encapsulated_options[0],
428 Tethering::kAndroidVendorEncapsulatedOptions,
429 vendor_encapsulated_options.size());
430 }
431
GetRpcIdentifier() const432 string Device::GetRpcIdentifier() const {
433 return adaptor_->GetRpcIdentifier();
434 }
435
GetStorageIdentifier() const436 string Device::GetStorageIdentifier() const {
437 string id = GetRpcIdentifier();
438 ControlInterface::RpcIdToStorageId(&id);
439 size_t needle = id.find('_');
440 DLOG_IF(ERROR, needle == string::npos) << "No _ in storage id?!?!";
441 id.replace(id.begin() + needle + 1, id.end(), hardware_address_);
442 return id;
443 }
444
GetGeolocationObjects() const445 vector<GeolocationInfo> Device::GetGeolocationObjects() const {
446 return vector<GeolocationInfo>();
447 }
448
GetTechnologyString(Error *)449 string Device::GetTechnologyString(Error* /*error*/) {
450 return Technology::NameFromIdentifier(technology());
451 }
452
FriendlyName() const453 const string& Device::FriendlyName() const {
454 return link_name_;
455 }
456
UniqueName() const457 const string& Device::UniqueName() const {
458 return unique_id_;
459 }
460
Load(StoreInterface * storage)461 bool Device::Load(StoreInterface* storage) {
462 const string id = GetStorageIdentifier();
463 if (!storage->ContainsGroup(id)) {
464 SLOG(this, 2) << "Device is not available in the persistent store: " << id;
465 return false;
466 }
467 enabled_persistent_ = true;
468 storage->GetBool(id, kStoragePowered, &enabled_persistent_);
469 uint64_t rx_byte_count = 0, tx_byte_count = 0;
470
471 manager_->device_info()->GetByteCounts(
472 interface_index_, &rx_byte_count, &tx_byte_count);
473 // If there is a byte-count present in the profile, the return value
474 // of Device::Get*ByteCount() should be the this stored value plus
475 // whatever additional bytes we receive since time-of-load. We
476 // accomplish this by the subtractions below, which can validly
477 // roll over "negative" in the subtractions below and in Get*ByteCount.
478 uint64_t profile_byte_count;
479 if (storage->GetUint64(id, kStorageReceiveByteCount, &profile_byte_count)) {
480 receive_byte_offset_ = rx_byte_count - profile_byte_count;
481 }
482 if (storage->GetUint64(id, kStorageTransmitByteCount, &profile_byte_count)) {
483 transmit_byte_offset_ = tx_byte_count - profile_byte_count;
484 }
485
486 return true;
487 }
488
Save(StoreInterface * storage)489 bool Device::Save(StoreInterface* storage) {
490 const string id = GetStorageIdentifier();
491 storage->SetBool(id, kStoragePowered, enabled_persistent_);
492 storage->SetUint64(id, kStorageReceiveByteCount, GetReceiveByteCount());
493 storage->SetUint64(id, kStorageTransmitByteCount, GetTransmitByteCount());
494 return true;
495 }
496
OnBeforeSuspend(const ResultCallback & callback)497 void Device::OnBeforeSuspend(const ResultCallback& callback) {
498 // Nothing to be done in the general case, so immediately report success.
499 callback.Run(Error(Error::kSuccess));
500 }
501
OnAfterResume()502 void Device::OnAfterResume() {
503 RenewDHCPLease();
504 if (link_monitor_) {
505 SLOG(this, 3) << "Informing Link Monitor of resume.";
506 link_monitor_->OnAfterResume();
507 }
508 // Resume from sleep, could be in different location now.
509 // Ignore previous link monitor failures.
510 if (selected_service_) {
511 selected_service_->set_unreliable(false);
512 reliable_link_callback_.Cancel();
513 }
514 last_link_monitor_failed_time_ = 0;
515 }
516
OnDarkResume(const ResultCallback & callback)517 void Device::OnDarkResume(const ResultCallback& callback) {
518 // Nothing to be done in the general case, so immediately report success.
519 callback.Run(Error(Error::kSuccess));
520 }
521
DropConnection()522 void Device::DropConnection() {
523 SLOG(this, 2) << __func__;
524 DestroyIPConfig();
525 SelectService(nullptr);
526 }
527
DestroyIPConfig()528 void Device::DestroyIPConfig() {
529 DisableIPv6();
530 bool ipconfig_changed = false;
531 if (ipconfig_.get()) {
532 ipconfig_->ReleaseIP(IPConfig::kReleaseReasonDisconnect);
533 ipconfig_ = nullptr;
534 ipconfig_changed = true;
535 }
536 if (ip6config_.get()) {
537 StopIPv6DNSServerTimer();
538 ip6config_ = nullptr;
539 ipconfig_changed = true;
540 }
541 if (dhcpv6_config_.get()) {
542 dhcpv6_config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect);
543 dhcpv6_config_ = nullptr;
544 ipconfig_changed = true;
545 }
546 // Emit updated IP configs if there are any changes.
547 if (ipconfig_changed) {
548 UpdateIPConfigsProperty();
549 }
550 DestroyConnection();
551 }
552
OnIPv6AddressChanged()553 void Device::OnIPv6AddressChanged() {
554 IPAddress address(IPAddress::kFamilyIPv6);
555 if (!manager_->device_info()->GetPrimaryIPv6Address(
556 interface_index_, &address)) {
557 if (ip6config_) {
558 ip6config_ = nullptr;
559 UpdateIPConfigsProperty();
560 }
561 return;
562 }
563
564 IPConfig::Properties properties;
565 if (!address.IntoString(&properties.address)) {
566 LOG(ERROR) << "Unable to convert IPv6 address into a string!";
567 return;
568 }
569 properties.subnet_prefix = address.prefix();
570
571 if (!ip6config_) {
572 ip6config_ = new IPConfig(control_interface_, link_name_);
573 } else if (properties.address == ip6config_->properties().address &&
574 properties.subnet_prefix ==
575 ip6config_->properties().subnet_prefix) {
576 SLOG(this, 2) << __func__ << " primary address for "
577 << link_name_ << " is unchanged.";
578 return;
579 }
580
581 properties.address_family = IPAddress::kFamilyIPv6;
582 properties.method = kTypeIPv6;
583 // It is possible for device to receive DNS server notification before IP
584 // address notification, so preserve the saved DNS server if it exist.
585 properties.dns_servers = ip6config_->properties().dns_servers;
586 PrependDNSServers(IPAddress::kFamilyIPv6, &properties.dns_servers);
587 ip6config_->set_properties(properties);
588 UpdateIPConfigsProperty();
589 OnIPv6ConfigUpdated();
590 }
591
OnIPv6DnsServerAddressesChanged()592 void Device::OnIPv6DnsServerAddressesChanged() {
593 vector<IPAddress> server_addresses;
594 uint32_t lifetime = 0;
595
596 // Stop any existing timer.
597 StopIPv6DNSServerTimer();
598
599 if (!manager_->device_info()->GetIPv6DnsServerAddresses(
600 interface_index_, &server_addresses, &lifetime) || lifetime == 0) {
601 IPv6DNSServerExpired();
602 return;
603 }
604
605 vector<string> addresses_str;
606 for (const auto& ip : server_addresses) {
607 string address_str;
608 if (!ip.IntoString(&address_str)) {
609 LOG(ERROR) << "Unable to convert IPv6 address into a string!";
610 IPv6DNSServerExpired();
611 return;
612 }
613 addresses_str.push_back(address_str);
614 }
615
616 if (!ip6config_) {
617 ip6config_ = new IPConfig(control_interface_, link_name_);
618 }
619
620 if (lifetime != ND_OPT_LIFETIME_INFINITY) {
621 // Setup timer to monitor DNS server lifetime if not infinite lifetime.
622 StartIPv6DNSServerTimer(lifetime);
623 ip6config_->UpdateLeaseExpirationTime(lifetime);
624 } else {
625 ip6config_->ResetLeaseExpirationTime();
626 }
627
628 PrependDNSServers(IPAddress::kFamilyIPv6, &addresses_str);
629
630 // Done if no change in server addresses.
631 if (ip6config_->properties().dns_servers == addresses_str) {
632 SLOG(this, 2) << __func__ << " IPv6 DNS server list for "
633 << link_name_ << " is unchanged.";
634 return;
635 }
636
637 ip6config_->UpdateDNSServers(addresses_str);
638 UpdateIPConfigsProperty();
639 OnIPv6ConfigUpdated();
640 }
641
StartIPv6DNSServerTimer(uint32_t lifetime_seconds)642 void Device::StartIPv6DNSServerTimer(uint32_t lifetime_seconds) {
643 int64_t delay = static_cast<int64_t>(lifetime_seconds) * 1000;
644 ipv6_dns_server_expired_callback_.Reset(
645 base::Bind(&Device::IPv6DNSServerExpired, base::Unretained(this)));
646 dispatcher_->PostDelayedTask(ipv6_dns_server_expired_callback_.callback(),
647 delay);
648 }
649
StopIPv6DNSServerTimer()650 void Device::StopIPv6DNSServerTimer() {
651 ipv6_dns_server_expired_callback_.Cancel();
652 }
653
IPv6DNSServerExpired()654 void Device::IPv6DNSServerExpired() {
655 if (!ip6config_) {
656 return;
657 }
658 ip6config_->UpdateDNSServers(vector<string>());
659 UpdateIPConfigsProperty();
660 }
661
StopAllActivities()662 void Device::StopAllActivities() {
663 StopTrafficMonitor();
664 StopPortalDetection();
665 StopConnectivityTest();
666 StopConnectionDiagnostics();
667 StopLinkMonitor();
668 StopDNSTest();
669 StopIPv6DNSServerTimer();
670 }
671
AddWakeOnPacketConnection(const string & ip_endpoint,Error * error)672 void Device::AddWakeOnPacketConnection(const string& ip_endpoint,
673 Error* error) {
674 Error::PopulateAndLog(
675 FROM_HERE, error, Error::kNotSupported,
676 "AddWakeOnPacketConnection not implemented for " + link_name_ + ".");
677 return;
678 }
679
RemoveWakeOnPacketConnection(const string & ip_endpoint,Error * error)680 void Device::RemoveWakeOnPacketConnection(const string& ip_endpoint,
681 Error* error) {
682 Error::PopulateAndLog(
683 FROM_HERE, error, Error::kNotSupported,
684 "RemoveWakeOnPacketConnection not implemented for " + link_name_ + ".");
685 return;
686 }
687
RemoveAllWakeOnPacketConnections(Error * error)688 void Device::RemoveAllWakeOnPacketConnections(Error* error) {
689 Error::PopulateAndLog(
690 FROM_HERE, error, Error::kNotSupported,
691 "RemoveAllWakeOnPacketConnections not implemented for " + link_name_ +
692 ".");
693 return;
694 }
695
RenewDHCPLease()696 void Device::RenewDHCPLease() {
697 LOG(INFO) << __func__;
698
699 if (ipconfig_) {
700 SLOG(this, 3) << "Renewing IPv4 Address";
701 ipconfig_->RenewIP();
702 }
703 if (ip6config_) {
704 SLOG(this, 3) << "Waiting for new IPv6 configuration";
705 // Invalidate the old IPv6 configuration, will receive notifications
706 // from kernel for new IPv6 configuration if there is one.
707 StopIPv6DNSServerTimer();
708 ip6config_ = nullptr;
709 UpdateIPConfigsProperty();
710 }
711 if (dhcpv6_config_) {
712 SLOG(this, 3) << "Renewing DHCPv6 lease";
713 dhcpv6_config_->RenewIP();
714 }
715 }
716
ShouldUseArpGateway() const717 bool Device::ShouldUseArpGateway() const {
718 return false;
719 }
720
IsUsingStaticIP() const721 bool Device::IsUsingStaticIP() const {
722 if (!selected_service_) {
723 return false;
724 }
725 return selected_service_->HasStaticIPAddress();
726 }
727
IsUsingStaticNameServers() const728 bool Device::IsUsingStaticNameServers() const {
729 if (!selected_service_) {
730 return false;
731 }
732 return selected_service_->HasStaticNameServers();
733 }
734
AcquireIPConfig()735 bool Device::AcquireIPConfig() {
736 return AcquireIPConfigWithLeaseName(string());
737 }
738
AcquireIPConfigWithLeaseName(const string & lease_name)739 bool Device::AcquireIPConfigWithLeaseName(const string& lease_name) {
740 DestroyIPConfig();
741 EnableIPv6();
742 bool arp_gateway = manager_->GetArpGateway() && ShouldUseArpGateway();
743 DHCPConfigRefPtr dhcp_config;
744 if (selected_service_) {
745 dhcp_config =
746 dhcp_provider_->CreateIPv4Config(
747 link_name_,
748 lease_name,
749 arp_gateway,
750 *(DhcpProperties::Combine(
751 manager_->dhcp_properties(),
752 selected_service_->dhcp_properties())));
753
754 } else {
755 dhcp_config =
756 dhcp_provider_->CreateIPv4Config(link_name_,
757 lease_name,
758 arp_gateway,
759 manager_->dhcp_properties());
760 }
761 const int minimum_mtu = manager()->GetMinimumMTU();
762 if (minimum_mtu != IPConfig::kUndefinedMTU) {
763 dhcp_config->set_minimum_mtu(minimum_mtu);
764 }
765
766 ipconfig_ = dhcp_config;
767 ipconfig_->RegisterUpdateCallback(Bind(&Device::OnIPConfigUpdated,
768 weak_ptr_factory_.GetWeakPtr()));
769 ipconfig_->RegisterFailureCallback(Bind(&Device::OnIPConfigFailed,
770 weak_ptr_factory_.GetWeakPtr()));
771 ipconfig_->RegisterRefreshCallback(Bind(&Device::OnIPConfigRefreshed,
772 weak_ptr_factory_.GetWeakPtr()));
773 ipconfig_->RegisterExpireCallback(Bind(&Device::OnIPConfigExpired,
774 weak_ptr_factory_.GetWeakPtr()));
775 dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask,
776 weak_ptr_factory_.GetWeakPtr()));
777 if (!ipconfig_->RequestIP()) {
778 return false;
779 }
780
781 #ifndef DISABLE_DHCPV6
782 // Only start DHCPv6 configuration instance only if DHCPv6 is enabled
783 // for this device.
784 if (manager_->IsDHCPv6EnabledForDevice(link_name_)) {
785 return AcquireIPv6ConfigWithLeaseName(lease_name);
786 }
787 #endif // DISABLE_DHCPV6
788 return true;
789 }
790
791 #ifndef DISABLE_DHCPV6
AcquireIPv6ConfigWithLeaseName(const string & lease_name)792 bool Device::AcquireIPv6ConfigWithLeaseName(const string& lease_name) {
793 auto dhcpv6_config =
794 dhcp_provider_->CreateIPv6Config(link_name_, lease_name);
795 dhcpv6_config_ = dhcpv6_config;
796 dhcpv6_config_->RegisterUpdateCallback(
797 Bind(&Device::OnDHCPv6ConfigUpdated, weak_ptr_factory_.GetWeakPtr()));
798 dhcpv6_config_->RegisterFailureCallback(
799 Bind(&Device::OnDHCPv6ConfigFailed, weak_ptr_factory_.GetWeakPtr()));
800 dhcpv6_config_->RegisterExpireCallback(
801 Bind(&Device::OnDHCPv6ConfigExpired, weak_ptr_factory_.GetWeakPtr()));
802 if (!dhcpv6_config_->RequestIP()) {
803 return false;
804 }
805 return true;
806 }
807 #endif // DISABLE_DHCPV6
808
AssignIPConfig(const IPConfig::Properties & properties)809 void Device::AssignIPConfig(const IPConfig::Properties& properties) {
810 DestroyIPConfig();
811 EnableIPv6();
812 ipconfig_ = new IPConfig(control_interface_, link_name_);
813 ipconfig_->set_properties(properties);
814 dispatcher_->PostTask(Bind(&Device::OnIPConfigUpdated,
815 weak_ptr_factory_.GetWeakPtr(), ipconfig_, true));
816 }
817
DestroyIPConfigLease(const string & name)818 void Device::DestroyIPConfigLease(const string& name) {
819 dhcp_provider_->DestroyLease(name);
820 }
821
HelpRegisterConstDerivedString(const string & name,string (Device::* get)(Error * error))822 void Device::HelpRegisterConstDerivedString(
823 const string& name,
824 string(Device::*get)(Error* error)) {
825 store_.RegisterDerivedString(
826 name,
827 StringAccessor(new CustomAccessor<Device, string>(this, get, nullptr)));
828 }
829
HelpRegisterConstDerivedRpcIdentifier(const string & name,RpcIdentifier (Device::* get)(Error * error))830 void Device::HelpRegisterConstDerivedRpcIdentifier(
831 const string& name,
832 RpcIdentifier(Device::*get)(Error* error)) {
833 store_.RegisterDerivedRpcIdentifier(
834 name,
835 RpcIdentifierAccessor(
836 new CustomAccessor<Device, RpcIdentifier>(this, get, nullptr)));
837 }
838
HelpRegisterConstDerivedRpcIdentifiers(const string & name,RpcIdentifiers (Device::* get)(Error *))839 void Device::HelpRegisterConstDerivedRpcIdentifiers(
840 const string& name,
841 RpcIdentifiers(Device::*get)(Error*)) {
842 store_.RegisterDerivedRpcIdentifiers(
843 name,
844 RpcIdentifiersAccessor(
845 new CustomAccessor<Device, RpcIdentifiers>(this, get, nullptr)));
846 }
847
HelpRegisterConstDerivedUint64(const string & name,uint64_t (Device::* get)(Error *))848 void Device::HelpRegisterConstDerivedUint64(
849 const string& name,
850 uint64_t(Device::*get)(Error*)) {
851 store_.RegisterDerivedUint64(
852 name,
853 Uint64Accessor(
854 new CustomAccessor<Device, uint64_t>(this, get, nullptr)));
855 }
856
ConnectionTesterCallback()857 void Device::ConnectionTesterCallback() {
858 LOG(INFO) << "Device " << FriendlyName() << ": Completed Connectivity Test";
859 return;
860 }
861
ConfigureStaticIPTask()862 void Device::ConfigureStaticIPTask() {
863 SLOG(this, 2) << __func__ << " selected_service " << selected_service_.get()
864 << " ipconfig " << ipconfig_.get();
865
866 if (!selected_service_ || !ipconfig_) {
867 return;
868 }
869
870 if (IsUsingStaticIP()) {
871 SLOG(this, 2) << __func__ << " " << " configuring static IP parameters.";
872 // If the parameters contain an IP address, apply them now and bring
873 // the interface up. When DHCP information arrives, it will supplement
874 // the static information.
875 OnIPConfigUpdated(ipconfig_, true);
876 } else {
877 // Either |ipconfig_| has just been created in AcquireIPConfig() or
878 // we're being called by OnIPConfigRefreshed(). In either case a
879 // DHCP client has been started, and will take care of calling
880 // OnIPConfigUpdated() when it completes.
881 SLOG(this, 2) << __func__ << " " << " no static IP address.";
882 }
883 }
884
IPConfigCompleted(const IPConfigRefPtr & ipconfig)885 bool Device::IPConfigCompleted(const IPConfigRefPtr& ipconfig) {
886 return ipconfig && !ipconfig->properties().address.empty() &&
887 !ipconfig->properties().dns_servers.empty();
888 }
889
OnIPv6ConfigUpdated()890 void Device::OnIPv6ConfigUpdated() {
891 // Setup connection using IPv6 configuration only if the IPv6 configuration
892 // is ready for connection (contained both IP address and DNS servers), and
893 // there is no existing IPv4 connection. We always prefer IPv4
894 // configuration over IPv6.
895 if (IPConfigCompleted(ip6config_) &&
896 (!connection_ || connection_->IsIPv6())) {
897 SetupConnection(ip6config_);
898 }
899 }
900
SetupConnection(const IPConfigRefPtr & ipconfig)901 void Device::SetupConnection(const IPConfigRefPtr& ipconfig) {
902 CreateConnection();
903 connection_->UpdateFromIPConfig(ipconfig);
904
905 // Report connection type.
906 Metrics::NetworkConnectionIPType ip_type =
907 connection_->IsIPv6() ? Metrics::kNetworkConnectionIPTypeIPv6
908 : Metrics::kNetworkConnectionIPTypeIPv4;
909 metrics_->NotifyNetworkConnectionIPType(technology_, ip_type);
910
911 // Report if device have IPv6 connectivity
912 bool ipv6_connectivity = IPConfigCompleted(ip6config_);
913 metrics_->NotifyIPv6ConnectivityStatus(technology_, ipv6_connectivity);
914
915 // SetConnection must occur after the UpdateFromIPConfig so the
916 // service can use the values derived from the connection.
917 if (selected_service_) {
918 selected_service_->SetConnection(connection_);
919
920 // The service state change needs to happen last, so that at the
921 // time we report the state change to the manager, the service
922 // has its connection.
923 SetServiceState(Service::kStateConnected);
924 OnConnected();
925 portal_attempts_to_online_ = 0;
926
927 // Subtle: Start portal detection after transitioning the service
928 // to the Connected state because this call may immediately transition
929 // to the Online state.
930 StartPortalDetection();
931 }
932
933 SetHostname(ipconfig->properties().accepted_hostname);
934 StartLinkMonitor();
935 StartTrafficMonitor();
936 }
937
SetHostname(const std::string & hostname)938 bool Device::SetHostname(const std::string& hostname) {
939 if (hostname.empty() || !manager()->ShouldAcceptHostnameFrom(link_name_)) {
940 return false;
941 }
942
943 string fixed_hostname = hostname;
944 if (fixed_hostname.length() > MAXHOSTNAMELEN) {
945 auto truncate_length = fixed_hostname.find('.');
946 if (truncate_length == string::npos || truncate_length > MAXHOSTNAMELEN) {
947 truncate_length = MAXHOSTNAMELEN;
948 }
949 fixed_hostname.resize(truncate_length);
950 }
951
952 return manager_->device_info()->SetHostname(fixed_hostname);
953 }
954
PrependDNSServersIntoIPConfig(const IPConfigRefPtr & ipconfig)955 void Device::PrependDNSServersIntoIPConfig(const IPConfigRefPtr& ipconfig) {
956 const auto& properties = ipconfig->properties();
957
958 vector<string> servers(properties.dns_servers.begin(),
959 properties.dns_servers.end());
960 PrependDNSServers(properties.address_family, &servers);
961 if (servers == properties.dns_servers) {
962 // If the server list is the same after being augmented then there's no need
963 // to update the config's list of servers.
964 return;
965 }
966
967 ipconfig->UpdateDNSServers(servers);
968 }
969
PrependDNSServers(const IPAddress::Family family,vector<string> * servers)970 void Device::PrependDNSServers(const IPAddress::Family family,
971 vector<string>* servers) {
972 vector<string>output_servers =
973 manager_->FilterPrependDNSServersByFamily(family);
974
975 set<string> unique(output_servers.begin(), output_servers.end());
976 for (const auto& server : *servers) {
977 if (unique.find(server) == unique.end()) {
978 output_servers.push_back(server);
979 unique.insert(server);
980 }
981 }
982 servers->swap(output_servers);
983 }
984
ConnectionDiagnosticsCallback(const std::string & connection_issue,const std::vector<ConnectionDiagnostics::Event> & diagnostic_events)985 void Device::ConnectionDiagnosticsCallback(
986 const std::string& connection_issue,
987 const std::vector<ConnectionDiagnostics::Event>& diagnostic_events) {
988 SLOG(this, 2) << "Device " << FriendlyName()
989 << ": Completed Connection diagnostics";
990 // TODO(samueltan): add connection diagnostics metrics.
991 }
992
OnIPConfigUpdated(const IPConfigRefPtr & ipconfig,bool)993 void Device::OnIPConfigUpdated(const IPConfigRefPtr& ipconfig,
994 bool /*new_lease_acquired*/) {
995 SLOG(this, 2) << __func__;
996 if (selected_service_) {
997 ipconfig->ApplyStaticIPParameters(
998 selected_service_->mutable_static_ip_parameters());
999 if (IsUsingStaticIP()) {
1000 // If we are using a statically configured IP address instead
1001 // of a leased IP address, release any acquired lease so it may
1002 // be used by others. This allows us to merge other non-leased
1003 // parameters (like DNS) when they're available from a DHCP server
1004 // and not overridden by static parameters, but at the same time
1005 // we avoid taking up a dynamic IP address the DHCP server could
1006 // assign to someone else who might actually use it.
1007 ipconfig->ReleaseIP(IPConfig::kReleaseReasonStaticIP);
1008 }
1009 }
1010 if (!IsUsingStaticNameServers()) {
1011 PrependDNSServersIntoIPConfig(ipconfig);
1012 }
1013 SetupConnection(ipconfig);
1014 UpdateIPConfigsProperty();
1015 }
1016
OnIPConfigFailed(const IPConfigRefPtr & ipconfig)1017 void Device::OnIPConfigFailed(const IPConfigRefPtr& ipconfig) {
1018 SLOG(this, 2) << __func__;
1019 // TODO(pstew): This logic gets yet more complex when multiple
1020 // IPConfig types are run in parallel (e.g. DHCP and DHCP6)
1021 if (selected_service_) {
1022 if (IsUsingStaticIP()) {
1023 // Consider three cases:
1024 //
1025 // 1. We're here because DHCP failed while starting up. There
1026 // are two subcases:
1027 // a. DHCP has failed, and Static IP config has _not yet_
1028 // completed. It's fine to do nothing, because we'll
1029 // apply the static config shortly.
1030 // b. DHCP has failed, and Static IP config has _already_
1031 // completed. It's fine to do nothing, because we can
1032 // continue to use the static config that's already
1033 // been applied.
1034 //
1035 // 2. We're here because a previously valid DHCP configuration
1036 // is no longer valid. There's still a static IP config,
1037 // because the condition in the if clause evaluated to true.
1038 // Furthermore, the static config includes an IP address for
1039 // us to use.
1040 //
1041 // The current configuration may include some DHCP
1042 // parameters, overriden by any static parameters
1043 // provided. We continue to use this configuration, because
1044 // the only configuration element that is leased to us (IP
1045 // address) will be overriden by a static parameter.
1046 return;
1047 }
1048 }
1049
1050 ipconfig->ResetProperties();
1051 UpdateIPConfigsProperty();
1052
1053 // Fallback to IPv6 if possible.
1054 if (IPConfigCompleted(ip6config_)) {
1055 if (!connection_ || !connection_->IsIPv6()) {
1056 // Setup IPv6 connection.
1057 SetupConnection(ip6config_);
1058 } else {
1059 // Ignore IPv4 config failure, since IPv6 is up.
1060 }
1061 return;
1062 }
1063
1064 OnIPConfigFailure();
1065 DestroyConnection();
1066 }
1067
OnIPConfigRefreshed(const IPConfigRefPtr & ipconfig)1068 void Device::OnIPConfigRefreshed(const IPConfigRefPtr& ipconfig) {
1069 // Clear the previously applied static IP parameters.
1070 ipconfig->RestoreSavedIPParameters(
1071 selected_service_->mutable_static_ip_parameters());
1072
1073 dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask,
1074 weak_ptr_factory_.GetWeakPtr()));
1075 }
1076
OnIPConfigFailure()1077 void Device::OnIPConfigFailure() {
1078 if (selected_service_) {
1079 Error error;
1080 selected_service_->DisconnectWithFailure(Service::kFailureDHCP,
1081 &error,
1082 __func__);
1083 }
1084 }
1085
OnIPConfigExpired(const IPConfigRefPtr & ipconfig)1086 void Device::OnIPConfigExpired(const IPConfigRefPtr& ipconfig) {
1087 metrics()->SendToUMA(
1088 metrics()->GetFullMetricName(
1089 Metrics::kMetricExpiredLeaseLengthSecondsSuffix, technology()),
1090 ipconfig->properties().lease_duration_seconds,
1091 Metrics::kMetricExpiredLeaseLengthSecondsMin,
1092 Metrics::kMetricExpiredLeaseLengthSecondsMax,
1093 Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets);
1094 }
1095
OnDHCPv6ConfigUpdated(const IPConfigRefPtr & ipconfig,bool)1096 void Device::OnDHCPv6ConfigUpdated(const IPConfigRefPtr& ipconfig,
1097 bool /*new_lease_acquired*/) {
1098 // Emit configuration update.
1099 UpdateIPConfigsProperty();
1100 }
1101
OnDHCPv6ConfigFailed(const IPConfigRefPtr & ipconfig)1102 void Device::OnDHCPv6ConfigFailed(const IPConfigRefPtr& ipconfig) {
1103 // Reset configuration data.
1104 ipconfig->ResetProperties();
1105 UpdateIPConfigsProperty();
1106 }
1107
OnDHCPv6ConfigExpired(const IPConfigRefPtr & ipconfig)1108 void Device::OnDHCPv6ConfigExpired(const IPConfigRefPtr& ipconfig) {
1109 // Reset configuration data.
1110 ipconfig->ResetProperties();
1111 UpdateIPConfigsProperty();
1112 }
1113
OnConnected()1114 void Device::OnConnected() {
1115 if (selected_service_->unreliable()) {
1116 // Post a delayed task to reset link back to reliable if no link
1117 // failure is detected in the next 5 minutes.
1118 reliable_link_callback_.Reset(
1119 base::Bind(&Device::OnReliableLink, base::Unretained(this)));
1120 dispatcher_->PostDelayedTask(
1121 reliable_link_callback_.callback(),
1122 kLinkUnreliableThresholdSeconds * 1000);
1123 }
1124 }
1125
OnConnectionUpdated()1126 void Device::OnConnectionUpdated() {
1127 if (selected_service_) {
1128 manager_->UpdateService(selected_service_);
1129 }
1130 }
1131
CreateConnection()1132 void Device::CreateConnection() {
1133 SLOG(this, 2) << __func__;
1134 if (!connection_.get()) {
1135 connection_ = new Connection(interface_index_,
1136 link_name_,
1137 technology_,
1138 manager_->device_info(),
1139 control_interface_);
1140 }
1141 }
1142
DestroyConnection()1143 void Device::DestroyConnection() {
1144 SLOG(this, 2) << __func__ << " on " << link_name_;
1145 StopAllActivities();
1146 if (selected_service_.get()) {
1147 SLOG(this, 3) << "Clearing connection of service "
1148 << selected_service_->unique_name();
1149 selected_service_->SetConnection(nullptr);
1150 }
1151 connection_ = nullptr;
1152 }
1153
SelectService(const ServiceRefPtr & service)1154 void Device::SelectService(const ServiceRefPtr& service) {
1155 SLOG(this, 2) << __func__ << ": service "
1156 << (service ? service->unique_name() : "*reset*")
1157 << " on " << link_name_;
1158
1159 if (selected_service_.get() == service.get()) {
1160 // No change to |selected_service_|. Return early to avoid
1161 // changing its state.
1162 return;
1163 }
1164
1165 if (selected_service_.get()) {
1166 if (selected_service_->state() != Service::kStateFailure) {
1167 selected_service_->SetState(Service::kStateIdle);
1168 }
1169 // Just in case the Device subclass has not already done so, make
1170 // sure the previously selected service has its connection removed.
1171 selected_service_->SetConnection(nullptr);
1172 // Reset link status for the previously selected service.
1173 selected_service_->set_unreliable(false);
1174 reliable_link_callback_.Cancel();
1175 StopAllActivities();
1176 }
1177
1178 // Newly selected service (network), previous failures doesn't apply
1179 // anymore.
1180 last_link_monitor_failed_time_ = 0;
1181
1182 selected_service_ = service;
1183 adaptor_->EmitRpcIdentifierChanged(
1184 kSelectedServiceProperty, GetSelectedServiceRpcIdentifier(nullptr));
1185 }
1186
SetServiceState(Service::ConnectState state)1187 void Device::SetServiceState(Service::ConnectState state) {
1188 if (selected_service_.get()) {
1189 selected_service_->SetState(state);
1190 }
1191 }
1192
SetServiceFailure(Service::ConnectFailure failure_state)1193 void Device::SetServiceFailure(Service::ConnectFailure failure_state) {
1194 if (selected_service_.get()) {
1195 selected_service_->SetFailure(failure_state);
1196 }
1197 }
1198
SetServiceFailureSilent(Service::ConnectFailure failure_state)1199 void Device::SetServiceFailureSilent(Service::ConnectFailure failure_state) {
1200 if (selected_service_.get()) {
1201 selected_service_->SetFailureSilent(failure_state);
1202 }
1203 }
1204
SetIPFlag(IPAddress::Family family,const string & flag,const string & value)1205 bool Device::SetIPFlag(IPAddress::Family family, const string& flag,
1206 const string& value) {
1207 string ip_version;
1208 if (family == IPAddress::kFamilyIPv4) {
1209 ip_version = kIPFlagVersion4;
1210 } else if (family == IPAddress::kFamilyIPv6) {
1211 ip_version = kIPFlagVersion6;
1212 } else {
1213 NOTIMPLEMENTED();
1214 }
1215 FilePath flag_file(StringPrintf(kIPFlagTemplate, ip_version.c_str(),
1216 link_name_.c_str(), flag.c_str()));
1217 SLOG(this, 2) << "Writing " << value << " to flag file "
1218 << flag_file.value();
1219 if (base::WriteFile(flag_file, value.c_str(), value.length()) != 1) {
1220 string message = StringPrintf("IP flag write failed: %s to %s",
1221 value.c_str(), flag_file.value().c_str());
1222 if (!base::PathExists(flag_file) &&
1223 ContainsValue(written_flags_, flag_file.value())) {
1224 SLOG(this, 2) << message << " (device is no longer present?)";
1225 } else {
1226 LOG(ERROR) << message;
1227 }
1228 return false;
1229 } else {
1230 written_flags_.insert(flag_file.value());
1231 }
1232 return true;
1233 }
1234
PerformTDLSOperation(const string &,const string &,Error *)1235 string Device::PerformTDLSOperation(const string& /* operation */,
1236 const string& /* peer */,
1237 Error* /* error */) {
1238 return "";
1239 }
1240
ResetByteCounters()1241 void Device::ResetByteCounters() {
1242 manager_->device_info()->GetByteCounts(
1243 interface_index_, &receive_byte_offset_, &transmit_byte_offset_);
1244 manager_->UpdateDevice(this);
1245 }
1246
RestartPortalDetection()1247 bool Device::RestartPortalDetection() {
1248 StopPortalDetection();
1249 return StartPortalDetection();
1250 }
1251
RequestPortalDetection()1252 bool Device::RequestPortalDetection() {
1253 if (!selected_service_) {
1254 SLOG(this, 2) << FriendlyName()
1255 << ": No selected service, so no need for portal check.";
1256 return false;
1257 }
1258
1259 if (!connection_.get()) {
1260 SLOG(this, 2) << FriendlyName()
1261 << ": No connection, so no need for portal check.";
1262 return false;
1263 }
1264
1265 if (selected_service_->state() != Service::kStatePortal) {
1266 SLOG(this, 2) << FriendlyName()
1267 << ": Service is not in portal state. "
1268 << "No need to start check.";
1269 return false;
1270 }
1271
1272 if (!connection_->is_default()) {
1273 SLOG(this, 2) << FriendlyName()
1274 << ": Service is not the default connection. "
1275 << "Don't start check.";
1276 return false;
1277 }
1278
1279 if (portal_detector_.get() && portal_detector_->IsInProgress()) {
1280 SLOG(this, 2) << FriendlyName()
1281 << ": Portal detection is already running.";
1282 return true;
1283 }
1284
1285 return StartPortalDetection();
1286 }
1287
StartPortalDetection()1288 bool Device::StartPortalDetection() {
1289 DCHECK(selected_service_);
1290 if (selected_service_->IsPortalDetectionDisabled()) {
1291 SLOG(this, 2) << "Service " << selected_service_->unique_name()
1292 << ": Portal detection is disabled; "
1293 << "marking service online.";
1294 SetServiceConnectedState(Service::kStateOnline);
1295 return false;
1296 }
1297
1298 if (selected_service_->IsPortalDetectionAuto() &&
1299 !manager_->IsPortalDetectionEnabled(technology())) {
1300 // If portal detection is disabled for this technology, immediately set
1301 // the service state to "Online".
1302 SLOG(this, 2) << "Device " << FriendlyName()
1303 << ": Portal detection is disabled; "
1304 << "marking service online.";
1305 SetServiceConnectedState(Service::kStateOnline);
1306 return false;
1307 }
1308
1309 if (selected_service_->HasProxyConfig()) {
1310 // Services with HTTP proxy configurations should not be checked by the
1311 // connection manager, since we don't have the ability to evaluate
1312 // arbitrary proxy configs and their possible credentials.
1313 SLOG(this, 2) << "Device " << FriendlyName()
1314 << ": Service has proxy config; marking it online.";
1315 SetServiceConnectedState(Service::kStateOnline);
1316 return false;
1317 }
1318
1319 portal_detector_.reset(new PortalDetector(connection_,
1320 dispatcher_,
1321 portal_detector_callback_));
1322 if (!portal_detector_->Start(manager_->GetPortalCheckURL())) {
1323 LOG(ERROR) << "Device " << FriendlyName()
1324 << ": Portal detection failed to start: likely bad URL: "
1325 << manager_->GetPortalCheckURL();
1326 SetServiceConnectedState(Service::kStateOnline);
1327 return false;
1328 }
1329
1330 SLOG(this, 2) << "Device " << FriendlyName()
1331 << ": Portal detection has started.";
1332 return true;
1333 }
1334
StopPortalDetection()1335 void Device::StopPortalDetection() {
1336 SLOG(this, 2) << "Device " << FriendlyName()
1337 << ": Portal detection stopping.";
1338 portal_detector_.reset();
1339 }
1340
StartConnectionDiagnosticsAfterPortalDetection(const PortalDetector::Result & result)1341 bool Device::StartConnectionDiagnosticsAfterPortalDetection(
1342 const PortalDetector::Result& result) {
1343 connection_diagnostics_.reset(new ConnectionDiagnostics(
1344 connection_, dispatcher_, metrics_, manager_->device_info(),
1345 connection_diagnostics_callback_));
1346 if (!connection_diagnostics_->StartAfterPortalDetection(
1347 manager_->GetPortalCheckURL(), result)) {
1348 LOG(ERROR) << "Device " << FriendlyName()
1349 << ": Connection diagnostics failed to start: likely bad URL: "
1350 << manager_->GetPortalCheckURL();
1351 connection_diagnostics_.reset();
1352 return false;
1353 }
1354
1355 SLOG(this, 2) << "Device " << FriendlyName()
1356 << ": Connection diagnostics has started.";
1357 return true;
1358 }
1359
StopConnectionDiagnostics()1360 void Device::StopConnectionDiagnostics() {
1361 SLOG(this, 2) << "Device " << FriendlyName()
1362 << ": Connection diagnostics stopping.";
1363 connection_diagnostics_.reset();
1364 }
1365
StartConnectivityTest()1366 bool Device::StartConnectivityTest() {
1367 LOG(INFO) << "Device " << FriendlyName() << " starting connectivity test.";
1368
1369 connection_tester_.reset(new ConnectionTester(connection_,
1370 dispatcher_,
1371 connection_tester_callback_));
1372 connection_tester_->Start();
1373 return true;
1374 }
1375
StopConnectivityTest()1376 void Device::StopConnectivityTest() {
1377 SLOG(this, 2) << "Device " << FriendlyName()
1378 << ": Connectivity test stopping.";
1379 connection_tester_.reset();
1380 }
1381
set_link_monitor(LinkMonitor * link_monitor)1382 void Device::set_link_monitor(LinkMonitor* link_monitor) {
1383 link_monitor_.reset(link_monitor);
1384 }
1385
StartLinkMonitor()1386 bool Device::StartLinkMonitor() {
1387 if (!manager_->IsTechnologyLinkMonitorEnabled(technology())) {
1388 SLOG(this, 2) << "Device " << FriendlyName()
1389 << ": Link Monitoring is disabled.";
1390 return false;
1391 }
1392
1393 if (selected_service_ && selected_service_->link_monitor_disabled()) {
1394 SLOG(this, 2) << "Device " << FriendlyName()
1395 << ": Link Monitoring is disabled for the selected service";
1396 return false;
1397 }
1398
1399 if (!link_monitor()) {
1400 set_link_monitor(
1401 new LinkMonitor(
1402 connection_, dispatcher_, metrics(), manager_->device_info(),
1403 Bind(&Device::OnLinkMonitorFailure, weak_ptr_factory_.GetWeakPtr()),
1404 Bind(&Device::OnLinkMonitorGatewayChange,
1405 weak_ptr_factory_.GetWeakPtr())));
1406 }
1407
1408 SLOG(this, 2) << "Device " << FriendlyName()
1409 << ": Link Monitor starting.";
1410 return link_monitor_->Start();
1411 }
1412
StopLinkMonitor()1413 void Device::StopLinkMonitor() {
1414 SLOG(this, 2) << "Device " << FriendlyName()
1415 << ": Link Monitor stopping.";
1416 link_monitor_.reset();
1417 }
1418
OnUnreliableLink()1419 void Device::OnUnreliableLink() {
1420 SLOG(this, 2) << "Device " << FriendlyName()
1421 << ": Link is unreliable.";
1422 selected_service_->set_unreliable(true);
1423 reliable_link_callback_.Cancel();
1424 metrics_->NotifyUnreliableLinkSignalStrength(
1425 technology_, selected_service_->strength());
1426 }
1427
OnReliableLink()1428 void Device::OnReliableLink() {
1429 SLOG(this, 2) << "Device " << FriendlyName()
1430 << ": Link is reliable.";
1431 selected_service_->set_unreliable(false);
1432 // TODO(zqiu): report signal strength to UMA.
1433 }
1434
OnLinkMonitorFailure()1435 void Device::OnLinkMonitorFailure() {
1436 SLOG(this, 2) << "Device " << FriendlyName()
1437 << ": Link Monitor indicates failure.";
1438 if (!selected_service_) {
1439 return;
1440 }
1441
1442 time_t now;
1443 time_->GetSecondsBoottime(&now);
1444
1445 if (last_link_monitor_failed_time_ != 0 &&
1446 now - last_link_monitor_failed_time_ < kLinkUnreliableThresholdSeconds) {
1447 OnUnreliableLink();
1448 }
1449 last_link_monitor_failed_time_ = now;
1450 }
1451
OnLinkMonitorGatewayChange()1452 void Device::OnLinkMonitorGatewayChange() {
1453 string gateway_mac = link_monitor()->gateway_mac_address().HexEncode();
1454 int connection_id = manager_->CalcConnectionId(
1455 ipconfig_->properties().gateway, gateway_mac);
1456
1457 CHECK(selected_service_);
1458 selected_service_->set_connection_id(connection_id);
1459
1460 manager_->ReportServicesOnSameNetwork(connection_id);
1461 }
1462
StartDNSTest(const vector<string> & dns_servers,bool retry_until_success,const Callback<void (const DNSServerTester::Status)> & callback)1463 bool Device::StartDNSTest(
1464 const vector<string>& dns_servers,
1465 bool retry_until_success,
1466 const Callback<void(const DNSServerTester::Status)>& callback) {
1467 if (dns_server_tester_.get()) {
1468 LOG(ERROR) << FriendlyName() << ": "
1469 << "Failed to start DNS Test: current test still running";
1470 return false;
1471 }
1472
1473 dns_server_tester_.reset(new DNSServerTester(connection_,
1474 dispatcher_,
1475 dns_servers,
1476 retry_until_success,
1477 callback));
1478 dns_server_tester_->Start();
1479 return true;
1480 }
1481
StopDNSTest()1482 void Device::StopDNSTest() {
1483 dns_server_tester_.reset();
1484 }
1485
FallbackDNSResultCallback(const DNSServerTester::Status status)1486 void Device::FallbackDNSResultCallback(const DNSServerTester::Status status) {
1487 StopDNSTest();
1488 int result = Metrics::kFallbackDNSTestResultFailure;
1489 if (status == DNSServerTester::kStatusSuccess) {
1490 result = Metrics::kFallbackDNSTestResultSuccess;
1491
1492 // Switch to fallback DNS server if service is configured to allow DNS
1493 // fallback.
1494 CHECK(selected_service_);
1495 if (selected_service_->is_dns_auto_fallback_allowed()) {
1496 LOG(INFO) << "Device " << FriendlyName()
1497 << ": Switching to fallback DNS servers.";
1498 // Save the DNS servers from ipconfig.
1499 config_dns_servers_ = ipconfig_->properties().dns_servers;
1500 SwitchDNSServers(vector<string>(std::begin(kFallbackDnsServers),
1501 std::end(kFallbackDnsServers)));
1502 // Start DNS test for configured DNS servers.
1503 StartDNSTest(config_dns_servers_,
1504 true,
1505 Bind(&Device::ConfigDNSResultCallback,
1506 weak_ptr_factory_.GetWeakPtr()));
1507 }
1508 }
1509 metrics()->NotifyFallbackDNSTestResult(technology_, result);
1510 }
1511
ConfigDNSResultCallback(const DNSServerTester::Status status)1512 void Device::ConfigDNSResultCallback(const DNSServerTester::Status status) {
1513 StopDNSTest();
1514 // DNS test failed to start due to internal error.
1515 if (status == DNSServerTester::kStatusFailure) {
1516 return;
1517 }
1518
1519 // Switch back to the configured DNS servers.
1520 LOG(INFO) << "Device " << FriendlyName()
1521 << ": Switching back to configured DNS servers.";
1522 SwitchDNSServers(config_dns_servers_);
1523 }
1524
SwitchDNSServers(const vector<string> & dns_servers)1525 void Device::SwitchDNSServers(const vector<string>& dns_servers) {
1526 CHECK(ipconfig_);
1527 CHECK(connection_);
1528 // Push new DNS servers setting to the IP config object.
1529 ipconfig_->UpdateDNSServers(dns_servers);
1530 // Push new DNS servers setting to the current connection, so the resolver
1531 // will be updated to use the new DNS servers.
1532 connection_->UpdateDNSServers(dns_servers);
1533 // Allow the service to notify Chrome of ipconfig changes.
1534 selected_service_->NotifyIPConfigChanges();
1535 // Restart the portal detection with the new DNS setting.
1536 RestartPortalDetection();
1537 }
1538
set_traffic_monitor(TrafficMonitor * traffic_monitor)1539 void Device::set_traffic_monitor(TrafficMonitor* traffic_monitor) {
1540 traffic_monitor_.reset(traffic_monitor);
1541 }
1542
TimeToNextDHCPLeaseRenewal(uint32_t * result)1543 bool Device::TimeToNextDHCPLeaseRenewal(uint32_t* result) {
1544 if (!ipconfig() && !ip6config()) {
1545 return false;
1546 }
1547 uint32_t time_to_ipv4_lease_expiry = UINT32_MAX;
1548 uint32_t time_to_ipv6_lease_expiry = UINT32_MAX;
1549 if (ipconfig()) {
1550 ipconfig()->TimeToLeaseExpiry(&time_to_ipv4_lease_expiry);
1551 }
1552 if (ip6config()) {
1553 ip6config()->TimeToLeaseExpiry(&time_to_ipv6_lease_expiry);
1554 }
1555 *result = std::min(time_to_ipv4_lease_expiry, time_to_ipv6_lease_expiry);
1556 return true;
1557 }
1558
IsTrafficMonitorEnabled() const1559 bool Device::IsTrafficMonitorEnabled() const {
1560 return false;
1561 }
1562
StartTrafficMonitor()1563 void Device::StartTrafficMonitor() {
1564 // Return if traffic monitor is not enabled for this device.
1565 if (!IsTrafficMonitorEnabled()) {
1566 return;
1567 }
1568
1569 SLOG(this, 2) << "Device " << FriendlyName()
1570 << ": Traffic Monitor starting.";
1571 if (!traffic_monitor_.get()) {
1572 traffic_monitor_.reset(new TrafficMonitor(this, dispatcher_));
1573 traffic_monitor_->set_network_problem_detected_callback(
1574 Bind(&Device::OnEncounterNetworkProblem,
1575 weak_ptr_factory_.GetWeakPtr()));
1576 }
1577 traffic_monitor_->Start();
1578 }
1579
StopTrafficMonitor()1580 void Device::StopTrafficMonitor() {
1581 // Return if traffic monitor is not enabled for this device.
1582 if (!IsTrafficMonitorEnabled()) {
1583 return;
1584 }
1585
1586 if (traffic_monitor_.get()) {
1587 SLOG(this, 2) << "Device " << FriendlyName()
1588 << ": Traffic Monitor stopping.";
1589 traffic_monitor_->Stop();
1590 }
1591 traffic_monitor_.reset();
1592 }
1593
OnEncounterNetworkProblem(int reason)1594 void Device::OnEncounterNetworkProblem(int reason) {
1595 int metric_code;
1596 switch (reason) {
1597 case TrafficMonitor::kNetworkProblemCongestedTxQueue:
1598 metric_code = Metrics::kNetworkProblemCongestedTCPTxQueue;
1599 break;
1600 case TrafficMonitor::kNetworkProblemDNSFailure:
1601 metric_code = Metrics::kNetworkProblemDNSFailure;
1602 break;
1603 default:
1604 LOG(ERROR) << "Invalid network problem code: " << reason;
1605 return;
1606 }
1607
1608 metrics()->NotifyNetworkProblemDetected(technology_, metric_code);
1609 // Stop the traffic monitor, only report the first network problem detected
1610 // on the connection for now.
1611 StopTrafficMonitor();
1612 }
1613
SetServiceConnectedState(Service::ConnectState state)1614 void Device::SetServiceConnectedState(Service::ConnectState state) {
1615 DCHECK(selected_service_.get());
1616
1617 if (!selected_service_.get()) {
1618 LOG(ERROR) << FriendlyName() << ": "
1619 << "Portal detection completed but no selected service exists!";
1620 return;
1621 }
1622
1623 if (!selected_service_->IsConnected()) {
1624 LOG(ERROR) << FriendlyName() << ": "
1625 << "Portal detection completed but selected service "
1626 << selected_service_->unique_name()
1627 << " is in non-connected state.";
1628 return;
1629 }
1630
1631 if (state == Service::kStatePortal && connection_->is_default() &&
1632 manager_->GetPortalCheckInterval() != 0) {
1633 CHECK(portal_detector_.get());
1634 if (!portal_detector_->StartAfterDelay(
1635 manager_->GetPortalCheckURL(),
1636 manager_->GetPortalCheckInterval())) {
1637 LOG(ERROR) << "Device " << FriendlyName()
1638 << ": Portal detection failed to restart: likely bad URL: "
1639 << manager_->GetPortalCheckURL();
1640 SetServiceState(Service::kStateOnline);
1641 portal_detector_.reset();
1642 return;
1643 }
1644 SLOG(this, 2) << "Device " << FriendlyName()
1645 << ": Portal detection retrying.";
1646 } else {
1647 SLOG(this, 2) << "Device " << FriendlyName()
1648 << ": Portal will not retry.";
1649 portal_detector_.reset();
1650 }
1651
1652 SetServiceState(state);
1653 }
1654
PortalDetectorCallback(const PortalDetector::Result & result)1655 void Device::PortalDetectorCallback(const PortalDetector::Result& result) {
1656 if (!result.final) {
1657 SLOG(this, 2) << "Device " << FriendlyName()
1658 << ": Received non-final status: "
1659 << ConnectivityTrial::StatusToString(
1660 result.trial_result.status);
1661 return;
1662 }
1663
1664 SLOG(this, 2) << "Device " << FriendlyName()
1665 << ": Received final status: "
1666 << ConnectivityTrial::StatusToString(
1667 result.trial_result.status);
1668
1669 portal_attempts_to_online_ += result.num_attempts;
1670
1671 int portal_status = Metrics::PortalDetectionResultToEnum(result);
1672 metrics()->SendEnumToUMA(
1673 metrics()->GetFullMetricName(Metrics::kMetricPortalResultSuffix,
1674 technology()),
1675 portal_status,
1676 Metrics::kPortalResultMax);
1677
1678 if (result.trial_result.status == ConnectivityTrial::kStatusSuccess) {
1679 SetServiceConnectedState(Service::kStateOnline);
1680
1681 metrics()->SendToUMA(
1682 metrics()->GetFullMetricName(
1683 Metrics::kMetricPortalAttemptsToOnlineSuffix, technology()),
1684 portal_attempts_to_online_,
1685 Metrics::kMetricPortalAttemptsToOnlineMin,
1686 Metrics::kMetricPortalAttemptsToOnlineMax,
1687 Metrics::kMetricPortalAttemptsToOnlineNumBuckets);
1688 } else {
1689 // Set failure phase and status.
1690 if (selected_service_.get()) {
1691 selected_service_->SetPortalDetectionFailure(
1692 ConnectivityTrial::PhaseToString(result.trial_result.phase),
1693 ConnectivityTrial::StatusToString(result.trial_result.status));
1694 }
1695 SetServiceConnectedState(Service::kStatePortal);
1696
1697 metrics()->SendToUMA(
1698 metrics()->GetFullMetricName(
1699 Metrics::kMetricPortalAttemptsSuffix, technology()),
1700 result.num_attempts,
1701 Metrics::kMetricPortalAttemptsMin,
1702 Metrics::kMetricPortalAttemptsMax,
1703 Metrics::kMetricPortalAttemptsNumBuckets);
1704
1705 StartConnectionDiagnosticsAfterPortalDetection(result);
1706
1707 // TODO(zqiu): Only support fallback DNS server for IPv4 for now.
1708 if (connection_->IsIPv6()) {
1709 return;
1710 }
1711
1712 // Perform fallback DNS test if the portal failure is DNS related.
1713 // The test will send a DNS request to Google's DNS server to determine
1714 // if the DNS failure is due to bad DNS server settings.
1715 if ((portal_status == Metrics::kPortalResultDNSFailure) ||
1716 (portal_status == Metrics::kPortalResultDNSTimeout)) {
1717 StartDNSTest(vector<string>(std::begin(kFallbackDnsServers),
1718 std::end(kFallbackDnsServers)),
1719 false,
1720 Bind(&Device::FallbackDNSResultCallback,
1721 weak_ptr_factory_.GetWeakPtr()));
1722 }
1723 }
1724 }
1725
GetSelectedServiceRpcIdentifier(Error *)1726 string Device::GetSelectedServiceRpcIdentifier(Error* /*error*/) {
1727 if (!selected_service_) {
1728 return "/";
1729 }
1730 return selected_service_->GetRpcIdentifier();
1731 }
1732
AvailableIPConfigs(Error *)1733 vector<string> Device::AvailableIPConfigs(Error* /*error*/) {
1734 vector<string> ipconfigs;
1735 if (ipconfig_) {
1736 ipconfigs.push_back(ipconfig_->GetRpcIdentifier());
1737 }
1738 if (ip6config_) {
1739 ipconfigs.push_back(ip6config_->GetRpcIdentifier());
1740 }
1741 if (dhcpv6_config_) {
1742 ipconfigs.push_back(dhcpv6_config_->GetRpcIdentifier());
1743 }
1744 return ipconfigs;
1745 }
1746
GetLinkMonitorResponseTime(Error * error)1747 uint64_t Device::GetLinkMonitorResponseTime(Error* error) {
1748 if (!link_monitor_.get()) {
1749 // It is not strictly an error that the link monitor does not
1750 // exist, but returning an error here allows the GetProperties
1751 // call in our Adaptor to omit this parameter.
1752 error->Populate(Error::kNotFound, "Device is not running LinkMonitor");
1753 return 0;
1754 }
1755 return link_monitor_->GetResponseTimeMilliseconds();
1756 }
1757
GetReceiveByteCount()1758 uint64_t Device::GetReceiveByteCount() {
1759 uint64_t rx_byte_count = 0, tx_byte_count = 0;
1760 manager_->device_info()->GetByteCounts(
1761 interface_index_, &rx_byte_count, &tx_byte_count);
1762 return rx_byte_count - receive_byte_offset_;
1763 }
1764
GetTransmitByteCount()1765 uint64_t Device::GetTransmitByteCount() {
1766 uint64_t rx_byte_count = 0, tx_byte_count = 0;
1767 manager_->device_info()->GetByteCounts(
1768 interface_index_, &rx_byte_count, &tx_byte_count);
1769 return tx_byte_count - transmit_byte_offset_;
1770 }
1771
GetReceiveByteCountProperty(Error *)1772 uint64_t Device::GetReceiveByteCountProperty(Error* /*error*/) {
1773 return GetReceiveByteCount();
1774 }
1775
GetTransmitByteCountProperty(Error *)1776 uint64_t Device::GetTransmitByteCountProperty(Error* /*error*/) {
1777 return GetTransmitByteCount();
1778 }
1779
IsUnderlyingDeviceEnabled() const1780 bool Device::IsUnderlyingDeviceEnabled() const {
1781 return false;
1782 }
1783
1784 // callback
OnEnabledStateChanged(const ResultCallback & callback,const Error & error)1785 void Device::OnEnabledStateChanged(const ResultCallback& callback,
1786 const Error& error) {
1787 SLOG(this, 2) << __func__
1788 << " (target: " << enabled_pending_ << ","
1789 << " success: " << error.IsSuccess() << ")"
1790 << " on " << link_name_;
1791 if (error.IsSuccess()) {
1792 enabled_ = enabled_pending_;
1793 manager_->UpdateEnabledTechnologies();
1794 adaptor_->EmitBoolChanged(kPoweredProperty, enabled_);
1795 }
1796 enabled_pending_ = enabled_;
1797 if (!callback.is_null())
1798 callback.Run(error);
1799 }
1800
SetEnabled(bool enable)1801 void Device::SetEnabled(bool enable) {
1802 SLOG(this, 2) << __func__ << "(" << enable << ")";
1803 Error error;
1804 SetEnabledChecked(enable, false, &error, ResultCallback());
1805
1806 // SetEnabledInternal might fail here if there is an unfinished enable or
1807 // disable operation. Don't log error in this case, as this method is only
1808 // called when the underlying device is already in the target state and the
1809 // pending operation should eventually bring the device to the expected
1810 // state.
1811 LOG_IF(ERROR,
1812 error.IsFailure() &&
1813 !error.IsOngoing() &&
1814 error.type() != Error::kInProgress)
1815 << "Enabled failed, but no way to report the failure.";
1816 }
1817
SetEnabledNonPersistent(bool enable,Error * error,const ResultCallback & callback)1818 void Device::SetEnabledNonPersistent(bool enable,
1819 Error* error,
1820 const ResultCallback& callback) {
1821 SetEnabledChecked(enable, false, error, callback);
1822 }
1823
SetEnabledPersistent(bool enable,Error * error,const ResultCallback & callback)1824 void Device::SetEnabledPersistent(bool enable,
1825 Error* error,
1826 const ResultCallback& callback) {
1827 SetEnabledChecked(enable, true, error, callback);
1828 }
1829
SetEnabledChecked(bool enable,bool persist,Error * error,const ResultCallback & callback)1830 void Device::SetEnabledChecked(bool enable,
1831 bool persist,
1832 Error* error,
1833 const ResultCallback& callback) {
1834 DCHECK(error);
1835 SLOG(this, 2) << "Device " << link_name_ << " "
1836 << (enable ? "starting" : "stopping");
1837 if (enable && manager_->IsTechnologyProhibited(technology())) {
1838 error->Populate(Error::kPermissionDenied, "The " +
1839 Technology::NameFromIdentifier(technology()) +
1840 " technology is prohibited");
1841 return;
1842 }
1843
1844 if (enable == enabled_) {
1845 if (enable != enabled_pending_ && persist) {
1846 // Return an error, as there is an ongoing operation to achieve the
1847 // opposite.
1848 Error::PopulateAndLog(
1849 FROM_HERE, error, Error::kOperationFailed,
1850 enable ? "Cannot enable while the device is disabling." :
1851 "Cannot disable while the device is enabling.");
1852 return;
1853 }
1854 LOG(INFO) << "Already in desired enable state.";
1855 error->Reset();
1856 return;
1857 }
1858
1859 if (enabled_pending_ == enable) {
1860 Error::PopulateAndLog(FROM_HERE, error, Error::kInProgress,
1861 "Enable operation already in progress");
1862 return;
1863 }
1864
1865 if (persist) {
1866 enabled_persistent_ = enable;
1867 manager_->UpdateDevice(this);
1868 }
1869
1870 SetEnabledUnchecked(enable, error, callback);
1871 }
1872
SetEnabledUnchecked(bool enable,Error * error,const ResultCallback & on_enable_complete)1873 void Device::SetEnabledUnchecked(bool enable, Error* error,
1874 const ResultCallback& on_enable_complete) {
1875 enabled_pending_ = enable;
1876 EnabledStateChangedCallback chained_callback =
1877 Bind(&Device::OnEnabledStateChanged,
1878 weak_ptr_factory_.GetWeakPtr(), on_enable_complete);
1879 if (enable) {
1880 running_ = true;
1881 Start(error, chained_callback);
1882 } else {
1883 running_ = false;
1884 DestroyIPConfig(); // breaks a reference cycle
1885 SelectService(nullptr); // breaks a reference cycle
1886 rtnl_handler_->SetInterfaceFlags(interface_index(), 0, IFF_UP);
1887 SLOG(this, 3) << "Device " << link_name_ << " ipconfig_ "
1888 << (ipconfig_ ? "is set." : "is not set.");
1889 SLOG(this, 3) << "Device " << link_name_ << " ip6config_ "
1890 << (ip6config_ ? "is set." : "is not set.");
1891 SLOG(this, 3) << "Device " << link_name_ << " connection_ "
1892 << (connection_ ? "is set." : "is not set.");
1893 SLOG(this, 3) << "Device " << link_name_ << " selected_service_ "
1894 << (selected_service_ ? "is set." : "is not set.");
1895 Stop(error, chained_callback);
1896 }
1897 }
1898
UpdateIPConfigsProperty()1899 void Device::UpdateIPConfigsProperty() {
1900 adaptor_->EmitRpcIdentifierArrayChanged(
1901 kIPConfigsProperty, AvailableIPConfigs(nullptr));
1902 }
1903
ResolvePeerMacAddress(const string & input,string * output,Error * error)1904 bool Device::ResolvePeerMacAddress(const string& input,
1905 string* output,
1906 Error* error) {
1907 if (!MakeHardwareAddressFromString(input).empty()) {
1908 // Input is already a MAC address.
1909 *output = input;
1910 return true;
1911 }
1912
1913 IPAddress ip_address(IPAddress::kFamilyIPv4);
1914 if (!ip_address.SetAddressFromString(input)) {
1915 Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
1916 "Peer is neither an IP Address nor a MAC address");
1917 return false;
1918 }
1919
1920 // Peer address was specified as an IP address which we need to resolve.
1921 const DeviceInfo* device_info = manager()->device_info();
1922 if (!device_info->HasDirectConnectivityTo(interface_index_, ip_address)) {
1923 Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
1924 "IP address is not local to this interface");
1925 return false;
1926 }
1927
1928 ByteString mac_address;
1929 if (device_info->GetMACAddressOfPeer(interface_index_,
1930 ip_address,
1931 &mac_address)) {
1932 *output = MakeStringFromHardwareAddress(
1933 vector<uint8_t>(mac_address.GetConstData(),
1934 mac_address.GetConstData() +
1935 mac_address.GetLength()));
1936 SLOG(this, 2) << "ARP cache lookup returned peer: " << *output;
1937 return true;
1938 }
1939
1940 if (!Icmp().TransmitEchoRequest(ip_address, 1, 1)) {
1941 Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
1942 "Failed to send ICMP request to peer to setup ARP");
1943 } else {
1944 // ARP request was transmitted successfully, address resolution is still
1945 // pending.
1946 error->Populate(Error::kInProgress,
1947 "Peer MAC address was not found in the ARP cache, "
1948 "but an ARP request was sent to find it. "
1949 "Please try again.");
1950 }
1951 return false;
1952 }
1953
1954 // static
MakeHardwareAddressFromString(const string & address_string)1955 vector<uint8_t> Device::MakeHardwareAddressFromString(
1956 const string& address_string) {
1957 string address_nosep;
1958 base::RemoveChars(address_string, ":", &address_nosep);
1959 vector<uint8_t> address_bytes;
1960 base::HexStringToBytes(address_nosep, &address_bytes);
1961 if (address_bytes.size() != kHardwareAddressLength) {
1962 return vector<uint8_t>();
1963 }
1964 return address_bytes;
1965 }
1966
1967 // static
MakeStringFromHardwareAddress(const vector<uint8_t> & address_bytes)1968 string Device::MakeStringFromHardwareAddress(
1969 const vector<uint8_t>& address_bytes) {
1970 CHECK_EQ(kHardwareAddressLength, address_bytes.size());
1971 return StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x",
1972 address_bytes[0], address_bytes[1], address_bytes[2],
1973 address_bytes[3], address_bytes[4], address_bytes[5]);
1974 }
1975
RequestRoam(const std::string & addr,Error * error)1976 bool Device::RequestRoam(const std::string& addr, Error* error) {
1977 return false;
1978 }
1979
1980 } // namespace shill
1981