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; 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 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 240 Device::~Device() { 241 LOG(INFO) << "Device destructed: " << link_name_ 242 << " index " << interface_index_; 243 } 244 245 void Device::Initialize() { 246 SLOG(this, 2) << "Initialized"; 247 DisableArpFiltering(); 248 EnableReversePathFilter(); 249 } 250 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 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 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 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 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 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 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 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 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 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 321 bool Device::IsIPv6Allowed() const { 322 return true; 323 } 324 325 void Device::DisableIPv6() { 326 SLOG(this, 2) << __func__; 327 SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "1"); 328 } 329 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 340 void Device::EnableIPv6Privacy() { 341 SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagUseTempAddr, 342 kIPFlagUseTempAddrUsedAndDefault); 343 } 344 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 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 368 void Device::EnableReversePathFilter() { 369 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter, 370 kIPFlagReversePathFilterEnabled); 371 } 372 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 393 void Device::DisableArpFiltering() { 394 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce, 395 kIPFlagArpAnnounceDefault); 396 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore, kIPFlagArpIgnoreDefault); 397 } 398 399 void Device::EnableArpFiltering() { 400 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce, 401 kIPFlagArpAnnounceBestLocal); 402 SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore, 403 kIPFlagArpIgnoreLocalOnly); 404 } 405 406 bool Device::IsConnected() const { 407 if (selected_service_) 408 return selected_service_->IsConnected(); 409 return false; 410 } 411 412 bool Device::IsConnectedToService(const ServiceRefPtr& service) const { 413 return service == selected_service_ && IsConnected(); 414 } 415 416 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 432 string Device::GetRpcIdentifier() const { 433 return adaptor_->GetRpcIdentifier(); 434 } 435 436 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 445 vector<GeolocationInfo> Device::GetGeolocationObjects() const { 446 return vector<GeolocationInfo>(); 447 } 448 449 string Device::GetTechnologyString(Error* /*error*/) { 450 return Technology::NameFromIdentifier(technology()); 451 } 452 453 const string& Device::FriendlyName() const { 454 return link_name_; 455 } 456 457 const string& Device::UniqueName() const { 458 return unique_id_; 459 } 460 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 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 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 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 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 522 void Device::DropConnection() { 523 SLOG(this, 2) << __func__; 524 DestroyIPConfig(); 525 SelectService(nullptr); 526 } 527 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 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 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 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 650 void Device::StopIPv6DNSServerTimer() { 651 ipv6_dns_server_expired_callback_.Cancel(); 652 } 653 654 void Device::IPv6DNSServerExpired() { 655 if (!ip6config_) { 656 return; 657 } 658 ip6config_->UpdateDNSServers(vector<string>()); 659 UpdateIPConfigsProperty(); 660 } 661 662 void Device::StopAllActivities() { 663 StopTrafficMonitor(); 664 StopPortalDetection(); 665 StopConnectivityTest(); 666 StopConnectionDiagnostics(); 667 StopLinkMonitor(); 668 StopDNSTest(); 669 StopIPv6DNSServerTimer(); 670 } 671 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 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 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 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 717 bool Device::ShouldUseArpGateway() const { 718 return false; 719 } 720 721 bool Device::IsUsingStaticIP() const { 722 if (!selected_service_) { 723 return false; 724 } 725 return selected_service_->HasStaticIPAddress(); 726 } 727 728 bool Device::IsUsingStaticNameServers() const { 729 if (!selected_service_) { 730 return false; 731 } 732 return selected_service_->HasStaticNameServers(); 733 } 734 735 bool Device::AcquireIPConfig() { 736 return AcquireIPConfigWithLeaseName(string()); 737 } 738 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 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 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 818 void Device::DestroyIPConfigLease(const string& name) { 819 dhcp_provider_->DestroyLease(name); 820 } 821 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 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 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 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 857 void Device::ConnectionTesterCallback() { 858 LOG(INFO) << "Device " << FriendlyName() << ": Completed Connectivity Test"; 859 return; 860 } 861 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 885 bool Device::IPConfigCompleted(const IPConfigRefPtr& ipconfig) { 886 return ipconfig && !ipconfig->properties().address.empty() && 887 !ipconfig->properties().dns_servers.empty(); 888 } 889 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 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 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 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 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 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 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 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 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 1077 void Device::OnIPConfigFailure() { 1078 if (selected_service_) { 1079 Error error; 1080 selected_service_->DisconnectWithFailure(Service::kFailureDHCP, 1081 &error, 1082 __func__); 1083 } 1084 } 1085 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 1096 void Device::OnDHCPv6ConfigUpdated(const IPConfigRefPtr& ipconfig, 1097 bool /*new_lease_acquired*/) { 1098 // Emit configuration update. 1099 UpdateIPConfigsProperty(); 1100 } 1101 1102 void Device::OnDHCPv6ConfigFailed(const IPConfigRefPtr& ipconfig) { 1103 // Reset configuration data. 1104 ipconfig->ResetProperties(); 1105 UpdateIPConfigsProperty(); 1106 } 1107 1108 void Device::OnDHCPv6ConfigExpired(const IPConfigRefPtr& ipconfig) { 1109 // Reset configuration data. 1110 ipconfig->ResetProperties(); 1111 UpdateIPConfigsProperty(); 1112 } 1113 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 1126 void Device::OnConnectionUpdated() { 1127 if (selected_service_) { 1128 manager_->UpdateService(selected_service_); 1129 } 1130 } 1131 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 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 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 1187 void Device::SetServiceState(Service::ConnectState state) { 1188 if (selected_service_.get()) { 1189 selected_service_->SetState(state); 1190 } 1191 } 1192 1193 void Device::SetServiceFailure(Service::ConnectFailure failure_state) { 1194 if (selected_service_.get()) { 1195 selected_service_->SetFailure(failure_state); 1196 } 1197 } 1198 1199 void Device::SetServiceFailureSilent(Service::ConnectFailure failure_state) { 1200 if (selected_service_.get()) { 1201 selected_service_->SetFailureSilent(failure_state); 1202 } 1203 } 1204 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 1235 string Device::PerformTDLSOperation(const string& /* operation */, 1236 const string& /* peer */, 1237 Error* /* error */) { 1238 return ""; 1239 } 1240 1241 void Device::ResetByteCounters() { 1242 manager_->device_info()->GetByteCounts( 1243 interface_index_, &receive_byte_offset_, &transmit_byte_offset_); 1244 manager_->UpdateDevice(this); 1245 } 1246 1247 bool Device::RestartPortalDetection() { 1248 StopPortalDetection(); 1249 return StartPortalDetection(); 1250 } 1251 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 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 1335 void Device::StopPortalDetection() { 1336 SLOG(this, 2) << "Device " << FriendlyName() 1337 << ": Portal detection stopping."; 1338 portal_detector_.reset(); 1339 } 1340 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 1360 void Device::StopConnectionDiagnostics() { 1361 SLOG(this, 2) << "Device " << FriendlyName() 1362 << ": Connection diagnostics stopping."; 1363 connection_diagnostics_.reset(); 1364 } 1365 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 1376 void Device::StopConnectivityTest() { 1377 SLOG(this, 2) << "Device " << FriendlyName() 1378 << ": Connectivity test stopping."; 1379 connection_tester_.reset(); 1380 } 1381 1382 void Device::set_link_monitor(LinkMonitor* link_monitor) { 1383 link_monitor_.reset(link_monitor); 1384 } 1385 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 1413 void Device::StopLinkMonitor() { 1414 SLOG(this, 2) << "Device " << FriendlyName() 1415 << ": Link Monitor stopping."; 1416 link_monitor_.reset(); 1417 } 1418 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 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 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 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 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 1482 void Device::StopDNSTest() { 1483 dns_server_tester_.reset(); 1484 } 1485 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 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 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 1539 void Device::set_traffic_monitor(TrafficMonitor* traffic_monitor) { 1540 traffic_monitor_.reset(traffic_monitor); 1541 } 1542 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 1559 bool Device::IsTrafficMonitorEnabled() const { 1560 return false; 1561 } 1562 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 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 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 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 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 1726 string Device::GetSelectedServiceRpcIdentifier(Error* /*error*/) { 1727 if (!selected_service_) { 1728 return "/"; 1729 } 1730 return selected_service_->GetRpcIdentifier(); 1731 } 1732 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 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 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 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 1772 uint64_t Device::GetReceiveByteCountProperty(Error* /*error*/) { 1773 return GetReceiveByteCount(); 1774 } 1775 1776 uint64_t Device::GetTransmitByteCountProperty(Error* /*error*/) { 1777 return GetTransmitByteCount(); 1778 } 1779 1780 bool Device::IsUnderlyingDeviceEnabled() const { 1781 return false; 1782 } 1783 1784 // callback 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 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 1818 void Device::SetEnabledNonPersistent(bool enable, 1819 Error* error, 1820 const ResultCallback& callback) { 1821 SetEnabledChecked(enable, false, error, callback); 1822 } 1823 1824 void Device::SetEnabledPersistent(bool enable, 1825 Error* error, 1826 const ResultCallback& callback) { 1827 SetEnabledChecked(enable, true, error, callback); 1828 } 1829 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 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 1899 void Device::UpdateIPConfigsProperty() { 1900 adaptor_->EmitRpcIdentifierArrayChanged( 1901 kIPConfigsProperty, AvailableIPConfigs(nullptr)); 1902 } 1903 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 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 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 1976 bool Device::RequestRoam(const std::string& addr, Error* error) { 1977 return false; 1978 } 1979 1980 } // namespace shill 1981