1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // A client specific quic::QuicSession subclass. This class owns the underlying 6 // quic::QuicConnection and QuicConnectionHelper objects. The connection stores 7 // a non-owning pointer to the helper so this session needs to ensure that 8 // the helper outlives the connection. 9 10 #ifndef NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_ 11 #define NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_ 12 13 #include <stddef.h> 14 15 #include <list> 16 #include <memory> 17 #include <set> 18 #include <string> 19 #include <vector> 20 21 #include "base/containers/mru_cache.h" 22 #include "base/macros.h" 23 #include "base/observer_list_types.h" 24 #include "base/time/time.h" 25 #include "base/timer/timer.h" 26 #include "net/base/completion_once_callback.h" 27 #include "net/base/load_timing_info.h" 28 #include "net/base/net_error_details.h" 29 #include "net/base/net_export.h" 30 #include "net/base/proxy_server.h" 31 #include "net/log/net_log_with_source.h" 32 #include "net/quic/quic_chromium_client_stream.h" 33 #include "net/quic/quic_chromium_packet_reader.h" 34 #include "net/quic/quic_chromium_packet_writer.h" 35 #include "net/quic/quic_connection_logger.h" 36 #include "net/quic/quic_connectivity_probing_manager.h" 37 #include "net/quic/quic_crypto_client_config_handle.h" 38 #include "net/quic/quic_http3_logger.h" 39 #include "net/quic/quic_session_key.h" 40 #include "net/socket/socket_performance_watcher.h" 41 #include "net/spdy/http2_priority_dependencies.h" 42 #include "net/spdy/multiplexed_session.h" 43 #include "net/spdy/server_push_delegate.h" 44 #include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h" 45 #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h" 46 #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h" 47 #include "net/third_party/quiche/src/quic/core/quic_packets.h" 48 #include "net/third_party/quiche/src/quic/core/quic_server_id.h" 49 #include "net/third_party/quiche/src/quic/core/quic_time.h" 50 #include "net/traffic_annotation/network_traffic_annotation.h" 51 52 namespace net { 53 54 class CertVerifyResult; 55 class DatagramClientSocket; 56 class NetLog; 57 class QuicCryptoClientStreamFactory; 58 class QuicServerInfo; 59 class QuicStreamFactory; 60 class SSLConfigService; 61 class SSLInfo; 62 class TransportSecurityState; 63 64 namespace test { 65 class QuicChromiumClientSessionPeer; 66 } // namespace test 67 68 // SETTINGS_MAX_HEADERS_LIST_SIZE, the maximum size of uncompressed QUIC headers 69 // that the server is allowed to send. 70 const size_t kQuicMaxHeaderListSize = 256 * 1024; 71 72 // Result of a session migration attempt. 73 enum class MigrationResult { 74 SUCCESS, // Migration succeeded. 75 NO_NEW_NETWORK, // Migration failed since no new network was found. 76 FAILURE // Migration failed for other reasons. 77 }; 78 79 // Mode of connection migration. 80 enum class ConnectionMigrationMode { 81 NO_MIGRATION, 82 NO_MIGRATION_ON_PATH_DEGRADING_V1, 83 FULL_MIGRATION_V1, 84 NO_MIGRATION_ON_PATH_DEGRADING_V2, 85 FULL_MIGRATION_V2 86 }; 87 88 // Cause of a migration. 89 enum MigrationCause { 90 UNKNOWN_CAUSE, 91 ON_NETWORK_CONNECTED, // No probing. 92 ON_NETWORK_DISCONNECTED, // No probing. 93 ON_WRITE_ERROR, // No probing. 94 ON_NETWORK_MADE_DEFAULT, // With probing. 95 ON_MIGRATE_BACK_TO_DEFAULT_NETWORK, // With probing. 96 CHANGE_NETWORK_ON_PATH_DEGRADING, // With probing. 97 CHANGE_PORT_ON_PATH_DEGRADING, // With probing. 98 NEW_NETWORK_CONNECTED_POST_PATH_DEGRADING, // With probing. 99 MIGRATION_CAUSE_MAX 100 }; 101 102 // Result of connection migration. 103 enum QuicConnectionMigrationStatus { 104 MIGRATION_STATUS_NO_MIGRATABLE_STREAMS, 105 MIGRATION_STATUS_ALREADY_MIGRATED, 106 MIGRATION_STATUS_INTERNAL_ERROR, 107 MIGRATION_STATUS_TOO_MANY_CHANGES, 108 MIGRATION_STATUS_SUCCESS, 109 MIGRATION_STATUS_NON_MIGRATABLE_STREAM, 110 MIGRATION_STATUS_NOT_ENABLED, 111 MIGRATION_STATUS_NO_ALTERNATE_NETWORK, 112 MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED, 113 MIGRATION_STATUS_DISABLED_BY_CONFIG, 114 MIGRATION_STATUS_PATH_DEGRADING_NOT_ENABLED, 115 MIGRATION_STATUS_TIMEOUT, 116 MIGRATION_STATUS_ON_WRITE_ERROR_DISABLED, 117 MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED, 118 MIGRATION_STATUS_IDLE_MIGRATION_TIMEOUT, 119 MIGRATION_STATUS_MAX 120 }; 121 122 // Result of a connectivity probing attempt. 123 enum class ProbingResult { 124 PENDING, // Probing started, pending result. 125 DISABLED_WITH_IDLE_SESSION, // Probing disabled with idle session. 126 DISABLED_BY_CONFIG, // Probing disabled by config. 127 DISABLED_BY_NON_MIGRABLE_STREAM, // Probing disabled by special stream. 128 INTERNAL_ERROR, // Probing failed for internal reason. 129 FAILURE, // Probing failed for other reason. 130 }; 131 132 class NET_EXPORT_PRIVATE QuicChromiumClientSession 133 : public quic::QuicSpdyClientSessionBase, 134 public MultiplexedSession, 135 public QuicConnectivityProbingManager::Delegate, 136 public QuicChromiumPacketReader::Visitor, 137 public QuicChromiumPacketWriter::Delegate { 138 public: 139 class StreamRequest; 140 141 // An interface that when implemented and added via 142 // AddConnectivityObserver(), provides notifications when connectivity 143 // quality changes. 144 class NET_EXPORT_PRIVATE ConnectivityObserver : public base::CheckedObserver { 145 public: 146 // Called when path degrading is detected on |network|. 147 virtual void OnSessionPathDegrading( 148 QuicChromiumClientSession* session, 149 NetworkChangeNotifier::NetworkHandle network) = 0; 150 151 // Called when forward progress is made after path degrading on |network|. 152 virtual void OnSessionResumedPostPathDegrading( 153 QuicChromiumClientSession* session, 154 NetworkChangeNotifier::NetworkHandle network) = 0; 155 156 // Called when |session| encounters write error on |network|. 157 // A write error may be caused by the change in the underlying network 158 // interface, and can be pre-emptive hints of connectivity quality changes 159 // based on the |error_code|. 160 virtual void OnSessionEncounteringWriteError( 161 QuicChromiumClientSession* session, 162 NetworkChangeNotifier::NetworkHandle network, 163 int error_code) = 0; 164 165 // Called when |session| is closed by |source| with |error_code| 166 // and handshake has been confirmed. 167 virtual void OnSessionClosedAfterHandshake( 168 QuicChromiumClientSession* session, 169 NetworkChangeNotifier::NetworkHandle network, 170 quic::ConnectionCloseSource source, 171 quic::QuicErrorCode error_code) = 0; 172 173 // Called when |this| is registered to monitor the connectivity of the 174 // |session|. 175 virtual void OnSessionRegistered( 176 QuicChromiumClientSession* session, 177 NetworkChangeNotifier::NetworkHandle network) = 0; 178 179 // Called when |session| is removed. 180 virtual void OnSessionRemoved(QuicChromiumClientSession* session) = 0; 181 }; 182 183 // Wrapper for interacting with the session in a restricted fashion which 184 // hides the details of the underlying session's lifetime. All methods of 185 // the Handle are safe to use even after the underlying session is destroyed. 186 class NET_EXPORT_PRIVATE Handle 187 : public MultiplexedSessionHandle, 188 public quic::QuicClientPushPromiseIndex::Delegate { 189 public: 190 // Constructs a handle to |session| which was created via the alternative 191 // server |destination|. 192 Handle(const base::WeakPtr<QuicChromiumClientSession>& session, 193 const HostPortPair& destination); 194 Handle(const Handle& other) = delete; 195 ~Handle() override; 196 197 // Returns true if the session is still connected. 198 bool IsConnected() const; 199 200 // Returns true if the handshake has been confirmed. 201 bool OneRttKeysAvailable() const; 202 203 // Starts a request to rendezvous with a promised a stream. If OK is 204 // returned, then |push_stream_| will be updated with the promised 205 // stream. If ERR_IO_PENDING is returned, then when the rendezvous is 206 // eventually completed |callback| will be called. 207 int RendezvousWithPromised(const spdy::Http2HeaderBlock& headers, 208 CompletionOnceCallback callback); 209 210 // Starts a request to create a stream. If OK is returned, then 211 // |stream_| will be updated with the newly created stream. If 212 // ERR_IO_PENDING is returned, then when the request is eventuallly 213 // complete |callback| will be called. 214 int RequestStream(bool requires_confirmation, 215 CompletionOnceCallback callback, 216 const NetworkTrafficAnnotationTag& traffic_annotation); 217 218 // Releases |stream_| to the caller. Returns nullptr if the underlying 219 // QuicChromiumClientSession is closed. 220 std::unique_ptr<QuicChromiumClientStream::Handle> ReleaseStream(); 221 222 // Releases |push_stream_| to the caller. 223 std::unique_ptr<QuicChromiumClientStream::Handle> ReleasePromisedStream(); 224 225 // Sends Rst for the stream, and makes sure that future calls to 226 // IsClosedStream(id) return true, which ensures that any subsequent 227 // frames related to this stream will be ignored (modulo flow 228 // control accounting). 229 void ResetPromised(quic::QuicStreamId id, 230 quic::QuicRstStreamErrorCode error_code); 231 232 // Returns a new packet bundler while will cause writes to be batched up 233 // until a packet is full, or the last bundler is destroyed. 234 std::unique_ptr<quic::QuicConnection::ScopedPacketFlusher> 235 CreatePacketBundler(); 236 237 // Populates network error details for this session. 238 void PopulateNetErrorDetails(NetErrorDetails* details) const; 239 240 // Returns the connection timing for the handshake of this session. 241 const LoadTimingInfo::ConnectTiming& GetConnectTiming(); 242 243 // Returns true if |other| is a handle to the same session as this handle. 244 bool SharesSameSession(const Handle& other) const; 245 246 // Returns the QUIC version used by the session. 247 quic::ParsedQuicVersion GetQuicVersion() const; 248 249 // Copies the remote udp address into |address| and returns a net error 250 // code. 251 int GetPeerAddress(IPEndPoint* address) const; 252 253 // Copies the local udp address into |address| and returns a net error 254 // code. 255 int GetSelfAddress(IPEndPoint* address) const; 256 257 // Returns the push promise index associated with the session. 258 quic::QuicClientPushPromiseIndex* GetPushPromiseIndex(); 259 260 // Returns the session's server ID. server_id()261 quic::QuicServerId server_id() const { return server_id_; } 262 263 // Returns the alternative server used for this session. destination()264 HostPortPair destination() const { return destination_; } 265 266 // Returns the session's net log. net_log()267 const NetLogWithSource& net_log() const { return net_log_; } 268 269 // Returns the session's connection migration mode. connection_migration_mode()270 ConnectionMigrationMode connection_migration_mode() const { 271 return session_->connection_migration_mode(); 272 } 273 274 // quic::QuicClientPushPromiseIndex::Delegate implementation 275 bool CheckVary(const spdy::Http2HeaderBlock& client_request, 276 const spdy::Http2HeaderBlock& promise_request, 277 const spdy::Http2HeaderBlock& promise_response) override; 278 void OnRendezvousResult(quic::QuicSpdyStream* stream) override; 279 280 // Returns true if the session's connection has sent or received any bytes. 281 bool WasEverUsed() const; 282 283 private: 284 friend class QuicChromiumClientSession; 285 friend class QuicChromiumClientSession::StreamRequest; 286 287 // Waits for the handshake to be confirmed and invokes |callback| when 288 // that happens. If the handshake has already been confirmed, returns OK. 289 // If the connection has already been closed, returns a net error. If the 290 // connection closes before the handshake is confirmed, |callback| will 291 // be invoked with an error. 292 int WaitForHandshakeConfirmation(CompletionOnceCallback callback); 293 294 // Called when the handshake is confirmed. 295 void OnCryptoHandshakeConfirmed(); 296 297 // Called when the session is closed with a net error. 298 void OnSessionClosed(quic::ParsedQuicVersion quic_version, 299 int net_error, 300 quic::QuicErrorCode quic_error, 301 bool port_migration_detected, 302 LoadTimingInfo::ConnectTiming connect_timing, 303 bool was_ever_used); 304 305 // Called by |request| to create a stream. 306 int TryCreateStream(StreamRequest* request); 307 308 // Called by |request| to cancel stream request. 309 void CancelRequest(StreamRequest* request); 310 311 // Underlying session which may be destroyed before this handle. 312 base::WeakPtr<QuicChromiumClientSession> session_; 313 314 HostPortPair destination_; 315 316 // Stream request created by |RequestStream()|. 317 std::unique_ptr<StreamRequest> stream_request_; 318 319 // Information saved from the session which can be used even after the 320 // session is destroyed. 321 NetLogWithSource net_log_; 322 bool was_handshake_confirmed_; 323 int net_error_; 324 quic::QuicErrorCode quic_error_; 325 bool port_migration_detected_; 326 quic::QuicServerId server_id_; 327 quic::ParsedQuicVersion quic_version_; 328 LoadTimingInfo::ConnectTiming connect_timing_; 329 quic::QuicClientPushPromiseIndex* push_promise_index_; 330 331 // |quic::QuicClientPromisedInfo| owns this. It will be set when |Try()| 332 // is asynchronous, i.e. it returned quic::QUIC_PENDING, and remains valid 333 // until |OnRendezvouResult()| fires or |push_handle_->Cancel()| is 334 // invoked. 335 quic::QuicClientPushPromiseIndex::TryHandle* push_handle_; 336 CompletionOnceCallback push_callback_; 337 std::unique_ptr<QuicChromiumClientStream::Handle> push_stream_; 338 339 bool was_ever_used_; 340 }; 341 342 // A helper class used to manage a request to create a stream. 343 class NET_EXPORT_PRIVATE StreamRequest { 344 public: 345 // Cancels any pending stream creation request and resets |stream_| if 346 // it has not yet been released. 347 ~StreamRequest(); 348 349 // Starts a request to create a stream. If OK is returned, then 350 // |stream_| will be updated with the newly created stream. If 351 // ERR_IO_PENDING is returned, then when the request is eventuallly 352 // complete |callback| will be called. 353 int StartRequest(CompletionOnceCallback callback); 354 355 // Releases |stream_| to the caller. 356 std::unique_ptr<QuicChromiumClientStream::Handle> ReleaseStream(); 357 traffic_annotation()358 const NetworkTrafficAnnotationTag traffic_annotation() { 359 return traffic_annotation_; 360 } 361 362 private: 363 friend class QuicChromiumClientSession; 364 365 enum State { 366 STATE_NONE, 367 STATE_WAIT_FOR_CONFIRMATION, 368 STATE_WAIT_FOR_CONFIRMATION_COMPLETE, 369 STATE_REQUEST_STREAM, 370 STATE_REQUEST_STREAM_COMPLETE, 371 }; 372 373 // |session| must outlive this request. 374 StreamRequest(QuicChromiumClientSession::Handle* session, 375 bool requires_confirmation, 376 const NetworkTrafficAnnotationTag& traffic_annotation); 377 378 void OnIOComplete(int rv); 379 void DoCallback(int rv); 380 381 int DoLoop(int rv); 382 int DoWaitForConfirmation(); 383 int DoWaitForConfirmationComplete(int rv); 384 int DoRequestStream(); 385 int DoRequestStreamComplete(int rv); 386 387 // Called by |session_| for an asynchronous request when the stream 388 // request has finished successfully. 389 void OnRequestCompleteSuccess( 390 std::unique_ptr<QuicChromiumClientStream::Handle> stream); 391 392 // Called by |session_| for an asynchronous request when the stream 393 // request has finished with an error. Also called with ERR_ABORTED 394 // if |session_| is destroyed while the stream request is still pending. 395 void OnRequestCompleteFailure(int rv); 396 397 QuicChromiumClientSession::Handle* session_; 398 const bool requires_confirmation_; 399 CompletionOnceCallback callback_; 400 std::unique_ptr<QuicChromiumClientStream::Handle> stream_; 401 // For tracking how much time pending stream requests wait. 402 base::TimeTicks pending_start_time_; 403 State next_state_; 404 405 const NetworkTrafficAnnotationTag traffic_annotation_; 406 407 base::WeakPtrFactory<StreamRequest> weak_factory_{this}; 408 409 DISALLOW_COPY_AND_ASSIGN(StreamRequest); 410 }; 411 412 // Constructs a new session which will own |connection|, but not 413 // |stream_factory|, which must outlive this session. 414 // TODO(rch): decouple the factory from the session via a Delegate interface. 415 // 416 // If |require_confirmation| is true, the returned session will wait for a 417 // successful QUIC handshake before vending any streams, to ensure that both 418 // the server and the current network support QUIC, as HTTP fallback can't 419 // trigger (or at least will take longer) after a QUIC stream has successfully 420 // been created. 421 QuicChromiumClientSession( 422 quic::QuicConnection* connection, 423 std::unique_ptr<DatagramClientSocket> socket, 424 QuicStreamFactory* stream_factory, 425 QuicCryptoClientStreamFactory* crypto_client_stream_factory, 426 const quic::QuicClock* clock, 427 TransportSecurityState* transport_security_state, 428 SSLConfigService* ssl_config_service, 429 std::unique_ptr<QuicServerInfo> server_info, 430 const QuicSessionKey& session_key, 431 bool require_confirmation, 432 quic::QuicStreamId max_allowed_push_id, 433 bool migrate_sesion_early_v2, 434 bool migrate_session_on_network_change_v2, 435 NetworkChangeNotifier::NetworkHandle default_network, 436 quic::QuicTime::Delta retransmittable_on_wire_timeout, 437 bool migrate_idle_session, 438 bool allow_port_migration, 439 base::TimeDelta idle_migration_period, 440 base::TimeDelta max_time_on_non_default_network, 441 int max_migrations_to_non_default_network_on_write_error, 442 int max_migrations_to_non_default_network_on_path_degrading, 443 int yield_after_packets, 444 quic::QuicTime::Delta yield_after_duration, 445 bool go_away_on_path_degrading, 446 bool headers_include_h2_stream_dependency, 447 int cert_verify_flags, 448 const quic::QuicConfig& config, 449 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config, 450 const char* const connection_description, 451 base::TimeTicks dns_resolution_start_time, 452 base::TimeTicks dns_resolution_end_time, 453 std::unique_ptr<quic::QuicClientPushPromiseIndex> push_promise_index, 454 ServerPushDelegate* push_delegate, 455 const base::TickClock* tick_clock, 456 base::SequencedTaskRunner* task_runner, 457 std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher, 458 NetLog* net_log); 459 ~QuicChromiumClientSession() override; 460 461 void Initialize() override; 462 463 void AddHandle(Handle* handle); 464 void RemoveHandle(Handle* handle); 465 466 void AddConnectivityObserver(ConnectivityObserver* observer); 467 void RemoveConnectivityObserver(ConnectivityObserver* observer); 468 469 // Returns the session's connection migration mode. 470 ConnectionMigrationMode connection_migration_mode() const; 471 472 // Waits for the handshake to be confirmed and invokes |callback| when 473 // that happens. If the handshake has already been confirmed, returns OK. 474 // If the connection has already been closed, returns a net error. If the 475 // connection closes before the handshake is confirmed, |callback| will 476 // be invoked with an error. 477 int WaitForHandshakeConfirmation(CompletionOnceCallback callback); 478 479 // Attempts to create a new stream. If the stream can be 480 // created immediately, returns OK. If the open stream limit 481 // has been reached, returns ERR_IO_PENDING, and |request| 482 // will be added to the stream requets queue and will 483 // be completed asynchronously. 484 // TODO(rch): remove |stream| from this and use setter on |request| 485 // and fix in spdy too. 486 int TryCreateStream(StreamRequest* request); 487 488 // Cancels the pending stream creation request. 489 void CancelRequest(StreamRequest* request); 490 491 // QuicChromiumPacketWriter::Delegate override. 492 int HandleWriteError(int error_code, 493 scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer> 494 last_packet) override; 495 void OnWriteError(int error_code) override; 496 // Called when the associated writer is unblocked. Write the cached |packet_| 497 // if |packet_| is set. May send a PING packet if 498 // |send_packet_after_migration_| is set and writer is not blocked after 499 // writing queued packets. 500 void OnWriteUnblocked() override; 501 502 // QuicConnectivityProbingManager::Delegate override. 503 void OnProbeSucceeded( 504 NetworkChangeNotifier::NetworkHandle network, 505 const quic::QuicSocketAddress& peer_address, 506 const quic::QuicSocketAddress& self_address, 507 std::unique_ptr<DatagramClientSocket> socket, 508 std::unique_ptr<QuicChromiumPacketWriter> writer, 509 std::unique_ptr<QuicChromiumPacketReader> reader) override; 510 511 void OnProbeFailed(NetworkChangeNotifier::NetworkHandle network, 512 const quic::QuicSocketAddress& peer_address) override; 513 514 bool OnSendConnectivityProbingPacket( 515 QuicChromiumPacketWriter* writer, 516 const quic::QuicSocketAddress& peer_address) override; 517 518 // quic::QuicSpdySession methods: 519 size_t WriteHeadersOnHeadersStream( 520 quic::QuicStreamId id, 521 spdy::Http2HeaderBlock headers, 522 bool fin, 523 const spdy::SpdyStreamPrecedence& precedence, 524 quic::QuicReferenceCountedPointer<quic::QuicAckListenerInterface> 525 ack_listener) override; 526 void UnregisterStreamPriority(quic::QuicStreamId id, bool is_static) override; 527 void UpdateStreamPriority( 528 quic::QuicStreamId id, 529 const spdy::SpdyStreamPrecedence& new_precedence) override; 530 void OnHttp3GoAway(uint64_t id) override; 531 532 // quic::QuicSession methods: 533 QuicChromiumClientStream* CreateOutgoingBidirectionalStream() override; 534 QuicChromiumClientStream* CreateOutgoingUnidirectionalStream() override; 535 const quic::QuicCryptoClientStream* GetCryptoStream() const override; 536 quic::QuicCryptoClientStream* GetMutableCryptoStream() override; 537 void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override; 538 void OnTlsHandshakeComplete() override; 539 void OnNewEncryptionKeyAvailable( 540 quic::EncryptionLevel level, 541 std::unique_ptr<quic::QuicEncrypter> encrypter) override; 542 void OnCryptoHandshakeMessageSent( 543 const quic::CryptoHandshakeMessage& message) override; 544 void OnCryptoHandshakeMessageReceived( 545 const quic::CryptoHandshakeMessage& message) override; 546 void OnGoAway(const quic::QuicGoAwayFrame& frame) override; 547 void OnCanCreateNewOutgoingStream(bool unidirectional) override; 548 bool ValidateStatelessReset( 549 const quic::QuicSocketAddress& self_address, 550 const quic::QuicSocketAddress& peer_address) override; 551 void SendPing() override; 552 553 // QuicSpdyClientSessionBase methods: 554 void OnConfigNegotiated() override; 555 void OnProofValid( 556 const quic::QuicCryptoClientConfig::CachedState& cached) override; 557 void OnProofVerifyDetailsAvailable( 558 const quic::ProofVerifyDetails& verify_details) override; 559 560 // quic::QuicConnectionVisitorInterface methods: 561 void OnConnectionClosed(const quic::QuicConnectionCloseFrame& frame, 562 quic::ConnectionCloseSource source) override; 563 void OnSuccessfulVersionNegotiation( 564 const quic::ParsedQuicVersion& version) override; 565 void OnPacketReceived(const quic::QuicSocketAddress& self_address, 566 const quic::QuicSocketAddress& peer_address, 567 bool is_connectivity_probe) override; 568 void OnPathDegrading() override; 569 void OnForwardProgressMadeAfterPathDegrading() override; 570 void OnKeyUpdate(quic::KeyUpdateReason reason) override; 571 572 // QuicChromiumPacketReader::Visitor methods: 573 void OnReadError(int result, const DatagramClientSocket* socket) override; 574 bool OnPacket(const quic::QuicReceivedPacket& packet, 575 const quic::QuicSocketAddress& local_address, 576 const quic::QuicSocketAddress& peer_address) override; 577 void OnStreamClosed(quic::QuicStreamId stream_id) override; 578 579 // MultiplexedSession methods: 580 bool GetRemoteEndpoint(IPEndPoint* endpoint) override; 581 bool GetSSLInfo(SSLInfo* ssl_info) const override; 582 583 // Performs a crypto handshake with the server. 584 int CryptoConnect(CompletionOnceCallback callback); 585 586 // Causes the QuicConnectionHelper to start reading from all sockets 587 // and passing the data along to the quic::QuicConnection. 588 void StartReading(); 589 590 // Close the session because of |net_error| and notifies the factory 591 // that this session has been closed, which will delete the session. 592 // |behavior| will suggest whether we should send connection close packets 593 // when closing the connection. 594 void CloseSessionOnError(int net_error, 595 quic::QuicErrorCode quic_error, 596 quic::ConnectionCloseBehavior behavior); 597 598 // Close the session because of |net_error| and notifies the factory 599 // that this session has been closed later, which will delete the session. 600 // |behavior| will suggest whether we should send connection close packets 601 // when closing the connection. 602 void CloseSessionOnErrorLater(int net_error, 603 quic::QuicErrorCode quic_error, 604 quic::ConnectionCloseBehavior behavior); 605 606 base::Value GetInfoAsValue(const std::set<HostPortPair>& aliases); 607 net_log()608 const NetLogWithSource& net_log() const { return net_log_; } 609 610 // Returns true if the stream factory disables gQUIC 0-RTT. 611 bool gquic_zero_rtt_disabled() const; 612 613 // Returns a Handle to this session. 614 std::unique_ptr<QuicChromiumClientSession::Handle> CreateHandle( 615 const HostPortPair& destination); 616 617 // Returns the number of client hello messages that have been sent on the 618 // crypto stream. If the handshake has completed then this is one greater 619 // than the number of round-trips needed for the handshake. 620 int GetNumSentClientHellos() const; 621 622 // Returns true if |hostname| may be pooled onto this session. 623 // |other_session_key| specifies the seession key associated with |hostname| 624 // (its own hostname and port fields are ignored). If this is a secure QUIC 625 // session, then |hostname| must match the certificate presented during the 626 // handshake. 627 bool CanPool(const std::string& hostname, 628 const QuicSessionKey& other_session_key) const; 629 server_id()630 const quic::QuicServerId& server_id() const { 631 return session_key_.server_id(); 632 } 633 quic_session_key()634 const QuicSessionKey& quic_session_key() const { return session_key_; } 635 636 // Attempts to migrate session when |writer| encounters a write error. 637 // If |writer| is no longer actively used, abort migration. 638 void MigrateSessionOnWriteError(int error_code, 639 quic::QuicPacketWriter* writer); 640 641 // Helper method that completes connection/server migration. 642 // Unblocks packet writer on network level. If the writer becomes unblocked 643 // then, OnWriteUnblocked() will be invoked to send packet after migration. 644 void WriteToNewSocket(); 645 646 // Migrates session over to use |peer_address| and |network|. 647 // If |network| is kInvalidNetworkHandle, default network is used. If the 648 // migration fails and |close_session_on_error| is true, session will be 649 // closed. 650 MigrationResult Migrate(NetworkChangeNotifier::NetworkHandle network, 651 IPEndPoint peer_address, 652 bool close_session_on_error); 653 654 // Migrates session onto new socket, i.e., sets |writer| to be the new 655 // default writer and post a task to write to |socket|. |reader| *must* 656 // has been started reading from the socket. Returns true if 657 // socket was successfully added to the session and the session was 658 // successfully migrated to using the new socket. Returns true on 659 // successful migration, or false if number of migrations exceeds 660 // kMaxReadersPerQuicSession. Takes ownership of |socket|, |reader|, 661 // and |writer|. 662 bool MigrateToSocket(std::unique_ptr<DatagramClientSocket> socket, 663 std::unique_ptr<QuicChromiumPacketReader> reader, 664 std::unique_ptr<QuicChromiumPacketWriter> writer); 665 666 // Called when NetworkChangeNotifier notifies observers of a newly 667 // connected network. Migrates this session to the newly connected 668 // network if the session has a pending migration. 669 void OnNetworkConnected(NetworkChangeNotifier::NetworkHandle network); 670 671 // Called when NetworkChangeNotifier broadcasts to observers of 672 // |disconnected_network|. 673 void OnNetworkDisconnectedV2( 674 NetworkChangeNotifier::NetworkHandle disconnected_network); 675 676 // Called when NetworkChangeNotifier broadcats to observers of a new default 677 // network. Migrates this session to |new_network| if appropriate. 678 void OnNetworkMadeDefault(NetworkChangeNotifier::NetworkHandle new_network); 679 680 // Schedules a migration alarm to wait for a new network. 681 void OnNoNewNetwork(); 682 683 // Called when migration alarm fires. If migration has not occurred 684 // since alarm was set, closes session with error. 685 void OnMigrationTimeout(size_t num_sockets); 686 687 // Populates network error details for this session. 688 void PopulateNetErrorDetails(NetErrorDetails* details) const; 689 690 // Returns current default socket. This is the socket over which all 691 // QUIC packets are sent. This default socket can change, so do not store the 692 // returned socket. 693 const DatagramClientSocket* GetDefaultSocket() const; 694 695 // Returns the network interface that is currently used to send packets. 696 // If NetworkHandle is not supported, always return 697 // NetworkChangeNotifier::kInvalidNetworkHandle. 698 NetworkChangeNotifier::NetworkHandle GetCurrentNetwork() const; 699 700 bool IsAuthorized(const std::string& hostname) override; 701 702 bool HandlePromised(quic::QuicStreamId associated_id, 703 quic::QuicStreamId promised_id, 704 const spdy::Http2HeaderBlock& headers) override; 705 706 void DeletePromised(quic::QuicClientPromisedInfo* promised) override; 707 708 void OnPushStreamTimedOut(quic::QuicStreamId stream_id) override; 709 710 // Cancels the push if the push stream for |url| has not been claimed and is 711 // still active. Otherwise, no-op. 712 void CancelPush(const GURL& url); 713 714 const LoadTimingInfo::ConnectTiming& GetConnectTiming(); 715 716 quic::ParsedQuicVersion GetQuicVersion() const; 717 718 // Returns the estimate of dynamically allocated memory in bytes. 719 // See base/trace_event/memory_usage_estimator.h. 720 // TODO(xunjieli): It only tracks |packet_readers_|. Write a better estimate. 721 size_t EstimateMemoryUsage() const; 722 723 // Looks for a push that matches the provided parameters. 724 quic::QuicClientPromisedInfo* GetPromised(const GURL& url, 725 const QuicSessionKey& session_key); 726 require_confirmation()727 bool require_confirmation() const { return require_confirmation_; } 728 729 protected: 730 // quic::QuicSession methods: 731 bool ShouldCreateIncomingStream(quic::QuicStreamId id) override; 732 bool ShouldCreateOutgoingBidirectionalStream() override; 733 bool ShouldCreateOutgoingUnidirectionalStream() override; 734 735 QuicChromiumClientStream* CreateIncomingStream( 736 quic::QuicStreamId id) override; 737 QuicChromiumClientStream* CreateIncomingStream( 738 quic::PendingStream* pending) override; 739 740 private: 741 friend class test::QuicChromiumClientSessionPeer; 742 743 typedef std::set<Handle*> HandleSet; 744 typedef std::list<StreamRequest*> StreamRequestQueue; 745 746 bool WasConnectionEverUsed(); 747 748 QuicChromiumClientStream* CreateOutgoingReliableStreamImpl( 749 const NetworkTrafficAnnotationTag& traffic_annotation); 750 QuicChromiumClientStream* CreateIncomingReliableStreamImpl( 751 quic::QuicStreamId id, 752 const NetworkTrafficAnnotationTag& traffic_annotation); 753 QuicChromiumClientStream* CreateIncomingReliableStreamImpl( 754 quic::PendingStream* pending, 755 const NetworkTrafficAnnotationTag& traffic_annotation); 756 // A completion callback invoked when a read completes. 757 void OnReadComplete(int result); 758 759 void NotifyAllStreamsOfError(int net_error); 760 void CloseAllHandles(int net_error); 761 void CancelAllRequests(int net_error); 762 void NotifyRequestsOfConfirmation(int net_error); 763 764 // Probe on <network, peer_address>. 765 // If <network, peer_addres> is identical to the current path, the probe 766 // is sent on a different port. 767 ProbingResult StartProbing(NetworkChangeNotifier::NetworkHandle network, 768 const quic::QuicSocketAddress& peer_address); 769 770 // Perform a few checks before StartProbing. If any of those checks fails, 771 // StartProbing will be skipped. 772 ProbingResult MaybeStartProbing(NetworkChangeNotifier::NetworkHandle network, 773 const quic::QuicSocketAddress& peer_address); 774 775 // Helper method to perform a few checks and initiate connection migration 776 // attempt when path degrading is detected. 777 // Called when path is degrading and there is an alternate network or a new 778 // network is connected after path degrading. 779 void MaybeMigrateToAlternateNetworkOnPathDegrading(); 780 781 // Helper method to initiate a port migration on path degrading is detected. 782 void MaybeMigrateToDifferentPortOnPathDegrading(); 783 784 // Called when there is only one possible working network: |network|, If any 785 // error encountered, this session will be closed. 786 // When the migration succeeds: 787 // - If no longer on the default network, set timer to migrate back to the 788 // default network; 789 // - If now on the default network, cancel timer to migrate back to default 790 // network. 791 void MigrateNetworkImmediately(NetworkChangeNotifier::NetworkHandle network); 792 793 void StartMigrateBackToDefaultNetworkTimer(base::TimeDelta delay); 794 void CancelMigrateBackToDefaultNetworkTimer(); 795 void TryMigrateBackToDefaultNetwork(base::TimeDelta timeout); 796 void MaybeRetryMigrateBackToDefaultNetwork(); 797 798 // If migrate idle session is enabled, returns true and post a task to close 799 // the connection if session's idle time exceeds the |idle_migration_period_|. 800 // If migrate idle session is not enabled, returns true and posts a task to 801 // close the connection if session doesn't have outstanding streams. 802 bool CheckIdleTimeExceedsIdleMigrationPeriod(); 803 804 // Close non-migratable streams in both directions by sending reset stream to 805 // peer when connection migration attempts to migrate to the alternate 806 // network. 807 void ResetNonMigratableStreams(); 808 void LogMetricsOnNetworkDisconnected(); 809 void LogMetricsOnNetworkMadeDefault(); 810 void LogMigrationResultToHistogram(QuicConnectionMigrationStatus status); 811 void LogHandshakeStatusOnMigrationSignal() const; 812 void HistogramAndLogMigrationFailure(QuicConnectionMigrationStatus status, 813 quic::QuicConnectionId connection_id, 814 const char* reason); 815 void HistogramAndLogMigrationSuccess(quic::QuicConnectionId connection_id); 816 817 // Notifies the factory that this session is going away and no more streams 818 // should be created from it. This needs to be called before closing any 819 // streams, because closing a stream may cause a new stream to be created. 820 void NotifyFactoryOfSessionGoingAway(); 821 822 // Posts a task to notify the factory that this session has been closed. 823 void NotifyFactoryOfSessionClosedLater(); 824 825 // Notifies the factory that this session has been closed which will 826 // delete |this|. 827 void NotifyFactoryOfSessionClosed(); 828 829 // Called when default encryption level switches to forward secure. 830 void OnCryptoHandshakeComplete(); 831 832 void LogZeroRttStats(); 833 834 QuicSessionKey session_key_; 835 bool require_confirmation_; 836 bool migrate_session_early_v2_; 837 bool migrate_session_on_network_change_v2_; 838 bool migrate_idle_session_; 839 bool allow_port_migration_; 840 // Session can be migrated if its idle time is within this period. 841 base::TimeDelta idle_migration_period_; 842 base::TimeDelta max_time_on_non_default_network_; 843 // Maximum allowed number of migrations to non-default network triggered by 844 // packet write error per default network. 845 int max_migrations_to_non_default_network_on_write_error_; 846 int current_migrations_to_non_default_network_on_write_error_; 847 // Maximum allowed number of migrations to non-default network triggered by 848 // path degrading per default network. 849 int max_migrations_to_non_default_network_on_path_degrading_; 850 int current_migrations_to_non_default_network_on_path_degrading_; 851 const quic::QuicClock* clock_; // Unowned. 852 int yield_after_packets_; 853 quic::QuicTime::Delta yield_after_duration_; 854 bool go_away_on_path_degrading_; 855 856 base::TimeTicks most_recent_path_degrading_timestamp_; 857 base::TimeTicks most_recent_network_disconnected_timestamp_; 858 const base::TickClock* tick_clock_; 859 base::TimeTicks most_recent_stream_close_time_; 860 861 int most_recent_write_error_; 862 base::TimeTicks most_recent_write_error_timestamp_; 863 864 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_; 865 866 std::unique_ptr<quic::QuicCryptoClientStream> crypto_stream_; 867 QuicStreamFactory* stream_factory_; 868 base::ObserverList<ConnectivityObserver> connectivity_observer_list_; 869 std::vector<std::unique_ptr<DatagramClientSocket>> sockets_; 870 TransportSecurityState* transport_security_state_; 871 SSLConfigService* ssl_config_service_; 872 std::unique_ptr<QuicServerInfo> server_info_; 873 std::unique_ptr<CertVerifyResult> cert_verify_result_; 874 std::string pinning_failure_log_; 875 bool pkp_bypassed_; 876 bool is_fatal_cert_error_; 877 HandleSet handles_; 878 StreamRequestQueue stream_requests_; 879 std::vector<CompletionOnceCallback> waiting_for_confirmation_callbacks_; 880 CompletionOnceCallback callback_; 881 size_t num_total_streams_; 882 base::SequencedTaskRunner* task_runner_; 883 NetLogWithSource net_log_; 884 std::vector<std::unique_ptr<QuicChromiumPacketReader>> packet_readers_; 885 LoadTimingInfo::ConnectTiming connect_timing_; 886 std::unique_ptr<QuicConnectionLogger> logger_; 887 std::unique_ptr<QuicHttp3Logger> http3_logger_; 888 // True when the session is going away, and streams may no longer be created 889 // on this session. Existing stream will continue to be processed. 890 bool going_away_; 891 // True when the session receives a go away from server due to port migration. 892 bool port_migration_detected_; 893 // Not owned. |push_delegate_| outlives the session and handles server pushes 894 // received by session. 895 ServerPushDelegate* push_delegate_; 896 // UMA histogram counters for streams pushed to this session. 897 int streams_pushed_count_; 898 int streams_pushed_and_claimed_count_; 899 uint64_t bytes_pushed_count_; 900 uint64_t bytes_pushed_and_unclaimed_count_; 901 // Stores the packet that witnesses socket write error. This packet will be 902 // written to an alternate socket when the migration completes and the 903 // alternate socket is unblocked. 904 scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer> packet_; 905 // Stores the latest default network platform marks if migration is enabled. 906 // Otherwise, stores the network interface that is used by the connection. 907 NetworkChangeNotifier::NetworkHandle default_network_; 908 QuicConnectivityProbingManager probing_manager_; 909 int retry_migrate_back_count_; 910 base::OneShotTimer migrate_back_to_default_timer_; 911 MigrationCause current_migration_cause_; 912 // True if a packet needs to be sent when packet writer is unblocked to 913 // complete connection migration. The packet can be a cached packet if 914 // |packet_| is set, a queued packet, or a PING packet. 915 bool send_packet_after_migration_; 916 // True if migration is triggered, and there is no alternate network to 917 // migrate to. 918 bool wait_for_new_network_; 919 // True if read errors should be ignored. Set when migration on write error is 920 // posted and unset until the first packet is written after migration. 921 bool ignore_read_error_; 922 923 // If true, client headers will include HTTP/2 stream dependency info derived 924 // from spdy::SpdyStreamPrecedence. 925 bool headers_include_h2_stream_dependency_; 926 Http2PriorityDependencies priority_dependency_state_; 927 928 quic::QuicStreamId max_allowed_push_id_; 929 930 bool attempted_zero_rtt_; 931 932 size_t num_pings_sent_; 933 934 size_t num_migrations_; 935 936 // The reason for the last 1-RTT key update on the connection. Will be 937 // kInvalid if no key updates have occurred. 938 quic::KeyUpdateReason last_key_update_reason_; 939 940 std::unique_ptr<quic::QuicClientPushPromiseIndex> push_promise_index_; 941 942 base::WeakPtrFactory<QuicChromiumClientSession> weak_factory_{this}; 943 944 DISALLOW_COPY_AND_ASSIGN(QuicChromiumClientSession); 945 }; 946 947 } // namespace net 948 949 #endif // NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_ 950