#include "net/base/dns_reloader.h"
#include "net/base/dns_util.h"
#include "net/base/host_port_pair.h"
+#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/base/net_util.h"
rv = socket->GetLocalAddress(&endpoint);
if (rv != OK)
return false;
- DCHECK(endpoint.GetFamily() == ADDRESS_FAMILY_IPV6);
+ DCHECK_EQ(ADDRESS_FAMILY_IPV6, endpoint.GetFamily());
const IPAddressNumber& address = endpoint.address();
bool is_link_local = (address[0] == 0xFE) && ((address[1] & 0xC0) == 0x80);
if (is_link_local)
DCHECK(!is_queued());
PrioritizedDispatcher::Handle handle;
if (!at_head) {
- handle = resolver_->dispatcher_.Add(this, priority());
+ handle = resolver_->dispatcher_->Add(this, priority());
} else {
- handle = resolver_->dispatcher_.AddAtHead(this, priority());
+ handle = resolver_->dispatcher_->AddAtHead(this, priority());
}
// The dispatcher could have started |this| in the above call to Add, which
// could have called Schedule again. In that case |handle| will be null,
void ReduceToOneJobSlot() {
DCHECK_GE(num_occupied_job_slots_, 1u);
if (is_queued()) {
- resolver_->dispatcher_.Cancel(handle_);
+ resolver_->dispatcher_->Cancel(handle_);
handle_.Reset();
} else if (num_occupied_job_slots_ > 1) {
- resolver_->dispatcher_.OnJobFinished();
+ resolver_->dispatcher_->OnJobFinished();
--num_occupied_job_slots_;
}
DCHECK_EQ(1u, num_occupied_job_slots_);
if (is_queued()) {
if (priority() != static_cast<RequestPriority>(handle_.priority()))
priority_change_time_ = base::TimeTicks::Now();
- handle_ = resolver_->dispatcher_.ChangePriority(handle_, priority());
+ handle_ = resolver_->dispatcher_->ChangePriority(handle_, priority());
}
}
KillDnsTask();
// Signal dispatcher that a slot has opened.
- resolver_->dispatcher_.OnJobFinished();
+ resolver_->dispatcher_->OnJobFinished();
} else if (is_queued()) {
- resolver_->dispatcher_.Cancel(handle_);
+ resolver_->dispatcher_->Cancel(handle_);
handle_.Reset();
}
max_retry_attempts(max_retry_attempts),
unresponsive_delay(base::TimeDelta::FromMilliseconds(6000)),
retry_factor(2) {
+ // Maximum of 4 retry attempts for host resolution.
+ static const size_t kDefaultMaxRetryAttempts = 4u;
+ if (max_retry_attempts == HostResolver::kDefaultRetryAttempts)
+ max_retry_attempts = kDefaultMaxRetryAttempts;
}
HostResolverImpl::ProcTaskParams::~ProcTaskParams() {}
-HostResolverImpl::HostResolverImpl(
- scoped_ptr<HostCache> cache,
- const PrioritizedDispatcher::Limits& job_limits,
- const ProcTaskParams& proc_params,
- NetLog* net_log)
- : cache_(cache.Pass()),
- dispatcher_(job_limits),
- max_queued_jobs_(job_limits.total_jobs * 100u),
- proc_params_(proc_params),
+HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log)
+ : max_queued_jobs_(0),
+ proc_params_(NULL, options.max_retry_attempts),
net_log_(net_log),
default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
- weak_ptr_factory_(this),
- probe_weak_ptr_factory_(this),
received_dns_config_(false),
num_dns_failures_(0),
probe_ipv6_support_(true),
use_local_ipv6_(false),
resolved_known_ipv6_hostname_(false),
additional_resolver_flags_(0),
- fallback_to_proctask_(true) {
+ fallback_to_proctask_(true),
+ weak_ptr_factory_(this),
+ probe_weak_ptr_factory_(this) {
+ if (options.enable_caching)
+ cache_ = HostCache::CreateDefaultCache();
- DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES));
+ PrioritizedDispatcher::Limits job_limits = options.GetDispatcherLimits();
+ dispatcher_.reset(new PrioritizedDispatcher(job_limits));
+ max_queued_jobs_ = job_limits.total_jobs * 100u;
- // Maximum of 4 retry attempts for host resolution.
- static const size_t kDefaultMaxRetryAttempts = 4u;
-
- if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts)
- proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts;
+ DCHECK_GE(dispatcher_->num_priorities(), static_cast<size_t>(NUM_PRIORITIES));
#if defined(OS_WIN)
EnsureWinsockInit();
HostResolverImpl::~HostResolverImpl() {
// Prevent the dispatcher from starting new jobs.
- dispatcher_.SetLimitsToZero();
+ dispatcher_->SetLimitsToZero();
// It's now safe for Jobs to call KillDsnTask on destruction, because
// OnJobComplete will not start any new jobs.
STLDeleteValues(&jobs_);
}
void HostResolverImpl::SetMaxQueuedJobs(size_t value) {
- DCHECK_EQ(0u, dispatcher_.num_queued_jobs());
+ DCHECK_EQ(0u, dispatcher_->num_queued_jobs());
DCHECK_GT(value, 0u);
max_queued_jobs_ = value;
}
job->Schedule(false);
// Check for queue overflow.
- if (dispatcher_.num_queued_jobs() > max_queued_jobs_) {
- Job* evicted = static_cast<Job*>(dispatcher_.EvictOldestLowest());
+ if (dispatcher_->num_queued_jobs() > max_queued_jobs_) {
+ Job* evicted = static_cast<Job*>(dispatcher_->EvictOldestLowest());
DCHECK(evicted);
evicted->OnEvicted(); // Deletes |evicted|.
if (evicted == job) {
~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY |
HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6),
0) << " Unhandled flag";
- bool ipv6_disabled = (default_address_family_ == ADDRESS_FAMILY_IPV4) &&
- !probe_ipv6_support_;
+
*net_error = OK;
- if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) {
+ AddressFamily family = GetAddressFamily(ip_number);
+ if (family == ADDRESS_FAMILY_IPV6 &&
+ !probe_ipv6_support_ &&
+ default_address_family_ == ADDRESS_FAMILY_IPV4) {
+ // Don't return IPv6 addresses if default address family is set to IPv4,
+ // and probes are disabled.
+ *net_error = ERR_NAME_NOT_RESOLVED;
+ } else if (key.address_family != ADDRESS_FAMILY_UNSPECIFIED &&
+ key.address_family != family) {
+ // Don't return IPv6 addresses for IPv4 queries, and vice versa.
*net_error = ERR_NAME_NOT_RESOLVED;
} else {
*addresses = AddressList::CreateFromIPAddress(ip_number, info.port());
addresses->clear();
// HOSTS lookups are case-insensitive.
- std::string hostname = StringToLowerASCII(key.hostname);
+ std::string hostname = base::StringToLowerASCII(key.hostname);
const DnsHosts& hosts = dns_client_->GetConfig()->hosts;
// aborting the old ones. This is needed so that it won't start the second
// DnsTransaction for a job in |jobs_to_abort| if the DnsConfig just became
// invalid.
- PrioritizedDispatcher::Limits limits = dispatcher_.GetLimits();
- dispatcher_.SetLimits(
+ PrioritizedDispatcher::Limits limits = dispatcher_->GetLimits();
+ dispatcher_->SetLimits(
PrioritizedDispatcher::Limits(limits.reserved_slots.size(), 0));
// Life check to bail once |this| is deleted.
}
if (self)
- dispatcher_.SetLimits(limits);
+ dispatcher_->SetLimits(limits);
}
void HostResolverImpl::AbortDnsTasks() {
// Pause the dispatcher so it won't start any new dispatcher jobs while
// aborting the old ones. This is needed so that it won't start the second
// DnsTransaction for a job if the DnsConfig just changed.
- PrioritizedDispatcher::Limits limits = dispatcher_.GetLimits();
- dispatcher_.SetLimits(
+ PrioritizedDispatcher::Limits limits = dispatcher_->GetLimits();
+ dispatcher_->SetLimits(
PrioritizedDispatcher::Limits(limits.reserved_slots.size(), 0));
for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
it->second->AbortDnsTask();
- dispatcher_.SetLimits(limits);
+ dispatcher_->SetLimits(limits);
}
void HostResolverImpl::TryServingAllJobsFromHosts() {