1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_DNS_HOST_RESOLVER_SYSTEM_TASK_H_ 6 #define NET_DNS_HOST_RESOLVER_SYSTEM_TASK_H_ 7 8 #include <optional> 9 #include <string> 10 #include <vector> 11 12 #include "base/functional/callback.h" 13 #include "base/functional/callback_helpers.h" 14 #include "base/memory/raw_ref.h" 15 #include "base/task/task_runner.h" 16 #include "net/base/address_list.h" 17 #include "net/base/ip_endpoint.h" 18 #include "net/base/net_export.h" 19 #include "net/base/network_anonymization_key.h" 20 #include "net/base/network_handle.h" 21 #include "net/dns/host_resolver_proc.h" 22 #include "net/dns/public/dns_query_type.h" 23 #include "net/log/net_log_with_source.h" 24 25 namespace net { 26 27 class HostResolverCache; 28 29 using SystemDnsResultsCallback = base::OnceCallback< 30 void(const AddressList& addr_list, int os_error, int net_error)>; 31 32 // Calls SystemHostResolverCall() (or in some tests, HostResolverProc::Resolve) 33 // in ThreadPool. So EnsureSystemHostResolverCallReady() must be called before 34 // using this class. 35 // 36 // Performs retries if specified by HostResolverSystemTask::Params. 37 // 38 // Whenever we try to resolve the host, we post a delayed task to check if host 39 // resolution (OnLookupComplete) is completed or not. If the original attempt 40 // hasn't completed, then we start another attempt for host resolution. We take 41 // the results from the first attempt that finishes and ignore the results from 42 // all other attempts. 43 // 44 // This class is designed to be used not just by HostResolverManager, but by 45 // general consumers. 46 // 47 // It should only be used on the main thread to ensure that hooks (see 48 // SetSystemHostResolverOverride()) only ever run on the main thread. 49 class NET_EXPORT HostResolverSystemTask { 50 public: 51 // Parameters for customizing HostResolverSystemTask behavior. 52 // 53 // |resolver_proc| is used to override resolution in tests; it must be 54 // thread-safe since it may be run from multiple worker threads. If 55 // |resolver_proc| is NULL then the default host resolver procedure is 56 // to call SystemHostResolverCall(). 57 // 58 // For each attempt, we could start another attempt if host is not resolved 59 // within |unresponsive_delay| time. We keep attempting to resolve the host 60 // for |max_retry_attempts|. For every retry attempt, we grow the 61 // |unresponsive_delay| by the |retry_factor| amount (that is retry interval 62 // is multiplied by the retry factor each time). Once we have retried 63 // |max_retry_attempts|, we give up on additional attempts. 64 struct NET_EXPORT_PRIVATE Params { 65 // Default delay between calls to the system resolver for the same hostname. 66 // (Can be overridden by field trial.) 67 static constexpr base::TimeDelta kDnsDefaultUnresponsiveDelay = 68 base::Seconds(6); 69 70 // Set |max_system_retry_attempts| to this to select a default retry value. 71 static constexpr size_t kDefaultRetryAttempts = -1; 72 73 // Sets up defaults. 74 Params(scoped_refptr<HostResolverProc> resolver_proc, 75 size_t max_retry_attempts); 76 77 Params(const Params& other); 78 79 ~Params(); 80 81 // The procedure to use for resolving host names. This will be NULL, except 82 // in the case of some-tests which inject custom host resolving behaviors. 83 scoped_refptr<HostResolverProc> resolver_proc; 84 85 // Maximum number retry attempts to resolve the hostname. 86 // Pass HostResolver::Options::kDefaultRetryAttempts to choose a default 87 // value. 88 size_t max_retry_attempts; 89 90 // This is the limit after which we make another attempt to resolve the host 91 // if the worker thread has not responded yet. 92 base::TimeDelta unresponsive_delay = kDnsDefaultUnresponsiveDelay; 93 94 // Factor to grow |unresponsive_delay| when we re-re-try. 95 uint32_t retry_factor = 2; 96 }; 97 98 struct CacheParams { 99 CacheParams(HostResolverCache& cache, 100 NetworkAnonymizationKey network_anonymization_key); 101 CacheParams(const CacheParams&); 102 CacheParams& operator=(const CacheParams&) = default; 103 CacheParams(CacheParams&&); 104 CacheParams& operator=(CacheParams&&) = default; 105 ~CacheParams(); 106 107 base::raw_ref<HostResolverCache> cache; 108 NetworkAnonymizationKey network_anonymization_key; 109 }; 110 111 static std::unique_ptr<HostResolverSystemTask> Create( 112 std::string hostname, 113 AddressFamily address_family, 114 HostResolverFlags flags, 115 const Params& params = Params(nullptr, 0), 116 const NetLogWithSource& job_net_log = NetLogWithSource(), 117 handles::NetworkHandle network = handles::kInvalidNetworkHandle, 118 std::optional<CacheParams> cache_params = std::nullopt); 119 120 // Same as above but resolves the result of GetHostName() (the machine's own 121 // hostname). 122 static std::unique_ptr<HostResolverSystemTask> CreateForOwnHostname( 123 AddressFamily address_family, 124 HostResolverFlags flags, 125 const Params& params = Params(nullptr, 0), 126 const NetLogWithSource& job_net_log = NetLogWithSource(), 127 handles::NetworkHandle network = handles::kInvalidNetworkHandle); 128 129 // If `hostname` is std::nullopt, resolves the result of GetHostName(). 130 // Prefer using the above 2 static functions for constructing a 131 // HostResolverSystemTask. 132 HostResolverSystemTask( 133 std::optional<std::string> hostname, 134 AddressFamily address_family, 135 HostResolverFlags flags, 136 const Params& params = Params(nullptr, 0), 137 const NetLogWithSource& job_net_log = NetLogWithSource(), 138 handles::NetworkHandle network = handles::kInvalidNetworkHandle, 139 std::optional<CacheParams> cache_params = std::nullopt); 140 141 HostResolverSystemTask(const HostResolverSystemTask&) = delete; 142 HostResolverSystemTask& operator=(const HostResolverSystemTask&) = delete; 143 144 // Cancels this HostResolverSystemTask. Any outstanding resolve attempts 145 // cannot be cancelled, but they will post back to the current thread before 146 // checking their WeakPtrs to find that this task is cancelled. 147 ~HostResolverSystemTask(); 148 149 // Starts the resolution task. This can only be called once per 150 // HostResolverSystemTask. `results_cb` will not be invoked synchronously and 151 // can own `this`. 152 void Start(SystemDnsResultsCallback results_cb); 153 was_completed()154 bool was_completed() const { 155 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 156 return results_cb_.is_null(); 157 } 158 159 private: 160 void StartLookupAttempt(); 161 162 // Callback for when DoLookup() completes. 163 void OnLookupComplete(const uint32_t attempt_number, 164 const AddressList& results, 165 const int os_error, 166 int error); 167 168 void MaybeCacheResults(const AddressList& address_list); 169 void CacheEndpoints(std::string domain_name, 170 std::vector<IPEndPoint> endpoints, 171 DnsQueryType query_type); 172 void CacheAlias(std::string domain_name, 173 DnsQueryType query_type, 174 std::string target_name); 175 176 // If `hostname_` is std::nullopt, this class should resolve the result of 177 // net::GetHostName() (the machine's own hostname). 178 const std::optional<std::string> hostname_; 179 const AddressFamily address_family_; 180 const HostResolverFlags flags_; 181 182 // Holds an owning reference to the HostResolverProc that we are going to use. 183 // This may not be the current resolver procedure by the time we call 184 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning 185 // reference ensures that it remains valid until we are done. 186 Params params_; 187 188 // The listener to the results of this HostResolverSystemTask. 189 SystemDnsResultsCallback results_cb_; 190 191 // Keeps track of the number of attempts we have made so far to resolve the 192 // host. Whenever we start an attempt to resolve the host, we increase this 193 // number. 194 uint32_t attempt_number_ = 0; 195 196 NetLogWithSource net_log_; 197 198 // Network to perform DNS lookups for. 199 const handles::NetworkHandle network_; 200 201 std::optional<CacheParams> cache_params_; 202 203 SEQUENCE_CHECKER(sequence_checker_); 204 205 // Used to loop back from the blocking lookup attempt tasks as well as from 206 // delayed retry tasks. Invalidate WeakPtrs on completion and cancellation to 207 // cancel handling of such posted tasks. 208 base::WeakPtrFactory<HostResolverSystemTask> weak_ptr_factory_{this}; 209 }; 210 211 // Ensures any necessary initialization occurs such that 212 // SystemHostResolverCall() can be called on other threads. 213 NET_EXPORT void EnsureSystemHostResolverCallReady(); 214 215 // Resolves `host` to an address list, using the system's default host resolver. 216 // (i.e. this calls out to getaddrinfo()). If successful returns OK and fills 217 // `addrlist` with a list of socket addresses. Otherwise returns a 218 // network error code, and fills `os_error` with a more specific error if it 219 // was non-NULL. 220 // `network` is an optional parameter, when specified (!= 221 // handles::kInvalidNetworkHandle) the lookup will be performed specifically for 222 // `network`. 223 // 224 // This should NOT be called in a sandboxed process. 225 NET_EXPORT_PRIVATE int SystemHostResolverCall( 226 const std::string& host, 227 AddressFamily address_family, 228 HostResolverFlags host_resolver_flags, 229 AddressList* addrlist, 230 int* os_error, 231 handles::NetworkHandle network = handles::kInvalidNetworkHandle); 232 233 // Sets the task runner that system DNS resolution will run on, which is mostly 234 // useful for tests and fuzzers that need reproducibilty of failures. 235 NET_EXPORT_PRIVATE void SetSystemDnsResolutionTaskRunnerForTesting( 236 scoped_refptr<base::TaskRunner> task_runner); 237 238 // The following will be used to override the behavior of 239 // HostResolverSystemTask. This override will be called instead of posting 240 // SystemHostResolverCall() to a worker thread. The override will only be 241 // invoked on the main thread. 242 // The override should never invoke `results_cb` synchronously. 243 NET_EXPORT void SetSystemDnsResolverOverride( 244 base::RepeatingCallback<void(const std::optional<std::string>& host, 245 AddressFamily address_family, 246 HostResolverFlags host_resolver_flags, 247 SystemDnsResultsCallback results_cb, 248 handles::NetworkHandle network)> dns_override); 249 250 } // namespace net 251 252 #endif // NET_DNS_HOST_RESOLVER_SYSTEM_TASK_H_ 253