1 // Copyright 2024 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_TLS_STREAM_ATTEMPT_H_ 6 #define NET_SOCKET_TLS_STREAM_ATTEMPT_H_ 7 8 #include <memory> 9 #include <optional> 10 #include <string_view> 11 #include <vector> 12 13 #include "base/memory/raw_ptr.h" 14 #include "base/memory/scoped_refptr.h" 15 #include "base/timer/timer.h" 16 #include "base/types/expected.h" 17 #include "base/values.h" 18 #include "net/base/completion_once_callback.h" 19 #include "net/base/host_port_pair.h" 20 #include "net/base/ip_endpoint.h" 21 #include "net/base/net_export.h" 22 #include "net/socket/stream_attempt.h" 23 #include "net/ssl/ssl_cert_request_info.h" 24 #include "net/ssl/ssl_config.h" 25 26 namespace net { 27 28 class TcpStreamAttempt; 29 class SSLClientSocket; 30 31 // Represents a single TLS connection attempt. 32 class NET_EXPORT_PRIVATE TlsStreamAttempt final : public StreamAttempt { 33 public: 34 // Timeout for the TLS handshake. The timeout is the same as SSLConnectJob. 35 static constexpr base::TimeDelta kTlsHandshakeTimeout = base::Seconds(30); 36 37 // Represents an error of getting a SSLConfig for an attempt. 38 enum class GetSSLConfigError { 39 // The attempt should abort. Currently this happens when we start an attempt 40 // without waiting for HTTPS RR and the DNS resolution resulted in making 41 // the attempt SVCB-reliant. 42 kAbort, 43 }; 44 45 // An interface that provides a SSLConfig to TlsStreamAttempt lazily. 46 class NET_EXPORT_PRIVATE SSLConfigProvider { 47 public: 48 SSLConfigProvider() = default; 49 virtual ~SSLConfigProvider() = default; 50 51 SSLConfigProvider(const SSLConfigProvider&) = delete; 52 SSLConfigProvider& operator=(const SSLConfigProvider&) = delete; 53 54 // Returns OK when a SSLConfig is immediately available. `callback` is never 55 // invoked. Otherwise, returns ERR_IO_PENDING when `this` can't provide a 56 // SSLConfig immediately. `callback` is invoked when a SSLConfig is ready. 57 virtual int WaitForSSLConfigReady(CompletionOnceCallback callback) = 0; 58 59 // Returns a SSLConfig. Should be called only after WaitForSSLConfigReady() 60 // returns OK or the callback is invoked. 61 virtual base::expected<SSLConfig, GetSSLConfigError> GetSSLConfig() = 0; 62 }; 63 64 // `params` and `ssl_config_provider` must outlive `this`. 65 TlsStreamAttempt(const StreamAttemptParams* params, 66 IPEndPoint ip_endpoint, 67 HostPortPair host_port_pair, 68 SSLConfigProvider* ssl_config_provider); 69 70 TlsStreamAttempt(const TlsStreamAttempt&) = delete; 71 TlsStreamAttempt& operator=(const TlsStreamAttempt&) = delete; 72 73 ~TlsStreamAttempt() override; 74 75 // StreamAttempt implementations: 76 LoadState GetLoadState() const override; 77 base::Value::Dict GetInfoAsValue() const override; 78 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override; 79 80 // Set a callback that will be invoked after the TCP handshake completes. 81 // Note that the callback won't be called and discarded immediately when 82 // `this` has already completed the TCP handshake. 83 void SetTcpHandshakeCompletionCallback(CompletionOnceCallback callback); 84 IsTcpHandshakeCompleted()85 bool IsTcpHandshakeCompleted() { return tcp_handshake_completed_; } 86 IsTlsHandshakeStarted()87 bool IsTlsHandshakeStarted() { return tls_handshake_started_; } 88 89 private: 90 enum class State { 91 kNone, 92 kTcpAttempt, 93 kTcpAttemptComplete, 94 kTlsAttempt, 95 kTlsAttemptComplete, 96 }; 97 98 static std::string_view StateToString(State state); 99 100 // StreamAttempt methods: 101 int StartInternal() override; 102 base::Value::Dict GetNetLogStartParams() override; 103 104 void OnIOComplete(int rv); 105 106 int DoLoop(int rv); 107 int DoTcpAttempt(); 108 int DoTcpAttemptComplete(int rv); 109 int DoTlsAttempt(int rv); 110 int DoTlsAttemptComplete(int rv); 111 112 void OnTlsHandshakeTimeout(); 113 114 State next_state_ = State::kNone; 115 const HostPortPair host_port_pair_; 116 raw_ptr<SSLConfigProvider> ssl_config_provider_; 117 118 std::unique_ptr<TcpStreamAttempt> nested_attempt_; 119 CompletionOnceCallback tcp_handshake_completion_callback_; 120 121 bool tcp_handshake_completed_ = false; 122 bool tls_handshake_started_ = false; 123 base::OneShotTimer tls_handshake_timeout_timer_; 124 std::unique_ptr<SSLClientSocket> ssl_socket_; 125 scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_; 126 127 std::optional<SSLConfig> ssl_config_; 128 std::optional<std::vector<uint8_t>> ech_retry_configs_; 129 }; 130 131 } // namespace net 132 133 #endif // NET_SOCKET_TLS_STREAM_ATTEMPT_H_ 134