xref: /aosp_15_r20/external/cronet/net/socket/connect_job.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 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_SOCKET_CONNECT_JOB_H_
6 #define NET_SOCKET_CONNECT_JOB_H_
7 
8 #include <memory>
9 #include <optional>
10 #include <set>
11 #include <string>
12 
13 #include "base/functional/callback_forward.h"
14 #include "base/functional/callback_helpers.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/memory/scoped_refptr.h"
17 #include "base/time/time.h"
18 #include "base/timer/timer.h"
19 #include "net/base/load_states.h"
20 #include "net/base/load_timing_info.h"
21 #include "net/base/net_export.h"
22 #include "net/base/request_priority.h"
23 #include "net/dns/public/host_resolver_results.h"
24 #include "net/dns/public/resolve_error_info.h"
25 #include "net/http/http_server_properties.h"
26 #include "net/log/net_log_with_source.h"
27 #include "net/socket/connection_attempts.h"
28 #include "net/socket/next_proto.h"
29 #include "net/socket/socket_tag.h"
30 #include "net/socket/ssl_client_socket.h"
31 #include "net/ssl/ssl_config.h"
32 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
33 
34 namespace net {
35 
36 class ClientSocketFactory;
37 class HostPortPair;
38 class HostResolver;
39 struct HostResolverEndpointResult;
40 class HttpAuthCache;
41 class HttpAuthController;
42 class HttpAuthHandlerFactory;
43 class HttpResponseInfo;
44 class HttpUserAgentSettings;
45 class NetLog;
46 class NetLogWithSource;
47 class NetworkQualityEstimator;
48 class ProxyDelegate;
49 class QuicSessionPool;
50 class SocketPerformanceWatcherFactory;
51 class SocketTag;
52 class SpdySessionPool;
53 class SSLCertRequestInfo;
54 class StreamSocket;
55 class WebSocketEndpointLockManager;
56 
57 // Immutable socket parameters intended for shared use by all ConnectJob types.
58 // Excludes priority because it can be modified over the lifetime of a
59 // ConnectJob. Excludes connection timeout and NetLogWithSource because
60 // ConnectJobs that wrap other ConnectJobs typically have different values for
61 // those.
62 struct NET_EXPORT_PRIVATE CommonConnectJobParams {
63   // TODO(https://crbug.com/1505765): Look into passing in HttpNetworkSession
64   // instead.
65   CommonConnectJobParams(
66       ClientSocketFactory* client_socket_factory,
67       HostResolver* host_resolver,
68       HttpAuthCache* http_auth_cache,
69       HttpAuthHandlerFactory* http_auth_handler_factory,
70       SpdySessionPool* spdy_session_pool,
71       const quic::ParsedQuicVersionVector* quic_supported_versions,
72       QuicSessionPool* quic_session_pool,
73       ProxyDelegate* proxy_delegate,
74       const HttpUserAgentSettings* http_user_agent_settings,
75       SSLClientContext* ssl_client_context,
76       SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
77       NetworkQualityEstimator* network_quality_estimator,
78       NetLog* net_log,
79       WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
80       HttpServerProperties* http_server_properties,
81       const NextProtoVector* alpn_protos,
82       const SSLConfig::ApplicationSettings* application_settings,
83       const bool* ignore_certificate_errors,
84       const bool* enable_early_data);
85   CommonConnectJobParams(const CommonConnectJobParams& other);
86   ~CommonConnectJobParams();
87 
88   CommonConnectJobParams& operator=(const CommonConnectJobParams& other);
89 
90   raw_ptr<ClientSocketFactory> client_socket_factory;
91   raw_ptr<HostResolver> host_resolver;
92   raw_ptr<HttpAuthCache> http_auth_cache;
93   raw_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
94   raw_ptr<SpdySessionPool> spdy_session_pool;
95   raw_ptr<const quic::ParsedQuicVersionVector> quic_supported_versions;
96   raw_ptr<QuicSessionPool> quic_session_pool;
97   raw_ptr<ProxyDelegate> proxy_delegate;
98   raw_ptr<const HttpUserAgentSettings> http_user_agent_settings;
99   raw_ptr<SSLClientContext> ssl_client_context;
100   raw_ptr<SocketPerformanceWatcherFactory> socket_performance_watcher_factory;
101   raw_ptr<NetworkQualityEstimator> network_quality_estimator;
102   raw_ptr<NetLog> net_log;
103 
104   // This must only be non-null for WebSockets.
105   raw_ptr<WebSocketEndpointLockManager> websocket_endpoint_lock_manager;
106 
107   raw_ptr<HttpServerProperties> http_server_properties;
108 
109   raw_ptr<const NextProtoVector> alpn_protos;
110   raw_ptr<const SSLConfig::ApplicationSettings> application_settings;
111   raw_ptr<const bool> ignore_certificate_errors;
112   raw_ptr<const bool> enable_early_data;
113 };
114 
115 // When a host resolution completes, OnHostResolutionCallback() is invoked. If
116 // it returns |kContinue|, the ConnectJob can continue immediately. If it
117 // returns |kMayBeDeletedAsync|, the ConnectJob may be slated for asychronous
118 // destruction, so should post a task before continuing, in case it will be
119 // deleted. The purpose of kMayBeDeletedAsync is to avoid needlessly creating
120 // and connecting a socket when it might not be needed.
121 enum class OnHostResolutionCallbackResult {
122   kContinue,
123   kMayBeDeletedAsync,
124 };
125 
126 // If non-null, invoked when host resolution completes. May not destroy the
127 // ConnectJob synchronously, but may signal the ConnectJob may be destroyed
128 // asynchronously. See OnHostResolutionCallbackResult above.
129 //
130 // `endpoint_results` is the list of endpoints the host being connected to was
131 // resolved to, with the port fields populated to the port being connected to.
132 using OnHostResolutionCallback =
133     base::RepeatingCallback<OnHostResolutionCallbackResult(
134         const HostPortPair& host_port_pair,
135         const std::vector<HostResolverEndpointResult>& endpoint_results,
136         const std::set<std::string>& aliases)>;
137 
138 // ConnectJob provides an abstract interface for "connecting" a socket.
139 // The connection may involve host resolution, tcp connection, ssl connection,
140 // etc.
141 class NET_EXPORT_PRIVATE ConnectJob {
142  public:
143   // Alerts the delegate that the connection completed. |job| must be destroyed
144   // by the delegate. A std::unique_ptr<> isn't used because the caller of this
145   // function doesn't own |job|.
146   class NET_EXPORT_PRIVATE Delegate {
147    public:
148     Delegate() = default;
149 
150     Delegate(const Delegate&) = delete;
151     Delegate& operator=(const Delegate&) = delete;
152 
153     virtual ~Delegate() = default;
154 
155     // Alerts the delegate that the connection completed. |job| must be
156     // destroyed by the delegate. A std::unique_ptr<> isn't used because the
157     // caller of this function doesn't own |job|.
158     virtual void OnConnectJobComplete(int result, ConnectJob* job) = 0;
159 
160     // Invoked when an HTTP proxy returns an HTTP auth challenge during tunnel
161     // establishment. Always invoked asynchronously. The caller should use
162     // |auth_controller| to set challenge response information and then invoke
163     // |restart_with_auth_callback| to continue establishing a connection, or
164     // delete the ConnectJob if it doesn't want to respond to the challenge.
165     //
166     // Will only be called once at a time. Neither OnConnectJobComplete() nor
167     // OnNeedsProxyAuth() will be called synchronously when
168     // |restart_with_auth_callback| is invoked. Will not be called after
169     // OnConnectJobComplete() has been invoked.
170     virtual void OnNeedsProxyAuth(const HttpResponseInfo& response,
171                                   HttpAuthController* auth_controller,
172                                   base::OnceClosure restart_with_auth_callback,
173                                   ConnectJob* job) = 0;
174   };
175 
176   // A |timeout_duration| of 0 corresponds to no timeout.
177   //
178   // If |net_log| is non-NULL, the ConnectJob will use it for logging.
179   // Otherwise, a new one will be created of type |net_log_source_type|.
180   //
181   // |net_log_connect_event_type| is the NetLog event type logged on Connect()
182   // and connect completion.
183   ConnectJob(RequestPriority priority,
184              const SocketTag& socket_tag,
185              base::TimeDelta timeout_duration,
186              const CommonConnectJobParams* common_connect_job_params,
187              Delegate* delegate,
188              const NetLogWithSource* net_log,
189              NetLogSourceType net_log_source_type,
190              NetLogEventType net_log_connect_event_type);
191 
192   ConnectJob(const ConnectJob&) = delete;
193   ConnectJob& operator=(const ConnectJob&) = delete;
194 
195   virtual ~ConnectJob();
196 
197   // Accessors
net_log()198   const NetLogWithSource& net_log() { return net_log_; }
priority()199   RequestPriority priority() const { return priority_; }
200 
201   // Releases ownership of the underlying socket to the caller. Returns the
202   // released socket, or nullptr if there was a connection error.
203   std::unique_ptr<StreamSocket> PassSocket();
204 
205   // Returns the connected socket, or nullptr if PassSocket() has already been
206   // called. Used to query the socket state. May only be called after the
207   // ConnectJob completes.
socket()208   StreamSocket* socket() { return socket_.get(); }
209 
210   void ChangePriority(RequestPriority priority);
211 
212   // Begins connecting the socket.  Returns OK on success, ERR_IO_PENDING if it
213   // cannot complete synchronously without blocking, or another net error code
214   // on error.  In asynchronous completion, the ConnectJob will notify
215   // |delegate_| via OnConnectJobComplete.  In both asynchronous and synchronous
216   // completion, ReleaseSocket() can be called to acquire the connected socket
217   // if it succeeded.
218   //
219   // On completion, the ConnectJob must be destroyed synchronously, since it
220   // doesn't bother to stop its timer when complete.
221   // TODO(mmenke): Can that be fixed?
222   int Connect();
223 
224   // Returns the current LoadState of the ConnectJob. Each ConnectJob class must
225   // start (optionally) with a LOAD_STATE_RESOLVING_HOST followed by
226   // LOAD_STATE_CONNECTING, and never return to LOAD_STATE_CONNECTING. This
227   // behavior is needed for backup ConnectJobs to function correctly.
228   //
229   // TODO(mmenke): Can something better be done here?
230   virtual LoadState GetLoadState() const = 0;
231 
232   // Returns true if the ConnectJob has ever successfully established a TCP
233   // connection. Used solely for deciding if a backup job is needed. Once it
234   // starts returning true, must always return true when called in the future.
235   // Not safe to call after NotifyComplete() is invoked.
236   virtual bool HasEstablishedConnection() const = 0;
237 
238   // Returns a list of failed attempts to connect to the destination server.
239   // Returns an empty list if connecting to a proxy.
240   virtual ConnectionAttempts GetConnectionAttempts() const;
241 
242   // Returns error information about any host resolution attempt.
243   virtual ResolveErrorInfo GetResolveErrorInfo() const = 0;
244 
245   // If the ConnectJob failed, returns true if the failure occurred after SSL
246   // negotiation started. If the ConnectJob succeeded, the returned value is
247   // undefined.
248   virtual bool IsSSLError() const;
249 
250   // If the ConnectJob failed with ERR_SSL_CLIENT_AUTH_CERT_NEEDED, returns the
251   // SSLCertRequestInfo received. Otherwise, returns nullptr.
252   virtual scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo();
253 
254   // Returns the `HostResolverEndpointResult` structure corresponding to the
255   // chosen route. Should only be called on a successful connect. If the
256   // `ConnectJob` does not make DNS queries, or does not use the SVCB/HTTPS
257   // record, it may return `std::nullopt`, to avoid callers getting confused by
258   // an empty `IPEndPoint` list.
259   virtual std::optional<HostResolverEndpointResult>
260   GetHostResolverEndpointResult() const;
261 
connect_timing()262   const LoadTimingInfo::ConnectTiming& connect_timing() const {
263     return connect_timing_;
264   }
265 
266   // Sets |done_closure_| which will be called when |this| is deleted.
267   void set_done_closure(base::OnceClosure done_closure);
268 
net_log()269   const NetLogWithSource& net_log() const { return net_log_; }
270 
271  protected:
socket_tag()272   const SocketTag& socket_tag() const { return socket_tag_; }
client_socket_factory()273   ClientSocketFactory* client_socket_factory() {
274     return common_connect_job_params_->client_socket_factory;
275   }
host_resolver()276   HostResolver* host_resolver() {
277     return common_connect_job_params_->host_resolver;
278   }
http_user_agent_settings()279   const HttpUserAgentSettings* http_user_agent_settings() const {
280     return common_connect_job_params_->http_user_agent_settings;
281   }
ssl_client_context()282   SSLClientContext* ssl_client_context() {
283     return common_connect_job_params_->ssl_client_context;
284   }
socket_performance_watcher_factory()285   SocketPerformanceWatcherFactory* socket_performance_watcher_factory() {
286     return common_connect_job_params_->socket_performance_watcher_factory;
287   }
network_quality_estimator()288   NetworkQualityEstimator* network_quality_estimator() {
289     return common_connect_job_params_->network_quality_estimator;
290   }
websocket_endpoint_lock_manager()291   WebSocketEndpointLockManager* websocket_endpoint_lock_manager() {
292     return common_connect_job_params_->websocket_endpoint_lock_manager;
293   }
http_server_properties()294   HttpServerProperties* http_server_properties() {
295     return common_connect_job_params_->http_server_properties;
296   }
common_connect_job_params()297   const CommonConnectJobParams* common_connect_job_params() const {
298     return common_connect_job_params_;
299   }
300 
301   void SetSocket(std::unique_ptr<StreamSocket> socket,
302                  std::optional<std::set<std::string>> dns_aliases);
303   void NotifyDelegateOfCompletion(int rv);
304   void NotifyDelegateOfProxyAuth(const HttpResponseInfo& response,
305                                  HttpAuthController* auth_controller,
306                                  base::OnceClosure restart_with_auth_callback);
307 
308   // If |remaining_time| is base::TimeDelta(), stops the timeout timer, if it's
309   // running. Otherwise, Starts / restarts the timeout timer to trigger in the
310   // specified amount of time.
311   void ResetTimer(base::TimeDelta remaining_time);
312 
313   // Returns whether or not the timeout timer is running. Only intended for use
314   // by DCHECKs.
315   bool TimerIsRunning() const;
316 
317   // Connection establishment timing information.
318   // TODO(mmenke): This should be private.
319   LoadTimingInfo::ConnectTiming connect_timing_;
320 
321  private:
322   virtual int ConnectInternal() = 0;
323 
324   virtual void ChangePriorityInternal(RequestPriority priority) = 0;
325 
326   void LogConnectStart();
327   void LogConnectCompletion(int net_error);
328 
329   // Alerts the delegate that the ConnectJob has timed out.
330   void OnTimeout();
331 
332   // Invoked to notify subclasses that the has request timed out.
333   virtual void OnTimedOutInternal();
334 
335   const base::TimeDelta timeout_duration_;
336   RequestPriority priority_;
337   const SocketTag socket_tag_;
338   raw_ptr<const CommonConnectJobParams> common_connect_job_params_;
339   // Timer to abort jobs that take too long.
340   base::OneShotTimer timer_;
341   raw_ptr<Delegate> delegate_;
342   std::unique_ptr<StreamSocket> socket_;
343   // Indicates if this is the topmost ConnectJob. The topmost ConnectJob logs an
344   // extra begin and end event, to allow callers to log extra data before the
345   // ConnectJob has started / after it has completed.
346   const bool top_level_job_;
347   NetLogWithSource net_log_;
348   // This is called when |this| is deleted.
349   base::ScopedClosureRunner done_closure_;
350   const NetLogEventType net_log_connect_event_type_;
351 };
352 
353 }  // namespace net
354 
355 #endif  // NET_SOCKET_CONNECT_JOB_H_
356