dns_config_service_android.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/dns/dns_config_service_android.h"
  5. #include <sys/system_properties.h>
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include "base/android/build_info.h"
  10. #include "base/bind.h"
  11. #include "base/files/file_path.h"
  12. #include "base/logging.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/sequence_checker.h"
  15. #include "base/time/time.h"
  16. #include "net/android/network_library.h"
  17. #include "net/base/address_tracker_linux.h"
  18. #include "net/base/ip_address.h"
  19. #include "net/base/ip_endpoint.h"
  20. #include "net/base/network_change_notifier.h"
  21. #include "net/base/network_interfaces.h"
  22. #include "net/dns/dns_config.h"
  23. #include "net/dns/dns_config_service.h"
  24. #include "net/dns/public/dns_protocol.h"
  25. #include "net/dns/serial_worker.h"
  26. #include "third_party/abseil-cpp/absl/types/optional.h"
  27. namespace net {
  28. namespace internal {
  29. namespace {
  30. constexpr base::FilePath::CharType kFilePathHosts[] =
  31. FILE_PATH_LITERAL("/system/etc/hosts");
  32. bool IsVpnPresent() {
  33. NetworkInterfaceList networks;
  34. if (!GetNetworkList(&networks, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES))
  35. return false;
  36. for (NetworkInterface network : networks) {
  37. if (AddressTrackerLinux::IsTunnelInterfaceName(network.name.c_str()))
  38. return true;
  39. }
  40. return false;
  41. }
  42. } // namespace
  43. // static
  44. constexpr base::TimeDelta DnsConfigServiceAndroid::kConfigChangeDelay;
  45. class DnsConfigServiceAndroid::Watcher
  46. : public DnsConfigService::Watcher,
  47. public NetworkChangeNotifier::NetworkChangeObserver {
  48. public:
  49. explicit Watcher(DnsConfigServiceAndroid& service)
  50. : DnsConfigService::Watcher(service) {}
  51. ~Watcher() override {
  52. NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
  53. }
  54. Watcher(const Watcher&) = delete;
  55. Watcher& operator=(const Watcher&) = delete;
  56. // DnsConfigService::Watcher:
  57. bool Watch() override {
  58. CheckOnCorrectSequence();
  59. // On Android, assume DNS config may have changed on every network change.
  60. NetworkChangeNotifier::AddNetworkChangeObserver(this);
  61. // Hosts file should never change on Android (and watching it is
  62. // problematic; see http://crbug.com/600442), so don't watch it.
  63. return true;
  64. }
  65. // NetworkChangeNotifier::NetworkChangeObserver:
  66. void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) override {
  67. if (type != NetworkChangeNotifier::CONNECTION_NONE)
  68. OnConfigChanged(true);
  69. }
  70. };
  71. class DnsConfigServiceAndroid::ConfigReader : public SerialWorker {
  72. public:
  73. explicit ConfigReader(DnsConfigServiceAndroid& service,
  74. android::DnsServerGetter dns_server_getter)
  75. : dns_server_getter_(std::move(dns_server_getter)), service_(&service) {}
  76. ~ConfigReader() override = default;
  77. ConfigReader(const ConfigReader&) = delete;
  78. ConfigReader& operator=(const ConfigReader&) = delete;
  79. std::unique_ptr<SerialWorker::WorkItem> CreateWorkItem() override {
  80. return std::make_unique<WorkItem>(dns_server_getter_);
  81. }
  82. bool OnWorkFinished(std::unique_ptr<SerialWorker::WorkItem>
  83. serial_worker_work_item) override {
  84. DCHECK(serial_worker_work_item);
  85. DCHECK(!IsCancelled());
  86. WorkItem* work_item = static_cast<WorkItem*>(serial_worker_work_item.get());
  87. if (work_item->dns_config_.has_value()) {
  88. service_->OnConfigRead(std::move(work_item->dns_config_).value());
  89. return true;
  90. } else {
  91. LOG(WARNING) << "Failed to read DnsConfig.";
  92. return false;
  93. }
  94. }
  95. private:
  96. class WorkItem : public SerialWorker::WorkItem {
  97. public:
  98. explicit WorkItem(android::DnsServerGetter dns_server_getter)
  99. : dns_server_getter_(std::move(dns_server_getter)) {}
  100. void DoWork() override {
  101. dns_config_.emplace();
  102. dns_config_->unhandled_options = false;
  103. if (base::android::BuildInfo::GetInstance()->sdk_int() >=
  104. base::android::SDK_VERSION_MARSHMALLOW) {
  105. if (!dns_server_getter_.Run(
  106. &dns_config_->nameservers, &dns_config_->dns_over_tls_active,
  107. &dns_config_->dns_over_tls_hostname, &dns_config_->search)) {
  108. dns_config_.reset();
  109. }
  110. return;
  111. }
  112. if (IsVpnPresent()) {
  113. dns_config_->unhandled_options = true;
  114. }
  115. // NOTE(pauljensen): __system_property_get and the net.dns1/2 properties
  116. // are not supported APIs, but they're only read on pre-Marshmallow
  117. // Android which was released years ago and isn't changing.
  118. char property_value[PROP_VALUE_MAX];
  119. __system_property_get("net.dns1", property_value);
  120. std::string dns1_string = property_value;
  121. __system_property_get("net.dns2", property_value);
  122. std::string dns2_string = property_value;
  123. if (dns1_string.empty() && dns2_string.empty()) {
  124. dns_config_.reset();
  125. return;
  126. }
  127. IPAddress dns1_address;
  128. IPAddress dns2_address;
  129. bool parsed1 = dns1_address.AssignFromIPLiteral(dns1_string);
  130. bool parsed2 = dns2_address.AssignFromIPLiteral(dns2_string);
  131. if (!parsed1 && !parsed2) {
  132. dns_config_.reset();
  133. return;
  134. }
  135. if (parsed1) {
  136. IPEndPoint dns1(dns1_address, dns_protocol::kDefaultPort);
  137. dns_config_->nameservers.push_back(dns1);
  138. }
  139. if (parsed2) {
  140. IPEndPoint dns2(dns2_address, dns_protocol::kDefaultPort);
  141. dns_config_->nameservers.push_back(dns2);
  142. }
  143. }
  144. private:
  145. friend class ConfigReader;
  146. android::DnsServerGetter dns_server_getter_;
  147. absl::optional<DnsConfig> dns_config_;
  148. };
  149. android::DnsServerGetter dns_server_getter_;
  150. // Raw pointer to owning DnsConfigService.
  151. const raw_ptr<DnsConfigServiceAndroid> service_;
  152. };
  153. DnsConfigServiceAndroid::DnsConfigServiceAndroid()
  154. : DnsConfigService(kFilePathHosts, kConfigChangeDelay) {
  155. // Allow constructing on one thread and living on another.
  156. DETACH_FROM_SEQUENCE(sequence_checker_);
  157. dns_server_getter_ = base::BindRepeating(&android::GetCurrentDnsServers);
  158. }
  159. DnsConfigServiceAndroid::~DnsConfigServiceAndroid() {
  160. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  161. if (config_reader_)
  162. config_reader_->Cancel();
  163. }
  164. void DnsConfigServiceAndroid::ReadConfigNow() {
  165. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  166. if (!config_reader_) {
  167. DCHECK(dns_server_getter_);
  168. config_reader_ =
  169. std::make_unique<ConfigReader>(*this, std::move(dns_server_getter_));
  170. }
  171. config_reader_->WorkNow();
  172. }
  173. bool DnsConfigServiceAndroid::StartWatching() {
  174. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  175. // TODO(crbug.com/116139): re-start watcher if that makes sense.
  176. watcher_ = std::make_unique<Watcher>(*this);
  177. return watcher_->Watch();
  178. }
  179. } // namespace internal
  180. // static
  181. std::unique_ptr<DnsConfigService> DnsConfigService::CreateSystemService() {
  182. return std::make_unique<internal::DnsConfigServiceAndroid>();
  183. }
  184. } // namespace net