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