220 lines
9.0 KiB
C++
220 lines
9.0 KiB
C++
// Copyright 2022 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef NET_DNS_HOST_RESOLVER_SYSTEM_TASK_H_
|
|
#define NET_DNS_HOST_RESOLVER_SYSTEM_TASK_H_
|
|
|
|
#include <string>
|
|
|
|
#include "base/functional/callback.h"
|
|
#include "base/functional/callback_helpers.h"
|
|
#include "base/task/task_runner.h"
|
|
#include "net/base/address_list.h"
|
|
#include "net/base/net_export.h"
|
|
#include "net/base/network_handle.h"
|
|
#include "net/dns/host_resolver_proc.h"
|
|
#include "net/log/net_log_with_source.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
|
|
|
namespace net {
|
|
|
|
using SystemDnsResultsCallback = base::OnceCallback<
|
|
void(const AddressList& addr_list, int os_error, int net_error)>;
|
|
|
|
// Calls SystemHostResolverCall() (or in some tests, HostResolverProc::Resolve)
|
|
// in ThreadPool. So EnsureSystemHostResolverCallReady() must be called before
|
|
// using this class.
|
|
//
|
|
// Performs retries if specified by HostResolverSystemTask::Params.
|
|
//
|
|
// Whenever we try to resolve the host, we post a delayed task to check if host
|
|
// resolution (OnLookupComplete) is completed or not. If the original attempt
|
|
// hasn't completed, then we start another attempt for host resolution. We take
|
|
// the results from the first attempt that finishes and ignore the results from
|
|
// all other attempts.
|
|
//
|
|
// This class is designed to be used not just by HostResolverManager, but by
|
|
// general consumers.
|
|
//
|
|
// It should only be used on the main thread to ensure that hooks (see
|
|
// SetSystemHostResolverOverride()) only ever run on the main thread.
|
|
class NET_EXPORT HostResolverSystemTask {
|
|
public:
|
|
// Parameters for customizing HostResolverSystemTask behavior.
|
|
//
|
|
// |resolver_proc| is used to override resolution in tests; it must be
|
|
// thread-safe since it may be run from multiple worker threads. If
|
|
// |resolver_proc| is NULL then the default host resolver procedure is
|
|
// to call SystemHostResolverCall().
|
|
//
|
|
// For each attempt, we could start another attempt if host is not resolved
|
|
// within |unresponsive_delay| time. We keep attempting to resolve the host
|
|
// for |max_retry_attempts|. For every retry attempt, we grow the
|
|
// |unresponsive_delay| by the |retry_factor| amount (that is retry interval
|
|
// is multiplied by the retry factor each time). Once we have retried
|
|
// |max_retry_attempts|, we give up on additional attempts.
|
|
struct NET_EXPORT_PRIVATE Params {
|
|
// Default delay between calls to the system resolver for the same hostname.
|
|
// (Can be overridden by field trial.)
|
|
static constexpr base::TimeDelta kDnsDefaultUnresponsiveDelay =
|
|
base::Seconds(6);
|
|
|
|
// Set |max_system_retry_attempts| to this to select a default retry value.
|
|
static constexpr size_t kDefaultRetryAttempts = -1;
|
|
|
|
// Sets up defaults.
|
|
Params(scoped_refptr<HostResolverProc> resolver_proc,
|
|
size_t max_retry_attempts);
|
|
|
|
Params(const Params& other);
|
|
|
|
~Params();
|
|
|
|
// The procedure to use for resolving host names. This will be NULL, except
|
|
// in the case of some-tests which inject custom host resolving behaviors.
|
|
scoped_refptr<HostResolverProc> resolver_proc;
|
|
|
|
// Maximum number retry attempts to resolve the hostname.
|
|
// Pass HostResolver::Options::kDefaultRetryAttempts to choose a default
|
|
// value.
|
|
size_t max_retry_attempts;
|
|
|
|
// This is the limit after which we make another attempt to resolve the host
|
|
// if the worker thread has not responded yet.
|
|
base::TimeDelta unresponsive_delay = kDnsDefaultUnresponsiveDelay;
|
|
|
|
// Factor to grow |unresponsive_delay| when we re-re-try.
|
|
uint32_t retry_factor = 2;
|
|
};
|
|
|
|
static std::unique_ptr<HostResolverSystemTask> Create(
|
|
std::string hostname,
|
|
AddressFamily address_family,
|
|
HostResolverFlags flags,
|
|
const Params& params = Params(nullptr, 0),
|
|
const NetLogWithSource& job_net_log = NetLogWithSource(),
|
|
handles::NetworkHandle network = handles::kInvalidNetworkHandle);
|
|
|
|
// Same as above but resolves the result of GetHostName() (the machine's own
|
|
// hostname).
|
|
static std::unique_ptr<HostResolverSystemTask> CreateForOwnHostname(
|
|
AddressFamily address_family,
|
|
HostResolverFlags flags,
|
|
const Params& params = Params(nullptr, 0),
|
|
const NetLogWithSource& job_net_log = NetLogWithSource(),
|
|
handles::NetworkHandle network = handles::kInvalidNetworkHandle);
|
|
|
|
// If `hostname` is absl::nullopt, resolves the result of GetHostName().
|
|
// Prefer using the above 2 static functions for constructing a
|
|
// HostResolverSystemTask.
|
|
HostResolverSystemTask(
|
|
absl::optional<std::string> hostname,
|
|
AddressFamily address_family,
|
|
HostResolverFlags flags,
|
|
const Params& params = Params(nullptr, 0),
|
|
const NetLogWithSource& job_net_log = NetLogWithSource(),
|
|
handles::NetworkHandle network = handles::kInvalidNetworkHandle);
|
|
|
|
HostResolverSystemTask(const HostResolverSystemTask&) = delete;
|
|
HostResolverSystemTask& operator=(const HostResolverSystemTask&) = delete;
|
|
|
|
// Cancels this HostResolverSystemTask. Any outstanding resolve attempts
|
|
// cannot be cancelled, but they will post back to the current thread before
|
|
// checking their WeakPtrs to find that this task is cancelled.
|
|
~HostResolverSystemTask();
|
|
|
|
// Starts the resolution task. This can only be called once per
|
|
// HostResolverSystemTask. `results_cb` will not be invoked synchronously and
|
|
// can own `this`.
|
|
void Start(SystemDnsResultsCallback results_cb);
|
|
|
|
bool was_completed() const {
|
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
return results_cb_.is_null();
|
|
}
|
|
|
|
private:
|
|
void StartLookupAttempt();
|
|
|
|
// Callback for when DoLookup() completes.
|
|
void OnLookupComplete(const uint32_t attempt_number,
|
|
const AddressList& results,
|
|
const int os_error,
|
|
int error);
|
|
|
|
// If `hostname_` is absl::nullopt, this class should resolve the result of
|
|
// net::GetHostName() (the machine's own hostname).
|
|
const absl::optional<std::string> hostname_;
|
|
const AddressFamily address_family_;
|
|
const HostResolverFlags flags_;
|
|
|
|
// Holds an owning reference to the HostResolverProc that we are going to use.
|
|
// This may not be the current resolver procedure by the time we call
|
|
// ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning
|
|
// reference ensures that it remains valid until we are done.
|
|
Params params_;
|
|
|
|
// The listener to the results of this HostResolverSystemTask.
|
|
SystemDnsResultsCallback results_cb_;
|
|
|
|
// Keeps track of the number of attempts we have made so far to resolve the
|
|
// host. Whenever we start an attempt to resolve the host, we increase this
|
|
// number.
|
|
uint32_t attempt_number_ = 0;
|
|
|
|
NetLogWithSource net_log_;
|
|
|
|
// Network to perform DNS lookups for.
|
|
const handles::NetworkHandle network_;
|
|
|
|
SEQUENCE_CHECKER(sequence_checker_);
|
|
|
|
// Used to loop back from the blocking lookup attempt tasks as well as from
|
|
// delayed retry tasks. Invalidate WeakPtrs on completion and cancellation to
|
|
// cancel handling of such posted tasks.
|
|
base::WeakPtrFactory<HostResolverSystemTask> weak_ptr_factory_{this};
|
|
};
|
|
|
|
// Ensures any necessary initialization occurs such that
|
|
// SystemHostResolverCall() can be called on other threads.
|
|
NET_EXPORT void EnsureSystemHostResolverCallReady();
|
|
|
|
// Resolves `host` to an address list, using the system's default host resolver.
|
|
// (i.e. this calls out to getaddrinfo()). If successful returns OK and fills
|
|
// `addrlist` with a list of socket addresses. Otherwise returns a
|
|
// network error code, and fills `os_error` with a more specific error if it
|
|
// was non-NULL.
|
|
// `network` is an optional parameter, when specified (!=
|
|
// handles::kInvalidNetworkHandle) the lookup will be performed specifically for
|
|
// `network`.
|
|
//
|
|
// This should NOT be called in a sandboxed process.
|
|
NET_EXPORT_PRIVATE int SystemHostResolverCall(
|
|
const std::string& host,
|
|
AddressFamily address_family,
|
|
HostResolverFlags host_resolver_flags,
|
|
AddressList* addrlist,
|
|
int* os_error,
|
|
handles::NetworkHandle network = handles::kInvalidNetworkHandle);
|
|
|
|
// Sets the task runner that system DNS resolution will run on, which is mostly
|
|
// useful for tests and fuzzers that need reproducibilty of failures.
|
|
NET_EXPORT_PRIVATE void SetSystemDnsResolutionTaskRunnerForTesting(
|
|
scoped_refptr<base::TaskRunner> task_runner);
|
|
|
|
// The following will be used to override the behavior of
|
|
// HostResolverSystemTask. This override will be called instead of posting
|
|
// SystemHostResolverCall() to a worker thread. The override will only be
|
|
// invoked on the main thread.
|
|
NET_EXPORT void SetSystemDnsResolverOverride(
|
|
base::RepeatingCallback<void(const absl::optional<std::string>& host,
|
|
AddressFamily address_family,
|
|
HostResolverFlags host_resolver_flags,
|
|
SystemDnsResultsCallback results_cb,
|
|
handles::NetworkHandle network)> dns_override);
|
|
|
|
} // namespace net
|
|
|
|
#endif // NET_DNS_HOST_RESOLVER_SYSTEM_TASK_H_
|