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