/net/socket/connect_job.h
C Header | 334 lines | 186 code | 47 blank | 101 comment | 0 complexity | 506b65cc3b0a4ebbcde2c6f42a29f857 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef NET_SOCKET_CONNECT_JOB_H_
- #define NET_SOCKET_CONNECT_JOB_H_
- #include <memory>
- #include <set>
- #include <string>
- #include "base/callback_forward.h"
- #include "base/callback_helpers.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/ref_counted.h"
- #include "base/time/time.h"
- #include "base/timer/timer.h"
- #include "net/base/address_list.h"
- #include "net/base/load_states.h"
- #include "net/base/load_timing_info.h"
- #include "net/base/net_export.h"
- #include "net/base/request_priority.h"
- #include "net/dns/public/resolve_error_info.h"
- #include "net/log/net_log_with_source.h"
- #include "net/socket/connection_attempts.h"
- #include "net/socket/socket_tag.h"
- #include "net/socket/ssl_client_socket.h"
- #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace net {
- class ClientSocketFactory;
- class HostPortPair;
- class HostResolver;
- struct HostResolverEndpointResult;
- class HttpAuthCache;
- class HttpAuthController;
- class HttpAuthHandlerFactory;
- class HttpResponseInfo;
- class HttpUserAgentSettings;
- class NetLog;
- class NetLogWithSource;
- class NetworkQualityEstimator;
- class ProxyDelegate;
- class QuicStreamFactory;
- class SocketPerformanceWatcherFactory;
- class SocketTag;
- class SpdySessionPool;
- class SSLCertRequestInfo;
- class StreamSocket;
- class WebSocketEndpointLockManager;
- // Immutable socket parameters intended for shared use by all ConnectJob types.
- // Excludes priority because it can be modified over the lifetime of a
- // ConnectJob. Excludes connection timeout and NetLogWithSource because
- // ConnectJobs that wrap other ConnectJobs typically have different values for
- // those.
- struct NET_EXPORT_PRIVATE CommonConnectJobParams {
- CommonConnectJobParams(
- ClientSocketFactory* client_socket_factory,
- HostResolver* host_resolver,
- HttpAuthCache* http_auth_cache,
- HttpAuthHandlerFactory* http_auth_handler_factory,
- SpdySessionPool* spdy_session_pool,
- const quic::ParsedQuicVersionVector* quic_supported_versions,
- QuicStreamFactory* quic_stream_factory,
- ProxyDelegate* proxy_delegate,
- const HttpUserAgentSettings* http_user_agent_settings,
- SSLClientContext* ssl_client_context,
- SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
- NetworkQualityEstimator* network_quality_estimator,
- NetLog* net_log,
- WebSocketEndpointLockManager* websocket_endpoint_lock_manager);
- CommonConnectJobParams(const CommonConnectJobParams& other);
- ~CommonConnectJobParams();
- CommonConnectJobParams& operator=(const CommonConnectJobParams& other);
- raw_ptr<ClientSocketFactory> client_socket_factory;
- raw_ptr<HostResolver> host_resolver;
- raw_ptr<HttpAuthCache> http_auth_cache;
- raw_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
- raw_ptr<SpdySessionPool> spdy_session_pool;
- raw_ptr<const quic::ParsedQuicVersionVector> quic_supported_versions;
- raw_ptr<QuicStreamFactory> quic_stream_factory;
- raw_ptr<ProxyDelegate> proxy_delegate;
- raw_ptr<const HttpUserAgentSettings> http_user_agent_settings;
- raw_ptr<SSLClientContext> ssl_client_context;
- raw_ptr<SocketPerformanceWatcherFactory> socket_performance_watcher_factory;
- raw_ptr<NetworkQualityEstimator> network_quality_estimator;
- raw_ptr<NetLog> net_log;
- // This must only be non-null for WebSockets.
- raw_ptr<WebSocketEndpointLockManager> websocket_endpoint_lock_manager;
- };
- // When a host resolution completes, OnHostResolutionCallback() is invoked. If
- // it returns |kContinue|, the ConnectJob can continue immediately. If it
- // returns |kMayBeDeletedAsync|, the ConnectJob may be slated for asychronous
- // destruction, so should post a task before continuing, in case it will be
- // deleted. The purpose of kMayBeDeletedAsync is to avoid needlessly creating
- // and connecting a socket when it might not be needed.
- enum class OnHostResolutionCallbackResult {
- kContinue,
- kMayBeDeletedAsync,
- };
- // If non-null, invoked when host resolution completes. May not destroy the
- // ConnectJob synchronously, but may signal the ConnectJob may be destroyed
- // asynchronously. See OnHostResolutionCallbackResult above.
- //
- // |address_list| is the list of addresses the host being connected to was
- // resolved to, with the port fields populated to the port being connected to.
- using OnHostResolutionCallback =
- base::RepeatingCallback<OnHostResolutionCallbackResult(
- const HostPortPair& host_port_pair,
- const AddressList& address_list)>;
- // ConnectJob provides an abstract interface for "connecting" a socket.
- // The connection may involve host resolution, tcp connection, ssl connection,
- // etc.
- class NET_EXPORT_PRIVATE ConnectJob {
- public:
- // Alerts the delegate that the connection completed. |job| must be destroyed
- // by the delegate. A std::unique_ptr<> isn't used because the caller of this
- // function doesn't own |job|.
- class NET_EXPORT_PRIVATE Delegate {
- public:
- Delegate() {}
- Delegate(const Delegate&) = delete;
- Delegate& operator=(const Delegate&) = delete;
- virtual ~Delegate() {}
- // Alerts the delegate that the connection completed. |job| must be
- // destroyed by the delegate. A std::unique_ptr<> isn't used because the
- // caller of this function doesn't own |job|.
- virtual void OnConnectJobComplete(int result, ConnectJob* job) = 0;
- // Invoked when an HTTP proxy returns an HTTP auth challenge during tunnel
- // establishment. Always invoked asynchronously. The caller should use
- // |auth_controller| to set challenge response information and then invoke
- // |restart_with_auth_callback| to continue establishing a connection, or
- // delete the ConnectJob if it doesn't want to respond to the challenge.
- //
- // Will only be called once at a time. Neither OnConnectJobComplete() nor
- // OnNeedsProxyAuth() will be called synchronously when
- // |restart_with_auth_callback| is invoked. Will not be called after
- // OnConnectJobComplete() has been invoked.
- virtual void OnNeedsProxyAuth(const HttpResponseInfo& response,
- HttpAuthController* auth_controller,
- base::OnceClosure restart_with_auth_callback,
- ConnectJob* job) = 0;
- };
- // A |timeout_duration| of 0 corresponds to no timeout.
- //
- // If |net_log| is non-NULL, the ConnectJob will use it for logging.
- // Otherwise, a new one will be created of type |net_log_source_type|.
- //
- // |net_log_connect_event_type| is the NetLog event type logged on Connect()
- // and connect completion.
- ConnectJob(RequestPriority priority,
- const SocketTag& socket_tag,
- base::TimeDelta timeout_duration,
- const CommonConnectJobParams* common_connect_job_params,
- Delegate* delegate,
- const NetLogWithSource* net_log,
- NetLogSourceType net_log_source_type,
- NetLogEventType net_log_connect_event_type);
- ConnectJob(const ConnectJob&) = delete;
- ConnectJob& operator=(const ConnectJob&) = delete;
- virtual ~ConnectJob();
- // Accessors
- const NetLogWithSource& net_log() { return net_log_; }
- RequestPriority priority() const { return priority_; }
- // Releases ownership of the underlying socket to the caller. Returns the
- // released socket, or nullptr if there was a connection error.
- std::unique_ptr<StreamSocket> PassSocket();
- // Returns the connected socket, or nullptr if PassSocket() has already been
- // called. Used to query the socket state. May only be called after the
- // ConnectJob completes.
- StreamSocket* socket() { return socket_.get(); }
- void ChangePriority(RequestPriority priority);
- // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it
- // cannot complete synchronously without blocking, or another net error code
- // on error. In asynchronous completion, the ConnectJob will notify
- // |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous
- // completion, ReleaseSocket() can be called to acquire the connected socket
- // if it succeeded.
- //
- // On completion, the ConnectJob must be destroyed synchronously, since it
- // doesn't bother to stop its timer when complete.
- // TODO(mmenke): Can that be fixed?
- int Connect();
- // Returns the current LoadState of the ConnectJob. Each ConnectJob class must
- // start (optionally) with a LOAD_STATE_RESOLVING_HOST followed by
- // LOAD_STATE_CONNECTING, and never return to LOAD_STATE_CONNECTING. This
- // behavior is needed for backup ConnectJobs to function correctly.
- //
- // TODO(mmenke): Can something better be done here?
- virtual LoadState GetLoadState() const = 0;
- // Returns true if the ConnectJob has ever successfully established a TCP
- // connection. Used solely for deciding if a backup job is needed. Once it
- // starts returning true, must always return true when called in the future.
- // Not safe to call after NotifyComplete() is invoked.
- virtual bool HasEstablishedConnection() const = 0;
- // Returns a list of failed attempts to connect to the destination server.
- // Returns an empty list if connecting to a proxy.
- virtual ConnectionAttempts GetConnectionAttempts() const;
- // Returns error information about any host resolution attempt.
- virtual ResolveErrorInfo GetResolveErrorInfo() const = 0;
- // If the ConnectJob failed, returns true if the failure occurred after SSL
- // negotiation started. If the ConnectJob succeeded, the returned value is
- // undefined.
- virtual bool IsSSLError() const;
- // If the ConnectJob failed with ERR_SSL_CLIENT_AUTH_CERT_NEEDED, returns the
- // SSLCertRequestInfo received. Otherwise, returns nullptr.
- virtual scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo();
- // Returns the `HostResolverEndpointResult` structure corresponding to the
- // chosen route. Should only be called on a successful connect. If the
- // `ConnectJob` does not make DNS queries, or does not use the SVCB/HTTPS
- // record, it may return `absl::nullopt`, to avoid callers getting confused by
- // an empty `IPEndPoint` list.
- virtual absl::optional<HostResolverEndpointResult>
- GetHostResolverEndpointResult() const;
- const LoadTimingInfo::ConnectTiming& connect_timing() const {
- return connect_timing_;
- }
- // Sets |done_closure_| which will be called when |this| is deleted.
- void set_done_closure(base::OnceClosure done_closure);
- const NetLogWithSource& net_log() const { return net_log_; }
- protected:
- const SocketTag& socket_tag() const { return socket_tag_; }
- ClientSocketFactory* client_socket_factory() {
- return common_connect_job_params_->client_socket_factory;
- }
- HostResolver* host_resolver() {
- return common_connect_job_params_->host_resolver;
- }
- const HttpUserAgentSettings* http_user_agent_settings() const {
- return common_connect_job_params_->http_user_agent_settings;
- }
- SSLClientContext* ssl_client_context() {
- return common_connect_job_params_->ssl_client_context;
- }
- SocketPerformanceWatcherFactory* socket_performance_watcher_factory() {
- return common_connect_job_params_->socket_performance_watcher_factory;
- }
- NetworkQualityEstimator* network_quality_estimator() {
- return common_connect_job_params_->network_quality_estimator;
- }
- WebSocketEndpointLockManager* websocket_endpoint_lock_manager() {
- return common_connect_job_params_->websocket_endpoint_lock_manager;
- }
- const CommonConnectJobParams* common_connect_job_params() {
- return common_connect_job_params_;
- }
- void SetSocket(std::unique_ptr<StreamSocket> socket,
- absl::optional<std::set<std::string>> dns_aliases);
- void NotifyDelegateOfCompletion(int rv);
- void NotifyDelegateOfProxyAuth(const HttpResponseInfo& response,
- HttpAuthController* auth_controller,
- base::OnceClosure restart_with_auth_callback);
- // If |remaining_time| is base::TimeDelta(), stops the timeout timer, if it's
- // running. Otherwise, Starts / restarts the timeout timer to trigger in the
- // specified amount of time.
- void ResetTimer(base::TimeDelta remaining_time);
- // Returns whether or not the timeout timer is running. Only intended for use
- // by DCHECKs.
- bool TimerIsRunning() const;
- // Connection establishment timing information.
- // TODO(mmenke): This should be private.
- LoadTimingInfo::ConnectTiming connect_timing_;
- private:
- virtual int ConnectInternal() = 0;
- virtual void ChangePriorityInternal(RequestPriority priority) = 0;
- void LogConnectStart();
- void LogConnectCompletion(int net_error);
- // Alerts the delegate that the ConnectJob has timed out.
- void OnTimeout();
- // Invoked to notify subclasses that the has request timed out.
- virtual void OnTimedOutInternal();
- const base::TimeDelta timeout_duration_;
- RequestPriority priority_;
- const SocketTag socket_tag_;
- raw_ptr<const CommonConnectJobParams> common_connect_job_params_;
- // Timer to abort jobs that take too long.
- base::OneShotTimer timer_;
- raw_ptr<Delegate> delegate_;
- std::unique_ptr<StreamSocket> socket_;
- // Indicates if this is the topmost ConnectJob. The topmost ConnectJob logs an
- // extra begin and end event, to allow callers to log extra data before the
- // ConnectJob has started / after it has completed.
- const bool top_level_job_;
- NetLogWithSource net_log_;
- // This is called when |this| is deleted.
- base::ScopedClosureRunner done_closure_;
- const NetLogEventType net_log_connect_event_type_;
- };
- } // namespace net
- #endif // NET_SOCKET_CONNECT_JOB_H_