1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License. 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 1675897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart 172b10554b6c736f3421102d483b74b70bb82f997cChris Masone#include "shill/device.h" 182b10554b6c736f3421102d483b74b70bb82f997cChris Masone 1908add488849f90600a5657a6f54f4dbc34701b8fMatthew Wein#include <errno.h> 205c4dd0b0886fb10deae0d3b40628fb2c521aff99mukesh agrawal#include <netinet/in.h> 21a41ab517725d036b63420f8445550246f8f50b99Alex Vakulenko#include <linux/if.h> // NOLINT - Needs definitions from netinet/in.h 2275897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart#include <stdio.h> 23b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu#include <string.h> 24208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart#include <sys/param.h> 255c4dd0b0886fb10deae0d3b40628fb2c521aff99mukesh agrawal#include <time.h> 2608add488849f90600a5657a6f54f4dbc34701b8fMatthew Wein#include <unistd.h> 27ee929b7ab2a89bbf2d1aecf85bbd49e53fbea059Chris Masone 28787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan#include <algorithm> 29c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly#include <set> 3075897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart#include <string> 318fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone#include <vector> 3275897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart 333e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood#include <base/bind.h> 3411c213f3cf64f27a0e42ee6da95e98bd1d4b3202Ben Chan#include <base/files/file_util.h> 35487b8bfc46a91e29bb23aaf3c59cfe67033bfc8bChris Masone#include <base/memory/ref_counted.h> 3638fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart#include <base/stl_util.h> 37a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/stringprintf.h> 3862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu#include <base/strings/string_number_conversions.h> 3962abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu#include <base/strings/string_util.h> 40289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#if defined(__ANDROID__) 41289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#include <dbus/service_constants.h> 42289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#else 433bd3c8c33917221d1074f1aa19272e45c0ce2793Chris Masone#include <chromeos/dbus/service_constants.h> 44289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#endif // __ANDROID__ 45ee929b7ab2a89bbf2d1aecf85bbd49e53fbea059Chris Masone 46f84a4242b4218dc375449ab2d68085226f43ce5bArman Uguray#include "shill/async_connection.h" 47e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart#include "shill/connection.h" 48f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein#include "shill/connection_tester.h" 4975897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart#include "shill/control_interface.h" 50675d0b0f04936050a357722f52dc078a3ab671d8Peter Qiu#include "shill/dhcp/dhcp_config.h" 51675d0b0f04936050a357722f52dc078a3ab671d8Peter Qiu#include "shill/dhcp/dhcp_provider.h" 5215d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein#include "shill/dhcp_properties.h" 538fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone#include "shill/error.h" 5426b327e559583d5a84b7e1605c29a4dcbc87d2a9Paul Stewart#include "shill/event_dispatcher.h" 556d2c72dddf3dbbc6a614d4fa1a7a3d670756c01fGaurav Shah#include "shill/geolocation_info.h" 56f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include "shill/http_proxy.h" 5762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu#include "shill/icmp.h" 58fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan#include "shill/ip_address_store.h" 59036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart#include "shill/link_monitor.h" 60b691efd71561246065eae3cdd73a96ca1b8a528dChristopher Wiley#include "shill/logging.h" 618fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone#include "shill/manager.h" 6285e050b4923878a57aec1415314d2b39ff233e00Thieu Le#include "shill/metrics.h" 638d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ip_address.h" 648d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ndisc.h" 658d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/rtnl_handler.h" 6695207da4b896bd0a4186163f6f9ebda044a5a7b9Chris Masone#include "shill/property_accessor.h" 672b10554b6c736f3421102d483b74b70bb82f997cChris Masone#include "shill/refptr_types.h" 682b10554b6c736f3421102d483b74b70bb82f997cChris Masone#include "shill/service.h" 69f84a4242b4218dc375449ab2d68085226f43ce5bArman Uguray#include "shill/socket_info_reader.h" 705dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone#include "shill/store_interface.h" 71435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah#include "shill/technology.h" 72fa11e28ddb81dab93971d5433a5274a1dc5c8283Paul Stewart#include "shill/tethering.h" 73dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu#include "shill/traffic_monitor.h" 7475897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart 753e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Bind; 766f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiuusing base::Callback; 770e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulkusing base::FilePath; 785dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masoneusing base::StringPrintf; 79c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kellyusing std::set; 808fe2c7eea92541b5282929361a19ad519e0608a9Chris Masoneusing std::string; 818fe2c7eea92541b5282929361a19ad519e0608a9Chris Masoneusing std::vector; 828fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone 8375897df1154ac38b7a4512a687241ad6a197ee40Paul Stewartnamespace shill { 845dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone 85c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silbersteinnamespace Logging { 86c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silbersteinstatic auto kModuleLogScope = ScopeLogger::kDevice; 87a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartstatic string ObjectID(Device* d) { return d->GetRpcIdentifier(); } 88c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein} 89c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein 905dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone// static 912bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartconst char Device::kIPFlagTemplate[] = "/proc/sys/net/%s/conf/%s/%s"; 922bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart// static 932bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartconst char Device::kIPFlagVersion4[] = "ipv4"; 942bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart// static 952bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartconst char Device::kIPFlagVersion6[] = "ipv6"; 962bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart// static 972bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartconst char Device::kIPFlagDisableIPv6[] = "disable_ipv6"; 982bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart// static 992bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartconst char Device::kIPFlagUseTempAddr[] = "use_tempaddr"; 1002bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart// static 1012bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartconst char Device::kIPFlagUseTempAddrUsedAndDefault[] = "2"; 102c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart// static 103c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewartconst char Device::kIPFlagReversePathFilter[] = "rp_filter"; 104c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart// static 105c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewartconst char Device::kIPFlagReversePathFilterEnabled[] = "1"; 106c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart// static 107c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewartconst char Device::kIPFlagReversePathFilterLooseMode[] = "2"; 1082bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart// static 1092cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartconst char Device::kIPFlagArpAnnounce[] = "arp_announce"; 1102cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart// static 1112cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartconst char Device::kIPFlagArpAnnounceDefault[] = "0"; 1122cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart// static 1132cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartconst char Device::kIPFlagArpAnnounceBestLocal[] = "2"; 1142cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart// static 1152cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartconst char Device::kIPFlagArpIgnore[] = "arp_ignore"; 1162cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart// static 1172cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartconst char Device::kIPFlagArpIgnoreDefault[] = "0"; 1182cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart// static 1192cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartconst char Device::kIPFlagArpIgnoreLocalOnly[] = "1"; 1202cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart// static 121ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhuconst char Device::kStoragePowered[] = "Powered"; 122ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu// static 1236ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewartconst char Device::kStorageReceiveByteCount[] = "ReceiveByteCount"; 1246ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart// static 1256ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewartconst char Device::kStorageTransmitByteCount[] = "TransmitByteCount"; 126b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu// static 127b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiuconst char Device::kFallbackDnsTestHostname[] = "www.gstatic.com"; 128b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu// static 129b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiuconst char* Device::kFallbackDnsServers[] = { 130b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu "8.8.8.8", 131a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu "8.8.4.4" 132b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu}; 133b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu 134b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu// static 135b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiuconst int Device::kDNSTimeoutMilliseconds = 5000; 136a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiuconst int Device::kLinkUnreliableThresholdSeconds = 60 * 60; 13762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiuconst size_t Device::kHardwareAddressLength = 6U; 1385dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone 139a794cd60a7339d576ea2eed263a4f0a20fb255afPaul StewartDevice::Device(ControlInterface* control_interface, 140a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart EventDispatcher* dispatcher, 141a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Metrics* metrics, 142a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Manager* manager, 143a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& link_name, 144a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& address, 145435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah int interface_index, 146435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah Technology::Identifier technology) 1479a24553461df7036755060423f90804011612249Eric Shienbrood : enabled_(false), 1489a24553461df7036755060423f90804011612249Eric Shienbrood enabled_persistent_(true), 1499a24553461df7036755060423f90804011612249Eric Shienbrood enabled_pending_(enabled_), 150b925cc8f481d21fddd9569fc68861f6e5b6e3eaeChris Masone reconnect_(true), 151626719f89881a949d8b5a8fa808beb924496489fChris Masone hardware_address_(address), 152f60e406392490f72982e7d1b1acb8b231a620cb7mukesh agrawal interface_index_(interface_index), 153f60e406392490f72982e7d1b1acb8b231a620cb7mukesh agrawal running_(false), 154afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov link_name_(link_name), 15519e30406a1d3123892007d20438527dc4b2f92c3Chris Masone unique_id_(link_name), 156d9661956a297e6d7a3e5809f50e332dc9c9811a9Darin Petkov control_interface_(control_interface), 157d9661956a297e6d7a3e5809f50e332dc9c9811a9Darin Petkov dispatcher_(dispatcher), 1583426c8fc7a3943f2d8fcb2ec78f0593088b42bedThieu Le metrics_(metrics), 1597df0c672458bee8f4ff33004103351d59a9f4b50Chris Masone manager_(manager), 1609a24553461df7036755060423f90804011612249Eric Shienbrood weak_ptr_factory_(this), 16177cb681ab58c6623464a355e646138ab84d38573Darin Petkov adaptor_(control_interface->CreateDeviceAdaptor(this)), 1629a24553461df7036755060423f90804011612249Eric Shienbrood portal_detector_callback_(Bind(&Device::PortalDetectorCallback, 1639a24553461df7036755060423f90804011612249Eric Shienbrood weak_ptr_factory_.GetWeakPtr())), 164435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah technology_(technology), 16585e050b4923878a57aec1415314d2b39ff233e00Thieu Le portal_attempts_to_online_(0), 1666ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart receive_byte_offset_(0), 1676ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart transmit_byte_offset_(0), 1685c4dd0b0886fb10deae0d3b40628fb2c521aff99mukesh agrawal dhcp_provider_(DHCPProvider::GetInstance()), 169a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu rtnl_handler_(RTNLHandler::GetInstance()), 170a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu time_(Time::GetInstance()), 171f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein last_link_monitor_failed_time_(0), 172f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein connection_tester_callback_(Bind(&Device::ConnectionTesterCallback, 1732cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart weak_ptr_factory_.GetWeakPtr())), 1742cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart is_loose_routing_(false), 175490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan is_multi_homed_(false), 176490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan connection_diagnostics_callback_( 177490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan Bind(&Device::ConnectionDiagnosticsCallback, 178490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan weak_ptr_factory_.GetWeakPtr())) { 179923a5025a5e1138b052cbeffa60ea387d479696fBen Chan store_.RegisterConstString(kAddressProperty, &hardware_address_); 180923a5025a5e1138b052cbeffa60ea387d479696fBen Chan 181923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kBgscanMethodProperty: Registered in WiFi 182923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kBgscanShortIntervalProperty: Registered in WiFi 183923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kBgscanSignalThresholdProperty: Registered in WiFi 184923a5025a5e1138b052cbeffa60ea387d479696fBen Chan 185923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kCellularAllowRoamingProperty: Registered in Cellular 186923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kCarrierProperty: Registered in Cellular 187923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kEsnProperty: Registered in Cellular 188923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kHomeProviderProperty: Registered in Cellular 189923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kImeiProperty: Registered in Cellular 190923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kIccidProperty: Registered in Cellular 191923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kImsiProperty: Registered in Cellular 192923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kManufacturerProperty: Registered in Cellular 193923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kMdnProperty: Registered in Cellular 194923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kMeidProperty: Registered in Cellular 195923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kMinProperty: Registered in Cellular 196923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kModelIDProperty: Registered in Cellular 197923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kFirmwareRevisionProperty: Registered in Cellular 198923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kHardwareRevisionProperty: Registered in Cellular 199923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kPRLVersionProperty: Registered in Cellular 200923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kSIMLockStatusProperty: Registered in Cellular 201923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kFoundNetworksProperty: Registered in Cellular 202923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kDBusObjectProperty: Register in Cellular 203923a5025a5e1138b052cbeffa60ea387d479696fBen Chan 204923a5025a5e1138b052cbeffa60ea387d479696fBen Chan store_.RegisterConstString(kInterfaceProperty, &link_name_); 205674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley HelpRegisterConstDerivedRpcIdentifier( 206674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley kSelectedServiceProperty, &Device::GetSelectedServiceRpcIdentifier); 207923a5025a5e1138b052cbeffa60ea387d479696fBen Chan HelpRegisterConstDerivedRpcIdentifiers(kIPConfigsProperty, 20808afdffc182c7f04a8acdbb63240585069af8040Jason Glasgow &Device::AvailableIPConfigs); 209923a5025a5e1138b052cbeffa60ea387d479696fBen Chan store_.RegisterConstString(kNameProperty, &link_name_); 210923a5025a5e1138b052cbeffa60ea387d479696fBen Chan store_.RegisterConstBool(kPoweredProperty, &enabled_); 211923a5025a5e1138b052cbeffa60ea387d479696fBen Chan HelpRegisterConstDerivedString(kTypeProperty, 212bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal &Device::GetTechnologyString); 21339a7beb18a0c24c9b73c3cc49008ccdca19f9ac2Ben Chan HelpRegisterConstDerivedUint64(kLinkMonitorResponseTimeProperty, 214036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart &Device::GetLinkMonitorResponseTime); 215b5790058b625a16e87a0ef1f9a0631f33f00701cJason Glasgow 216b925cc8f481d21fddd9569fc68861f6e5b6e3eaeChris Masone // TODO(cmasone): Chrome doesn't use this...does anyone? 217923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // store_.RegisterConstBool(kReconnectProperty, &reconnect_); 218b925cc8f481d21fddd9569fc68861f6e5b6e3eaeChris Masone 2194e85161f12699d8eb2116ae24766676ed8227a71Chris Masone // TODO(cmasone): Figure out what shill concept maps to flimflam's "Network". 220923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // known_properties_.push_back(kNetworksProperty); 221b925cc8f481d21fddd9569fc68861f6e5b6e3eaeChris Masone 222227c774828f02cb2c60fc3588263f67e1a768eb9Wade Guthrie // kRoamThresholdProperty: Registered in WiFi 223923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kScanningProperty: Registered in WiFi, Cellular 224923a5025a5e1138b052cbeffa60ea387d479696fBen Chan // kScanIntervalProperty: Registered in WiFi, Cellular 22596e35cf43e6d5aa2378cdae6fea507e5335d12bbSamuel Tan // kWakeOnWiFiFeaturesEnabledProperty: Registered in WiFi 2266ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 2276ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart if (manager_ && manager_->device_info()) { // Unit tests may not have these. 2286ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart manager_->device_info()->GetByteCounts( 2296ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart interface_index_, &receive_byte_offset_, &transmit_byte_offset_); 23039a7beb18a0c24c9b73c3cc49008ccdca19f9ac2Ben Chan HelpRegisterConstDerivedUint64(kReceiveByteCountProperty, 231b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan &Device::GetReceiveByteCountProperty); 23239a7beb18a0c24c9b73c3cc49008ccdca19f9ac2Ben Chan HelpRegisterConstDerivedUint64(kTransmitByteCountProperty, 233b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan &Device::GetTransmitByteCountProperty); 2346ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart } 2356ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 236a0a0efe79e5cf4c13a99f6212e9c98839d7a8ed1Darin Petkov LOG(INFO) << "Device created: " << link_name_ 237a0a0efe79e5cf4c13a99f6212e9c98839d7a8ed1Darin Petkov << " index " << interface_index_; 23875897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart} 23975897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart 24075897df1154ac38b7a4512a687241ad6a197ee40Paul StewartDevice::~Device() { 241a0a0efe79e5cf4c13a99f6212e9c98839d7a8ed1Darin Petkov LOG(INFO) << "Device destructed: " << link_name_ 242a0a0efe79e5cf4c13a99f6212e9c98839d7a8ed1Darin Petkov << " index " << interface_index_; 24375897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart} 24475897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart 2458ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grantvoid Device::Initialize() { 2468ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant SLOG(this, 2) << "Initialized"; 2478ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant DisableArpFiltering(); 2488ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant EnableReversePathFilter(); 2498ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant} 2508ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant 251f1ce5d27adbfcaf9c46e650252b46e02b0d8addaPaul Stewartvoid Device::LinkEvent(unsigned flags, unsigned change) { 252c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << link_name_ 253c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << std::showbase << std::hex 254c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << " flags " << flags << " changed " << change 255c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << std::dec << std::noshowbase; 256f1ce5d27adbfcaf9c46e650252b46e02b0d8addaPaul Stewart} 257f1ce5d27adbfcaf9c46e650252b46e02b0d8addaPaul Stewart 258a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::Scan(ScanType scan_type, Error* error, const string& reason) { 259c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << " [Device] on " << link_name() << " from " 260c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << reason; 26134f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 262be005174bce39ddad185c2eb6808117484d522adPaul Stewart "Device doesn't support scan."); 263f1ce5d27adbfcaf9c46e650252b46e02b0d8addaPaul Stewart} 264f1ce5d27adbfcaf9c46e650252b46e02b0d8addaPaul Stewart 265a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::SetSchedScan(bool enable, Error* error) { 266d51b24406ed78691abe1c8110029a197c351a6e9Peter Qiu SLOG(this, 2) << __func__ << " [Device] on " << link_name(); 267d51b24406ed78691abe1c8110029a197c351a6e9Peter Qiu Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 268d51b24406ed78691abe1c8110029a197c351a6e9Peter Qiu "Device doesn't support scheduled scan."); 269d51b24406ed78691abe1c8110029a197c351a6e9Peter Qiu} 270d51b24406ed78691abe1c8110029a197c351a6e9Peter Qiu 271a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::RegisterOnNetwork(const std::string& /*network_id*/, Error* error, 272a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const ResultCallback& /*callback*/) { 27334f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 274be005174bce39ddad185c2eb6808117484d522adPaul Stewart "Device doesn't support network registration."); 2759ae310f08aadf2d865dc131a629670d5d4dee478Darin Petkov} 2769ae310f08aadf2d865dc131a629670d5d4dee478Darin Petkov 277c64fe5e866c5f97a5e5676b28931bc9f6d81946aDarin Petkovvoid Device::RequirePIN( 278a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& /*pin*/, bool /*require*/, 279a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, const ResultCallback& /*callback*/) { 280c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 28134f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 2829a24553461df7036755060423f90804011612249Eric Shienbrood "Device doesn't support RequirePIN."); 283e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov} 284e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov 285a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::EnterPIN(const string& /*pin*/, 286a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, const ResultCallback& /*callback*/) { 287c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 28834f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 2899a24553461df7036755060423f90804011612249Eric Shienbrood "Device doesn't support EnterPIN."); 290e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov} 291e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov 292a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::UnblockPIN(const string& /*unblock_code*/, 293a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& /*pin*/, 294a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, const ResultCallback& /*callback*/) { 295c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 29634f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 2979a24553461df7036755060423f90804011612249Eric Shienbrood "Device doesn't support UnblockPIN."); 298e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov} 299e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov 300a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::ChangePIN(const string& /*old_pin*/, 301a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& /*new_pin*/, 302a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, const ResultCallback& /*callback*/) { 303c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 30434f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 3059a24553461df7036755060423f90804011612249Eric Shienbrood "Device doesn't support ChangePIN."); 306e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov} 307e42e101ca1e3938ee7c7973a0615154d279c688eDarin Petkov 308a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::Reset(Error* error, const ResultCallback& /*callback*/) { 309c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 31034f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 311ad663e146042b80fcaaaa4902e6ddc156140a356Ben Chan "Device doesn't support Reset."); 312ad663e146042b80fcaaaa4902e6ddc156140a356Ben Chan} 313ad663e146042b80fcaaaa4902e6ddc156140a356Ben Chan 314a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::SetCarrier(const string& /*carrier*/, 315a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, const ResultCallback& /*callback*/) { 316c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 31734f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported, 318c37a9c4ee413984342d53c6151edcb7dc3800d78Darin Petkov "Device doesn't support SetCarrier."); 319c37a9c4ee413984342d53c6151edcb7dc3800d78Darin Petkov} 320c37a9c4ee413984342d53c6151edcb7dc3800d78Darin Petkov 321bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chanbool Device::IsIPv6Allowed() const { 322bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan return true; 323bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan} 324bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan 3252bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartvoid Device::DisableIPv6() { 326c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 3272bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "1"); 3282bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart} 3292bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart 3302bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartvoid Device::EnableIPv6() { 331c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 332bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan if (!IsIPv6Allowed()) { 333bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan LOG(INFO) << "Skip enabling IPv6 on " << link_name_ 334bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan << " as it is not allowed."; 335bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan return; 336bcc6e016d71c396feefa1ace75b5dcfcd116c659Ben Chan } 3372bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "0"); 3382bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart} 3392bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart 3402bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartvoid Device::EnableIPv6Privacy() { 3412bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagUseTempAddr, 3422bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart kIPFlagUseTempAddrUsedAndDefault); 3432bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart} 3442bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart 3452cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartvoid Device::SetLooseRouting(bool is_loose_routing) { 3462cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart if (is_loose_routing == is_loose_routing_) { 3472cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart return; 3482cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } 3492cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart is_loose_routing_ = is_loose_routing; 3502cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart if (is_multi_homed_) { 3512cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart // Nothing to do: loose routing is already enabled, and should remain so. 3522cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart return; 3532cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } 3542cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart if (is_loose_routing) { 3552cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart DisableReversePathFilter(); 3562cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } else { 3572cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart EnableReversePathFilter(); 3582cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } 3592cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart} 3602cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart 361c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewartvoid Device::DisableReversePathFilter() { 362c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart // TODO(pstew): Current kernel doesn't offer reverse-path filtering flag 363ee6b3d7f9d49fa52072a352fbb59f06127b1ba4cPaul Stewart // for IPv6. crbug.com/207193 364c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter, 365c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart kIPFlagReversePathFilterLooseMode); 366c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart} 367c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart 368c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewartvoid Device::EnableReversePathFilter() { 369c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter, 370c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart kIPFlagReversePathFilterEnabled); 371c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart} 372c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart 3732cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartvoid Device::SetIsMultiHomed(bool is_multi_homed) { 3742cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart if (is_multi_homed == is_multi_homed_) { 3752cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart return; 3762cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } 3772cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart LOG(INFO) << "Device " << FriendlyName() << " multi-home state is now " 3782cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart << is_multi_homed; 3792cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart is_multi_homed_ = is_multi_homed; 3802cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart if (is_multi_homed) { 3812cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart EnableArpFiltering(); 3822cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart if (!is_loose_routing_) { 3832cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart DisableReversePathFilter(); 3842cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } 3852cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } else { 3862cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart DisableArpFiltering(); 3872cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart if (!is_loose_routing_) { 3882cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart EnableReversePathFilter(); 3892cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } 3902cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart } 3912cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart} 3922cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart 3932cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartvoid Device::DisableArpFiltering() { 3942cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce, 3952cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart kIPFlagArpAnnounceDefault); 3962cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore, kIPFlagArpIgnoreDefault); 3972cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart} 3982cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart 3992cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewartvoid Device::EnableArpFiltering() { 4002cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce, 4012cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart kIPFlagArpAnnounceBestLocal); 4022cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore, 4032cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart kIPFlagArpIgnoreLocalOnly); 4042cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart} 4052cb3fa7317cfa3248cff72d0b9d64c4f2f630472Paul Stewart 406435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shahbool Device::IsConnected() const { 407435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah if (selected_service_) 408435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah return selected_service_->IsConnected(); 409435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah return false; 410435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah} 411435de2cd55a95836381b53acbce8cbbad98ec04dGaurav Shah 412a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::IsConnectedToService(const ServiceRefPtr& service) const { 413d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart return service == selected_service_ && IsConnected(); 414d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart} 415d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart 416fa11e28ddb81dab93971d5433a5274a1dc5c8283Paul Stewartbool Device::IsConnectedViaTether() const { 417b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu if (!ipconfig_.get()) 418b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu return false; 419b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu 420b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu ByteArray vendor_encapsulated_options = 421b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu ipconfig_->properties().vendor_encapsulated_options; 422b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu size_t android_vendor_encapsulated_options_len = 423b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu strlen(Tethering::kAndroidVendorEncapsulatedOptions); 424b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu 425b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu return (vendor_encapsulated_options.size() == 426b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu android_vendor_encapsulated_options_len) && 427b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu !memcmp(&vendor_encapsulated_options[0], 428b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu Tethering::kAndroidVendorEncapsulatedOptions, 429b2267c9c1cb77564df9d74b5e81689c7e43b8e10Peter Qiu vendor_encapsulated_options.size()); 430fa11e28ddb81dab93971d5433a5274a1dc5c8283Paul Stewart} 431fa11e28ddb81dab93971d5433a5274a1dc5c8283Paul Stewart 432f6b3209a6789171badd65537f72fefb00ca87b8bmukesh agrawalstring Device::GetRpcIdentifier() const { 43327c4aa55b33d3a3836cf70c8f7094bce1c5ead8cChris Masone return adaptor_->GetRpcIdentifier(); 4348fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone} 4358fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone 436515873d543d43b5e7b24c3a48ad0b588370d2216mukesh agrawalstring Device::GetStorageIdentifier() const { 4375dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone string id = GetRpcIdentifier(); 4385dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone ControlInterface::RpcIdToStorageId(&id); 439626719f89881a949d8b5a8fa808beb924496489fChris Masone size_t needle = id.find('_'); 44034af218abe6a99144ffe01332ce36fbad94f2628Chris Masone DLOG_IF(ERROR, needle == string::npos) << "No _ in storage id?!?!"; 441626719f89881a949d8b5a8fa808beb924496489fChris Masone id.replace(id.begin() + needle + 1, id.end(), hardware_address_); 4425dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone return id; 4435dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone} 4445dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone 4456d2c72dddf3dbbc6a614d4fa1a7a3d670756c01fGaurav Shahvector<GeolocationInfo> Device::GetGeolocationObjects() const { 4466d2c72dddf3dbbc6a614d4fa1a7a3d670756c01fGaurav Shah return vector<GeolocationInfo>(); 447227c774828f02cb2c60fc3588263f67e1a768eb9Wade Guthrie} 4486d2c72dddf3dbbc6a614d4fa1a7a3d670756c01fGaurav Shah 449a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartstring Device::GetTechnologyString(Error* /*error*/) { 450b5790058b625a16e87a0ef1f9a0631f33f00701cJason Glasgow return Technology::NameFromIdentifier(technology()); 451b5790058b625a16e87a0ef1f9a0631f33f00701cJason Glasgow} 452b5790058b625a16e87a0ef1f9a0631f33f00701cJason Glasgow 45319e30406a1d3123892007d20438527dc4b2f92c3Chris Masoneconst string& Device::FriendlyName() const { 4547df0c672458bee8f4ff33004103351d59a9f4b50Chris Masone return link_name_; 455afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov} 456afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov 45719e30406a1d3123892007d20438527dc4b2f92c3Chris Masoneconst string& Device::UniqueName() const { 45819e30406a1d3123892007d20438527dc4b2f92c3Chris Masone return unique_id_; 45919e30406a1d3123892007d20438527dc4b2f92c3Chris Masone} 46019e30406a1d3123892007d20438527dc4b2f92c3Chris Masone 461a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::Load(StoreInterface* storage) { 4625dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone const string id = GetStorageIdentifier(); 4635dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone if (!storage->ContainsGroup(id)) { 46434b3f128bc9f4aa5a48af98a62460ebcdf6c38b4Paul Stewart SLOG(this, 2) << "Device is not available in the persistent store: " << id; 4655dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone return false; 4665dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone } 4679a24553461df7036755060423f90804011612249Eric Shienbrood enabled_persistent_ = true; 4689a24553461df7036755060423f90804011612249Eric Shienbrood storage->GetBool(id, kStoragePowered, &enabled_persistent_); 4697fab89734d88724a288e96a9996b15548c5294c7Ben Chan uint64_t rx_byte_count = 0, tx_byte_count = 0; 4706ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 4716ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart manager_->device_info()->GetByteCounts( 4726ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart interface_index_, &rx_byte_count, &tx_byte_count); 4736ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart // If there is a byte-count present in the profile, the return value 4746ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart // of Device::Get*ByteCount() should be the this stored value plus 4756ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart // whatever additional bytes we receive since time-of-load. We 4766ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart // accomplish this by the subtractions below, which can validly 4776ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart // roll over "negative" in the subtractions below and in Get*ByteCount. 4787fab89734d88724a288e96a9996b15548c5294c7Ben Chan uint64_t profile_byte_count; 4796ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart if (storage->GetUint64(id, kStorageReceiveByteCount, &profile_byte_count)) { 4806ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart receive_byte_offset_ = rx_byte_count - profile_byte_count; 4816ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart } 4826ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart if (storage->GetUint64(id, kStorageTransmitByteCount, &profile_byte_count)) { 4836ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart transmit_byte_offset_ = tx_byte_count - profile_byte_count; 4846ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart } 4856ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 4865dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone return true; 4875dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone} 4885dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone 489a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::Save(StoreInterface* storage) { 4905dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone const string id = GetStorageIdentifier(); 4919a24553461df7036755060423f90804011612249Eric Shienbrood storage->SetBool(id, kStoragePowered, enabled_persistent_); 492b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan storage->SetUint64(id, kStorageReceiveByteCount, GetReceiveByteCount()); 493b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan storage->SetUint64(id, kStorageTransmitByteCount, GetTransmitByteCount()); 4945dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone return true; 4955dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone} 4965dec5f4e469a24f1ad508a210d1d23f228bc09a3Chris Masone 497a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnBeforeSuspend(const ResultCallback& callback) { 498fbe8d2b361a51e89fcf1207050729be86a961f5fSamuel Tan // Nothing to be done in the general case, so immediately report success. 499fbe8d2b361a51e89fcf1207050729be86a961f5fSamuel Tan callback.Run(Error(Error::kSuccess)); 500784566d196431b97657760cab5d805a020b2712amukesh agrawal} 501784566d196431b97657760cab5d805a020b2712amukesh agrawal 502784566d196431b97657760cab5d805a020b2712amukesh agrawalvoid Device::OnAfterResume() { 503787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan RenewDHCPLease(); 504bb2231c2d6e39267a3f9e55e74efd9a1ea8e4c98mukesh agrawal if (link_monitor_) { 505c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 3) << "Informing Link Monitor of resume."; 506bb2231c2d6e39267a3f9e55e74efd9a1ea8e4c98mukesh agrawal link_monitor_->OnAfterResume(); 507bb2231c2d6e39267a3f9e55e74efd9a1ea8e4c98mukesh agrawal } 508a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu // Resume from sleep, could be in different location now. 509a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu // Ignore previous link monitor failures. 510a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu if (selected_service_) { 511a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu selected_service_->set_unreliable(false); 512a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu reliable_link_callback_.Cancel(); 513a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu } 514a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu last_link_monitor_failed_time_ = 0; 515784566d196431b97657760cab5d805a020b2712amukesh agrawal} 516784566d196431b97657760cab5d805a020b2712amukesh agrawal 517a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnDarkResume(const ResultCallback& callback) { 51868b73d232e8a03ed55401f36ea1a72a2b69cf912Samuel Tan // Nothing to be done in the general case, so immediately report success. 51968b73d232e8a03ed55401f36ea1a72a2b69cf912Samuel Tan callback.Run(Error(Error::kSuccess)); 52064ad2383c4555a99f4f09fe8f5faa088f99f5b90Prathmesh Prabhu} 52164ad2383c4555a99f4f09fe8f5faa088f99f5b90Prathmesh Prabhu 5222b8e44e4559ef85394e868963d9084b4e4148824Darin Petkovvoid Device::DropConnection() { 523c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 5242b8e44e4559ef85394e868963d9084b4e4148824Darin Petkov DestroyIPConfig(); 525cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan SelectService(nullptr); 5262b8e44e4559ef85394e868963d9084b4e4148824Darin Petkov} 5272b8e44e4559ef85394e868963d9084b4e4148824Darin Petkov 528afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkovvoid Device::DestroyIPConfig() { 5292bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart DisableIPv6(); 530d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu bool ipconfig_changed = false; 531afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov if (ipconfig_.get()) { 532217c61dfafa2ddc800daa227d032d84daf668382Paul Stewart ipconfig_->ReleaseIP(IPConfig::kReleaseReasonDisconnect); 533cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan ipconfig_ = nullptr; 534d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu ipconfig_changed = true; 535afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov } 53625f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu if (ip6config_.get()) { 53725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopIPv6DNSServerTimer(); 538cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan ip6config_ = nullptr; 539d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu ipconfig_changed = true; 540d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu } 541d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu if (dhcpv6_config_.get()) { 542d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu dhcpv6_config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect); 543d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu dhcpv6_config_ = nullptr; 544d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu ipconfig_changed = true; 545d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu } 546d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu // Emit updated IP configs if there are any changes. 547d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu if (ipconfig_changed) { 54825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu UpdateIPConfigsProperty(); 54925f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu } 550e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart DestroyConnection(); 551afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov} 552afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov 553d4f26486b237fae831d4b682481de785fc99c66ePaul Stewartvoid Device::OnIPv6AddressChanged() { 554d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart IPAddress address(IPAddress::kFamilyIPv6); 555d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart if (!manager_->device_info()->GetPrimaryIPv6Address( 556d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart interface_index_, &address)) { 557d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart if (ip6config_) { 558cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan ip6config_ = nullptr; 559d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart UpdateIPConfigsProperty(); 560d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart } 561d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart return; 562d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart } 563d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart 564d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart IPConfig::Properties properties; 565d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart if (!address.IntoString(&properties.address)) { 566d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart LOG(ERROR) << "Unable to convert IPv6 address into a string!"; 567d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart return; 568d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart } 569d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart properties.subnet_prefix = address.prefix(); 570d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart 571d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart if (!ip6config_) { 572d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart ip6config_ = new IPConfig(control_interface_, link_name_); 573d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart } else if (properties.address == ip6config_->properties().address && 574d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart properties.subnet_prefix == 575d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart ip6config_->properties().subnet_prefix) { 576c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << " primary address for " 577c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << link_name_ << " is unchanged."; 578d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart return; 579d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart } 580d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart 581d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart properties.address_family = IPAddress::kFamilyIPv6; 582d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart properties.method = kTypeIPv6; 58325f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu // It is possible for device to receive DNS server notification before IP 58425f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu // address notification, so preserve the saved DNS server if it exist. 58525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu properties.dns_servers = ip6config_->properties().dns_servers; 586c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly PrependDNSServers(IPAddress::kFamilyIPv6, &properties.dns_servers); 587d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart ip6config_->set_properties(properties); 588d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart UpdateIPConfigsProperty(); 589b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu OnIPv6ConfigUpdated(); 590d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart} 591d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart 5929855170e6e2de08db343640c82795c9b4020a166Peter Qiuvoid Device::OnIPv6DnsServerAddressesChanged() { 59325f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu vector<IPAddress> server_addresses; 5943a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko uint32_t lifetime = 0; 59525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 59625f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu // Stop any existing timer. 59725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopIPv6DNSServerTimer(); 59825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 59925f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu if (!manager_->device_info()->GetIPv6DnsServerAddresses( 60025f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu interface_index_, &server_addresses, &lifetime) || lifetime == 0) { 60125f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu IPv6DNSServerExpired(); 60225f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu return; 60325f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu } 60425f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 60525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu vector<string> addresses_str; 606a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart for (const auto& ip : server_addresses) { 60725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu string address_str; 60825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu if (!ip.IntoString(&address_str)) { 60925f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu LOG(ERROR) << "Unable to convert IPv6 address into a string!"; 61025f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu IPv6DNSServerExpired(); 61125f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu return; 61225f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu } 61325f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu addresses_str.push_back(address_str); 61425f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu } 61525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 61625f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu if (!ip6config_) { 61725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu ip6config_ = new IPConfig(control_interface_, link_name_); 61825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu } 61925f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 620815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan if (lifetime != ND_OPT_LIFETIME_INFINITY) { 621815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan // Setup timer to monitor DNS server lifetime if not infinite lifetime. 622815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan StartIPv6DNSServerTimer(lifetime); 623815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan ip6config_->UpdateLeaseExpirationTime(lifetime); 624815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan } else { 625815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan ip6config_->ResetLeaseExpirationTime(); 626815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan } 627815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan 628c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly PrependDNSServers(IPAddress::kFamilyIPv6, &addresses_str); 629c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly 63025f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu // Done if no change in server addresses. 63125f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu if (ip6config_->properties().dns_servers == addresses_str) { 632c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << " IPv6 DNS server list for " 633c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << link_name_ << " is unchanged."; 63425f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu return; 63525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu } 63625f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 63725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu ip6config_->UpdateDNSServers(addresses_str); 63825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu UpdateIPConfigsProperty(); 639b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu OnIPv6ConfigUpdated(); 64025f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu} 64125f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 6423a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenkovoid Device::StartIPv6DNSServerTimer(uint32_t lifetime_seconds) { 6433a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko int64_t delay = static_cast<int64_t>(lifetime_seconds) * 1000; 64425f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu ipv6_dns_server_expired_callback_.Reset( 64525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu base::Bind(&Device::IPv6DNSServerExpired, base::Unretained(this))); 64625f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu dispatcher_->PostDelayedTask(ipv6_dns_server_expired_callback_.callback(), 64725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu delay); 64825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu} 64925f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 65025f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiuvoid Device::StopIPv6DNSServerTimer() { 65125f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu ipv6_dns_server_expired_callback_.Cancel(); 65225f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu} 65325f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 65425f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiuvoid Device::IPv6DNSServerExpired() { 65525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu if (!ip6config_) { 65625f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu return; 65725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu } 65825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu ip6config_->UpdateDNSServers(vector<string>()); 65925f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu UpdateIPConfigsProperty(); 66025f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu} 66125f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu 66225f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiuvoid Device::StopAllActivities() { 66325f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopTrafficMonitor(); 66425f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopPortalDetection(); 665e8303eb267df8904623f16cba64e87df6e8a1563Paul Stewart StopConnectivityTest(); 666490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan StopConnectionDiagnostics(); 66725f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopLinkMonitor(); 66825f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopDNSTest(); 66925f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopIPv6DNSServerTimer(); 6709855170e6e2de08db343640c82795c9b4020a166Peter Qiu} 6719855170e6e2de08db343640c82795c9b4020a166Peter Qiu 672a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::AddWakeOnPacketConnection(const string& ip_endpoint, 673a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error) { 6745412de0a46893b44f60fee4058c5b0d744b74b4dSamuel Tan Error::PopulateAndLog( 67534f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kNotSupported, 676fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan "AddWakeOnPacketConnection not implemented for " + link_name_ + "."); 677fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan return; 678fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan} 679fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan 680a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::RemoveWakeOnPacketConnection(const string& ip_endpoint, 681a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error) { 6825412de0a46893b44f60fee4058c5b0d744b74b4dSamuel Tan Error::PopulateAndLog( 68334f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kNotSupported, 684fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan "RemoveWakeOnPacketConnection not implemented for " + link_name_ + "."); 685fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan return; 686fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan} 687fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan 688a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::RemoveAllWakeOnPacketConnections(Error* error) { 6895412de0a46893b44f60fee4058c5b0d744b74b4dSamuel Tan Error::PopulateAndLog( 69034f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kNotSupported, 691fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan "RemoveAllWakeOnPacketConnections not implemented for " + link_name_ + 692fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan "."); 693fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan return; 694fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan} 695fe734676357045eab81ab62fc3ea7ae1a40ed905Samuel Tan 696787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tanvoid Device::RenewDHCPLease() { 697787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan LOG(INFO) << __func__; 698787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan 699787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan if (ipconfig_) { 700787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan SLOG(this, 3) << "Renewing IPv4 Address"; 701787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan ipconfig_->RenewIP(); 702787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan } 703787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan if (ip6config_) { 704787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan SLOG(this, 3) << "Waiting for new IPv6 configuration"; 705787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan // Invalidate the old IPv6 configuration, will receive notifications 706787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan // from kernel for new IPv6 configuration if there is one. 707787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan StopIPv6DNSServerTimer(); 708787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan ip6config_ = nullptr; 709787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan UpdateIPConfigsProperty(); 710787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan } 711d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu if (dhcpv6_config_) { 712d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu SLOG(this, 3) << "Renewing DHCPv6 lease"; 713d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu dhcpv6_config_->RenewIP(); 714d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu } 715787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan} 716787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan 717ed8e610bb7b8759bcb62b20fbc4ac30a9f242b04Arman Uguraybool Device::ShouldUseArpGateway() const { 718ed8e610bb7b8759bcb62b20fbc4ac30a9f242b04Arman Uguray return false; 719ed8e610bb7b8759bcb62b20fbc4ac30a9f242b04Arman Uguray} 720ed8e610bb7b8759bcb62b20fbc4ac30a9f242b04Arman Uguray 721316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewartbool Device::IsUsingStaticIP() const { 722316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart if (!selected_service_) { 723316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart return false; 724316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart } 725316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart return selected_service_->HasStaticIPAddress(); 726316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart} 727316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart 728d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kellybool Device::IsUsingStaticNameServers() const { 729d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly if (!selected_service_) { 730d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly return false; 731d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly } 732d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly return selected_service_->HasStaticNameServers(); 733d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly} 734d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly 7352bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewartbool Device::AcquireIPConfig() { 736d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart return AcquireIPConfigWithLeaseName(string()); 737d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart} 738d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart 739a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::AcquireIPConfigWithLeaseName(const string& lease_name) { 740afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov DestroyIPConfig(); 7412bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart EnableIPv6(); 742ed8e610bb7b8759bcb62b20fbc4ac30a9f242b04Arman Uguray bool arp_gateway = manager_->GetArpGateway() && ShouldUseArpGateway(); 74315d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein DHCPConfigRefPtr dhcp_config; 74415d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein if (selected_service_) { 74515d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein dhcp_config = 74615d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein dhcp_provider_->CreateIPv4Config( 74715d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein link_name_, 74815d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein lease_name, 74915d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein arp_gateway, 75015d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein *(DhcpProperties::Combine( 75115d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein manager_->dhcp_properties(), 75215d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein selected_service_->dhcp_properties()))); 75315d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein 75415d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein } else { 75515d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein dhcp_config = 75615d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein dhcp_provider_->CreateIPv4Config(link_name_, 75715d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein lease_name, 75815d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein arp_gateway, 75915d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein manager_->dhcp_properties()); 76015d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein } 761782cdcea789d76a7ad7802cf9410b14a2399c0a9Garret Kelly const int minimum_mtu = manager()->GetMinimumMTU(); 762782cdcea789d76a7ad7802cf9410b14a2399c0a9Garret Kelly if (minimum_mtu != IPConfig::kUndefinedMTU) { 763782cdcea789d76a7ad7802cf9410b14a2399c0a9Garret Kelly dhcp_config->set_minimum_mtu(minimum_mtu); 764782cdcea789d76a7ad7802cf9410b14a2399c0a9Garret Kelly } 765782cdcea789d76a7ad7802cf9410b14a2399c0a9Garret Kelly 766782cdcea789d76a7ad7802cf9410b14a2399c0a9Garret Kelly ipconfig_ = dhcp_config; 7679a24553461df7036755060423f90804011612249Eric Shienbrood ipconfig_->RegisterUpdateCallback(Bind(&Device::OnIPConfigUpdated, 7689a24553461df7036755060423f90804011612249Eric Shienbrood weak_ptr_factory_.GetWeakPtr())); 769c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart ipconfig_->RegisterFailureCallback(Bind(&Device::OnIPConfigFailed, 770c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart weak_ptr_factory_.GetWeakPtr())); 7718223653e57318b02c40d018b47ea32f062734abdPaul Stewart ipconfig_->RegisterRefreshCallback(Bind(&Device::OnIPConfigRefreshed, 7728223653e57318b02c40d018b47ea32f062734abdPaul Stewart weak_ptr_factory_.GetWeakPtr())); 7731f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart ipconfig_->RegisterExpireCallback(Bind(&Device::OnIPConfigExpired, 7741f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart weak_ptr_factory_.GetWeakPtr())); 7751062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask, 7761062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart weak_ptr_factory_.GetWeakPtr())); 777d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu if (!ipconfig_->RequestIP()) { 778d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu return false; 779d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu } 780d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu 781d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu#ifndef DISABLE_DHCPV6 782d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu // Only start DHCPv6 configuration instance only if DHCPv6 is enabled 783d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu // for this device. 784d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu if (manager_->IsDHCPv6EnabledForDevice(link_name_)) { 785d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu return AcquireIPv6ConfigWithLeaseName(lease_name); 786d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu } 787d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu#endif // DISABLE_DHCPV6 788d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu return true; 789d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu} 790d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu 791d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu#ifndef DISABLE_DHCPV6 792d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiubool Device::AcquireIPv6ConfigWithLeaseName(const string& lease_name) { 793d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu auto dhcpv6_config = 794d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu dhcp_provider_->CreateIPv6Config(link_name_, lease_name); 795d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu dhcpv6_config_ = dhcpv6_config; 796d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu dhcpv6_config_->RegisterUpdateCallback( 797d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu Bind(&Device::OnDHCPv6ConfigUpdated, weak_ptr_factory_.GetWeakPtr())); 798d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu dhcpv6_config_->RegisterFailureCallback( 799d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu Bind(&Device::OnDHCPv6ConfigFailed, weak_ptr_factory_.GetWeakPtr())); 800d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu dhcpv6_config_->RegisterExpireCallback( 801d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu Bind(&Device::OnDHCPv6ConfigExpired, weak_ptr_factory_.GetWeakPtr())); 802d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu if (!dhcpv6_config_->RequestIP()) { 803d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu return false; 804d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu } 805d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu return true; 806afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov} 807d1d3278b365e866a7381de2a640219b51fe0e27aPeter Qiu#endif // DISABLE_DHCPV6 808afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov 809a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::AssignIPConfig(const IPConfig::Properties& properties) { 810539ab0266ef93a3198f12b8be83a6312d35d6ba0Ben Chan DestroyIPConfig(); 811539ab0266ef93a3198f12b8be83a6312d35d6ba0Ben Chan EnableIPv6(); 812539ab0266ef93a3198f12b8be83a6312d35d6ba0Ben Chan ipconfig_ = new IPConfig(control_interface_, link_name_); 813539ab0266ef93a3198f12b8be83a6312d35d6ba0Ben Chan ipconfig_->set_properties(properties); 814539ab0266ef93a3198f12b8be83a6312d35d6ba0Ben Chan dispatcher_->PostTask(Bind(&Device::OnIPConfigUpdated, 8153c3c36a37a885d0a2e180998587af8390744f757Samuel Tan weak_ptr_factory_.GetWeakPtr(), ipconfig_, true)); 816539ab0266ef93a3198f12b8be83a6312d35d6ba0Ben Chan} 817539ab0266ef93a3198f12b8be83a6312d35d6ba0Ben Chan 818a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::DestroyIPConfigLease(const string& name) { 8190e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk dhcp_provider_->DestroyLease(name); 8200e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk} 8210e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk 822bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawalvoid Device::HelpRegisterConstDerivedString( 823a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& name, 824a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart string(Device::*get)(Error* error)) { 825b5790058b625a16e87a0ef1f9a0631f33f00701cJason Glasgow store_.RegisterDerivedString( 826b5790058b625a16e87a0ef1f9a0631f33f00701cJason Glasgow name, 827cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan StringAccessor(new CustomAccessor<Device, string>(this, get, nullptr))); 8284e85161f12699d8eb2116ae24766676ed8227a71Chris Masone} 8294e85161f12699d8eb2116ae24766676ed8227a71Chris Masone 830674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wileyvoid Device::HelpRegisterConstDerivedRpcIdentifier( 831a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& name, 832a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart RpcIdentifier(Device::*get)(Error* error)) { 833674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley store_.RegisterDerivedRpcIdentifier( 834674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley name, 835674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley RpcIdentifierAccessor( 836674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley new CustomAccessor<Device, RpcIdentifier>(this, get, nullptr))); 837674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley} 838674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley 83908afdffc182c7f04a8acdbb63240585069af8040Jason Glasgowvoid Device::HelpRegisterConstDerivedRpcIdentifiers( 840a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& name, 841a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart RpcIdentifiers(Device::*get)(Error*)) { 84208afdffc182c7f04a8acdbb63240585069af8040Jason Glasgow store_.RegisterDerivedRpcIdentifiers( 84308afdffc182c7f04a8acdbb63240585069af8040Jason Glasgow name, 84408afdffc182c7f04a8acdbb63240585069af8040Jason Glasgow RpcIdentifiersAccessor( 845cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan new CustomAccessor<Device, RpcIdentifiers>(this, get, nullptr))); 84608afdffc182c7f04a8acdbb63240585069af8040Jason Glasgow} 84708afdffc182c7f04a8acdbb63240585069af8040Jason Glasgow 8486ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewartvoid Device::HelpRegisterConstDerivedUint64( 849a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& name, 850a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart uint64_t(Device::*get)(Error*)) { 8516ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart store_.RegisterDerivedUint64( 8526ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart name, 8536ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart Uint64Accessor( 854cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan new CustomAccessor<Device, uint64_t>(this, get, nullptr))); 8556ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart} 8566ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 857f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silbersteinvoid Device::ConnectionTesterCallback() { 858f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein LOG(INFO) << "Device " << FriendlyName() << ": Completed Connectivity Test"; 859f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein return; 860f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein} 861f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein 8621062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewartvoid Device::ConfigureStaticIPTask() { 863c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << " selected_service " << selected_service_.get() 864c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << " ipconfig " << ipconfig_.get(); 8651062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart 8661062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart if (!selected_service_ || !ipconfig_) { 8671062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart return; 8681062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart } 8691062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart 870316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart if (IsUsingStaticIP()) { 871c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << " " << " configuring static IP parameters."; 8721062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart // If the parameters contain an IP address, apply them now and bring 8731062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart // the interface up. When DHCP information arrives, it will supplement 8741062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart // the static information. 8753c3c36a37a885d0a2e180998587af8390744f757Samuel Tan OnIPConfigUpdated(ipconfig_, true); 8761062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart } else { 8778223653e57318b02c40d018b47ea32f062734abdPaul Stewart // Either |ipconfig_| has just been created in AcquireIPConfig() or 8788223653e57318b02c40d018b47ea32f062734abdPaul Stewart // we're being called by OnIPConfigRefreshed(). In either case a 8798223653e57318b02c40d018b47ea32f062734abdPaul Stewart // DHCP client has been started, and will take care of calling 8808223653e57318b02c40d018b47ea32f062734abdPaul Stewart // OnIPConfigUpdated() when it completes. 881c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << " " << " no static IP address."; 8821062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart } 8831062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart} 8841062d9deedace1cf4b3b374c5d40c53047fd6778Paul Stewart 885a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::IPConfigCompleted(const IPConfigRefPtr& ipconfig) { 886b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu return ipconfig && !ipconfig->properties().address.empty() && 887b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu !ipconfig->properties().dns_servers.empty(); 888b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu} 889b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 890b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiuvoid Device::OnIPv6ConfigUpdated() { 891b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // Setup connection using IPv6 configuration only if the IPv6 configuration 892b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // is ready for connection (contained both IP address and DNS servers), and 893b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // there is no existing IPv4 connection. We always prefer IPv4 894b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // configuration over IPv6. 895b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu if (IPConfigCompleted(ip6config_) && 896b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu (!connection_ || connection_->IsIPv6())) { 897b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu SetupConnection(ip6config_); 898b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu } 899b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu} 900b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 901a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::SetupConnection(const IPConfigRefPtr& ipconfig) { 902b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu CreateConnection(); 903b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu connection_->UpdateFromIPConfig(ipconfig); 904b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 905300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu // Report connection type. 906300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu Metrics::NetworkConnectionIPType ip_type = 907300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu connection_->IsIPv6() ? Metrics::kNetworkConnectionIPTypeIPv6 908300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu : Metrics::kNetworkConnectionIPTypeIPv4; 909300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu metrics_->NotifyNetworkConnectionIPType(technology_, ip_type); 910300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu 911300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu // Report if device have IPv6 connectivity 912300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu bool ipv6_connectivity = IPConfigCompleted(ip6config_); 913300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu metrics_->NotifyIPv6ConnectivityStatus(technology_, ipv6_connectivity); 914300769ea57941a26bccfa7fe1e1cc4d9ad96b23ePeter Qiu 915b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // SetConnection must occur after the UpdateFromIPConfig so the 916b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // service can use the values derived from the connection. 917b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu if (selected_service_) { 918b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu selected_service_->SetConnection(connection_); 919b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 920b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // The service state change needs to happen last, so that at the 921b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // time we report the state change to the manager, the service 922b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // has its connection. 923b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu SetServiceState(Service::kStateConnected); 924b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu OnConnected(); 925b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu portal_attempts_to_online_ = 0; 926b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 927b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // Subtle: Start portal detection after transitioning the service 928b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // to the Connected state because this call may immediately transition 929b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // to the Online state. 930b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu StartPortalDetection(); 931b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu } 932b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 933208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart SetHostname(ipconfig->properties().accepted_hostname); 934208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart StartLinkMonitor(); 935208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart StartTrafficMonitor(); 936208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart} 937208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart 938a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::SetHostname(const std::string& hostname) { 939208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart if (hostname.empty() || !manager()->ShouldAcceptHostnameFrom(link_name_)) { 940208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart return false; 94108add488849f90600a5657a6f54f4dbc34701b8fMatthew Wein } 94208add488849f90600a5657a6f54f4dbc34701b8fMatthew Wein 943208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart string fixed_hostname = hostname; 944208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart if (fixed_hostname.length() > MAXHOSTNAMELEN) { 945208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart auto truncate_length = fixed_hostname.find('.'); 946208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart if (truncate_length == string::npos || truncate_length > MAXHOSTNAMELEN) { 947208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart truncate_length = MAXHOSTNAMELEN; 948208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart } 949208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart fixed_hostname.resize(truncate_length); 950208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart } 95108add488849f90600a5657a6f54f4dbc34701b8fMatthew Wein 952208a97ed32c62bc11b0a20eaf01833482e8c0fbcPaul Stewart return manager_->device_info()->SetHostname(fixed_hostname); 953b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu} 954b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 955a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::PrependDNSServersIntoIPConfig(const IPConfigRefPtr& ipconfig) { 956a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const auto& properties = ipconfig->properties(); 957c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly 958c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly vector<string> servers(properties.dns_servers.begin(), 959c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly properties.dns_servers.end()); 960c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly PrependDNSServers(properties.address_family, &servers); 961c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly if (servers == properties.dns_servers) { 962c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly // If the server list is the same after being augmented then there's no need 963c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly // to update the config's list of servers. 964c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly return; 965c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly } 966c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly 967c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly ipconfig->UpdateDNSServers(servers); 968c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly} 969c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly 970c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kellyvoid Device::PrependDNSServers(const IPAddress::Family family, 971a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart vector<string>* servers) { 9721ce231c71932200e4d02c71567f8e93788120781Paul Stewart vector<string>output_servers = 9731ce231c71932200e4d02c71567f8e93788120781Paul Stewart manager_->FilterPrependDNSServersByFamily(family); 974c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly 9751ce231c71932200e4d02c71567f8e93788120781Paul Stewart set<string> unique(output_servers.begin(), output_servers.end()); 976a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart for (const auto& server : *servers) { 977c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly if (unique.find(server) == unique.end()) { 9781ce231c71932200e4d02c71567f8e93788120781Paul Stewart output_servers.push_back(server); 979c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly unique.insert(server); 980c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly } 981c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly } 9821ce231c71932200e4d02c71567f8e93788120781Paul Stewart servers->swap(output_servers); 983c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly} 984c5f89d131e5b03f448b73fd02d16cab30e438521Garret Kelly 985490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tanvoid Device::ConnectionDiagnosticsCallback( 986490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan const std::string& connection_issue, 987490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan const std::vector<ConnectionDiagnostics::Event>& diagnostic_events) { 988490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan SLOG(this, 2) << "Device " << FriendlyName() 989490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan << ": Completed Connection diagnostics"; 990490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan // TODO(samueltan): add connection diagnostics metrics. 991490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan} 992490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan 993a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnIPConfigUpdated(const IPConfigRefPtr& ipconfig, 9943c3c36a37a885d0a2e180998587af8390744f757Samuel Tan bool /*new_lease_acquired*/) { 995c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 996c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart if (selected_service_) { 997c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart ipconfig->ApplyStaticIPParameters( 998c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart selected_service_->mutable_static_ip_parameters()); 999316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart if (IsUsingStaticIP()) { 1000c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // If we are using a statically configured IP address instead 1001c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // of a leased IP address, release any acquired lease so it may 1002c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // be used by others. This allows us to merge other non-leased 1003c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // parameters (like DNS) when they're available from a DHCP server 1004c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // and not overridden by static parameters, but at the same time 1005c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // we avoid taking up a dynamic IP address the DHCP server could 1006c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // assign to someone else who might actually use it. 1007c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart ipconfig->ReleaseIP(IPConfig::kReleaseReasonStaticIP); 1008cc0fded2a80c2c6c7fb46cbd7eee578e7a78c50amukesh agrawal } 1009c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart } 1010d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly if (!IsUsingStaticNameServers()) { 1011d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly PrependDNSServersIntoIPConfig(ipconfig); 1012d01b5cc35185e022b66e08832e12fe7f59b5aa24Garret Kelly } 1013b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu SetupConnection(ipconfig); 1014d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart UpdateIPConfigsProperty(); 1015c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart} 1016cc0fded2a80c2c6c7fb46cbd7eee578e7a78c50amukesh agrawal 1017a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnIPConfigFailed(const IPConfigRefPtr& ipconfig) { 1018c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 1019c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // TODO(pstew): This logic gets yet more complex when multiple 1020c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // IPConfig types are run in parallel (e.g. DHCP and DHCP6) 1021c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart if (selected_service_) { 1022316acef85ecfc128bf06cc2d2699f21880aa5a7ePaul Stewart if (IsUsingStaticIP()) { 1023c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // Consider three cases: 1024c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // 1025c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // 1. We're here because DHCP failed while starting up. There 1026c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // are two subcases: 1027c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // a. DHCP has failed, and Static IP config has _not yet_ 1028c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // completed. It's fine to do nothing, because we'll 1029c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // apply the static config shortly. 1030c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // b. DHCP has failed, and Static IP config has _already_ 1031c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // completed. It's fine to do nothing, because we can 1032c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // continue to use the static config that's already 1033c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // been applied. 1034c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // 1035c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // 2. We're here because a previously valid DHCP configuration 1036c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // is no longer valid. There's still a static IP config, 1037c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // because the condition in the if clause evaluated to true. 1038c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // Furthermore, the static config includes an IP address for 1039c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // us to use. 1040c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // 1041c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // The current configuration may include some DHCP 1042c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // parameters, overriden by any static parameters 1043c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // provided. We continue to use this configuration, because 1044c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // the only configuration element that is leased to us (IP 1045c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart // address) will be overriden by a static parameter. 1046c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart return; 1047c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart } 1048c39f1134c8f1ca15324a7eb2ba9ccc243bc82531Paul Stewart } 1049c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart 1050c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart ipconfig->ResetProperties(); 1051d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart UpdateIPConfigsProperty(); 1052b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 10538f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu // Fallback to IPv6 if possible. 10548f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu if (IPConfigCompleted(ip6config_)) { 10558f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu if (!connection_ || !connection_->IsIPv6()) { 10568f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu // Setup IPv6 connection. 10578f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu SetupConnection(ip6config_); 10588f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu } else { 10598f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu // Ignore IPv4 config failure, since IPv6 is up. 10608f254a17249abf206ad08c5bb17e4499f08ab5d2Peter Qiu } 1061b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu return; 1062b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu } 1063b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 1064b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu OnIPConfigFailure(); 1065c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart DestroyConnection(); 10668fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone} 10678fe2c7eea92541b5282929361a19ad519e0608a9Chris Masone 1068a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnIPConfigRefreshed(const IPConfigRefPtr& ipconfig) { 10698223653e57318b02c40d018b47ea32f062734abdPaul Stewart // Clear the previously applied static IP parameters. 10708223653e57318b02c40d018b47ea32f062734abdPaul Stewart ipconfig->RestoreSavedIPParameters( 10718223653e57318b02c40d018b47ea32f062734abdPaul Stewart selected_service_->mutable_static_ip_parameters()); 10728223653e57318b02c40d018b47ea32f062734abdPaul Stewart 10738223653e57318b02c40d018b47ea32f062734abdPaul Stewart dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask, 10748223653e57318b02c40d018b47ea32f062734abdPaul Stewart weak_ptr_factory_.GetWeakPtr())); 10758223653e57318b02c40d018b47ea32f062734abdPaul Stewart} 10768223653e57318b02c40d018b47ea32f062734abdPaul Stewart 1077f6f9648d5b2beb387ada690b8a20482c694433f1Paul Stewartvoid Device::OnIPConfigFailure() { 1078f6f9648d5b2beb387ada690b8a20482c694433f1Paul Stewart if (selected_service_) { 1079f6f9648d5b2beb387ada690b8a20482c694433f1Paul Stewart Error error; 10800d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan selected_service_->DisconnectWithFailure(Service::kFailureDHCP, 10810d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan &error, 10820d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan __func__); 1083f6f9648d5b2beb387ada690b8a20482c694433f1Paul Stewart } 1084f6f9648d5b2beb387ada690b8a20482c694433f1Paul Stewart} 1085f6f9648d5b2beb387ada690b8a20482c694433f1Paul Stewart 1086a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnIPConfigExpired(const IPConfigRefPtr& ipconfig) { 10871f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart metrics()->SendToUMA( 10881f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart metrics()->GetFullMetricName( 1089132e96ff1c3dade1b08cdae82b0f4ed27a9a45d0mukesh agrawal Metrics::kMetricExpiredLeaseLengthSecondsSuffix, technology()), 10901f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart ipconfig->properties().lease_duration_seconds, 10911f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart Metrics::kMetricExpiredLeaseLengthSecondsMin, 10921f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart Metrics::kMetricExpiredLeaseLengthSecondsMax, 10931f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets); 10941f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart} 10951f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart 1096a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnDHCPv6ConfigUpdated(const IPConfigRefPtr& ipconfig, 1097d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu bool /*new_lease_acquired*/) { 1098d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu // Emit configuration update. 1099d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu UpdateIPConfigsProperty(); 1100d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu} 1101d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu 1102a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnDHCPv6ConfigFailed(const IPConfigRefPtr& ipconfig) { 1103d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu // Reset configuration data. 1104d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu ipconfig->ResetProperties(); 1105d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu UpdateIPConfigsProperty(); 1106d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu} 1107d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu 1108a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnDHCPv6ConfigExpired(const IPConfigRefPtr& ipconfig) { 1109d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu // Reset configuration data. 1110d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu ipconfig->ResetProperties(); 1111d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu UpdateIPConfigsProperty(); 1112d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu} 1113d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu 1114a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiuvoid Device::OnConnected() { 1115a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu if (selected_service_->unreliable()) { 1116a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu // Post a delayed task to reset link back to reliable if no link 1117a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu // failure is detected in the next 5 minutes. 1118a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu reliable_link_callback_.Reset( 1119a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu base::Bind(&Device::OnReliableLink, base::Unretained(this))); 1120a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu dispatcher_->PostDelayedTask( 1121a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu reliable_link_callback_.callback(), 1122a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu kLinkUnreliableThresholdSeconds * 1000); 1123a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu } 1124a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu} 11255519e9e7021ba05af8c38291710746fac3528f21Christopher Wiley 11268596f9f1341d3698543e1010ac1710cbe91e35d5Paul Stewartvoid Device::OnConnectionUpdated() { 11278596f9f1341d3698543e1010ac1710cbe91e35d5Paul Stewart if (selected_service_) { 11288596f9f1341d3698543e1010ac1710cbe91e35d5Paul Stewart manager_->UpdateService(selected_service_); 11298596f9f1341d3698543e1010ac1710cbe91e35d5Paul Stewart } 11308596f9f1341d3698543e1010ac1710cbe91e35d5Paul Stewart} 11318596f9f1341d3698543e1010ac1710cbe91e35d5Paul Stewart 1132e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewartvoid Device::CreateConnection() { 1133c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 1134e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart if (!connection_.get()) { 113523ac6b72d44c446bca88175883ba26b39c5ed817mukesh agrawal connection_ = new Connection(interface_index_, 113623ac6b72d44c446bca88175883ba26b39c5ed817mukesh agrawal link_name_, 113723ac6b72d44c446bca88175883ba26b39c5ed817mukesh agrawal technology_, 1138608ec29525f553d51f0a92e84176e3d4b45930a9Peter Qiu manager_->device_info(), 1139608ec29525f553d51f0a92e84176e3d4b45930a9Peter Qiu control_interface_); 1140e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart } 1141e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart} 1142e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart 1143e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewartvoid Device::DestroyConnection() { 1144c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << " on " << link_name_; 114525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopAllActivities(); 1146be5f5b341ba4b85d45ffb6c0430ef5ab84c7b961Paul Stewart if (selected_service_.get()) { 1147c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 3) << "Clearing connection of service " 1148c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << selected_service_->unique_name(); 1149cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan selected_service_->SetConnection(nullptr); 1150be5f5b341ba4b85d45ffb6c0430ef5ab84c7b961Paul Stewart } 1151cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan connection_ = nullptr; 1152e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart} 1153e613202d36e3bfb06a40eea1888694413210ef7ePaul Stewart 1154a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::SelectService(const ServiceRefPtr& service) { 1155c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << ": service " 1156c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << (service ? service->unique_name() : "*reset*") 1157c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << " on " << link_name_; 11588a3188dbc04245c17a4729d16a632547ce4bf585mukesh agrawal 11598a3188dbc04245c17a4729d16a632547ce4bf585mukesh agrawal if (selected_service_.get() == service.get()) { 11608a3188dbc04245c17a4729d16a632547ce4bf585mukesh agrawal // No change to |selected_service_|. Return early to avoid 11618a3188dbc04245c17a4729d16a632547ce4bf585mukesh agrawal // changing its state. 11628a3188dbc04245c17a4729d16a632547ce4bf585mukesh agrawal return; 11638a3188dbc04245c17a4729d16a632547ce4bf585mukesh agrawal } 11648a3188dbc04245c17a4729d16a632547ce4bf585mukesh agrawal 1165be5f5b341ba4b85d45ffb6c0430ef5ab84c7b961Paul Stewart if (selected_service_.get()) { 1166be5f5b341ba4b85d45ffb6c0430ef5ab84c7b961Paul Stewart if (selected_service_->state() != Service::kStateFailure) { 1167be5f5b341ba4b85d45ffb6c0430ef5ab84c7b961Paul Stewart selected_service_->SetState(Service::kStateIdle); 1168be5f5b341ba4b85d45ffb6c0430ef5ab84c7b961Paul Stewart } 116920b0a09afa73250a276863c51b7c80ebee332369Paul Stewart // Just in case the Device subclass has not already done so, make 117020b0a09afa73250a276863c51b7c80ebee332369Paul Stewart // sure the previously selected service has its connection removed. 1171cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan selected_service_->SetConnection(nullptr); 1172a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu // Reset link status for the previously selected service. 1173a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu selected_service_->set_unreliable(false); 1174a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu reliable_link_callback_.Cancel(); 117525f1be6cc1919da0af4564127db3a98ab5555c10Peter Qiu StopAllActivities(); 117603dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart } 1177a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu 1178a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu // Newly selected service (network), previous failures doesn't apply 1179a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu // anymore. 1180a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu last_link_monitor_failed_time_ = 0; 1181a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu 118203dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart selected_service_ = service; 1183674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley adaptor_->EmitRpcIdentifierChanged( 1184674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley kSelectedServiceProperty, GetSelectedServiceRpcIdentifier(nullptr)); 118503dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart} 118603dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart 118703dba0bccc3a39cded5083212e56713a6d349e01Paul Stewartvoid Device::SetServiceState(Service::ConnectState state) { 118803dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart if (selected_service_.get()) { 118903dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart selected_service_->SetState(state); 119003dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart } 119103dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart} 119203dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart 119303dba0bccc3a39cded5083212e56713a6d349e01Paul Stewartvoid Device::SetServiceFailure(Service::ConnectFailure failure_state) { 119403dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart if (selected_service_.get()) { 119503dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart selected_service_->SetFailure(failure_state); 119603dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart } 119703dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart} 119803dba0bccc3a39cded5083212e56713a6d349e01Paul Stewart 1199cc95c5dcc848552c87d1368fbb655a93666b6659Eric Shienbroodvoid Device::SetServiceFailureSilent(Service::ConnectFailure failure_state) { 1200cc95c5dcc848552c87d1368fbb655a93666b6659Eric Shienbrood if (selected_service_.get()) { 1201cc95c5dcc848552c87d1368fbb655a93666b6659Eric Shienbrood selected_service_->SetFailureSilent(failure_state); 1202cc95c5dcc848552c87d1368fbb655a93666b6659Eric Shienbrood } 1203cc95c5dcc848552c87d1368fbb655a93666b6659Eric Shienbrood} 1204cc95c5dcc848552c87d1368fbb655a93666b6659Eric Shienbrood 1205a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::SetIPFlag(IPAddress::Family family, const string& flag, 1206a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& value) { 12072bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart string ip_version; 12082bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart if (family == IPAddress::kFamilyIPv4) { 12092bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart ip_version = kIPFlagVersion4; 12102bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart } else if (family == IPAddress::kFamilyIPv6) { 12112bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart ip_version = kIPFlagVersion6; 12122bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart } else { 12132bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart NOTIMPLEMENTED(); 12142bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart } 12152bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart FilePath flag_file(StringPrintf(kIPFlagTemplate, ip_version.c_str(), 12162bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart link_name_.c_str(), flag.c_str())); 1217c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Writing " << value << " to flag file " 1218c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << flag_file.value(); 12196fbf64f493a9aae7d743888039c61a57386203dbBen Chan if (base::WriteFile(flag_file, value.c_str(), value.length()) != 1) { 122038fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart string message = StringPrintf("IP flag write failed: %s to %s", 122138fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart value.c_str(), flag_file.value().c_str()); 122238fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart if (!base::PathExists(flag_file) && 122338fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart ContainsValue(written_flags_, flag_file.value())) { 122438fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart SLOG(this, 2) << message << " (device is no longer present?)"; 122538fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart } else { 122638fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart LOG(ERROR) << message; 122738fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart } 12282bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart return false; 122938fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart } else { 123038fcf16b182fae0e3dd88403ac5362c9f16f1297Paul Stewart written_flags_.insert(flag_file.value()); 12312bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart } 12322bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart return true; 12332bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart} 12342bf1d356e76564adb64b8bc8bc1049e74bf8e4d8Paul Stewart 1235a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartstring Device::PerformTDLSOperation(const string& /* operation */, 1236a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& /* peer */, 1237a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* /* error */) { 1238c6fbad96f565fda1caae9cd80569314685c99b90Paul Stewart return ""; 1239c6fbad96f565fda1caae9cd80569314685c99b90Paul Stewart} 1240c6fbad96f565fda1caae9cd80569314685c99b90Paul Stewart 12416ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewartvoid Device::ResetByteCounters() { 12426ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart manager_->device_info()->GetByteCounts( 12436ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart interface_index_, &receive_byte_offset_, &transmit_byte_offset_); 12446ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart manager_->UpdateDevice(this); 12456ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart} 12466ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 1247d215af6f72d012f43057c34f17a12506baa21e66Paul Stewartbool Device::RestartPortalDetection() { 1248d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart StopPortalDetection(); 1249d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart return StartPortalDetection(); 1250d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart} 1251d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart 1252c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewartbool Device::RequestPortalDetection() { 1253c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart if (!selected_service_) { 1254c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << FriendlyName() 1255c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": No selected service, so no need for portal check."; 1256c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart return false; 1257c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } 1258c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart 1259c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart if (!connection_.get()) { 1260c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << FriendlyName() 1261c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": No connection, so no need for portal check."; 1262c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart return false; 1263c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } 1264c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart 1265c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart if (selected_service_->state() != Service::kStatePortal) { 1266c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << FriendlyName() 1267c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Service is not in portal state. " 1268c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << "No need to start check."; 1269c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart return false; 1270c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } 1271c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart 1272c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart if (!connection_->is_default()) { 1273c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << FriendlyName() 1274c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Service is not the default connection. " 1275c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << "Don't start check."; 1276c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart return false; 1277c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } 1278c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart 1279c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart if (portal_detector_.get() && portal_detector_->IsInProgress()) { 1280c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << FriendlyName() 1281c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Portal detection is already running."; 1282c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart return true; 1283c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } 1284c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart 1285c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart return StartPortalDetection(); 1286c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart} 1287c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart 128820088d860631a67c151a12783fbbee63c708792fPaul Stewartbool Device::StartPortalDetection() { 1289457728b3eeb2d67c980e0d20675f0a0f750903e1Darin Petkov DCHECK(selected_service_); 1290d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart if (selected_service_->IsPortalDetectionDisabled()) { 1291c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Service " << selected_service_->unique_name() 1292c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Portal detection is disabled; " 1293c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << "marking service online."; 1294d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart SetServiceConnectedState(Service::kStateOnline); 1295d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart return false; 1296d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart } 1297d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart 1298d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart if (selected_service_->IsPortalDetectionAuto() && 1299d215af6f72d012f43057c34f17a12506baa21e66Paul Stewart !manager_->IsPortalDetectionEnabled(technology())) { 130020088d860631a67c151a12783fbbee63c708792fPaul Stewart // If portal detection is disabled for this technology, immediately set 130120088d860631a67c151a12783fbbee63c708792fPaul Stewart // the service state to "Online". 1302c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1303c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Portal detection is disabled; " 1304c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << "marking service online."; 130520088d860631a67c151a12783fbbee63c708792fPaul Stewart SetServiceConnectedState(Service::kStateOnline); 130620088d860631a67c151a12783fbbee63c708792fPaul Stewart return false; 130720088d860631a67c151a12783fbbee63c708792fPaul Stewart } 130820088d860631a67c151a12783fbbee63c708792fPaul Stewart 130920088d860631a67c151a12783fbbee63c708792fPaul Stewart if (selected_service_->HasProxyConfig()) { 131020088d860631a67c151a12783fbbee63c708792fPaul Stewart // Services with HTTP proxy configurations should not be checked by the 131120088d860631a67c151a12783fbbee63c708792fPaul Stewart // connection manager, since we don't have the ability to evaluate 131220088d860631a67c151a12783fbbee63c708792fPaul Stewart // arbitrary proxy configs and their possible credentials. 1313c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1314c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Service has proxy config; marking it online."; 131520088d860631a67c151a12783fbbee63c708792fPaul Stewart SetServiceConnectedState(Service::kStateOnline); 131620088d860631a67c151a12783fbbee63c708792fPaul Stewart return false; 131720088d860631a67c151a12783fbbee63c708792fPaul Stewart } 131820088d860631a67c151a12783fbbee63c708792fPaul Stewart 131920088d860631a67c151a12783fbbee63c708792fPaul Stewart portal_detector_.reset(new PortalDetector(connection_, 132020088d860631a67c151a12783fbbee63c708792fPaul Stewart dispatcher_, 13213e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood portal_detector_callback_)); 132220088d860631a67c151a12783fbbee63c708792fPaul Stewart if (!portal_detector_->Start(manager_->GetPortalCheckURL())) { 132320088d860631a67c151a12783fbbee63c708792fPaul Stewart LOG(ERROR) << "Device " << FriendlyName() 132420088d860631a67c151a12783fbbee63c708792fPaul Stewart << ": Portal detection failed to start: likely bad URL: " 132520088d860631a67c151a12783fbbee63c708792fPaul Stewart << manager_->GetPortalCheckURL(); 132620088d860631a67c151a12783fbbee63c708792fPaul Stewart SetServiceConnectedState(Service::kStateOnline); 132720088d860631a67c151a12783fbbee63c708792fPaul Stewart return false; 132820088d860631a67c151a12783fbbee63c708792fPaul Stewart } 132920088d860631a67c151a12783fbbee63c708792fPaul Stewart 1330c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1331c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Portal detection has started."; 133220088d860631a67c151a12783fbbee63c708792fPaul Stewart return true; 133320088d860631a67c151a12783fbbee63c708792fPaul Stewart} 133420088d860631a67c151a12783fbbee63c708792fPaul Stewart 133520088d860631a67c151a12783fbbee63c708792fPaul Stewartvoid Device::StopPortalDetection() { 1336c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1337c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Portal detection stopping."; 133820088d860631a67c151a12783fbbee63c708792fPaul Stewart portal_detector_.reset(); 133920088d860631a67c151a12783fbbee63c708792fPaul Stewart} 134020088d860631a67c151a12783fbbee63c708792fPaul Stewart 1341490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tanbool Device::StartConnectionDiagnosticsAfterPortalDetection( 1342490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan const PortalDetector::Result& result) { 1343490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan connection_diagnostics_.reset(new ConnectionDiagnostics( 1344d1c7166402c414a851da721c2a3aaec713c25badSamuel Tan connection_, dispatcher_, metrics_, manager_->device_info(), 1345490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan connection_diagnostics_callback_)); 1346490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan if (!connection_diagnostics_->StartAfterPortalDetection( 1347490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan manager_->GetPortalCheckURL(), result)) { 1348490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan LOG(ERROR) << "Device " << FriendlyName() 1349490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan << ": Connection diagnostics failed to start: likely bad URL: " 1350490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan << manager_->GetPortalCheckURL(); 1351490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan connection_diagnostics_.reset(); 1352490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan return false; 1353490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan } 1354490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan 1355490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan SLOG(this, 2) << "Device " << FriendlyName() 1356490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan << ": Connection diagnostics has started."; 1357490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan return true; 1358490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan} 1359490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan 1360490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tanvoid Device::StopConnectionDiagnostics() { 1361490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan SLOG(this, 2) << "Device " << FriendlyName() 1362490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan << ": Connection diagnostics stopping."; 1363490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan connection_diagnostics_.reset(); 1364490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan} 1365490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan 13666862b38f4691f6f927a5efffa3f587846ff96c72Rebecca Silbersteinbool Device::StartConnectivityTest() { 1367f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein LOG(INFO) << "Device " << FriendlyName() << " starting connectivity test."; 13686862b38f4691f6f927a5efffa3f587846ff96c72Rebecca Silberstein 1369f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein connection_tester_.reset(new ConnectionTester(connection_, 1370f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein dispatcher_, 1371f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein connection_tester_callback_)); 1372f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein connection_tester_->Start(); 1373f4365a68767063e87dc7f68ff24b6c3955e88c5dRebecca Silberstein return true; 13746862b38f4691f6f927a5efffa3f587846ff96c72Rebecca Silberstein} 13756862b38f4691f6f927a5efffa3f587846ff96c72Rebecca Silberstein 1376e8303eb267df8904623f16cba64e87df6e8a1563Paul Stewartvoid Device::StopConnectivityTest() { 1377c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1378c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Connectivity test stopping."; 1379e8303eb267df8904623f16cba64e87df6e8a1563Paul Stewart connection_tester_.reset(); 1380e8303eb267df8904623f16cba64e87df6e8a1563Paul Stewart} 1381e8303eb267df8904623f16cba64e87df6e8a1563Paul Stewart 1382a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::set_link_monitor(LinkMonitor* link_monitor) { 1383036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart link_monitor_.reset(link_monitor); 1384036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart} 1385036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart 1386036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewartbool Device::StartLinkMonitor() { 1387036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart if (!manager_->IsTechnologyLinkMonitorEnabled(technology())) { 1388c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1389c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Link Monitoring is disabled."; 1390036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart return false; 1391036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart } 1392036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart 1393d49760e19d137f43df29e00265259d395b07994cPeter Qiu if (selected_service_ && selected_service_->link_monitor_disabled()) { 1394c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1395c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Link Monitoring is disabled for the selected service"; 1396d49760e19d137f43df29e00265259d395b07994cPeter Qiu return false; 1397d49760e19d137f43df29e00265259d395b07994cPeter Qiu } 1398d49760e19d137f43df29e00265259d395b07994cPeter Qiu 1399036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart if (!link_monitor()) { 1400036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart set_link_monitor( 1401036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart new LinkMonitor( 1402036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart connection_, dispatcher_, metrics(), manager_->device_info(), 1403b5d124f4e789e7dd6afef6cc798b517650da5affPeter Qiu Bind(&Device::OnLinkMonitorFailure, weak_ptr_factory_.GetWeakPtr()), 1404b5d124f4e789e7dd6afef6cc798b517650da5affPeter Qiu Bind(&Device::OnLinkMonitorGatewayChange, 1405b5d124f4e789e7dd6afef6cc798b517650da5affPeter Qiu weak_ptr_factory_.GetWeakPtr()))); 1406036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart } 1407036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart 1408c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1409c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Link Monitor starting."; 1410036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart return link_monitor_->Start(); 1411036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart} 1412036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart 1413036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewartvoid Device::StopLinkMonitor() { 1414c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1415c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Link Monitor stopping."; 1416036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart link_monitor_.reset(); 1417036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart} 1418036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart 14198e1ad1684e2dd34619315c14f4b5312b93de0a83Peter Qiuvoid Device::OnUnreliableLink() { 1420a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu SLOG(this, 2) << "Device " << FriendlyName() 1421a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu << ": Link is unreliable."; 1422a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu selected_service_->set_unreliable(true); 1423a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu reliable_link_callback_.Cancel(); 14248e1ad1684e2dd34619315c14f4b5312b93de0a83Peter Qiu metrics_->NotifyUnreliableLinkSignalStrength( 14258e1ad1684e2dd34619315c14f4b5312b93de0a83Peter Qiu technology_, selected_service_->strength()); 14268e1ad1684e2dd34619315c14f4b5312b93de0a83Peter Qiu} 14278e1ad1684e2dd34619315c14f4b5312b93de0a83Peter Qiu 1428a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiuvoid Device::OnReliableLink() { 1429a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu SLOG(this, 2) << "Device " << FriendlyName() 1430a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu << ": Link is reliable."; 1431a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu selected_service_->set_unreliable(false); 1432a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu // TODO(zqiu): report signal strength to UMA. 1433a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu} 1434a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu 1435036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewartvoid Device::OnLinkMonitorFailure() { 1436c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1437c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Link Monitor indicates failure."; 1438a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu if (!selected_service_) { 1439a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu return; 1440a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu } 1441a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu 1442a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu time_t now; 1443a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu time_->GetSecondsBoottime(&now); 1444a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu 1445a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu if (last_link_monitor_failed_time_ != 0 && 1446a388fdb2e74717ba2440a605f208647dd7cd3e06Peter Qiu now - last_link_monitor_failed_time_ < kLinkUnreliableThresholdSeconds) { 14478e1ad1684e2dd34619315c14f4b5312b93de0a83Peter Qiu OnUnreliableLink(); 1448a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu } 1449a0572036bd4374282fb26e861e7a242fe55a54a3Peter Qiu last_link_monitor_failed_time_ = now; 1450036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart} 1451036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart 14529d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiuvoid Device::OnLinkMonitorGatewayChange() { 14539d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu string gateway_mac = link_monitor()->gateway_mac_address().HexEncode(); 14549d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu int connection_id = manager_->CalcConnectionId( 14559d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu ipconfig_->properties().gateway, gateway_mac); 14569d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu 14579d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu CHECK(selected_service_); 14589d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu selected_service_->set_connection_id(connection_id); 14599d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu 14609d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu manager_->ReportServicesOnSameNetwork(connection_id); 14619d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu} 14629d58193108f55edf0f06cd54f44464da633cb8aaPeter Qiu 14636f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiubool Device::StartDNSTest( 1464a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const vector<string>& dns_servers, 14656f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu bool retry_until_success, 1466a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const Callback<void(const DNSServerTester::Status)>& callback) { 14676f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu if (dns_server_tester_.get()) { 14686f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu LOG(ERROR) << FriendlyName() << ": " 14696f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu << "Failed to start DNS Test: current test still running"; 14706f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu return false; 1471b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu } 1472b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu 14736f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu dns_server_tester_.reset(new DNSServerTester(connection_, 14746f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu dispatcher_, 14756f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu dns_servers, 14766f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu retry_until_success, 14776f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu callback)); 14786f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu dns_server_tester_->Start(); 14796f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu return true; 14806f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu} 14816f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu 14826f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiuvoid Device::StopDNSTest() { 14836f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu dns_server_tester_.reset(); 1484b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu} 1485b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu 1486d670d03b90f4372bb085c7d2a128c6025e998d78Peter Qiuvoid Device::FallbackDNSResultCallback(const DNSServerTester::Status status) { 14876f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu StopDNSTest(); 1488f18e7717c642dcfd6b4dbe1f01f50e2d9671f5cePeter Qiu int result = Metrics::kFallbackDNSTestResultFailure; 1489d670d03b90f4372bb085c7d2a128c6025e998d78Peter Qiu if (status == DNSServerTester::kStatusSuccess) { 1490f18e7717c642dcfd6b4dbe1f01f50e2d9671f5cePeter Qiu result = Metrics::kFallbackDNSTestResultSuccess; 1491a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu 1492a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu // Switch to fallback DNS server if service is configured to allow DNS 1493a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu // fallback. 1494a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu CHECK(selected_service_); 1495a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu if (selected_service_->is_dns_auto_fallback_allowed()) { 14966f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu LOG(INFO) << "Device " << FriendlyName() 14976f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu << ": Switching to fallback DNS servers."; 14986f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu // Save the DNS servers from ipconfig. 14996f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu config_dns_servers_ = ipconfig_->properties().dns_servers; 1500a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu SwitchDNSServers(vector<string>(std::begin(kFallbackDnsServers), 1501a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu std::end(kFallbackDnsServers))); 15026f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu // Start DNS test for configured DNS servers. 15036f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu StartDNSTest(config_dns_servers_, 15046f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu true, 15056f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu Bind(&Device::ConfigDNSResultCallback, 15066f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu weak_ptr_factory_.GetWeakPtr())); 1507a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu } 1508b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu } 1509f18e7717c642dcfd6b4dbe1f01f50e2d9671f5cePeter Qiu metrics()->NotifyFallbackDNSTestResult(technology_, result); 15106f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu} 15116f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu 15126f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiuvoid Device::ConfigDNSResultCallback(const DNSServerTester::Status status) { 15136f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu StopDNSTest(); 15146f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu // DNS test failed to start due to internal error. 15156f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu if (status == DNSServerTester::kStatusFailure) { 15166f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu return; 15176f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu } 15186f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu 15196f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu // Switch back to the configured DNS servers. 15206f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu LOG(INFO) << "Device " << FriendlyName() 15216f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu << ": Switching back to configured DNS servers."; 15226f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu SwitchDNSServers(config_dns_servers_); 1523b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu} 1524b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu 1525a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::SwitchDNSServers(const vector<string>& dns_servers) { 1526a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu CHECK(ipconfig_); 1527a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu CHECK(connection_); 1528a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu // Push new DNS servers setting to the IP config object. 1529a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu ipconfig_->UpdateDNSServers(dns_servers); 1530a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu // Push new DNS servers setting to the current connection, so the resolver 1531a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu // will be updated to use the new DNS servers. 1532a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu connection_->UpdateDNSServers(dns_servers); 1533a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu // Allow the service to notify Chrome of ipconfig changes. 1534a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu selected_service_->NotifyIPConfigChanges(); 15356f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu // Restart the portal detection with the new DNS setting. 15366f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu RestartPortalDetection(); 1537a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu} 1538a89154bfedfd8872242083ffe4f084fdc774c078Peter Qiu 1539a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::set_traffic_monitor(TrafficMonitor* traffic_monitor) { 1540dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu traffic_monitor_.reset(traffic_monitor); 1541dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu} 1542dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 1543a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::TimeToNextDHCPLeaseRenewal(uint32_t* result) { 1544787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan if (!ipconfig() && !ip6config()) { 1545787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan return false; 1546787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan } 1547787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan uint32_t time_to_ipv4_lease_expiry = UINT32_MAX; 1548787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan uint32_t time_to_ipv6_lease_expiry = UINT32_MAX; 1549787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan if (ipconfig()) { 1550787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan ipconfig()->TimeToLeaseExpiry(&time_to_ipv4_lease_expiry); 1551787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan } 1552787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan if (ip6config()) { 1553787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan ip6config()->TimeToLeaseExpiry(&time_to_ipv6_lease_expiry); 1554787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan } 1555787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan *result = std::min(time_to_ipv4_lease_expiry, time_to_ipv6_lease_expiry); 1556787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan return true; 1557787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan} 1558787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan 1559dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiubool Device::IsTrafficMonitorEnabled() const { 1560dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu return false; 1561dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu} 1562dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 1563dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiuvoid Device::StartTrafficMonitor() { 1564dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu // Return if traffic monitor is not enabled for this device. 1565dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu if (!IsTrafficMonitorEnabled()) { 1566dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu return; 1567dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu } 1568dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 1569c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1570c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Traffic Monitor starting."; 1571dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu if (!traffic_monitor_.get()) { 1572dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu traffic_monitor_.reset(new TrafficMonitor(this, dispatcher_)); 1573dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu traffic_monitor_->set_network_problem_detected_callback( 1574dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu Bind(&Device::OnEncounterNetworkProblem, 1575dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu weak_ptr_factory_.GetWeakPtr())); 1576dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu } 1577dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu traffic_monitor_->Start(); 1578dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu} 1579dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 1580dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiuvoid Device::StopTrafficMonitor() { 1581dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu // Return if traffic monitor is not enabled for this device. 1582dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu if (!IsTrafficMonitorEnabled()) { 1583dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu return; 1584dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu } 1585dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 1586dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu if (traffic_monitor_.get()) { 1587c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1588c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Traffic Monitor stopping."; 1589dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu traffic_monitor_->Stop(); 1590dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu } 1591dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu traffic_monitor_.reset(); 1592dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu} 1593dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 1594dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiuvoid Device::OnEncounterNetworkProblem(int reason) { 1595dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu int metric_code; 1596dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu switch (reason) { 1597dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu case TrafficMonitor::kNetworkProblemCongestedTxQueue: 1598dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu metric_code = Metrics::kNetworkProblemCongestedTCPTxQueue; 1599dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu break; 1600dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu case TrafficMonitor::kNetworkProblemDNSFailure: 1601dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu metric_code = Metrics::kNetworkProblemDNSFailure; 1602dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu break; 1603dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu default: 1604dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu LOG(ERROR) << "Invalid network problem code: " << reason; 1605dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu return; 1606dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu } 1607dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 1608dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu metrics()->NotifyNetworkProblemDetected(technology_, metric_code); 1609dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu // Stop the traffic monitor, only report the first network problem detected 1610dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu // on the connection for now. 1611dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu StopTrafficMonitor(); 1612dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu} 1613dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 161420088d860631a67c151a12783fbbee63c708792fPaul Stewartvoid Device::SetServiceConnectedState(Service::ConnectState state) { 161520088d860631a67c151a12783fbbee63c708792fPaul Stewart DCHECK(selected_service_.get()); 161620088d860631a67c151a12783fbbee63c708792fPaul Stewart 161720088d860631a67c151a12783fbbee63c708792fPaul Stewart if (!selected_service_.get()) { 161820088d860631a67c151a12783fbbee63c708792fPaul Stewart LOG(ERROR) << FriendlyName() << ": " 161920088d860631a67c151a12783fbbee63c708792fPaul Stewart << "Portal detection completed but no selected service exists!"; 162020088d860631a67c151a12783fbbee63c708792fPaul Stewart return; 162120088d860631a67c151a12783fbbee63c708792fPaul Stewart } 162220088d860631a67c151a12783fbbee63c708792fPaul Stewart 162320088d860631a67c151a12783fbbee63c708792fPaul Stewart if (!selected_service_->IsConnected()) { 162420088d860631a67c151a12783fbbee63c708792fPaul Stewart LOG(ERROR) << FriendlyName() << ": " 162520088d860631a67c151a12783fbbee63c708792fPaul Stewart << "Portal detection completed but selected service " 1626457728b3eeb2d67c980e0d20675f0a0f750903e1Darin Petkov << selected_service_->unique_name() 162720088d860631a67c151a12783fbbee63c708792fPaul Stewart << " is in non-connected state."; 162820088d860631a67c151a12783fbbee63c708792fPaul Stewart return; 162920088d860631a67c151a12783fbbee63c708792fPaul Stewart } 163020088d860631a67c151a12783fbbee63c708792fPaul Stewart 1631c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart if (state == Service::kStatePortal && connection_->is_default() && 1632c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart manager_->GetPortalCheckInterval() != 0) { 1633c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart CHECK(portal_detector_.get()); 1634c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart if (!portal_detector_->StartAfterDelay( 1635c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart manager_->GetPortalCheckURL(), 1636c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart manager_->GetPortalCheckInterval())) { 1637c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart LOG(ERROR) << "Device " << FriendlyName() 1638c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart << ": Portal detection failed to restart: likely bad URL: " 1639c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart << manager_->GetPortalCheckURL(); 1640c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart SetServiceState(Service::kStateOnline); 1641c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart portal_detector_.reset(); 1642c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart return; 1643c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } 1644c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1645c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Portal detection retrying."; 1646c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } else { 1647c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1648c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Portal will not retry."; 1649c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart portal_detector_.reset(); 1650c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart } 1651c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart 165220088d860631a67c151a12783fbbee63c708792fPaul Stewart SetServiceState(state); 165320088d860631a67c151a12783fbbee63c708792fPaul Stewart} 165420088d860631a67c151a12783fbbee63c708792fPaul Stewart 1655a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::PortalDetectorCallback(const PortalDetector::Result& result) { 165620088d860631a67c151a12783fbbee63c708792fPaul Stewart if (!result.final) { 1657c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1658c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Received non-final status: " 1659c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ConnectivityTrial::StatusToString( 1660c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein result.trial_result.status); 166120088d860631a67c151a12783fbbee63c708792fPaul Stewart return; 166220088d860631a67c151a12783fbbee63c708792fPaul Stewart } 166320088d860631a67c151a12783fbbee63c708792fPaul Stewart 1664c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << FriendlyName() 1665c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ": Received final status: " 1666c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << ConnectivityTrial::StatusToString( 1667c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein result.trial_result.status); 166820088d860631a67c151a12783fbbee63c708792fPaul Stewart 166985e050b4923878a57aec1415314d2b39ff233e00Thieu Le portal_attempts_to_online_ += result.num_attempts; 167085e050b4923878a57aec1415314d2b39ff233e00Thieu Le 1671b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu int portal_status = Metrics::PortalDetectionResultToEnum(result); 167285e050b4923878a57aec1415314d2b39ff233e00Thieu Le metrics()->SendEnumToUMA( 1673132e96ff1c3dade1b08cdae82b0f4ed27a9a45d0mukesh agrawal metrics()->GetFullMetricName(Metrics::kMetricPortalResultSuffix, 1674132e96ff1c3dade1b08cdae82b0f4ed27a9a45d0mukesh agrawal technology()), 1675b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu portal_status, 167685e050b4923878a57aec1415314d2b39ff233e00Thieu Le Metrics::kPortalResultMax); 167785e050b4923878a57aec1415314d2b39ff233e00Thieu Le 16783d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein if (result.trial_result.status == ConnectivityTrial::kStatusSuccess) { 167920088d860631a67c151a12783fbbee63c708792fPaul Stewart SetServiceConnectedState(Service::kStateOnline); 168085e050b4923878a57aec1415314d2b39ff233e00Thieu Le 168185e050b4923878a57aec1415314d2b39ff233e00Thieu Le metrics()->SendToUMA( 168285e050b4923878a57aec1415314d2b39ff233e00Thieu Le metrics()->GetFullMetricName( 1683132e96ff1c3dade1b08cdae82b0f4ed27a9a45d0mukesh agrawal Metrics::kMetricPortalAttemptsToOnlineSuffix, technology()), 168485e050b4923878a57aec1415314d2b39ff233e00Thieu Le portal_attempts_to_online_, 168585e050b4923878a57aec1415314d2b39ff233e00Thieu Le Metrics::kMetricPortalAttemptsToOnlineMin, 168685e050b4923878a57aec1415314d2b39ff233e00Thieu Le Metrics::kMetricPortalAttemptsToOnlineMax, 168785e050b4923878a57aec1415314d2b39ff233e00Thieu Le Metrics::kMetricPortalAttemptsToOnlineNumBuckets); 168820088d860631a67c151a12783fbbee63c708792fPaul Stewart } else { 16899b83c897f8e197ff7846e4fe7cec1d83d54e7b7bPeter Qiu // Set failure phase and status. 16909b83c897f8e197ff7846e4fe7cec1d83d54e7b7bPeter Qiu if (selected_service_.get()) { 16919b83c897f8e197ff7846e4fe7cec1d83d54e7b7bPeter Qiu selected_service_->SetPortalDetectionFailure( 16923d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein ConnectivityTrial::PhaseToString(result.trial_result.phase), 16933d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein ConnectivityTrial::StatusToString(result.trial_result.status)); 16949b83c897f8e197ff7846e4fe7cec1d83d54e7b7bPeter Qiu } 169520088d860631a67c151a12783fbbee63c708792fPaul Stewart SetServiceConnectedState(Service::kStatePortal); 169685e050b4923878a57aec1415314d2b39ff233e00Thieu Le 169785e050b4923878a57aec1415314d2b39ff233e00Thieu Le metrics()->SendToUMA( 169885e050b4923878a57aec1415314d2b39ff233e00Thieu Le metrics()->GetFullMetricName( 1699132e96ff1c3dade1b08cdae82b0f4ed27a9a45d0mukesh agrawal Metrics::kMetricPortalAttemptsSuffix, technology()), 170085e050b4923878a57aec1415314d2b39ff233e00Thieu Le result.num_attempts, 170185e050b4923878a57aec1415314d2b39ff233e00Thieu Le Metrics::kMetricPortalAttemptsMin, 170285e050b4923878a57aec1415314d2b39ff233e00Thieu Le Metrics::kMetricPortalAttemptsMax, 170385e050b4923878a57aec1415314d2b39ff233e00Thieu Le Metrics::kMetricPortalAttemptsNumBuckets); 1704b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu 1705490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan StartConnectionDiagnosticsAfterPortalDetection(result); 1706490063ebd172dbaf5328c682f7338b2c1f6331dfSamuel Tan 1707b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu // TODO(zqiu): Only support fallback DNS server for IPv4 for now. 1708b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu if (connection_->IsIPv6()) { 1709b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu return; 1710b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu } 1711b25083f4ec00167ceed71a7f961e3f1435dbe070Peter Qiu 1712b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu // Perform fallback DNS test if the portal failure is DNS related. 1713b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu // The test will send a DNS request to Google's DNS server to determine 1714b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu // if the DNS failure is due to bad DNS server settings. 1715b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu if ((portal_status == Metrics::kPortalResultDNSFailure) || 1716b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu (portal_status == Metrics::kPortalResultDNSTimeout)) { 17176f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu StartDNSTest(vector<string>(std::begin(kFallbackDnsServers), 17186f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu std::end(kFallbackDnsServers)), 17196f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu false, 17206f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu Bind(&Device::FallbackDNSResultCallback, 17216f5618beb7e382b1b122e7a63b63f1bca7723417Peter Qiu weak_ptr_factory_.GetWeakPtr())); 1722b9256f3d485e4c6c5c301a0aa00554059473b41dPeter Qiu } 172320088d860631a67c151a12783fbbee63c708792fPaul Stewart } 172420088d860631a67c151a12783fbbee63c708792fPaul Stewart} 172520088d860631a67c151a12783fbbee63c708792fPaul Stewart 1726a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartstring Device::GetSelectedServiceRpcIdentifier(Error* /*error*/) { 1727674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley if (!selected_service_) { 1728674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley return "/"; 1729674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley } 1730674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley return selected_service_->GetRpcIdentifier(); 1731674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley} 1732674598d8b8fd78424bf1b0d4e18ec3bc57cf56cdChristopher Wiley 1733a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvector<string> Device::AvailableIPConfigs(Error* /*error*/) { 1734d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart vector<string> ipconfigs; 1735d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart if (ipconfig_) { 1736d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart ipconfigs.push_back(ipconfig_->GetRpcIdentifier()); 1737d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart } 1738d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart if (ip6config_) { 1739d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart ipconfigs.push_back(ip6config_->GetRpcIdentifier()); 174008afdffc182c7f04a8acdbb63240585069af8040Jason Glasgow } 1741d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu if (dhcpv6_config_) { 1742d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu ipconfigs.push_back(dhcpv6_config_->GetRpcIdentifier()); 1743d48fa0c5531e2102d4f537e81b9f92afc2d60955Peter Qiu } 1744d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart return ipconfigs; 17454e85161f12699d8eb2116ae24766676ed8227a71Chris Masone} 17464e85161f12699d8eb2116ae24766676ed8227a71Chris Masone 1747a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartuint64_t Device::GetLinkMonitorResponseTime(Error* error) { 1748036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart if (!link_monitor_.get()) { 1749036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart // It is not strictly an error that the link monitor does not 1750036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart // exist, but returning an error here allows the GetProperties 1751036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart // call in our Adaptor to omit this parameter. 1752036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart error->Populate(Error::kNotFound, "Device is not running LinkMonitor"); 1753036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart return 0; 1754036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart } 1755036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart return link_monitor_->GetResponseTimeMilliseconds(); 1756036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart} 1757036dba0c6641acdbe02d52260c6fa6dca84b1af2Paul Stewart 17587fab89734d88724a288e96a9996b15548c5294c7Ben Chanuint64_t Device::GetReceiveByteCount() { 17597fab89734d88724a288e96a9996b15548c5294c7Ben Chan uint64_t rx_byte_count = 0, tx_byte_count = 0; 17606ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart manager_->device_info()->GetByteCounts( 17616ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart interface_index_, &rx_byte_count, &tx_byte_count); 17626ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart return rx_byte_count - receive_byte_offset_; 17636ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart} 17646ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 17657fab89734d88724a288e96a9996b15548c5294c7Ben Chanuint64_t Device::GetTransmitByteCount() { 17667fab89734d88724a288e96a9996b15548c5294c7Ben Chan uint64_t rx_byte_count = 0, tx_byte_count = 0; 17676ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart manager_->device_info()->GetByteCounts( 17686ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart interface_index_, &rx_byte_count, &tx_byte_count); 17696ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart return tx_byte_count - transmit_byte_offset_; 17706ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart} 17716ff27f578d3a4474d82dc3881441fc365e813ec9Paul Stewart 1772a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartuint64_t Device::GetReceiveByteCountProperty(Error* /*error*/) { 1773b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan return GetReceiveByteCount(); 1774b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} 1775b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 1776a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartuint64_t Device::GetTransmitByteCountProperty(Error* /*error*/) { 1777b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan return GetTransmitByteCount(); 1778b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} 1779b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 17807fce52c4afdc5e73a9e740dc9b90f1e61ae8cea4Eric Shienbroodbool Device::IsUnderlyingDeviceEnabled() const { 17817fce52c4afdc5e73a9e740dc9b90f1e61ae8cea4Eric Shienbrood return false; 17827fce52c4afdc5e73a9e740dc9b90f1e61ae8cea4Eric Shienbrood} 17837fce52c4afdc5e73a9e740dc9b90f1e61ae8cea4Eric Shienbrood 17849a24553461df7036755060423f90804011612249Eric Shienbrood// callback 1785a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::OnEnabledStateChanged(const ResultCallback& callback, 1786a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const Error& error) { 1787c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ 1788c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << " (target: " << enabled_pending_ << "," 1789c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << " success: " << error.IsSuccess() << ")" 1790c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << " on " << link_name_; 17919a24553461df7036755060423f90804011612249Eric Shienbrood if (error.IsSuccess()) { 17929a24553461df7036755060423f90804011612249Eric Shienbrood enabled_ = enabled_pending_; 17939a24553461df7036755060423f90804011612249Eric Shienbrood manager_->UpdateEnabledTechnologies(); 1794923a5025a5e1138b052cbeffa60ea387d479696fBen Chan adaptor_->EmitBoolChanged(kPoweredProperty, enabled_); 17959a24553461df7036755060423f90804011612249Eric Shienbrood } 1796baeefdf544bfcfe2895e4e15c348db3f7ce4d45bGary Morain enabled_pending_ = enabled_; 17979a24553461df7036755060423f90804011612249Eric Shienbrood if (!callback.is_null()) 17989a24553461df7036755060423f90804011612249Eric Shienbrood callback.Run(error); 17999a24553461df7036755060423f90804011612249Eric Shienbrood} 18009a24553461df7036755060423f90804011612249Eric Shienbrood 18019a24553461df7036755060423f90804011612249Eric Shienbroodvoid Device::SetEnabled(bool enable) { 1802c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << "(" << enable << ")"; 18034a4907904affddc3cf6f88ce3b4662d66a9e18ebJason Glasgow Error error; 180428185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal SetEnabledChecked(enable, false, &error, ResultCallback()); 18058bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray 18068bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray // SetEnabledInternal might fail here if there is an unfinished enable or 18078bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray // disable operation. Don't log error in this case, as this method is only 18088bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray // called when the underlying device is already in the target state and the 18098bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray // pending operation should eventually bring the device to the expected 18108bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray // state. 18118bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray LOG_IF(ERROR, 18128bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray error.IsFailure() && 18138bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray !error.IsOngoing() && 18148bf6a5c1b559d57fe448132cfff5795a14cf9685Arman Uguray error.type() != Error::kInProgress) 18154a4907904affddc3cf6f88ce3b4662d66a9e18ebJason Glasgow << "Enabled failed, but no way to report the failure."; 18169a24553461df7036755060423f90804011612249Eric Shienbrood} 18179a24553461df7036755060423f90804011612249Eric Shienbrood 18189f3dcf80a84c07701b7c224fca5ed637c966fa3eBen Chanvoid Device::SetEnabledNonPersistent(bool enable, 1819a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, 1820a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const ResultCallback& callback) { 182128185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal SetEnabledChecked(enable, false, error, callback); 18229f3dcf80a84c07701b7c224fca5ed637c966fa3eBen Chan} 18239f3dcf80a84c07701b7c224fca5ed637c966fa3eBen Chan 18249a24553461df7036755060423f90804011612249Eric Shienbroodvoid Device::SetEnabledPersistent(bool enable, 1825a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, 1826a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const ResultCallback& callback) { 182728185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal SetEnabledChecked(enable, true, error, callback); 18289a24553461df7036755060423f90804011612249Eric Shienbrood} 18299a24553461df7036755060423f90804011612249Eric Shienbrood 183028185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawalvoid Device::SetEnabledChecked(bool enable, 183128185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal bool persist, 1832a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error, 1833a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const ResultCallback& callback) { 18344a4907904affddc3cf6f88ce3b4662d66a9e18ebJason Glasgow DCHECK(error); 1835c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << "Device " << link_name_ << " " 1836c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << (enable ? "starting" : "stopping"); 1837ff6be29bd74abd31640abcf9ad4332e0a9657196Paul Stewart if (enable && manager_->IsTechnologyProhibited(technology())) { 1838ff6be29bd74abd31640abcf9ad4332e0a9657196Paul Stewart error->Populate(Error::kPermissionDenied, "The " + 1839ff6be29bd74abd31640abcf9ad4332e0a9657196Paul Stewart Technology::NameFromIdentifier(technology()) + 1840ff6be29bd74abd31640abcf9ad4332e0a9657196Paul Stewart " technology is prohibited"); 1841ff6be29bd74abd31640abcf9ad4332e0a9657196Paul Stewart return; 1842ff6be29bd74abd31640abcf9ad4332e0a9657196Paul Stewart } 1843ff6be29bd74abd31640abcf9ad4332e0a9657196Paul Stewart 18449a24553461df7036755060423f90804011612249Eric Shienbrood if (enable == enabled_) { 18452f352e606bbe6074eeca93eb457837e501420be7Arman Uguray if (enable != enabled_pending_ && persist) { 18462f352e606bbe6074eeca93eb457837e501420be7Arman Uguray // Return an error, as there is an ongoing operation to achieve the 18472f352e606bbe6074eeca93eb457837e501420be7Arman Uguray // opposite. 18482f352e606bbe6074eeca93eb457837e501420be7Arman Uguray Error::PopulateAndLog( 184934f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kOperationFailed, 18502f352e606bbe6074eeca93eb457837e501420be7Arman Uguray enable ? "Cannot enable while the device is disabling." : 18512f352e606bbe6074eeca93eb457837e501420be7Arman Uguray "Cannot disable while the device is enabling."); 18522f352e606bbe6074eeca93eb457837e501420be7Arman Uguray return; 18532f352e606bbe6074eeca93eb457837e501420be7Arman Uguray } 185428185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal LOG(INFO) << "Already in desired enable state."; 18554a4907904affddc3cf6f88ce3b4662d66a9e18ebJason Glasgow error->Reset(); 18569a24553461df7036755060423f90804011612249Eric Shienbrood return; 18579a24553461df7036755060423f90804011612249Eric Shienbrood } 18589a24553461df7036755060423f90804011612249Eric Shienbrood 18599a24553461df7036755060423f90804011612249Eric Shienbrood if (enabled_pending_ == enable) { 186034f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart Error::PopulateAndLog(FROM_HERE, error, Error::kInProgress, 18614a4907904affddc3cf6f88ce3b4662d66a9e18ebJason Glasgow "Enable operation already in progress"); 18629a24553461df7036755060423f90804011612249Eric Shienbrood return; 18639a24553461df7036755060423f90804011612249Eric Shienbrood } 18649a24553461df7036755060423f90804011612249Eric Shienbrood 18659a24553461df7036755060423f90804011612249Eric Shienbrood if (persist) { 18669a24553461df7036755060423f90804011612249Eric Shienbrood enabled_persistent_ = enable; 1867e7c6ad35cafed32a0fd1390487c74e66eae1961dDarin Petkov manager_->UpdateDevice(this); 18689a24553461df7036755060423f90804011612249Eric Shienbrood } 18699a24553461df7036755060423f90804011612249Eric Shienbrood 187028185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal SetEnabledUnchecked(enable, error, callback); 187128185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal} 187228185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal 1873a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartvoid Device::SetEnabledUnchecked(bool enable, Error* error, 1874a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const ResultCallback& on_enable_complete) { 18759a24553461df7036755060423f90804011612249Eric Shienbrood enabled_pending_ = enable; 187628185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal EnabledStateChangedCallback chained_callback = 18779a24553461df7036755060423f90804011612249Eric Shienbrood Bind(&Device::OnEnabledStateChanged, 187828185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal weak_ptr_factory_.GetWeakPtr(), on_enable_complete); 18799a24553461df7036755060423f90804011612249Eric Shienbrood if (enable) { 18809a24553461df7036755060423f90804011612249Eric Shienbrood running_ = true; 188128185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal Start(error, chained_callback); 18829a24553461df7036755060423f90804011612249Eric Shienbrood } else { 18839a24553461df7036755060423f90804011612249Eric Shienbrood running_ = false; 18849a24553461df7036755060423f90804011612249Eric Shienbrood DestroyIPConfig(); // breaks a reference cycle 1885cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan SelectService(nullptr); // breaks a reference cycle 18869a24553461df7036755060423f90804011612249Eric Shienbrood rtnl_handler_->SetInterfaceFlags(interface_index(), 0, IFF_UP); 1887c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 3) << "Device " << link_name_ << " ipconfig_ " 1888c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << (ipconfig_ ? "is set." : "is not set."); 1889c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 3) << "Device " << link_name_ << " ip6config_ " 1890c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << (ip6config_ ? "is set." : "is not set."); 1891c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 3) << "Device " << link_name_ << " connection_ " 1892c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << (connection_ ? "is set." : "is not set."); 1893c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 3) << "Device " << link_name_ << " selected_service_ " 1894c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << (selected_service_ ? "is set." : "is not set."); 189528185511575e3a670c6dc2499b33ef992e4fc2f0mukesh agrawal Stop(error, chained_callback); 18969a24553461df7036755060423f90804011612249Eric Shienbrood } 18979a24553461df7036755060423f90804011612249Eric Shienbrood} 18989a24553461df7036755060423f90804011612249Eric Shienbrood 1899d4f26486b237fae831d4b682481de785fc99c66ePaul Stewartvoid Device::UpdateIPConfigsProperty() { 1900d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart adaptor_->EmitRpcIdentifierArrayChanged( 1901cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan kIPConfigsProperty, AvailableIPConfigs(nullptr)); 1902d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart} 1903d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart 1904a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewartbool Device::ResolvePeerMacAddress(const string& input, 1905a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart string* output, 1906a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error) { 190762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu if (!MakeHardwareAddressFromString(input).empty()) { 190862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu // Input is already a MAC address. 190962abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu *output = input; 191062abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return true; 191162abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu } 191262abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu 191362abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu IPAddress ip_address(IPAddress::kFamilyIPv4); 191462abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu if (!ip_address.SetAddressFromString(input)) { 191562abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments, 191662abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu "Peer is neither an IP Address nor a MAC address"); 191762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return false; 191862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu } 191962abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu 192062abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu // Peer address was specified as an IP address which we need to resolve. 1921a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const DeviceInfo* device_info = manager()->device_info(); 192262abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu if (!device_info->HasDirectConnectivityTo(interface_index_, ip_address)) { 192362abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments, 192462abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu "IP address is not local to this interface"); 192562abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return false; 192662abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu } 192762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu 192862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu ByteString mac_address; 192962abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu if (device_info->GetMACAddressOfPeer(interface_index_, 193062abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu ip_address, 193162abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu &mac_address)) { 193262abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu *output = MakeStringFromHardwareAddress( 193362abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu vector<uint8_t>(mac_address.GetConstData(), 193462abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu mac_address.GetConstData() + 193562abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu mac_address.GetLength())); 193662abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu SLOG(this, 2) << "ARP cache lookup returned peer: " << *output; 193762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return true; 193862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu } 193962abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu 1940f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan if (!Icmp().TransmitEchoRequest(ip_address, 1, 1)) { 194162abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed, 194262abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu "Failed to send ICMP request to peer to setup ARP"); 194362abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu } else { 194462abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu // ARP request was transmitted successfully, address resolution is still 194562abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu // pending. 194662abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu error->Populate(Error::kInProgress, 194762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu "Peer MAC address was not found in the ARP cache, " 194862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu "but an ARP request was sent to find it. " 194962abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu "Please try again."); 195062abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu } 195162abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return false; 195262abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu} 195362abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu 195462abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu// static 195562abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiuvector<uint8_t> Device::MakeHardwareAddressFromString( 1956a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const string& address_string) { 195762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu string address_nosep; 195862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu base::RemoveChars(address_string, ":", &address_nosep); 195962abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu vector<uint8_t> address_bytes; 196062abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu base::HexStringToBytes(address_nosep, &address_bytes); 196162abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu if (address_bytes.size() != kHardwareAddressLength) { 196262abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return vector<uint8_t>(); 196362abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu } 196462abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return address_bytes; 196562abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu} 196662abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu 196762abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu// static 196862abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiustring Device::MakeStringFromHardwareAddress( 1969a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const vector<uint8_t>& address_bytes) { 197062abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu CHECK_EQ(kHardwareAddressLength, address_bytes.size()); 197162abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu return StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x", 197262abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu address_bytes[0], address_bytes[1], address_bytes[2], 197362abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu address_bytes[3], address_bytes[4], address_bytes[5]); 197462abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu} 197562abf31989c52dc1e4ee5aae71664ba81d6fe2dbPeter Qiu 19768ff81329524eb3af0d8e7b2642a4a4c262d6b4fdNingyuan Wangbool Device::RequestRoam(const std::string& addr, Error* error) { 19778ff81329524eb3af0d8e7b2642a4a4c262d6b4fdNingyuan Wang return false; 19788ff81329524eb3af0d8e7b2642a4a4c262d6b4fdNingyuan Wang} 19798ff81329524eb3af0d8e7b2642a4a4c262d6b4fdNingyuan Wang 198075897df1154ac38b7a4512a687241ad6a197ee40Paul Stewart} // namespace shill 1981