summaryrefslogtreecommitdiffstats
path: root/net/dns/dns_config_service_posix.cc
diff options
context:
space:
mode:
authorszym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-31 19:52:40 +0000
committerszym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-31 19:52:40 +0000
commitbb0e34549798b05741950f793b572e600de0c2cd (patch)
treed8ec98dc3d9378c3036bfa92493ae9b83ea1b92d /net/dns/dns_config_service_posix.cc
parent90c8b9ca6040546b9b08c03188a604a9f348dd89 (diff)
downloadchromium_src-bb0e34549798b05741950f793b572e600de0c2cd.zip
chromium_src-bb0e34549798b05741950f793b572e600de0c2cd.tar.gz
chromium_src-bb0e34549798b05741950f793b572e600de0c2cd.tar.bz2
[net] Move DnsConfigService to NetworkChangeNotifier.
This merges DnsConfigWatcher back into DnsConfigService and installs DnsConfigService at NetworkChangeNotifier. It removes |detail| from OnDNSChanged callback, and exposes NetworkChangeNotifier::GetDnsConfig. BUG=142142 Review URL: https://chromiumcodereview.appspot.com/10873018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154485 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/dns/dns_config_service_posix.cc')
-rw-r--r--net/dns/dns_config_service_posix.cc158
1 files changed, 120 insertions, 38 deletions
diff --git a/net/dns/dns_config_service_posix.cc b/net/dns/dns_config_service_posix.cc
index cd57b44..4dda0fc 100644
--- a/net/dns/dns_config_service_posix.cc
+++ b/net/dns/dns_config_service_posix.cc
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/bind.h"
+#include "base/files/file_path_watcher.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
@@ -17,6 +18,7 @@
#include "net/base/net_util.h"
#include "net/dns/dns_hosts.h"
#include "net/dns/dns_protocol.h"
+#include "net/dns/notify_watcher_mac.h"
#include "net/dns/serial_worker.h"
namespace net {
@@ -26,11 +28,51 @@ namespace internal {
namespace {
+const FilePath::CharType* kFilePathHosts = FILE_PATH_LITERAL("/etc/hosts");
+
+#if defined(OS_MACOSX)
+// From 10.7.3 configd-395.10/dnsinfo/dnsinfo.h
+static const char* kDnsNotifyKey =
+ "com.apple.system.SystemConfiguration.dns_configuration";
+
+class ConfigWatcher {
+ public:
+ bool Watch(const base::Callback<void(bool succeeded)>& callback) {
+ return watcher_.Watch(kDnsNotifyKey, callback);
+ }
+
+ private:
+ NotifyWatcherMac watcher_;
+};
+#else
+
#ifndef _PATH_RESCONF // Normally defined in <resolv.h>
#define _PATH_RESCONF "/etc/resolv.conf"
#endif
-const FilePath::CharType* kFilePathHosts = FILE_PATH_LITERAL("/etc/hosts");
+static const FilePath::CharType* kFilePathConfig =
+ FILE_PATH_LITERAL(_PATH_RESCONF);
+
+class ConfigWatcher {
+ public:
+ typedef base::Callback<void(bool succeeded)> CallbackType;
+
+ bool Watch(const CallbackType& callback) {
+ callback_ = callback;
+ return watcher_.Watch(FilePath(kFilePathConfig),
+ base::Bind(&ConfigWatcher::OnCallback,
+ base::Unretained(this)));
+ }
+
+ private:
+ void OnCallback(const FilePath& path, bool error) {
+ callback_.Run(!error);
+ }
+
+ base::files::FilePathWatcher watcher_;
+ CallbackType callback_;
+};
+#endif
ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) {
ConfigParsePosixResult result;
@@ -63,13 +105,48 @@ ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) {
return result;
}
+} // namespace
+
+class DnsConfigServicePosix::Watcher {
+ public:
+ explicit Watcher(DnsConfigServicePosix* service) : service_(service) {}
+ ~Watcher() {}
+
+ bool Watch() {
+ bool success = true;
+ if (!config_watcher_.Watch(
+ base::Bind(&DnsConfigServicePosix::OnConfigChanged,
+ base::Unretained(service_)))) {
+ LOG(ERROR) << "DNS config watch failed to start.";
+ success = false;
+ }
+ if (!hosts_watcher_.Watch(FilePath(kFilePathHosts),
+ base::Bind(&Watcher::OnHostsChanged,
+ base::Unretained(this)))) {
+ LOG(ERROR) << "DNS hosts watch failed to start.";
+ success = false;
+ }
+ return success;
+ }
+
+ private:
+ void OnHostsChanged(const FilePath& path, bool error) {
+ service_->OnHostsChanged(!error);
+ }
+
+ DnsConfigServicePosix* service_;
+ ConfigWatcher config_watcher_;
+ base::files::FilePathWatcher hosts_watcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(Watcher);
+};
+
// A SerialWorker that uses libresolv to initialize res_state and converts
// it to DnsConfig.
-class ConfigReader : public SerialWorker {
+class DnsConfigServicePosix::ConfigReader : public SerialWorker {
public:
- typedef base::Callback<void(const DnsConfig& config)> CallbackType;
- explicit ConfigReader(const CallbackType& callback)
- : callback_(callback), success_(false) {}
+ explicit ConfigReader(DnsConfigServicePosix* service)
+ : service_(service), success_(false) {}
virtual void DoWork() OVERRIDE {
base::TimeTicks start_time = base::TimeTicks::Now();
@@ -85,7 +162,7 @@ class ConfigReader : public SerialWorker {
virtual void OnWorkFinished() OVERRIDE {
DCHECK(!IsCancelled());
if (success_) {
- callback_.Run(dns_config_);
+ service_->OnConfigRead(dns_config_);
} else {
LOG(WARNING) << "Failed to read DnsConfig.";
}
@@ -94,7 +171,7 @@ class ConfigReader : public SerialWorker {
private:
virtual ~ConfigReader() {}
- const CallbackType callback_;
+ DnsConfigServicePosix* service_;
// Written in DoWork, read in OnWorkFinished, no locking necessary.
DnsConfig dns_config_;
bool success_;
@@ -103,11 +180,10 @@ class ConfigReader : public SerialWorker {
};
// A SerialWorker that reads the HOSTS file and runs Callback.
-class HostsReader : public SerialWorker {
+class DnsConfigServicePosix::HostsReader : public SerialWorker {
public:
- typedef base::Callback<void(const DnsHosts& hosts)> CallbackType;
- explicit HostsReader(const CallbackType& callback)
- : path_(kFilePathHosts), callback_(callback), success_(false) {}
+ explicit HostsReader(DnsConfigServicePosix* service)
+ : service_(service), path_(kFilePathHosts), success_(false) {}
private:
virtual ~HostsReader() {}
@@ -122,12 +198,13 @@ class HostsReader : public SerialWorker {
virtual void OnWorkFinished() OVERRIDE {
if (success_) {
- callback_.Run(hosts_);
+ service_->OnHostsRead(hosts_);
} else {
LOG(WARNING) << "Failed to read DnsHosts.";
}
}
+ DnsConfigServicePosix* service_;
const FilePath path_;
const CallbackType callback_;
// Written in DoWork, read in OnWorkFinished, no locking necessary.
@@ -137,40 +214,43 @@ class HostsReader : public SerialWorker {
DISALLOW_COPY_AND_ASSIGN(HostsReader);
};
-} // namespace
-
-DnsConfigServicePosix::DnsConfigServicePosix() {
- config_reader_ = new ConfigReader(
- base::Bind(&DnsConfigServicePosix::OnConfigRead,
- base::Unretained(this)));
- hosts_reader_ = new HostsReader(
- base::Bind(&DnsConfigServicePosix::OnHostsRead,
- base::Unretained(this)));
-}
+DnsConfigServicePosix::DnsConfigServicePosix()
+ : watcher_(new Watcher(this)),
+ config_reader_(new ConfigReader(this)),
+ hosts_reader_(new HostsReader(this)) {}
DnsConfigServicePosix::~DnsConfigServicePosix() {
config_reader_->Cancel();
hosts_reader_->Cancel();
}
-void DnsConfigServicePosix::OnDNSChanged(unsigned detail) {
- if (detail & NetworkChangeNotifier::CHANGE_DNS_WATCH_FAILED) {
- InvalidateConfig();
- InvalidateHosts();
- // We don't trust a config that we cannot watch in the future.
- config_reader_->Cancel();
- hosts_reader_->Cancel();
- return;
- }
- if (detail & NetworkChangeNotifier::CHANGE_DNS_WATCH_STARTED)
- detail = ~0; // Assume everything changed.
- if (detail & NetworkChangeNotifier::CHANGE_DNS_SETTINGS) {
- InvalidateConfig();
+void DnsConfigServicePosix::ReadNow() {
+ config_reader_->WorkNow();
+ hosts_reader_->WorkNow();
+}
+
+bool DnsConfigServicePosix::StartWatching() {
+ // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
+ return watcher_->Watch();
+}
+
+void DnsConfigServicePosix::OnConfigChanged(bool succeeded) {
+ InvalidateConfig();
+ if (succeeded) {
config_reader_->WorkNow();
+ } else {
+ LOG(ERROR) << "DNS config watch failed.";
+ set_watch_failed(true);
}
- if (detail & NetworkChangeNotifier::CHANGE_DNS_HOSTS) {
- InvalidateHosts();
+}
+
+void DnsConfigServicePosix::OnHostsChanged(bool succeeded) {
+ InvalidateHosts();
+ if (succeeded) {
hosts_reader_->WorkNow();
+ } else {
+ LOG(ERROR) << "DNS hosts watch failed.";
+ set_watch_failed(true);
}
}
@@ -283,7 +363,9 @@ class StubDnsConfigService : public DnsConfigService {
public:
StubDnsConfigService() {}
virtual ~StubDnsConfigService() {}
- virtual void OnDNSChanged(unsigned detail) OVERRIDE {}
+ private:
+ virtual void ReadNow() OVERRIDE {}
+ virtual bool StartWatching() OVERRIDE { return false; }
};
// static
scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() {