| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/dns/dns_config_service.h" |
| |
| #include "base/file_util.h" |
| #include "net/base/ip_endpoint.h" |
| |
| namespace net { |
| |
| // Default values are taken from glibc resolv.h. |
| DnsConfig::DnsConfig() |
| : ndots(1), |
| timeout(base::TimeDelta::FromSeconds(5)), |
| attempts(2), |
| rotate(false), |
| edns0(false) {} |
| |
| DnsConfig::~DnsConfig() {} |
| |
| bool DnsConfig::EqualsIgnoreHosts(const DnsConfig& d) const { |
| return (nameservers == d.nameservers) && |
| (search == d.search) && |
| (ndots == d.ndots) && |
| (timeout == d.timeout) && |
| (attempts == d.attempts) && |
| (rotate == d.rotate) && |
| (edns0 == d.edns0); |
| } |
| |
| bool DnsConfig::Equals(const DnsConfig& d) const { |
| return EqualsIgnoreHosts(d) && (hosts == d.hosts); |
| } |
| |
| DnsConfigService::DnsConfigService() |
| : have_config_(false), |
| have_hosts_(false) {} |
| |
| DnsConfigService::~DnsConfigService() {} |
| |
| void DnsConfigService::AddObserver(Observer* observer) { |
| DCHECK(CalledOnValidThread()); |
| observers_.AddObserver(observer); |
| if (have_config_ && have_hosts_) { |
| observer->OnConfigChanged(dns_config_); |
| } |
| } |
| |
| void DnsConfigService::RemoveObserver(Observer* observer) { |
| DCHECK(CalledOnValidThread()); |
| observers_.RemoveObserver(observer); |
| } |
| |
| void DnsConfigService::OnConfigRead(const DnsConfig& config) { |
| DCHECK(CalledOnValidThread()); |
| if (!config.EqualsIgnoreHosts(dns_config_)) { |
| DnsHosts current_hosts = dns_config_.hosts; |
| dns_config_ = config; |
| dns_config_.hosts.swap(current_hosts); |
| have_config_ = true; |
| if (have_hosts_) { |
| FOR_EACH_OBSERVER(Observer, observers_, OnConfigChanged(dns_config_)); |
| } |
| } |
| } |
| |
| void DnsConfigService::OnHostsRead(const DnsHosts& hosts) { |
| DCHECK(CalledOnValidThread()); |
| if (hosts != dns_config_.hosts || !have_hosts_) { |
| dns_config_.hosts = hosts; |
| have_hosts_ = true; |
| if (have_config_) { |
| FOR_EACH_OBSERVER(Observer, observers_, OnConfigChanged(dns_config_)); |
| } |
| } |
| } |
| |
| DnsHostsReader::DnsHostsReader(const FilePath& path, DnsConfigService* service) |
| : path_(path), |
| service_(service), |
| success_(false) { |
| DCHECK(service); |
| } |
| |
| // Reads the contents of the file at |path| into |str| if the total length is |
| // less than |size|. |
| static bool ReadFile(const FilePath& path, int64 size, std::string* str) { |
| int64 sz; |
| if (!file_util::GetFileSize(path, &sz) || sz > size) |
| return false; |
| return file_util::ReadFileToString(path, str); |
| } |
| |
| void DnsHostsReader::DoWork() { |
| success_ = false; |
| std::string contents; |
| const int64 kMaxHostsSize = 1 << 16; |
| if (ReadFile(path_, kMaxHostsSize, &contents)) { |
| success_ = true; |
| ParseHosts(contents, &dns_hosts_); |
| } |
| } |
| |
| void DnsHostsReader::OnWorkFinished() { |
| DCHECK(!IsCancelled()); |
| if (success_) |
| service_->OnHostsRead(dns_hosts_); |
| } |
| |
| DnsHostsReader::~DnsHostsReader() {} |
| |
| } // namespace net |
| |