• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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