File: host_resolver_system_task.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (220 lines) | stat: -rw-r--r-- 9,263 bytes parent folder | download
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_