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