Commit fac52799 authored by Eric Orth's avatar Eric Orth Committed by Commit Bot

Add new ResolveHost API.

Primarily an interface-only change. Only change past the interface level
of the stack was to internally pass rawer information rather than
use RequestInfo as that struct is specific to the old Resolve API.

Only handles the basic case for now (HostPortPair input without any
significant options), but additional funtionality will be added in
subsequent changes.

Copy and convert all the unittests that can be implemented using the new
method with its current basic functionality. If we ever convert all
usage to the new method and delete the old, we'll be able to cleanly
delete all the old tests.

Design doc:
https://docs.google.com/document/d/1NmADJX00oRe9TxFCJTWl8ofdfyR22pbKT8-5Ad5lBsU

Bug: 821021
Cq-Include-Trybots: luci.chromium.try:linux_mojo;master.tryserver.chromium.android:android_cronet_tester;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I4fe454761e2930d6f235e8e505b689f8917fdeed
Reviewed-on: https://chromium-review.googlesource.com/1099427
Commit-Queue: Eric Orth <ericorth@chromium.org>
Reviewed-by: default avatarHelen Li <xunjieli@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575065}
parent 0551f0d9
...@@ -381,6 +381,14 @@ StaleHostResolver::StaleHostResolver( ...@@ -381,6 +381,14 @@ StaleHostResolver::StaleHostResolver(
StaleHostResolver::~StaleHostResolver() {} StaleHostResolver::~StaleHostResolver() {}
std::unique_ptr<net::HostResolver::ResolveHostRequest>
StaleHostResolver::CreateRequest(const net::HostPortPair& host,
const net::NetLogWithSource& net_log) {
// TODO(crbug.com/821021): Implement.
NOTIMPLEMENTED();
return nullptr;
}
int StaleHostResolver::Resolve(const RequestInfo& info, int StaleHostResolver::Resolve(const RequestInfo& info,
net::RequestPriority priority, net::RequestPriority priority,
net::AddressList* addresses, net::AddressList* addresses,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef COMPONENTS_CRONET_STALE_HOST_RESOLVER_H_ #ifndef COMPONENTS_CRONET_STALE_HOST_RESOLVER_H_
#define COMPONENTS_CRONET_STALE_HOST_RESOLVER_H_ #define COMPONENTS_CRONET_STALE_HOST_RESOLVER_H_
#include <memory>
#include <unordered_set> #include <unordered_set>
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
...@@ -61,6 +62,10 @@ class StaleHostResolver : public net::HostResolver { ...@@ -61,6 +62,10 @@ class StaleHostResolver : public net::HostResolver {
// HostResolver implementation: // HostResolver implementation:
std::unique_ptr<ResolveHostRequest> CreateRequest(
const net::HostPortPair& host,
const net::NetLogWithSource& net_log) override;
// Resolves as a regular HostResolver, but if stale data is available and // Resolves as a regular HostResolver, but if stale data is available and
// usable (according to the options passed to the constructor), and fresh data // usable (according to the options passed to the constructor), and fresh data
// is not returned before the specified delay, returns the stale data instead. // is not returned before the specified delay, returns the stale data instead.
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
#include "net/base/address_family.h" #include "net/base/address_family.h"
#include "net/base/completion_once_callback.h" #include "net/base/completion_once_callback.h"
...@@ -45,6 +46,9 @@ class NET_EXPORT HostResolver { ...@@ -45,6 +46,9 @@ class NET_EXPORT HostResolver {
public: public:
// HostResolver::Request class is used to cancel the request and change it's // HostResolver::Request class is used to cancel the request and change it's
// priority. It must be owned by consumer. Deletion cancels the request. // priority. It must be owned by consumer. Deletion cancels the request.
//
// TODO(crbug.com/821021): Delete this class once all usage has been
// converted to the new CreateRequest() API.
class Request { class Request {
public: public:
virtual ~Request() {} virtual ~Request() {}
...@@ -55,6 +59,41 @@ class NET_EXPORT HostResolver { ...@@ -55,6 +59,41 @@ class NET_EXPORT HostResolver {
virtual void ChangeRequestPriority(RequestPriority priority) = 0; virtual void ChangeRequestPriority(RequestPriority priority) = 0;
}; };
// Handler for an individual host resolution request. Created by
// HostResolver::CreateRequest().
class ResolveHostRequest {
public:
// Destruction cancels the request if running asynchronously, causing the
// callback to never be invoked.
virtual ~ResolveHostRequest() {}
// Starts the request and returns a network error code.
//
// If the request could not be handled synchronously, returns
// |ERR_IO_PENDING|, and completion will be signaled later via |callback|.
// On any other returned value, the request was handled synchronously and
// |callback| will not be invoked.
//
// Results in ERR_NAME_NOT_RESOLVED if the hostname is invalid, or if it is
// an incompatible IP literal (e.g. IPv6 is disabled and it is an IPv6
// literal).
//
// The parent HostResolver must still be alive when Start() is called, but
// if it is destroyed before an asynchronous result completes, the request
// will be automatically cancelled.
//
// If cancelled before |callback| is invoked, it will never be invoked.
virtual int Start(CompletionOnceCallback callback) = 0;
// Result of the request. Should only be called after Start() signals
// completion, either by invoking the callback or by returning a result
// other than |ERR_IO_PENDING|.
//
// TODO(crbug.com/821021): Implement other GetResults() methods for requests
// that return other data (eg DNS TXT requests).
virtual const base::Optional<AddressList>& GetAddressResults() const = 0;
};
// |max_concurrent_resolves| is how many resolve requests will be allowed to // |max_concurrent_resolves| is how many resolve requests will be allowed to
// run in parallel. Pass HostResolver::kDefaultParallelism to choose a // run in parallel. Pass HostResolver::kDefaultParallelism to choose a
// default value. // default value.
...@@ -144,6 +183,21 @@ class NET_EXPORT HostResolver { ...@@ -144,6 +183,21 @@ class NET_EXPORT HostResolver {
// be called. // be called.
virtual ~HostResolver(); virtual ~HostResolver();
// Creates a request to resolve the given hostname (or IP address literal).
// Profiling information for the request is saved to |net_log| if non-NULL.
//
// This method is intended as a direct replacement for the old Resolve()
// method, but it may not yet cover all the capabilities of the old method.
//
// TODO(crbug.com/821021): Implement more complex functionality to meet
// capabilities of Resolve() and M/DnsClient functionality.
virtual std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) = 0;
// DEPRECATION NOTE: This method is being replaced by CreateRequest(). New
// callers should prefer CreateRequest() if it works for their needs.
//
// Resolves the given hostname (or IP address literal), filling out the // Resolves the given hostname (or IP address literal), filling out the
// |addresses| object upon success. The |info.port| parameter will be set as // |addresses| object upon success. The |info.port| parameter will be set as
// the sin(6)_port field of the sockaddr_in{6} struct. Returns OK if // the sin(6)_port field of the sockaddr_in{6} struct. Returns OK if
...@@ -165,6 +219,9 @@ class NET_EXPORT HostResolver { ...@@ -165,6 +219,9 @@ class NET_EXPORT HostResolver {
// |out_req| will cancel the request, and cause |callback| not to be invoked. // |out_req| will cancel the request, and cause |callback| not to be invoked.
// //
// Profiling information for the request is saved to |net_log| if non-NULL. // Profiling information for the request is saved to |net_log| if non-NULL.
//
// TODO(crbug.com/821021): Delete this method once all usage has been
// converted to ResolveHost().
virtual int Resolve(const RequestInfo& info, virtual int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
#endif // !defined(OS_NACL) #endif // !defined(OS_NACL)
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
#include <algorithm>
#include <cmath> #include <cmath>
#include <limits>
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <vector> #include <vector>
...@@ -425,7 +427,8 @@ std::unique_ptr<base::Value> NetLogDnsTaskFailedCallback( ...@@ -425,7 +427,8 @@ std::unique_ptr<base::Value> NetLogDnsTaskFailedCallback(
} }
// Creates NetLog parameters containing the information in a RequestInfo object, // Creates NetLog parameters containing the information in a RequestInfo object,
// along with the associated NetLogSource. // along with the associated NetLogSource. Use NetLogRequestCallback() if the
// request information is not specified via RequestInfo.
std::unique_ptr<base::Value> NetLogRequestInfoCallback( std::unique_ptr<base::Value> NetLogRequestInfoCallback(
const HostResolver::RequestInfo* info, const HostResolver::RequestInfo* info,
NetLogCaptureMode /* capture_mode */) { NetLogCaptureMode /* capture_mode */) {
...@@ -439,12 +442,27 @@ std::unique_ptr<base::Value> NetLogRequestInfoCallback( ...@@ -439,12 +442,27 @@ std::unique_ptr<base::Value> NetLogRequestInfoCallback(
return std::move(dict); return std::move(dict);
} }
// Creates NetLog parameters containing the information of the request. Use
// NetLogRequestInfoCallback if the request is specified via RequestInfo.
std::unique_ptr<base::Value> NetLogRequestCallback(
const HostPortPair& host,
NetLogCaptureMode /* capture_mode */) {
auto dict = std::make_unique<base::DictionaryValue>();
dict->SetString("host", host.ToString());
dict->SetInteger("address_family",
static_cast<int>(ADDRESS_FAMILY_UNSPECIFIED));
dict->SetBoolean("allow_cached_response", true);
dict->SetBoolean("is_speculative", false);
return std::move(dict);
}
// Creates NetLog parameters for the creation of a HostResolverImpl::Job. // Creates NetLog parameters for the creation of a HostResolverImpl::Job.
std::unique_ptr<base::Value> NetLogJobCreationCallback( std::unique_ptr<base::Value> NetLogJobCreationCallback(
const NetLogSource& source, const NetLogSource& source,
const std::string* host, const std::string* host,
NetLogCaptureMode /* capture_mode */) { NetLogCaptureMode /* capture_mode */) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); auto dict = std::make_unique<base::DictionaryValue>();
source.AddToEventParameters(dict.get()); source.AddToEventParameters(dict.get());
dict->SetString("host", *host); dict->SetString("host", *host);
return std::move(dict); return std::move(dict);
...@@ -481,24 +499,27 @@ std::unique_ptr<base::Value> NetLogIPv6AvailableCallback( ...@@ -481,24 +499,27 @@ std::unique_ptr<base::Value> NetLogIPv6AvailableCallback(
// The logging routines are defined here because some requests are resolved // The logging routines are defined here because some requests are resolved
// without a Request object. // without a Request object.
// Logs when a request has just been started. // Logs when a request has just been started. Overloads for whether or not the
// request information is specified via a RequestInfo object.
void LogStartRequest(const NetLogWithSource& source_net_log, void LogStartRequest(const NetLogWithSource& source_net_log,
const HostResolver::RequestInfo& info) { const HostResolver::RequestInfo& info) {
source_net_log.BeginEvent(NetLogEventType::HOST_RESOLVER_IMPL_REQUEST, source_net_log.BeginEvent(NetLogEventType::HOST_RESOLVER_IMPL_REQUEST,
base::Bind(&NetLogRequestInfoCallback, &info)); base::Bind(&NetLogRequestInfoCallback, &info));
} }
void LogStartRequest(const NetLogWithSource& source_net_log,
const HostPortPair& host) {
source_net_log.BeginEvent(NetLogEventType::HOST_RESOLVER_IMPL_REQUEST,
base::BindRepeating(&NetLogRequestCallback, host));
}
// Logs when a request has just completed (before its callback is run). // Logs when a request has just completed (before its callback is run).
void LogFinishRequest(const NetLogWithSource& source_net_log, void LogFinishRequest(const NetLogWithSource& source_net_log, int net_error) {
const HostResolver::RequestInfo& info,
int net_error) {
source_net_log.EndEventWithNetErrorCode( source_net_log.EndEventWithNetErrorCode(
NetLogEventType::HOST_RESOLVER_IMPL_REQUEST, net_error); NetLogEventType::HOST_RESOLVER_IMPL_REQUEST, net_error);
} }
// Logs when a request has been cancelled. // Logs when a request has been cancelled.
void LogCancelRequest(const NetLogWithSource& source_net_log, void LogCancelRequest(const NetLogWithSource& source_net_log) {
const HostResolverImpl::RequestInfo& info) {
source_net_log.AddEvent(NetLogEventType::CANCELLED); source_net_log.AddEvent(NetLogEventType::CANCELLED);
source_net_log.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_REQUEST); source_net_log.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_REQUEST);
} }
...@@ -591,83 +612,242 @@ const unsigned HostResolverImpl::kMaximumDnsFailures = 16; ...@@ -591,83 +612,242 @@ const unsigned HostResolverImpl::kMaximumDnsFailures = 16;
// cancellation is initiated by the Job (OnJobCancelled) vs by the end user // cancellation is initiated by the Job (OnJobCancelled) vs by the end user
// (~RequestImpl). // (~RequestImpl).
class HostResolverImpl::RequestImpl class HostResolverImpl::RequestImpl
: public HostResolver::Request, : public HostResolver::ResolveHostRequest,
public base::LinkNode<HostResolverImpl::RequestImpl> { public base::LinkNode<HostResolverImpl::RequestImpl> {
public: public:
RequestImpl(const NetLogWithSource& source_net_log, RequestImpl(const NetLogWithSource& source_net_log,
const RequestInfo& info, const HostPortPair& request_host,
bool is_speculative,
RequestPriority priority, RequestPriority priority,
CompletionOnceCallback callback, base::WeakPtr<HostResolverImpl> resolver)
AddressList* addresses, : RequestImpl(source_net_log,
Job* job, request_host,
base::TimeTicks request_time) ADDRESS_FAMILY_UNSPECIFIED,
0 /* host_resolver_flags */,
true /* allow_cached_response */,
is_speculative,
priority,
resolver) {}
// Overload for use by the legacy Resolve() API. Has more advanced parameters
// not yet supported by the CreateRequest() API.
RequestImpl(const NetLogWithSource& source_net_log,
const HostPortPair& request_host,
AddressFamily address_family,
HostResolverFlags host_resolver_flags,
bool allow_cached_response,
bool is_speculative,
RequestPriority priority,
base::WeakPtr<HostResolverImpl> resolver)
: source_net_log_(source_net_log), : source_net_log_(source_net_log),
info_(info), request_host_(request_host),
address_family_(address_family),
host_resolver_flags_(host_resolver_flags),
allow_cached_response_(allow_cached_response),
is_speculative_(is_speculative),
priority_(priority), priority_(priority),
job_(job), job_(nullptr),
callback_(std::move(callback)), resolver_(resolver),
addresses_(addresses), complete_(false) {}
request_time_(request_time) {}
~RequestImpl() override; ~RequestImpl() override;
void ChangeRequestPriority(RequestPriority priority) override; int Start(CompletionOnceCallback callback) override {
DCHECK(callback);
// Start() may only be called once per request.
DCHECK(!job_);
DCHECK(!complete_);
DCHECK(!callback_);
// Parent HostResolver must still be alive to call Start().
DCHECK(resolver_);
int rv = resolver_->Resolve(this);
DCHECK(!complete_);
if (rv == ERR_IO_PENDING) {
DCHECK(job_);
callback_ = std::move(callback);
} else {
DCHECK(!job_);
complete_ = true;
}
resolver_ = nullptr;
return rv;
}
const base::Optional<AddressList>& GetAddressResults() const override {
DCHECK(complete_);
return address_results_;
}
void set_address_results(const AddressList& address_results) {
// Should only be called at most once and before request is marked
// completed.
DCHECK(!complete_);
DCHECK(!address_results_);
address_results_ = address_results;
}
void ChangeRequestPriority(RequestPriority priority);
void AssignJob(Job* job) {
DCHECK(job);
DCHECK(!job_);
job_ = job;
}
// Unassigns the Job without calling completion callback.
void OnJobCancelled(Job* job) { void OnJobCancelled(Job* job) {
DCHECK_EQ(job_, job); DCHECK_EQ(job_, job);
job_ = nullptr; job_ = nullptr;
addresses_ = nullptr; DCHECK(!complete_);
DCHECK(callback_);
callback_.Reset(); callback_.Reset();
// No results should be set.
DCHECK(!address_results_);
} }
// Prepare final AddressList and call completion callback. // Cleans up Job assignment, marks request completed, and calls the completion
void OnJobCompleted(Job* job, int error, const AddressList& addr_list) { // callback.
void OnJobCompleted(Job* job, int error) {
DCHECK_EQ(job_, job); DCHECK_EQ(job_, job);
if (error == OK)
*addresses_ = EnsurePortOnAddressList(addr_list, info_.port());
job_ = nullptr; job_ = nullptr;
addresses_ = nullptr;
DCHECK(!complete_);
complete_ = true;
DCHECK(callback_);
std::move(callback_).Run(error); std::move(callback_).Run(error);
} }
Job* job() const { Job* job() const { return job_; }
return job_;
}
// NetLog for the source, passed in HostResolver::Resolve. // NetLog for the source, passed in HostResolver::Resolve.
const NetLogWithSource& source_net_log() { return source_net_log_; } const NetLogWithSource& source_net_log() { return source_net_log_; }
const RequestInfo& info() const { const HostPortPair& request_host() const { return request_host_; }
return info_;
} AddressFamily address_family() const { return address_family_; }
HostResolverFlags host_resolver_flags() const { return host_resolver_flags_; }
bool allow_cached_response() const { return allow_cached_response_; }
bool is_speculative() const { return is_speculative_; }
RequestPriority priority() const { return priority_; } RequestPriority priority() const { return priority_; }
void set_priority(RequestPriority priority) { priority_ = priority; } void set_priority(RequestPriority priority) { priority_ = priority; }
base::TimeTicks request_time() const { return request_time_; } bool complete() const { return complete_; }
base::TimeTicks request_time() const {
DCHECK(!request_time_.is_null());
return request_time_;
}
void set_request_time(base::TimeTicks request_time) {
DCHECK(request_time_.is_null());
DCHECK(!request_time.is_null());
request_time_ = request_time;
}
private: private:
const NetLogWithSource source_net_log_; const NetLogWithSource source_net_log_;
// The request info that started the request. const HostPortPair request_host_;
const RequestInfo info_; const AddressFamily address_family_;
const HostResolverFlags host_resolver_flags_;
const bool allow_cached_response_;
const bool is_speculative_;
RequestPriority priority_; RequestPriority priority_;
// The resolve job that this request is dependent on. // The resolve job that this request is dependent on.
Job* job_; Job* job_;
base::WeakPtr<HostResolverImpl> resolver_;
// The user's callback to invoke when the request completes. // The user's callback to invoke when the request completes.
CompletionOnceCallback callback_; CompletionOnceCallback callback_;
// The address list to save result into. bool complete_;
AddressList* addresses_; base::Optional<AddressList> address_results_;
const base::TimeTicks request_time_; base::TimeTicks request_time_;
DISALLOW_COPY_AND_ASSIGN(RequestImpl); DISALLOW_COPY_AND_ASSIGN(RequestImpl);
}; };
// Wraps a RequestImpl to implement Request objects from the legacy Resolve()
// API. The wrapped request must not yet have been started.
//
// TODO(crbug.com/821021): Delete this class once all usage has been
// converted to the new CreateRequest() API.
class HostResolverImpl::LegacyRequestImpl : public HostResolver::Request {
public:
explicit LegacyRequestImpl(std::unique_ptr<RequestImpl> inner_request)
: inner_request_(std::move(inner_request)) {
DCHECK(!inner_request_->job());
DCHECK(!inner_request_->complete());
}
~LegacyRequestImpl() override {}
void ChangeRequestPriority(RequestPriority priority) override {
inner_request_->ChangeRequestPriority(priority);
}
int Start() {
return inner_request_->Start(base::BindOnce(
&LegacyRequestImpl::LegacyApiCallback, base::Unretained(this)));
}
// Do not call to assign the callback until we are running an async job (after
// Start() returns ERR_IO_PENDING) and before completion. Until then, the
// legacy HostResolverImpl::Resolve() needs to hang onto |callback| to ensure
// it stays alive for the duration of the method call, as some callers may be
// binding objects, eg the AddressList, with the callback.
void AssignCallback(CompletionOnceCallback callback,
AddressList* addresses_result_ptr) {
DCHECK(callback);
DCHECK(addresses_result_ptr);
DCHECK(inner_request_->job());
DCHECK(!inner_request_->complete());
callback_ = std::move(callback);
addresses_result_ptr_ = addresses_result_ptr;
}
const RequestImpl& inner_request() const { return *inner_request_; }
private:
// Result callback to bridge results handled entirely via ResolveHostRequest
// to legacy API styles where AddressList was a separate method out parameter.
void LegacyApiCallback(int error) {
// Must call AssignCallback() before async results.
DCHECK(callback_);
if (error == OK) {
// Legacy API does not allow non-address results (eg TXT), so AddressList
// is always expected to be present on OK.
DCHECK(inner_request_->GetAddressResults());
*addresses_result_ptr_ = inner_request_->GetAddressResults().value();
}
addresses_result_ptr_ = nullptr;
std::move(callback_).Run(error);
}
const std::unique_ptr<RequestImpl> inner_request_;
CompletionOnceCallback callback_;
// This is a caller-provided pointer and should not be used once |callback_|
// is invoked.
AddressList* addresses_result_ptr_;
DISALLOW_COPY_AND_ASSIGN(LegacyRequestImpl);
};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Calls HostResolverProc in TaskScheduler. Performs retries if necessary. // Calls HostResolverProc in TaskScheduler. Performs retries if necessary.
...@@ -843,10 +1023,10 @@ class HostResolverImpl::ProcTask { ...@@ -843,10 +1023,10 @@ class HostResolverImpl::ProcTask {
NetLogParametersCallback net_log_callback; NetLogParametersCallback net_log_callback;
NetLogParametersCallback attempt_net_log_callback; NetLogParametersCallback attempt_net_log_callback;
if (error != OK) { if (error != OK) {
net_log_callback = base::Bind(&NetLogProcTaskFailedCallback, net_log_callback = base::BindRepeating(&NetLogProcTaskFailedCallback, 0,
0, error, os_error); error, os_error);
attempt_net_log_callback = base::Bind(&NetLogProcTaskFailedCallback, attempt_net_log_callback = base::BindRepeating(
attempt_number, error, os_error); &NetLogProcTaskFailedCallback, attempt_number, error, os_error);
} else { } else {
net_log_callback = results.CreateNetLogCallback(); net_log_callback = results.CreateNetLogCallback();
attempt_net_log_callback = attempt_net_log_callback =
...@@ -1237,7 +1417,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1237,7 +1417,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
RequestImpl* req = requests_.head()->value(); RequestImpl* req = requests_.head()->value();
req->RemoveFromList(); req->RemoveFromList();
DCHECK_EQ(this, req->job()); DCHECK_EQ(this, req->job());
LogCancelRequest(req->source_net_log(), req->info()); LogCancelRequest(req->source_net_log());
req->OnJobCancelled(this); req->OnJobCancelled(this);
} }
} }
...@@ -1262,7 +1442,9 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1262,7 +1442,9 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
} }
void AddRequest(RequestImpl* request) { void AddRequest(RequestImpl* request) {
DCHECK_EQ(key_.hostname, request->info().hostname()); DCHECK_EQ(key_.hostname, request->request_host().host());
request->AssignJob(this);
priority_tracker_.Add(request->priority()); priority_tracker_.Add(request->priority());
...@@ -1275,7 +1457,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1275,7 +1457,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
base::Bind(&NetLogJobAttachCallback, request->source_net_log().source(), base::Bind(&NetLogJobAttachCallback, request->source_net_log().source(),
priority())); priority()));
if (!request->info().is_speculative()) if (!request->is_speculative())
had_non_speculative_request_ = true; had_non_speculative_request_ = true;
requests_.Append(request); requests_.Append(request);
...@@ -1284,7 +1466,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1284,7 +1466,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
} }
void ChangeRequestPriority(RequestImpl* req, RequestPriority priority) { void ChangeRequestPriority(RequestImpl* req, RequestPriority priority) {
DCHECK_EQ(key_.hostname, req->info().hostname()); DCHECK_EQ(key_.hostname, req->request_host().host());
priority_tracker_.Remove(req->priority()); priority_tracker_.Remove(req->priority());
req->set_priority(priority); req->set_priority(priority);
...@@ -1295,10 +1477,10 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1295,10 +1477,10 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
// Detach cancelled request. If it was the last active Request, also finishes // Detach cancelled request. If it was the last active Request, also finishes
// this Job. // this Job.
void CancelRequest(RequestImpl* request) { void CancelRequest(RequestImpl* request) {
DCHECK_EQ(key_.hostname, request->info().hostname()); DCHECK_EQ(key_.hostname, request->request_host().host());
DCHECK(!requests_.empty()); DCHECK(!requests_.empty());
LogCancelRequest(request->source_net_log(), request->info()); LogCancelRequest(request->source_net_log());
priority_tracker_.Remove(request->priority()); priority_tracker_.Remove(request->priority());
net_log_.AddEvent( net_log_.AddEvent(
...@@ -1352,8 +1534,9 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1352,8 +1534,9 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
bool ServeFromHosts() { bool ServeFromHosts() {
DCHECK_GT(num_active_requests(), 0u); DCHECK_GT(num_active_requests(), 0u);
AddressList addr_list; AddressList addr_list;
if (resolver_->ServeFromHosts(key(), requests_.head()->value()->info(), if (resolver_->ServeFromHosts(
&addr_list)) { key(), requests_.head()->value()->request_host().port(),
&addr_list)) {
// This will destroy the Job. // This will destroy the Job.
CompleteRequests( CompleteRequests(
MakeCacheEntry(OK, addr_list, HostCache::Entry::SOURCE_HOSTS), MakeCacheEntry(OK, addr_list, HostCache::Entry::SOURCE_HOSTS),
...@@ -1422,8 +1605,8 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1422,8 +1605,8 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
AddressList MakeAddressListForRequest(const AddressList& list) const { AddressList MakeAddressListForRequest(const AddressList& list) const {
if (requests_.empty()) if (requests_.empty())
return list; return list;
return AddressList::CopyWithPort(list, return AddressList::CopyWithPort(
requests_.head()->value()->info().port()); list, requests_.head()->value()->request_host().port());
} }
void UpdatePriority() { void UpdatePriority() {
...@@ -1481,8 +1664,8 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1481,8 +1664,8 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
DCHECK(!is_dns_running()); DCHECK(!is_dns_running());
proc_task_ = std::make_unique<ProcTask>( proc_task_ = std::make_unique<ProcTask>(
key_, resolver_->proc_params_, key_, resolver_->proc_params_,
base::Bind(&Job::OnProcTaskComplete, base::Unretained(this), base::BindOnce(&Job::OnProcTaskComplete, base::Unretained(this),
tick_clock_->NowTicks()), tick_clock_->NowTicks()),
proc_task_runner_, net_log_, tick_clock_); proc_task_runner_, net_log_, tick_clock_);
// Start() could be called from within Resolve(), hence it must NOT directly // Start() could be called from within Resolve(), hence it must NOT directly
...@@ -1590,7 +1773,6 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1590,7 +1773,6 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
} }
} }
// HostResolverImpl::DnsTask::Delegate implementation: // HostResolverImpl::DnsTask::Delegate implementation:
void OnDnsTaskComplete(base::TimeTicks start_time, void OnDnsTaskComplete(base::TimeTicks start_time,
...@@ -1770,13 +1952,17 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job, ...@@ -1770,13 +1952,17 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
req->RemoveFromList(); req->RemoveFromList();
DCHECK_EQ(this, req->job()); DCHECK_EQ(this, req->job());
// Update the net log and notify registered observers. // Update the net log and notify registered observers.
LogFinishRequest(req->source_net_log(), req->info(), entry.error()); LogFinishRequest(req->source_net_log(), entry.error());
if (did_complete) { if (did_complete) {
// Record effective total time from creation to completion. // Record effective total time from creation to completion.
RecordTotalTime(req->info().is_speculative(), false, RecordTotalTime(req->is_speculative(), false /* from_cache */,
tick_clock_->NowTicks() - req->request_time()); tick_clock_->NowTicks() - req->request_time());
} }
req->OnJobCompleted(this, entry.error(), entry.addresses()); if (entry.error() == OK) {
req->set_address_results(EnsurePortOnAddressList(
entry.addresses(), req->request_host().port()));
}
req->OnJobCompleted(this, entry.error());
// Check if the resolver was destroyed as a result of running the // Check if the resolver was destroyed as a result of running the
// callback. If it was, we could continue, but we choose to bail. // callback. If it was, we could continue, but we choose to bail.
...@@ -1867,85 +2053,6 @@ HostResolverImpl::ProcTaskParams::ProcTaskParams(const ProcTaskParams& other) = ...@@ -1867,85 +2053,6 @@ HostResolverImpl::ProcTaskParams::ProcTaskParams(const ProcTaskParams& other) =
HostResolverImpl::ProcTaskParams::~ProcTaskParams() = default; HostResolverImpl::ProcTaskParams::~ProcTaskParams() = default;
HostResolverImpl::~HostResolverImpl() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Prevent the dispatcher from starting new jobs.
dispatcher_->SetLimitsToZero();
// It's now safe for Jobs to call KillDnsTask on destruction, because
// OnJobComplete will not start any new jobs.
jobs_.clear();
NetworkChangeNotifier::RemoveIPAddressObserver(this);
NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
NetworkChangeNotifier::RemoveDNSObserver(this);
}
void HostResolverImpl::SetMaxQueuedJobs(size_t value) {
DCHECK_EQ(0u, dispatcher_->num_queued_jobs());
DCHECK_GT(value, 0u);
max_queued_jobs_ = value;
}
int HostResolverImpl::Resolve(const RequestInfo& info,
RequestPriority priority,
AddressList* addresses,
CompletionOnceCallback callback,
std::unique_ptr<Request>* out_req,
const NetLogWithSource& source_net_log) {
DCHECK(addresses);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_EQ(false, callback.is_null());
DCHECK(out_req);
LogStartRequest(source_net_log, info);
Key key;
int rv = ResolveHelper(info, false, nullptr, source_net_log, addresses, &key);
if (rv != ERR_DNS_CACHE_MISS) {
LogFinishRequest(source_net_log, info, rv);
RecordTotalTime(info.is_speculative(), true, base::TimeDelta());
return rv;
}
// Next we need to attach our request to a "job". This job is responsible for
// calling "getaddrinfo(hostname)" on a worker thread.
auto jobit = jobs_.find(key);
Job* job;
if (jobit == jobs_.end()) {
auto new_job =
std::make_unique<Job>(weak_ptr_factory_.GetWeakPtr(), key, priority,
proc_task_runner_, source_net_log, tick_clock_);
job = new_job.get();
new_job->Schedule(false);
// Check for queue overflow.
if (dispatcher_->num_queued_jobs() > max_queued_jobs_) {
Job* evicted = static_cast<Job*>(dispatcher_->EvictOldestLowest());
DCHECK(evicted);
evicted->OnEvicted();
if (evicted == new_job.get()) {
rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
LogFinishRequest(source_net_log, info, rv);
return rv;
}
}
jobs_[key] = std::move(new_job);
} else {
job = jobit->second.get();
}
// Can't complete synchronously. Create and attach request.
auto req = std::make_unique<RequestImpl>(source_net_log, info, priority,
std::move(callback), addresses, job,
tick_clock_->NowTicks());
job->AddRequest(req.get());
*out_req = std::move(req);
// Completion happens during Job::CompleteRequests().
return ERR_IO_PENDING;
}
HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log)
: max_queued_jobs_(0), : max_queued_jobs_(0),
proc_params_(NULL, options.max_retry_attempts), proc_params_(NULL, options.max_retry_attempts),
...@@ -2002,79 +2109,74 @@ HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) ...@@ -2002,79 +2109,74 @@ HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log)
fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial(); fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial();
} }
void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) { HostResolverImpl::~HostResolverImpl() {
if (result) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; // Prevent the dispatcher from starting new jobs.
} else { dispatcher_->SetLimitsToZero();
additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; // It's now safe for Jobs to call KillDnsTask on destruction, because
} // OnJobComplete will not start any new jobs.
} jobs_.clear();
void HostResolverImpl::SetTaskRunnerForTesting( NetworkChangeNotifier::RemoveIPAddressObserver(this);
scoped_refptr<base::TaskRunner> task_runner) { NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
proc_task_runner_ = std::move(task_runner); NetworkChangeNotifier::RemoveDNSObserver(this);
} }
int HostResolverImpl::ResolveHelper(const RequestInfo& info, void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
bool allow_stale, // DnsClient and config must be updated before aborting DnsTasks, since doing
HostCache::EntryStaleness* stale_info, // so may start new jobs.
const NetLogWithSource& source_net_log, dns_client_ = std::move(dns_client);
AddressList* addresses, if (dns_client_ && !dns_client_->GetConfig() &&
Key* key) { num_dns_failures_ < kMaximumDnsFailures) {
IPAddress ip_address; DnsConfig dns_config;
IPAddress* ip_address_ptr = nullptr; NetworkChangeNotifier::GetDnsConfig(&dns_config);
if (ip_address.AssignFromIPLiteral(info.hostname())) { dns_config.dns_over_https_servers = dns_over_https_servers_;
ip_address_ptr = &ip_address; dns_client_->SetConfig(dns_config);
} else { num_dns_failures_ = 0;
// Check that the caller supplied a valid hostname to resolve. if (dns_client_->GetConfig())
if (!IsValidDNSDomain(info.hostname())) UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
return ERR_NAME_NOT_RESOLVED;
} }
// Build a key that identifies the request in the cache and in the AbortDnsTasks();
// outstanding jobs map. }
*key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log);
DCHECK(allow_stale == !!stale_info); std::unique_ptr<HostResolver::ResolveHostRequest>
// The result of |getaddrinfo| for empty hosts is inconsistent across systems. HostResolverImpl::CreateRequest(const HostPortPair& host,
// On Windows it gives the default interface's address, whereas on Linux it const NetLogWithSource& net_log) {
// gives an error. We will make it fail on all platforms for consistency. return std::make_unique<RequestImpl>(
if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) { net_log, host, false /* is_speculative */,
MakeNotStale(stale_info); RequestPriority::DEFAULT_PRIORITY, weak_ptr_factory_.GetWeakPtr());
return ERR_NAME_NOT_RESOLVED; }
}
int net_error = ERR_UNEXPECTED; int HostResolverImpl::Resolve(const RequestInfo& info,
if (ResolveAsIP(*key, info, ip_address_ptr, &net_error, addresses)) { RequestPriority priority,
MakeNotStale(stale_info); AddressList* addresses,
return net_error; CompletionOnceCallback callback,
} std::unique_ptr<Request>* out_req,
const NetLogWithSource& source_net_log) {
DCHECK(addresses);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(callback);
DCHECK(out_req);
// Special-case localhost names, as per the recommendations in auto request = std::make_unique<RequestImpl>(
// https://tools.ietf.org/html/draft-west-let-localhost-be-localhost. source_net_log, info.host_port_pair(), info.address_family(),
if (ServeLocalhost(*key, info, addresses)) { info.host_resolver_flags(), info.allow_cached_response(),
MakeNotStale(stale_info); info.is_speculative(), priority, weak_ptr_factory_.GetWeakPtr());
return OK; auto wrapped_request =
} std::make_unique<LegacyRequestImpl>(std::move(request));
if (ServeFromCache(*key, info, &net_error, addresses, allow_stale, int rv = wrapped_request->Start();
stale_info)) {
source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
addresses->CreateNetLogCallback());
// |ServeFromCache()| will set |*stale_info| as needed.
return net_error;
}
// TODO(szym): Do not do this if nsswitch.conf instructs not to. if (rv == OK) {
// http://crbug.com/117655 DCHECK(wrapped_request->inner_request().GetAddressResults());
if (ServeFromHosts(*key, info, addresses)) { *addresses = wrapped_request->inner_request().GetAddressResults().value();
source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_HOSTS_HIT, } else if (rv == ERR_IO_PENDING) {
addresses->CreateNetLogCallback()); wrapped_request->AssignCallback(std::move(callback), addresses);
MakeNotStale(stale_info); *out_req = std::move(wrapped_request);
return OK;
} }
return ERR_DNS_CACHE_MISS; return rv;
} }
int HostResolverImpl::ResolveFromCache(const RequestInfo& info, int HostResolverImpl::ResolveFromCache(const RequestInfo& info,
...@@ -2087,9 +2189,33 @@ int HostResolverImpl::ResolveFromCache(const RequestInfo& info, ...@@ -2087,9 +2189,33 @@ int HostResolverImpl::ResolveFromCache(const RequestInfo& info,
LogStartRequest(source_net_log, info); LogStartRequest(source_net_log, info);
Key key; Key key;
int rv = ResolveHelper(info, false, nullptr, source_net_log, addresses, &key); int rv = ResolveLocally(
info.host_port_pair(), info.address_family(), info.host_resolver_flags(),
info.allow_cached_response(), false /* allow_stale */,
nullptr /* stale_info */, source_net_log, addresses, &key);
LogFinishRequest(source_net_log, info, rv); LogFinishRequest(source_net_log, rv);
return rv;
}
int HostResolverImpl::ResolveStaleFromCache(
const RequestInfo& info,
AddressList* addresses,
HostCache::EntryStaleness* stale_info,
const NetLogWithSource& source_net_log) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(addresses);
DCHECK(stale_info);
// Update the net log and notify registered observers.
LogStartRequest(source_net_log, info);
Key key;
int rv = ResolveLocally(info.host_port_pair(), info.address_family(),
info.host_resolver_flags(),
info.allow_cached_response(), true /* allow_stale */,
stale_info, source_net_log, addresses, &key);
LogFinishRequest(source_net_log, rv);
return rv; return rv;
} }
...@@ -2131,25 +2257,6 @@ std::unique_ptr<base::Value> HostResolverImpl::GetDnsConfigAsValue() const { ...@@ -2131,25 +2257,6 @@ std::unique_ptr<base::Value> HostResolverImpl::GetDnsConfigAsValue() const {
return dns_config->ToValue(); return dns_config->ToValue();
} }
int HostResolverImpl::ResolveStaleFromCache(
const RequestInfo& info,
AddressList* addresses,
HostCache::EntryStaleness* stale_info,
const NetLogWithSource& source_net_log) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(addresses);
DCHECK(stale_info);
// Update the net log and notify registered observers.
LogStartRequest(source_net_log, info);
Key key;
int rv =
ResolveHelper(info, true, stale_info, source_net_log, addresses, &key);
LogFinishRequest(source_net_log, info, rv);
return rv;
}
size_t HostResolverImpl::LastRestoredCacheSize() const { size_t HostResolverImpl::LastRestoredCacheSize() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -2177,28 +2284,22 @@ void HostResolverImpl::SetRequestContext(URLRequestContext* context) { ...@@ -2177,28 +2284,22 @@ void HostResolverImpl::SetRequestContext(URLRequestContext* context) {
} }
} }
void HostResolverImpl::SetTickClockForTesting( void HostResolverImpl::AddDnsOverHttpsServer(std::string spec, bool use_post) {
const base::TickClock* tick_clock) { GURL url(spec);
tick_clock_ = tick_clock; if (!url.SchemeIs("https"))
cache_->set_tick_clock_for_testing(tick_clock);
}
void HostResolverImpl::ClearDnsOverHttpsServers() {
if (dns_over_https_servers_.size() == 0)
return; return;
dns_over_https_servers_.clear(); dns_over_https_servers_.emplace_back(url, use_post);
if (dns_client_.get() && dns_client_->GetConfig()) if (dns_client_.get() && dns_client_->GetConfig())
UpdateDNSConfig(true); UpdateDNSConfig(true);
} }
void HostResolverImpl::AddDnsOverHttpsServer(std::string spec, bool use_post) { void HostResolverImpl::ClearDnsOverHttpsServers() {
GURL url(spec); if (dns_over_https_servers_.size() == 0)
if (!url.SchemeIs("https"))
return; return;
dns_over_https_servers_.emplace_back(url, use_post); dns_over_https_servers_.clear();
if (dns_client_.get() && dns_client_->GetConfig()) if (dns_client_.get() && dns_client_->GetConfig())
UpdateDNSConfig(true); UpdateDNSConfig(true);
...@@ -2211,8 +2312,165 @@ HostResolverImpl::GetDnsOverHttpsServersForTesting() const { ...@@ -2211,8 +2312,165 @@ HostResolverImpl::GetDnsOverHttpsServersForTesting() const {
return &dns_over_https_servers_; return &dns_over_https_servers_;
} }
void HostResolverImpl::SetTickClockForTesting(
const base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
cache_->set_tick_clock_for_testing(tick_clock);
}
void HostResolverImpl::SetMaxQueuedJobsForTesting(size_t value) {
DCHECK_EQ(0u, dispatcher_->num_queued_jobs());
DCHECK_GE(value, 0u);
max_queued_jobs_ = value;
}
void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) {
if (result) {
additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
} else {
additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY;
}
}
void HostResolverImpl::SetTaskRunnerForTesting(
scoped_refptr<base::TaskRunner> task_runner) {
proc_task_runner_ = std::move(task_runner);
}
int HostResolverImpl::Resolve(RequestImpl* request) {
// Request should not yet have a scheduled Job.
DCHECK(!request->job());
// Request may only be resolved once.
DCHECK(!request->complete());
request->set_request_time(tick_clock_->NowTicks());
LogStartRequest(request->source_net_log(), request->request_host());
AddressList addresses;
Key key;
int rv = ResolveLocally(request->request_host(), request->address_family(),
request->host_resolver_flags(),
request->allow_cached_response(),
false /* allow_stale */, nullptr /* stale_info */,
request->source_net_log(), &addresses, &key);
if (rv == OK) {
request->set_address_results(
EnsurePortOnAddressList(addresses, request->request_host().port()));
}
if (rv != ERR_DNS_CACHE_MISS) {
LogFinishRequest(request->source_net_log(), rv);
RecordTotalTime(request->is_speculative(), true /* from_cache */,
base::TimeDelta());
return rv;
}
rv = CreateAndStartJob(key, request);
// At this point, expect only async or errors.
DCHECK_NE(OK, rv);
return rv;
}
int HostResolverImpl::ResolveLocally(const HostPortPair& host,
AddressFamily requested_address_family,
HostResolverFlags flags,
bool allow_cache,
bool allow_stale,
HostCache::EntryStaleness* stale_info,
const NetLogWithSource& source_net_log,
AddressList* addresses,
Key* key) {
IPAddress ip_address;
IPAddress* ip_address_ptr = nullptr;
if (ip_address.AssignFromIPLiteral(host.host())) {
ip_address_ptr = &ip_address;
} else {
// Check that the caller supplied a valid hostname to resolve.
if (!IsValidDNSDomain(host.host()))
return ERR_NAME_NOT_RESOLVED;
}
// Build a key that identifies the request in the cache and in the
// outstanding jobs map.
*key = GetEffectiveKeyForRequest(host.host(), requested_address_family, flags,
ip_address_ptr, source_net_log);
DCHECK(allow_stale == !!stale_info);
// The result of |getaddrinfo| for empty hosts is inconsistent across systems.
// On Windows it gives the default interface's address, whereas on Linux it
// gives an error. We will make it fail on all platforms for consistency.
if (host.host().empty() || host.host().size() > kMaxHostLength) {
MakeNotStale(stale_info);
return ERR_NAME_NOT_RESOLVED;
}
int net_error = ERR_UNEXPECTED;
if (ResolveAsIP(*key, host.port(), ip_address_ptr, &net_error, addresses)) {
MakeNotStale(stale_info);
return net_error;
}
// Special-case localhost names, as per the recommendations in
// https://tools.ietf.org/html/draft-west-let-localhost-be-localhost.
if (ServeLocalhost(*key, host.port(), addresses)) {
MakeNotStale(stale_info);
return OK;
}
if (allow_cache && ServeFromCache(*key, host.port(), &net_error, addresses,
allow_stale, stale_info)) {
source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
addresses->CreateNetLogCallback());
// |ServeFromCache()| will set |*stale_info| as needed.
return net_error;
}
// TODO(szym): Do not do this if nsswitch.conf instructs not to.
// http://crbug.com/117655
if (ServeFromHosts(*key, host.port(), addresses)) {
source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_HOSTS_HIT,
addresses->CreateNetLogCallback());
MakeNotStale(stale_info);
return OK;
}
return ERR_DNS_CACHE_MISS;
}
int HostResolverImpl::CreateAndStartJob(const Key& key, RequestImpl* request) {
auto jobit = jobs_.find(key);
Job* job;
if (jobit == jobs_.end()) {
auto new_job = std::make_unique<Job>(
weak_ptr_factory_.GetWeakPtr(), key, request->priority(),
proc_task_runner_, request->source_net_log(), tick_clock_);
job = new_job.get();
new_job->Schedule(false);
// Check for queue overflow.
if (dispatcher_->num_queued_jobs() > max_queued_jobs_) {
Job* evicted = static_cast<Job*>(dispatcher_->EvictOldestLowest());
DCHECK(evicted);
evicted->OnEvicted();
if (evicted == new_job.get()) {
LogFinishRequest(request->source_net_log(),
ERR_HOST_RESOLVER_QUEUE_TOO_LARGE);
return ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
}
}
jobs_[key] = std::move(new_job);
} else {
job = jobit->second.get();
}
// Can't complete synchronously. Attach request and job to each other.
job->AddRequest(request);
return ERR_IO_PENDING;
}
bool HostResolverImpl::ResolveAsIP(const Key& key, bool HostResolverImpl::ResolveAsIP(const Key& key,
const RequestInfo& info, uint16_t host_port,
const IPAddress* ip_address, const IPAddress* ip_address,
int* net_error, int* net_error,
AddressList* addresses) { AddressList* addresses) {
...@@ -2228,7 +2486,7 @@ bool HostResolverImpl::ResolveAsIP(const Key& key, ...@@ -2228,7 +2486,7 @@ bool HostResolverImpl::ResolveAsIP(const Key& key,
// Don't return IPv6 addresses for IPv4 queries, and vice versa. // Don't return IPv6 addresses for IPv4 queries, and vice versa.
*net_error = ERR_NAME_NOT_RESOLVED; *net_error = ERR_NAME_NOT_RESOLVED;
} else { } else {
*addresses = AddressList::CreateFromIPAddress(*ip_address, info.port()); *addresses = AddressList::CreateFromIPAddress(*ip_address, host_port);
if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME) if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)
addresses->SetDefaultCanonicalName(); addresses->SetDefaultCanonicalName();
} }
...@@ -2236,7 +2494,7 @@ bool HostResolverImpl::ResolveAsIP(const Key& key, ...@@ -2236,7 +2494,7 @@ bool HostResolverImpl::ResolveAsIP(const Key& key,
} }
bool HostResolverImpl::ServeFromCache(const Key& key, bool HostResolverImpl::ServeFromCache(const Key& key,
const RequestInfo& info, uint16_t host_port,
int* net_error, int* net_error,
AddressList* addresses, AddressList* addresses,
bool allow_stale, bool allow_stale,
...@@ -2244,7 +2502,7 @@ bool HostResolverImpl::ServeFromCache(const Key& key, ...@@ -2244,7 +2502,7 @@ bool HostResolverImpl::ServeFromCache(const Key& key,
DCHECK(addresses); DCHECK(addresses);
DCHECK(net_error); DCHECK(net_error);
DCHECK(allow_stale == !!stale_info); DCHECK(allow_stale == !!stale_info);
if (!info.allow_cached_response() || !cache_.get()) if (!cache_.get())
return false; return false;
const HostCache::Entry* cache_entry; const HostCache::Entry* cache_entry;
...@@ -2259,13 +2517,13 @@ bool HostResolverImpl::ServeFromCache(const Key& key, ...@@ -2259,13 +2517,13 @@ bool HostResolverImpl::ServeFromCache(const Key& key,
if (*net_error == OK) { if (*net_error == OK) {
if (cache_entry->has_ttl()) if (cache_entry->has_ttl())
RecordTTL(cache_entry->ttl()); RecordTTL(cache_entry->ttl());
*addresses = EnsurePortOnAddressList(cache_entry->addresses(), info.port()); *addresses = EnsurePortOnAddressList(cache_entry->addresses(), host_port);
} }
return true; return true;
} }
bool HostResolverImpl::ServeFromHosts(const Key& key, bool HostResolverImpl::ServeFromHosts(const Key& key,
const RequestInfo& info, uint16_t host_port,
AddressList* addresses) { AddressList* addresses) {
DCHECK(addresses); DCHECK(addresses);
if (!HaveDnsConfig()) if (!HaveDnsConfig())
...@@ -2287,7 +2545,7 @@ bool HostResolverImpl::ServeFromHosts(const Key& key, ...@@ -2287,7 +2545,7 @@ bool HostResolverImpl::ServeFromHosts(const Key& key,
DnsHosts::const_iterator it = hosts.find( DnsHosts::const_iterator it = hosts.find(
DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6)); DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6));
if (it != hosts.end()) if (it != hosts.end())
addresses->push_back(IPEndPoint(it->second, info.port())); addresses->push_back(IPEndPoint(it->second, host_port));
} }
if (key.address_family == ADDRESS_FAMILY_IPV4 || if (key.address_family == ADDRESS_FAMILY_IPV4 ||
...@@ -2295,7 +2553,7 @@ bool HostResolverImpl::ServeFromHosts(const Key& key, ...@@ -2295,7 +2553,7 @@ bool HostResolverImpl::ServeFromHosts(const Key& key,
DnsHosts::const_iterator it = hosts.find( DnsHosts::const_iterator it = hosts.find(
DnsHostsKey(hostname, ADDRESS_FAMILY_IPV4)); DnsHostsKey(hostname, ADDRESS_FAMILY_IPV4));
if (it != hosts.end()) if (it != hosts.end())
addresses->push_back(IPEndPoint(it->second, info.port())); addresses->push_back(IPEndPoint(it->second, host_port));
} }
// If got only loopback addresses and the family was restricted, resolve // If got only loopback addresses and the family was restricted, resolve
...@@ -2307,16 +2565,16 @@ bool HostResolverImpl::ServeFromHosts(const Key& key, ...@@ -2307,16 +2565,16 @@ bool HostResolverImpl::ServeFromHosts(const Key& key,
new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED; new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED;
new_key.host_resolver_flags &= new_key.host_resolver_flags &=
~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
return ServeFromHosts(new_key, info, addresses); return ServeFromHosts(new_key, host_port, addresses);
} }
return !addresses->empty(); return !addresses->empty();
} }
bool HostResolverImpl::ServeLocalhost(const Key& key, bool HostResolverImpl::ServeLocalhost(const Key& key,
const RequestInfo& info, uint16_t host_port,
AddressList* addresses) { AddressList* addresses) {
AddressList resolved_addresses; AddressList resolved_addresses;
if (!ResolveLocalHostname(key.hostname, info.port(), &resolved_addresses)) if (!ResolveLocalHostname(key.hostname, host_port, &resolved_addresses))
return false; return false;
addresses->clear(); addresses->clear();
...@@ -2361,12 +2619,13 @@ std::unique_ptr<HostResolverImpl::Job> HostResolverImpl::RemoveJob(Job* job) { ...@@ -2361,12 +2619,13 @@ std::unique_ptr<HostResolverImpl::Job> HostResolverImpl::RemoveJob(Job* job) {
} }
HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
const RequestInfo& info, const std::string& hostname,
AddressFamily requested_address_family,
HostResolverFlags flags,
const IPAddress* ip_address, const IPAddress* ip_address,
const NetLogWithSource& net_log) { const NetLogWithSource& net_log) {
HostResolverFlags effective_flags = HostResolverFlags effective_flags = flags | additional_resolver_flags_;
info.host_resolver_flags() | additional_resolver_flags_; AddressFamily effective_address_family = requested_address_family;
AddressFamily effective_address_family = info.address_family();
if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED && if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED &&
// When resolving IPv4 literals, there's no need to probe for IPv6. // When resolving IPv4 literals, there's no need to probe for IPv6.
...@@ -2380,7 +2639,7 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( ...@@ -2380,7 +2639,7 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
} }
return Key(info.hostname(), effective_address_family, effective_flags); return Key(hostname, effective_address_family, effective_flags);
} }
bool HostResolverImpl::IsIPv6Reachable(const NetLogWithSource& net_log) { bool HostResolverImpl::IsIPv6Reachable(const NetLogWithSource& net_log) {
...@@ -2624,24 +2883,6 @@ void HostResolverImpl::OnDnsTaskResolve(int net_error) { ...@@ -2624,24 +2883,6 @@ void HostResolverImpl::OnDnsTaskResolve(int net_error) {
std::abs(net_error)); std::abs(net_error));
} }
void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
// DnsClient and config must be updated before aborting DnsTasks, since doing
// so may start new jobs.
dns_client_ = std::move(dns_client);
if (dns_client_ && !dns_client_->GetConfig() &&
num_dns_failures_ < kMaximumDnsFailures) {
DnsConfig dns_config;
NetworkChangeNotifier::GetDnsConfig(&dns_config);
dns_config.dns_over_https_servers = dns_over_https_servers_;
dns_client_->SetConfig(dns_config);
num_dns_failures_ = 0;
if (dns_client_->GetConfig())
UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
}
AbortDnsTasks();
}
HostResolverImpl::RequestImpl::~RequestImpl() { HostResolverImpl::RequestImpl::~RequestImpl() {
if (job_) if (job_)
job_->CancelRequest(this); job_->CancelRequest(this);
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -125,10 +128,6 @@ class NET_EXPORT HostResolverImpl ...@@ -125,10 +128,6 @@ class NET_EXPORT HostResolverImpl
// be called. // be called.
~HostResolverImpl() override; ~HostResolverImpl() override;
// Configures maximum number of Jobs in the queue. Exposed for testing.
// Only allowed when the queue is empty.
void SetMaxQueuedJobs(size_t value);
// Set the DnsClient to be used for resolution. In case of failure, the // Set the DnsClient to be used for resolution. In case of failure, the
// HostResolverProc from ProcTaskParams will be queried. If the DnsClient is // HostResolverProc from ProcTaskParams will be queried. If the DnsClient is
// not pre-configured with a valid DnsConfig, a new config is fetched from // not pre-configured with a valid DnsConfig, a new config is fetched from
...@@ -136,6 +135,9 @@ class NET_EXPORT HostResolverImpl ...@@ -136,6 +135,9 @@ class NET_EXPORT HostResolverImpl
void SetDnsClient(std::unique_ptr<DnsClient> dns_client); void SetDnsClient(std::unique_ptr<DnsClient> dns_client);
// HostResolver methods: // HostResolver methods:
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override;
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
...@@ -179,6 +181,10 @@ class NET_EXPORT HostResolverImpl ...@@ -179,6 +181,10 @@ class NET_EXPORT HostResolverImpl
void SetTickClockForTesting(const base::TickClock* tick_clock); void SetTickClockForTesting(const base::TickClock* tick_clock);
// Configures maximum number of Jobs in the queue. Exposed for testing.
// Only allowed when the queue is empty.
void SetMaxQueuedJobsForTesting(size_t value);
protected: protected:
// Callback from HaveOnlyLoopbackAddresses probe. // Callback from HaveOnlyLoopbackAddresses probe.
void SetHaveOnlyLoopbackAddresses(bool result); void SetHaveOnlyLoopbackAddresses(bool result);
...@@ -193,6 +199,7 @@ class NET_EXPORT HostResolverImpl ...@@ -193,6 +199,7 @@ class NET_EXPORT HostResolverImpl
class LoopbackProbeJob; class LoopbackProbeJob;
class DnsTask; class DnsTask;
class RequestImpl; class RequestImpl;
class LegacyRequestImpl;
using Key = HostCache::Key; using Key = HostCache::Key;
using JobMap = std::map<Key, std::unique_ptr<Job>>; using JobMap = std::map<Key, std::unique_ptr<Job>>;
...@@ -200,11 +207,14 @@ class NET_EXPORT HostResolverImpl ...@@ -200,11 +207,14 @@ class NET_EXPORT HostResolverImpl
// ProcTask) before the DnsClient is disabled until the next DNS change. // ProcTask) before the DnsClient is disabled until the next DNS change.
static const unsigned kMaximumDnsFailures; static const unsigned kMaximumDnsFailures;
// Helper used by |Resolve()| and |ResolveFromCache()|. Performs IP // Attempts host resolution for |request|. Generally only expected to be
// literal, cache and HOSTS lookup (if enabled), returns OK if successful, // called from RequestImpl::Start().
// ERR_NAME_NOT_RESOLVED if either hostname is invalid or IP literal is int Resolve(RequestImpl* request);
// incompatible, ERR_DNS_CACHE_MISS if entry was not found in cache and
// HOSTS and is not localhost. // Attempts host resolution using fast local sources: IP literal resolution,
// cache lookup, HOSTS lookup (if enabled), and localhost. Returns OK if
// successful, ERR_NAME_NOT_RESOLVED if input is invalid, or
// ERR_DNS_CACHE_MISS if the host could not be resolved using local sources.
// //
// On success, the resulting addresses are written to |addresses|. // On success, the resulting addresses are written to |addresses|.
// //
...@@ -217,17 +227,25 @@ class NET_EXPORT HostResolverImpl ...@@ -217,17 +227,25 @@ class NET_EXPORT HostResolverImpl
// //
// If |allow_stale| is false, then stale cache entries will not be returned, // If |allow_stale| is false, then stale cache entries will not be returned,
// and |stale_info| must be null. // and |stale_info| must be null.
int ResolveHelper(const RequestInfo& info, int ResolveLocally(const HostPortPair& host,
bool allow_stale, AddressFamily requested_address_family,
HostCache::EntryStaleness* stale_info, HostResolverFlags flags,
const NetLogWithSource& request_net_log, bool allow_cache,
AddressList* addresses, bool allow_stale,
Key* key); HostCache::EntryStaleness* stale_info,
const NetLogWithSource& request_net_log,
AddressList* addresses,
Key* key);
// Attempts to create and start a Job to asynchronously attempt to resolve
// |key|. On success, returns ERR_IO_PENDING and attaches the Job to
// |request|. On error, marks |request| completed and returns the error.
int CreateAndStartJob(const Key& key, RequestImpl* request);
// Tries to resolve |key| as an IP, returns true and sets |net_error| if // Tries to resolve |key| as an IP, returns true and sets |net_error| if
// succeeds, returns false otherwise. // succeeds, returns false otherwise.
bool ResolveAsIP(const Key& key, bool ResolveAsIP(const Key& key,
const RequestInfo& info, uint16_t host_port,
const IPAddress* ip_address, const IPAddress* ip_address,
int* net_error, int* net_error,
AddressList* addresses); AddressList* addresses);
...@@ -243,7 +261,7 @@ class NET_EXPORT HostResolverImpl ...@@ -243,7 +261,7 @@ class NET_EXPORT HostResolverImpl
// If |allow_stale| is false, then stale cache entries will not be returned, // If |allow_stale| is false, then stale cache entries will not be returned,
// and |stale_info| must be null. // and |stale_info| must be null.
bool ServeFromCache(const Key& key, bool ServeFromCache(const Key& key,
const RequestInfo& info, uint16_t host_port,
int* net_error, int* net_error,
AddressList* addresses, AddressList* addresses,
bool allow_stale, bool allow_stale,
...@@ -252,19 +270,21 @@ class NET_EXPORT HostResolverImpl ...@@ -252,19 +270,21 @@ class NET_EXPORT HostResolverImpl
// If we have a DnsClient with a valid DnsConfig, and |key| is found in the // If we have a DnsClient with a valid DnsConfig, and |key| is found in the
// HOSTS file, returns true and fills |addresses|. Otherwise returns false. // HOSTS file, returns true and fills |addresses|. Otherwise returns false.
bool ServeFromHosts(const Key& key, bool ServeFromHosts(const Key& key,
const RequestInfo& info, uint16_t host_port,
AddressList* addresses); AddressList* addresses);
// If |key| is for a localhost name (RFC 6761), returns true and fills // If |key| is for a localhost name (RFC 6761), returns true and fills
// |addresses| with the loopback IP. Otherwise returns false. // |addresses| with the loopback IP. Otherwise returns false.
bool ServeLocalhost(const Key& key, bool ServeLocalhost(const Key& key,
const RequestInfo& info, uint16_t host_port,
AddressList* addresses); AddressList* addresses);
// Returns the (hostname, address_family) key to use for |info|, choosing an // Returns the (hostname, address_family) key to use for |info|, choosing an
// "effective" address family by inheriting the resolver's default address // "effective" address family by inheriting the resolver's default address
// family when the request leaves it unspecified. // family when the request leaves it unspecified.
Key GetEffectiveKeyForRequest(const RequestInfo& info, Key GetEffectiveKeyForRequest(const std::string& hostname,
AddressFamily requested_address_family,
HostResolverFlags flags,
const IPAddress* ip_address, const IPAddress* ip_address,
const NetLogWithSource& net_log); const NetLogWithSource& net_log);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -70,6 +70,14 @@ HostResolverMojo::HostResolverMojo(Impl* impl) ...@@ -70,6 +70,14 @@ HostResolverMojo::HostResolverMojo(Impl* impl)
HostResolverMojo::~HostResolverMojo() = default; HostResolverMojo::~HostResolverMojo() = default;
std::unique_ptr<HostResolver::ResolveHostRequest>
HostResolverMojo::CreateRequest(const HostPortPair& host,
const NetLogWithSource& source_net_log) {
// TODO(crbug.com/821021): Implement.
NOTIMPLEMENTED();
return nullptr;
}
int HostResolverMojo::Resolve(const RequestInfo& info, int HostResolverMojo::Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef NET_DNS_HOST_RESOLVER_MOJO_H_ #ifndef NET_DNS_HOST_RESOLVER_MOJO_H_
#define NET_DNS_HOST_RESOLVER_MOJO_H_ #define NET_DNS_HOST_RESOLVER_MOJO_H_
#include <memory>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
...@@ -34,6 +36,9 @@ class HostResolverMojo : public HostResolver { ...@@ -34,6 +36,9 @@ class HostResolverMojo : public HostResolver {
~HostResolverMojo() override; ~HostResolverMojo() override;
// HostResolver overrides. // HostResolver overrides.
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override;
// Note: |Resolve()| currently ignores |priority|. // Note: |Resolve()| currently ignores |priority|.
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
......
...@@ -18,6 +18,14 @@ MappedHostResolver::MappedHostResolver(std::unique_ptr<HostResolver> impl) ...@@ -18,6 +18,14 @@ MappedHostResolver::MappedHostResolver(std::unique_ptr<HostResolver> impl)
MappedHostResolver::~MappedHostResolver() = default; MappedHostResolver::~MappedHostResolver() = default;
std::unique_ptr<HostResolver::ResolveHostRequest>
MappedHostResolver::CreateRequest(const HostPortPair& host,
const NetLogWithSource& source_net_log) {
// TODO(crbug.com/821021): Implement.
NOTIMPLEMENTED();
return nullptr;
}
int MappedHostResolver::Resolve(const RequestInfo& original_info, int MappedHostResolver::Resolve(const RequestInfo& original_info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -46,6 +46,9 @@ class NET_EXPORT MappedHostResolver : public HostResolver { ...@@ -46,6 +46,9 @@ class NET_EXPORT MappedHostResolver : public HostResolver {
} }
// HostResolver methods: // HostResolver methods:
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override;
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -103,6 +103,14 @@ MockHostResolverBase::~MockHostResolverBase() { ...@@ -103,6 +103,14 @@ MockHostResolverBase::~MockHostResolverBase() {
DCHECK(requests_.empty()); DCHECK(requests_.empty());
} }
std::unique_ptr<HostResolver::ResolveHostRequest>
MockHostResolverBase::CreateRequest(const HostPortPair& host,
const NetLogWithSource& source_net_log) {
// TODO(crbug.com/821021): Implement.
NOTIMPLEMENTED();
return nullptr;
}
int MockHostResolverBase::Resolve(const RequestInfo& info, int MockHostResolverBase::Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
...@@ -514,6 +522,14 @@ RuleBasedHostResolverProc* CreateCatchAllHostResolverProc() { ...@@ -514,6 +522,14 @@ RuleBasedHostResolverProc* CreateCatchAllHostResolverProc() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
std::unique_ptr<HostResolver::ResolveHostRequest>
HangingHostResolver::CreateRequest(const HostPortPair& host,
const NetLogWithSource& source_net_log) {
// TODO(crbug.com/821021): Implement.
NOTIMPLEMENTED();
return nullptr;
}
int HangingHostResolver::Resolve(const RequestInfo& info, int HangingHostResolver::Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <memory>
#include <string> #include <string>
#include "base/macros.h" #include "base/macros.h"
...@@ -83,6 +84,9 @@ class MockHostResolverBase ...@@ -83,6 +84,9 @@ class MockHostResolverBase
} }
// HostResolver methods: // HostResolver methods:
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override;
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
...@@ -287,6 +291,9 @@ RuleBasedHostResolverProc* CreateCatchAllHostResolverProc(); ...@@ -287,6 +291,9 @@ RuleBasedHostResolverProc* CreateCatchAllHostResolverProc();
// HangingHostResolver never completes its |Resolve| request. // HangingHostResolver never completes its |Resolve| request.
class HangingHostResolver : public HostResolver { class HangingHostResolver : public HostResolver {
public: public:
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override;
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -693,6 +693,13 @@ class BlockableHostResolver : public HostResolver { ...@@ -693,6 +693,13 @@ class BlockableHostResolver : public HostResolver {
BlockableHostResolver() BlockableHostResolver()
: num_cancelled_requests_(0), waiting_for_resolve_(false) {} : num_cancelled_requests_(0), waiting_for_resolve_(false) {}
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override {
NOTIMPLEMENTED();
return nullptr;
}
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -790,6 +790,13 @@ class BlockableHostResolver : public HostResolver { ...@@ -790,6 +790,13 @@ class BlockableHostResolver : public HostResolver {
BlockableHostResolver() BlockableHostResolver()
: num_cancelled_requests_(0), waiting_for_resolve_(false) {} : num_cancelled_requests_(0), waiting_for_resolve_(false) {}
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override {
NOTIMPLEMENTED();
return nullptr;
}
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -107,6 +107,13 @@ class HangingHostResolverWithCancel : public HostResolver { ...@@ -107,6 +107,13 @@ class HangingHostResolverWithCancel : public HostResolver {
public: public:
HangingHostResolverWithCancel() : outstanding_request_(NULL) {} HangingHostResolverWithCancel() : outstanding_request_(NULL) {}
std::unique_ptr<ResolveHostRequest> CreateRequest(
const HostPortPair& host,
const NetLogWithSource& net_log) override {
NOTIMPLEMENTED();
return nullptr;
}
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
RequestPriority priority, RequestPriority priority,
AddressList* addresses, AddressList* addresses,
......
...@@ -478,6 +478,14 @@ class MockHostResolver : public net::HostResolver { ...@@ -478,6 +478,14 @@ class MockHostResolver : public net::HostResolver {
}; };
// net::HostResolver overrides. // net::HostResolver overrides.
std::unique_ptr<HostResolver::ResolveHostRequest> CreateRequest(
const net::HostPortPair& host,
const net::NetLogWithSource& source_net_log) override {
// TODO(crbug.com/821021): Implement.
NOTIMPLEMENTED();
return nullptr;
}
int Resolve(const RequestInfo& info, int Resolve(const RequestInfo& info,
net::RequestPriority priority, net::RequestPriority priority,
net::AddressList* addresses, net::AddressList* addresses,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment