226 lines
8.1 KiB
C++
226 lines
8.1 KiB
C++
// Copyright 2012 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_SOCKET_SSL_CONNECT_JOB_H_
|
|
#define NET_SOCKET_SSL_CONNECT_JOB_H_
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <memory>
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "base/memory/ref_counted.h"
|
|
#include "base/time/time.h"
|
|
#include "net/base/completion_once_callback.h"
|
|
#include "net/base/completion_repeating_callback.h"
|
|
#include "net/base/net_export.h"
|
|
#include "net/base/network_anonymization_key.h"
|
|
#include "net/base/privacy_mode.h"
|
|
#include "net/dns/public/host_resolver_results.h"
|
|
#include "net/dns/public/resolve_error_info.h"
|
|
#include "net/socket/connect_job.h"
|
|
#include "net/socket/connection_attempts.h"
|
|
#include "net/socket/ssl_client_socket.h"
|
|
#include "net/ssl/ssl_cert_request_info.h"
|
|
#include "net/ssl/ssl_config_service.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
|
|
|
namespace net {
|
|
|
|
class HostPortPair;
|
|
class HttpProxySocketParams;
|
|
class SocketTag;
|
|
class SOCKSSocketParams;
|
|
class TransportSocketParams;
|
|
|
|
class NET_EXPORT_PRIVATE SSLSocketParams
|
|
: public base::RefCounted<SSLSocketParams> {
|
|
public:
|
|
enum ConnectionType { DIRECT, SOCKS_PROXY, HTTP_PROXY };
|
|
|
|
// Exactly one of |direct_params|, |socks_proxy_params|, and
|
|
// |http_proxy_params| must be non-NULL.
|
|
SSLSocketParams(scoped_refptr<TransportSocketParams> direct_params,
|
|
scoped_refptr<SOCKSSocketParams> socks_proxy_params,
|
|
scoped_refptr<HttpProxySocketParams> http_proxy_params,
|
|
const HostPortPair& host_and_port,
|
|
const SSLConfig& ssl_config,
|
|
PrivacyMode privacy_mode,
|
|
NetworkAnonymizationKey network_anonymization_key);
|
|
|
|
SSLSocketParams(const SSLSocketParams&) = delete;
|
|
SSLSocketParams& operator=(const SSLSocketParams&) = delete;
|
|
|
|
// Returns the type of the underlying connection.
|
|
ConnectionType GetConnectionType() const;
|
|
|
|
// Must be called only when GetConnectionType() returns DIRECT.
|
|
const scoped_refptr<TransportSocketParams>& GetDirectConnectionParams() const;
|
|
|
|
// Must be called only when GetConnectionType() returns SOCKS_PROXY.
|
|
const scoped_refptr<SOCKSSocketParams>& GetSocksProxyConnectionParams() const;
|
|
|
|
// Must be called only when GetConnectionType() returns HTTP_PROXY.
|
|
const scoped_refptr<HttpProxySocketParams>& GetHttpProxyConnectionParams()
|
|
const;
|
|
|
|
const HostPortPair& host_and_port() const { return host_and_port_; }
|
|
const SSLConfig& ssl_config() const { return ssl_config_; }
|
|
PrivacyMode privacy_mode() const { return privacy_mode_; }
|
|
const NetworkAnonymizationKey& network_anonymization_key() const {
|
|
return network_anonymization_key_;
|
|
}
|
|
|
|
private:
|
|
friend class base::RefCounted<SSLSocketParams>;
|
|
~SSLSocketParams();
|
|
|
|
const scoped_refptr<TransportSocketParams> direct_params_;
|
|
const scoped_refptr<SOCKSSocketParams> socks_proxy_params_;
|
|
const scoped_refptr<HttpProxySocketParams> http_proxy_params_;
|
|
const HostPortPair host_and_port_;
|
|
const SSLConfig ssl_config_;
|
|
const PrivacyMode privacy_mode_;
|
|
const NetworkAnonymizationKey network_anonymization_key_;
|
|
};
|
|
|
|
// SSLConnectJob establishes a connection, through a proxy if needed, and then
|
|
// handles the SSL handshake. It returns an SSLClientSocket on success.
|
|
class NET_EXPORT_PRIVATE SSLConnectJob : public ConnectJob,
|
|
public ConnectJob::Delegate {
|
|
public:
|
|
class NET_EXPORT_PRIVATE Factory {
|
|
public:
|
|
Factory() = default;
|
|
virtual ~Factory() = default;
|
|
|
|
virtual std::unique_ptr<SSLConnectJob> Create(
|
|
RequestPriority priority,
|
|
const SocketTag& socket_tag,
|
|
const CommonConnectJobParams* common_connect_job_params,
|
|
scoped_refptr<SSLSocketParams> params,
|
|
ConnectJob::Delegate* delegate,
|
|
const NetLogWithSource* net_log);
|
|
};
|
|
|
|
// Note: the SSLConnectJob does not own |messenger| so it must outlive the
|
|
// job.
|
|
SSLConnectJob(RequestPriority priority,
|
|
const SocketTag& socket_tag,
|
|
const CommonConnectJobParams* common_connect_job_params,
|
|
scoped_refptr<SSLSocketParams> params,
|
|
ConnectJob::Delegate* delegate,
|
|
const NetLogWithSource* net_log);
|
|
|
|
SSLConnectJob(const SSLConnectJob&) = delete;
|
|
SSLConnectJob& operator=(const SSLConnectJob&) = delete;
|
|
|
|
~SSLConnectJob() override;
|
|
|
|
// ConnectJob methods.
|
|
LoadState GetLoadState() const override;
|
|
bool HasEstablishedConnection() const override;
|
|
|
|
// ConnectJob::Delegate methods.
|
|
void OnConnectJobComplete(int result, ConnectJob* job) override;
|
|
void OnNeedsProxyAuth(const HttpResponseInfo& response,
|
|
HttpAuthController* auth_controller,
|
|
base::OnceClosure restart_with_auth_callback,
|
|
ConnectJob* job) override;
|
|
ConnectionAttempts GetConnectionAttempts() const override;
|
|
ResolveErrorInfo GetResolveErrorInfo() const override;
|
|
bool IsSSLError() const override;
|
|
scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override;
|
|
|
|
// Returns the timeout for the SSL handshake. This is the same for all
|
|
// connections regardless of whether or not there is a proxy in use.
|
|
static base::TimeDelta HandshakeTimeoutForTesting();
|
|
|
|
private:
|
|
enum State {
|
|
STATE_TRANSPORT_CONNECT,
|
|
STATE_TRANSPORT_CONNECT_COMPLETE,
|
|
STATE_SOCKS_CONNECT,
|
|
STATE_SOCKS_CONNECT_COMPLETE,
|
|
STATE_TUNNEL_CONNECT,
|
|
STATE_TUNNEL_CONNECT_COMPLETE,
|
|
STATE_SSL_CONNECT,
|
|
STATE_SSL_CONNECT_COMPLETE,
|
|
STATE_NONE,
|
|
};
|
|
|
|
void OnIOComplete(int result);
|
|
|
|
// Runs the state transition loop.
|
|
int DoLoop(int result);
|
|
|
|
int DoTransportConnect();
|
|
int DoTransportConnectComplete(int result);
|
|
int DoSOCKSConnect();
|
|
int DoSOCKSConnectComplete(int result);
|
|
int DoTunnelConnect();
|
|
int DoTunnelConnectComplete(int result);
|
|
int DoSSLConnect();
|
|
int DoSSLConnectComplete(int result);
|
|
|
|
// Returns the initial state for the state machine based on the
|
|
// |connection_type|.
|
|
static State GetInitialState(SSLSocketParams::ConnectionType connection_type);
|
|
|
|
// Starts the SSL connection process. Returns OK on success and
|
|
// ERR_IO_PENDING if it cannot immediately service the request.
|
|
// Otherwise, it returns a net error code.
|
|
int ConnectInternal() override;
|
|
|
|
void ResetStateForRestart();
|
|
|
|
void ChangePriorityInternal(RequestPriority priority) override;
|
|
|
|
scoped_refptr<SSLSocketParams> params_;
|
|
|
|
State next_state_;
|
|
CompletionRepeatingCallback callback_;
|
|
std::unique_ptr<ConnectJob> nested_connect_job_;
|
|
std::unique_ptr<StreamSocket> nested_socket_;
|
|
std::unique_ptr<SSLClientSocket> ssl_socket_;
|
|
|
|
// True once SSL negotiation has started.
|
|
bool ssl_negotiation_started_ = false;
|
|
|
|
// True if legacy crypto should be disabled for the job's current connection
|
|
// attempt. On error, the connection will be retried with legacy crypto
|
|
// enabled.
|
|
bool disable_legacy_crypto_with_fallback_ = true;
|
|
|
|
scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_;
|
|
|
|
ConnectionAttempts connection_attempts_;
|
|
ResolveErrorInfo resolve_error_info_;
|
|
// The address of the server the connect job is connected to. Populated if
|
|
// and only if the connect job is connected *directly* to the server (not
|
|
// through an HTTPS CONNECT request or a SOCKS proxy).
|
|
IPEndPoint server_address_;
|
|
|
|
// Any DNS aliases for the remote endpoint. Includes all known aliases, e.g.
|
|
// from A, AAAA, or HTTPS, not just from the address used for the connection,
|
|
// in no particular order. Stored because `nested_connect_job_` has a limited
|
|
// lifetime and the aliases can no longer be retrieved from there by by the
|
|
// time that the aliases are needed to be passed in SetSocket.
|
|
std::set<std::string> dns_aliases_;
|
|
|
|
// The endpoint result used by `nested_connect_job_`. Stored because
|
|
// `nested_connect_job_` has a limited lifetime.
|
|
absl::optional<HostResolverEndpointResult> endpoint_result_;
|
|
|
|
// If not `absl::nullopt`, the ECH retry configs to use in the ECH recovery
|
|
// flow. `endpoint_result_` will then contain the endpoint to reconnect to.
|
|
absl::optional<std::vector<uint8_t>> ech_retry_configs_;
|
|
};
|
|
|
|
} // namespace net
|
|
|
|
#endif // NET_SOCKET_SSL_CONNECT_JOB_H_
|