1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
// 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.
// The override should never invoke `results_cb` synchronously.
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_
|