Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Side by Side Diff: net/dns/dns_config_service_posix.cc

Issue 1965553005: Async DNS: Don't watch hosts file on Android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/dns/dns_config_service_posix_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/dns/dns_config_service_posix.h" 5 #include "net/dns/dns_config_service_posix.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file.h" 10 #include "base/files/file.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 class DnsConfigWatcher { 54 class DnsConfigWatcher {
55 public: 55 public:
56 typedef base::Callback<void(bool succeeded)> CallbackType; 56 typedef base::Callback<void(bool succeeded)> CallbackType;
57 57
58 bool Watch(const CallbackType& callback) { 58 bool Watch(const CallbackType& callback) {
59 return false; 59 return false;
60 } 60 }
61 }; 61 };
62 62
63 #elif defined(OS_ANDROID) 63 #elif defined(OS_ANDROID)
64
64 // On Android, assume DNS config may have changed on every network change. 65 // On Android, assume DNS config may have changed on every network change.
65 class DnsConfigWatcher { 66 class DnsConfigWatcher {
66 public: 67 public:
67 bool Watch(const base::Callback<void(bool succeeded)>& callback) { 68 bool Watch(const base::Callback<void(bool succeeded)>& callback) {
68 callback_ = callback; 69 callback_ = callback;
69 return true; 70 return true;
70 } 71 }
71 72
72 void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) { 73 void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) {
73 if (!callback_.is_null() && type != NetworkChangeNotifier::CONNECTION_NONE) 74 if (!callback_.is_null() && type != NetworkChangeNotifier::CONNECTION_NONE)
74 callback_.Run(true); 75 callback_.Run(true);
75 } 76 }
76 77
77 private: 78 private:
78 base::Callback<void(bool succeeded)> callback_; 79 base::Callback<void(bool succeeded)> callback_;
79 }; 80 };
80 #elif !defined(OS_MACOSX) 81
82 #elif defined(OS_MACOSX)
83
81 // DnsConfigWatcher for OS_MACOSX is in dns_config_watcher_mac.{hh,cc}. 84 // DnsConfigWatcher for OS_MACOSX is in dns_config_watcher_mac.{hh,cc}.
82 85
86 #else // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
87
83 #ifndef _PATH_RESCONF // Normally defined in <resolv.h> 88 #ifndef _PATH_RESCONF // Normally defined in <resolv.h>
84 #define _PATH_RESCONF "/etc/resolv.conf" 89 #define _PATH_RESCONF "/etc/resolv.conf"
85 #endif 90 #endif
86 91
87 static const base::FilePath::CharType* kFilePathConfig = 92 static const base::FilePath::CharType* kFilePathConfig =
88 FILE_PATH_LITERAL(_PATH_RESCONF); 93 FILE_PATH_LITERAL(_PATH_RESCONF);
89 94
90 class DnsConfigWatcher { 95 class DnsConfigWatcher {
91 public: 96 public:
92 typedef base::Callback<void(bool succeeded)> CallbackType; 97 typedef base::Callback<void(bool succeeded)> CallbackType;
93 98
94 bool Watch(const CallbackType& callback) { 99 bool Watch(const CallbackType& callback) {
95 callback_ = callback; 100 callback_ = callback;
96 return watcher_.Watch(base::FilePath(kFilePathConfig), false, 101 return watcher_.Watch(base::FilePath(kFilePathConfig), false,
97 base::Bind(&DnsConfigWatcher::OnCallback, 102 base::Bind(&DnsConfigWatcher::OnCallback,
98 base::Unretained(this))); 103 base::Unretained(this)));
99 } 104 }
100 105
101 private: 106 private:
102 void OnCallback(const base::FilePath& path, bool error) { 107 void OnCallback(const base::FilePath& path, bool error) {
103 callback_.Run(!error); 108 callback_.Run(!error);
104 } 109 }
105 110
106 base::FilePathWatcher watcher_; 111 base::FilePathWatcher watcher_;
107 CallbackType callback_; 112 CallbackType callback_;
108 }; 113 };
114
109 #endif 115 #endif
110 116
111 #if !defined(OS_ANDROID) 117 #if !defined(OS_ANDROID)
112 ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) { 118 ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) {
113 ConfigParsePosixResult result; 119 ConfigParsePosixResult result;
114 config->unhandled_options = false; 120 config->unhandled_options = false;
115 #if defined(OS_OPENBSD) 121 #if defined(OS_OPENBSD)
116 // Note: res_ninit in glibc always returns 0 and sets RES_INIT. 122 // Note: res_ninit in glibc always returns 0 and sets RES_INIT.
117 // res_init behaves the same way. 123 // res_init behaves the same way.
118 memset(&_res, 0, sizeof(_res)); 124 memset(&_res, 0, sizeof(_res));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 bool Watch() { 209 bool Watch() {
204 bool success = true; 210 bool success = true;
205 if (!config_watcher_.Watch(base::Bind(&Watcher::OnConfigChanged, 211 if (!config_watcher_.Watch(base::Bind(&Watcher::OnConfigChanged,
206 base::Unretained(this)))) { 212 base::Unretained(this)))) {
207 LOG(ERROR) << "DNS config watch failed to start."; 213 LOG(ERROR) << "DNS config watch failed to start.";
208 success = false; 214 success = false;
209 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", 215 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus",
210 DNS_CONFIG_WATCH_FAILED_TO_START_CONFIG, 216 DNS_CONFIG_WATCH_FAILED_TO_START_CONFIG,
211 DNS_CONFIG_WATCH_MAX); 217 DNS_CONFIG_WATCH_MAX);
212 } 218 }
213 #if !defined(OS_IOS) 219 // Hosts file should never change on Android or iOS (and watching it on Android
220 // is problematic; see http://crbug.com/600442), so don't watch it there.
221 #if !defined(OS_ANDROID) && !defined(OS_IOS)
214 if (!hosts_watcher_.Watch( 222 if (!hosts_watcher_.Watch(
215 base::FilePath(service_->file_path_hosts_), false, 223 base::FilePath(service_->file_path_hosts_), false,
216 base::Bind(&Watcher::OnHostsChanged, base::Unretained(this)))) { 224 base::Bind(&Watcher::OnHostsChanged, base::Unretained(this)))) {
217 LOG(ERROR) << "DNS hosts watch failed to start."; 225 LOG(ERROR) << "DNS hosts watch failed to start.";
218 success = false; 226 success = false;
219 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", 227 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus",
220 DNS_CONFIG_WATCH_FAILED_TO_START_HOSTS, 228 DNS_CONFIG_WATCH_FAILED_TO_START_HOSTS,
221 DNS_CONFIG_WATCH_MAX); 229 DNS_CONFIG_WATCH_MAX);
222 } 230 }
223 #endif 231 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
224 return success; 232 return success;
225 } 233 }
226 234
227 #if defined(OS_ANDROID) 235 #if defined(OS_ANDROID)
228 void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) { 236 void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) {
229 config_watcher_.OnNetworkChanged(type); 237 config_watcher_.OnNetworkChanged(type);
230 } 238 }
231 #endif // defined(OS_ANDROID) 239 #endif // defined(OS_ANDROID)
232 240
233 private: 241 private:
(...skipping 10 matching lines...) Expand all
244 } 252 }
245 void OnConfigChangedDelayed(bool succeeded) { 253 void OnConfigChangedDelayed(bool succeeded) {
246 service_->OnConfigChanged(succeeded); 254 service_->OnConfigChanged(succeeded);
247 } 255 }
248 void OnHostsChanged(const base::FilePath& path, bool error) { 256 void OnHostsChanged(const base::FilePath& path, bool error) {
249 service_->OnHostsChanged(!error); 257 service_->OnHostsChanged(!error);
250 } 258 }
251 259
252 DnsConfigServicePosix* service_; 260 DnsConfigServicePosix* service_;
253 DnsConfigWatcher config_watcher_; 261 DnsConfigWatcher config_watcher_;
254 #if !defined(OS_IOS) 262 #if !defined(OS_ANDROID) && !defined(OS_IOS)
255 base::FilePathWatcher hosts_watcher_; 263 base::FilePathWatcher hosts_watcher_;
256 #endif 264 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
257 265
258 base::WeakPtrFactory<Watcher> weak_factory_; 266 base::WeakPtrFactory<Watcher> weak_factory_;
259 267
260 DISALLOW_COPY_AND_ASSIGN(Watcher); 268 DISALLOW_COPY_AND_ASSIGN(Watcher);
261 }; 269 };
262 270
263 // A SerialWorker that uses libresolv to initialize res_state and converts 271 // A SerialWorker that uses libresolv to initialize res_state and converts
264 // it to DnsConfig (except on Android, where it reads system properties 272 // it to DnsConfig (except on Android, where it reads system properties
265 // net.dns1 and net.dns2; see #if around ReadDnsConfig above.) 273 // net.dns1 and net.dns2; see #if around ReadDnsConfig above.)
266 class DnsConfigServicePosix::ConfigReader : public SerialWorker { 274 class DnsConfigServicePosix::ConfigReader : public SerialWorker {
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 return CONFIG_PARSE_POSIX_NULL_ADDRESS; 555 return CONFIG_PARSE_POSIX_NULL_ADDRESS;
548 } 556 }
549 return CONFIG_PARSE_POSIX_OK; 557 return CONFIG_PARSE_POSIX_OK;
550 } 558 }
551 559
552 #else // defined(OS_ANDROID) 560 #else // defined(OS_ANDROID)
553 561
554 bool DnsConfigServicePosix::SeenChangeSince( 562 bool DnsConfigServicePosix::SeenChangeSince(
555 const base::Time& since_time) const { 563 const base::Time& since_time) const {
556 DCHECK(CalledOnValidThread()); 564 DCHECK(CalledOnValidThread());
557 if (seen_config_change_) 565 return seen_config_change_;
558 return true;
559 base::File hosts(base::FilePath(file_path_hosts_),
560 base::File::FLAG_OPEN | base::File::FLAG_READ);
561 base::File::Info hosts_info;
562 // File last modified times are not nearly as accurate as Time::Now() and are
563 // rounded down. This means a file modified at 1:23.456 might only
564 // be given a last modified time of 1:23.450. If we compared the last
565 // modified time directly to |since_time| we might miss changes to the hosts
566 // file because of this rounding down. To account for this the |since_time|
567 // is pushed back by 1s which should more than account for any rounding.
568 // In practice file modified times on Android are two orders of magnitude
569 // more accurate than this 1s. In practice the hosts file on Android always
570 // contains "127.0.0.1 localhost" and is never modified after Android is
571 // installed.
572 return !hosts.GetInfo(&hosts_info) ||
573 hosts_info.last_modified >=
574 (since_time - base::TimeDelta::FromSeconds(1));
575 } 566 }
576 567
577 void DnsConfigServicePosix::OnNetworkChanged( 568 void DnsConfigServicePosix::OnNetworkChanged(
578 NetworkChangeNotifier::ConnectionType type) { 569 NetworkChangeNotifier::ConnectionType type) {
579 DCHECK(CalledOnValidThread()); 570 DCHECK(CalledOnValidThread());
580 DCHECK(watcher_); 571 DCHECK(watcher_);
581 watcher_->OnNetworkChanged(type); 572 watcher_->OnNetworkChanged(type);
582 } 573 }
583 #endif // defined(OS_ANDROID) 574 #endif // defined(OS_ANDROID)
584 575
585 } // namespace internal 576 } // namespace internal
586 577
587 // static 578 // static
588 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { 579 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() {
589 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix()); 580 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix());
590 } 581 }
591 582
592 } // namespace net 583 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/dns/dns_config_service_posix_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698