• 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 #include <set>
6 #include <string>
7 
8 #include "base/memory/raw_ptr.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/time/time.h"
11 #include "base/types/expected.h"
12 #include "net/base/completion_once_callback.h"
13 #include "net/base/connection_endpoint_metadata.h"
14 #include "net/base/http_user_agent_settings.h"
15 #include "net/base/ip_endpoint.h"
16 #include "net/base/net_error_details.h"
17 #include "net/base/net_export.h"
18 #include "net/base/network_handle.h"
19 #include "net/quic/quic_chromium_client_session.h"
20 #include "net/quic/quic_session_alias_key.h"
21 #include "net/spdy/multiplexed_session_creation_initiator.h"
22 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
23 
24 #ifndef NET_QUIC_QUIC_SESSION_ATTEMPT_H_
25 #define NET_QUIC_QUIC_SESSION_ATTEMPT_H_
26 
27 namespace net {
28 
29 class QuicSessionPool;
30 
31 // Handles a single attempt to create a new QUIC session for an endpoint.
32 // On success, the new session is activated unless another session has been
33 // activated for the same endpoint. When failed on the default network, it may
34 // retry on an alternate network if the system supports non-default networks.
35 class NET_EXPORT_PRIVATE QuicSessionAttempt {
36  public:
37   // Represents a successful QUIC session creation. Used for QUIC session
38   // creations that could complete asynchronously.
39   struct CreateSessionResult {
40     raw_ptr<QuicChromiumClientSession> session;
41     handles::NetworkHandle network = handles::kInvalidNetworkHandle;
42   };
43 
44   class Delegate {
45    public:
46     virtual ~Delegate() = default;
47 
48     // Returns the QuicSessionPool that the attempt will use.
49     virtual QuicSessionPool* GetQuicSessionPool() = 0;
50 
51     // Returns the QuicSessionAliasKey that the attempt will use to identify
52     // the session.
53     virtual const QuicSessionAliasKey& GetKey() = 0;
54 
55     // Returns the NetLogWithSource that the attempt should use.
56     virtual const NetLogWithSource& GetNetLog() = 0;
57 
58     // Called when the attempt is failed on the default network.
OnConnectionFailedOnDefaultNetwork()59     virtual void OnConnectionFailedOnDefaultNetwork() {}
60 
61     // Called when the attempt completed creating the session.
OnQuicSessionCreationComplete(int rv)62     virtual void OnQuicSessionCreationComplete(int rv) {}
63   };
64 
65   // Create a SessionAttempt for a direct connection.
66   // The `crypto_client_config_handle` is retained to keep the corresponding
67   // CryptoClientConfig alive until `this` completes. Call sites can pass
68   // nullptr to `crypto_client_config_handle` if the corresponding
69   // CryptoClientConfig is guaranteed to be alive.
70   QuicSessionAttempt(
71       Delegate* delegate,
72       IPEndPoint ip_endpoint,
73       ConnectionEndpointMetadata metadata,
74       quic::ParsedQuicVersion quic_version,
75       int cert_verify_flags,
76       base::TimeTicks dns_resolution_start_time,
77       base::TimeTicks dns_resolution_end_time,
78       bool retry_on_alternate_network_before_handshake,
79       bool use_dns_aliases,
80       std::set<std::string> dns_aliases,
81       std::unique_ptr<QuicCryptoClientConfigHandle> crypto_client_config_handle,
82       MultiplexedSessionCreationInitiator session_creation_initiator);
83   // Create a SessionAttempt for a connection proxied over the given stream.
84   QuicSessionAttempt(
85       Delegate* delegate,
86       IPEndPoint local_endpoint,
87       IPEndPoint proxy_peer_endpoint,
88       quic::ParsedQuicVersion quic_version,
89       int cert_verify_flags,
90       std::unique_ptr<QuicChromiumClientStream::Handle> proxy_stream,
91       const HttpUserAgentSettings* http_user_agent_settings,
92       MultiplexedSessionCreationInitiator session_creation_initiator);
93 
94   ~QuicSessionAttempt();
95 
96   QuicSessionAttempt(const QuicSessionAttempt&) = delete;
97   QuicSessionAttempt& operator=(const QuicSessionAttempt&) = delete;
98 
99   int Start(CompletionOnceCallback callback);
100 
session_creation_finished()101   bool session_creation_finished() const { return session_creation_finished_; }
102 
session()103   QuicChromiumClientSession* session() const { return session_.get(); }
104 
105   void PopulateNetErrorDetails(NetErrorDetails* details) const;
106 
107  private:
108   enum class State {
109     kNone,
110     kCreateSession,
111     kCreateSessionComplete,
112     kCryptoConnect,
113     kConfirmConnection,
114   };
115 
pool()116   QuicSessionPool* pool() { return delegate_->GetQuicSessionPool(); }
key()117   const QuicSessionAliasKey& key() { return delegate_->GetKey(); }
net_log()118   const NetLogWithSource& net_log() { return delegate_->GetNetLog(); }
119 
120   int DoLoop(int rv);
121 
122   int DoCreateSession();
123   int DoCreateSessionComplete(int rv);
124   int DoCryptoConnect(int rv);
125   int DoConfirmConnection(int rv);
126 
127   void OnCreateSessionComplete(base::expected<CreateSessionResult, int> result);
128   void OnCryptoConnectComplete(int rv);
129 
130   void ResetSession();
131 
132   const raw_ptr<Delegate> delegate_;
133 
134   const IPEndPoint ip_endpoint_;
135   const ConnectionEndpointMetadata metadata_;
136   const quic::ParsedQuicVersion quic_version_;
137   const int cert_verify_flags_;
138   const base::TimeTicks dns_resolution_start_time_;
139   const base::TimeTicks dns_resolution_end_time_;
140   const bool was_alternative_service_recently_broken_;
141   const bool retry_on_alternate_network_before_handshake_;
142   const bool use_dns_aliases_;
143   std::set<std::string> dns_aliases_;
144   std::unique_ptr<QuicCryptoClientConfigHandle> crypto_client_config_handle_;
145 
146   // Fields only used for session attempts to a proxy.
147   std::unique_ptr<QuicChromiumClientStream::Handle> proxy_stream_;
148   const raw_ptr<const HttpUserAgentSettings> http_user_agent_settings_;
149   const IPEndPoint local_endpoint_;
150 
151   const MultiplexedSessionCreationInitiator session_creation_initiator_;
152 
153   State next_state_ = State::kNone;
154   bool in_loop_ = false;
155 
156   raw_ptr<QuicChromiumClientSession> session_ = nullptr;
157   bool session_creation_finished_ = false;
158   bool connection_retried_ = false;
159 
160   // Used to populate NetErrorDetails after we reset `session_`.
161   HttpConnectionInfo connection_info_;
162   quic::QuicErrorCode quic_connection_error_ = quic::QUIC_NO_ERROR;
163 
164   base::TimeTicks quic_connection_start_time_;
165 
166   // If connection migraiton is supported, |network_| denotes the network on
167   // which |session_| is created.
168   handles::NetworkHandle network_ = handles::kInvalidNetworkHandle;
169 
170   CompletionOnceCallback callback_;
171 
172   base::WeakPtrFactory<QuicSessionAttempt> weak_ptr_factory_{this};
173 };
174 
175 }  // namespace net
176 
177 #endif  // NET_QUIC_QUIC_SESSION_ATTEMPT_H_
178