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 QuicSession, which demuxes a single connection to individual streams. 6 7 #ifndef QUICHE_QUIC_CORE_QUIC_SESSION_H_ 8 #define QUICHE_QUIC_CORE_QUIC_SESSION_H_ 9 10 #include <cstddef> 11 #include <cstdint> 12 #include <map> 13 #include <memory> 14 #include <optional> 15 #include <string> 16 #include <vector> 17 18 #include "absl/container/flat_hash_map.h" 19 #include "absl/strings/string_view.h" 20 #include "absl/types/span.h" 21 #include "quiche/quic/core/crypto/tls_connection.h" 22 #include "quiche/quic/core/frames/quic_ack_frequency_frame.h" 23 #include "quiche/quic/core/frames/quic_stop_sending_frame.h" 24 #include "quiche/quic/core/frames/quic_window_update_frame.h" 25 #include "quiche/quic/core/handshaker_delegate_interface.h" 26 #include "quiche/quic/core/legacy_quic_stream_id_manager.h" 27 #include "quiche/quic/core/proto/cached_network_parameters_proto.h" 28 #include "quiche/quic/core/quic_connection.h" 29 #include "quiche/quic/core/quic_constants.h" 30 #include "quiche/quic/core/quic_control_frame_manager.h" 31 #include "quiche/quic/core/quic_crypto_stream.h" 32 #include "quiche/quic/core/quic_datagram_queue.h" 33 #include "quiche/quic/core/quic_error_codes.h" 34 #include "quiche/quic/core/quic_packet_creator.h" 35 #include "quiche/quic/core/quic_packets.h" 36 #include "quiche/quic/core/quic_path_validator.h" 37 #include "quiche/quic/core/quic_stream.h" 38 #include "quiche/quic/core/quic_stream_frame_data_producer.h" 39 #include "quiche/quic/core/quic_stream_priority.h" 40 #include "quiche/quic/core/quic_types.h" 41 #include "quiche/quic/core/quic_write_blocked_list.h" 42 #include "quiche/quic/core/session_notifier_interface.h" 43 #include "quiche/quic/core/stream_delegate_interface.h" 44 #include "quiche/quic/core/uber_quic_stream_id_manager.h" 45 #include "quiche/quic/platform/api/quic_export.h" 46 #include "quiche/quic/platform/api/quic_flags.h" 47 #include "quiche/quic/platform/api/quic_socket_address.h" 48 #include "quiche/common/platform/api/quiche_mem_slice.h" 49 #include "quiche/common/quiche_callbacks.h" 50 #include "quiche/common/quiche_linked_hash_map.h" 51 52 namespace quic { 53 54 class QuicCryptoStream; 55 class QuicFlowController; 56 class QuicStream; 57 class QuicStreamIdManager; 58 59 namespace test { 60 class QuicSessionPeer; 61 } // namespace test 62 63 class QUICHE_EXPORT QuicSession 64 : public QuicConnectionVisitorInterface, 65 public SessionNotifierInterface, 66 public QuicStreamFrameDataProducer, 67 public QuicStreamIdManager::DelegateInterface, 68 public HandshakerDelegateInterface, 69 public StreamDelegateInterface, 70 public QuicControlFrameManager::DelegateInterface { 71 public: 72 // An interface from the session to the entity owning the session. 73 // This lets the session notify its owner when the connection 74 // is closed, blocked, etc. 75 // TODO(danzh): split this visitor to separate visitors for client and server 76 // respectively as not all methods in this class are interesting to both 77 // perspectives. 78 class QUICHE_EXPORT Visitor { 79 public: ~Visitor()80 virtual ~Visitor() {} 81 82 // Called when the connection is closed after the streams have been closed. 83 virtual void OnConnectionClosed(QuicConnectionId server_connection_id, 84 QuicErrorCode error, 85 const std::string& error_details, 86 ConnectionCloseSource source) = 0; 87 88 // Called when the session has become write blocked. 89 virtual void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) = 0; 90 91 // Called when the session receives reset on a stream from the peer. 92 virtual void OnRstStreamReceived(const QuicRstStreamFrame& frame) = 0; 93 94 // Called when the session receives a STOP_SENDING for a stream from the 95 // peer. 96 virtual void OnStopSendingReceived(const QuicStopSendingFrame& frame) = 0; 97 98 // Called when on whether a NewConnectionId frame can been sent. 99 virtual bool TryAddNewConnectionId( 100 const QuicConnectionId& server_connection_id, 101 const QuicConnectionId& new_connection_id) = 0; 102 103 // Called when a ConnectionId has been retired. 104 virtual void OnConnectionIdRetired( 105 const QuicConnectionId& server_connection_id) = 0; 106 107 virtual void OnServerPreferredAddressAvailable( 108 const QuicSocketAddress& /*server_preferred_address*/) = 0; 109 110 // Called when connection detected path degrading. 111 virtual void OnPathDegrading() = 0; 112 }; 113 114 // Does not take ownership of |connection| or |visitor|. 115 QuicSession(QuicConnection* connection, Visitor* owner, 116 const QuicConfig& config, 117 const ParsedQuicVersionVector& supported_versions, 118 QuicStreamCount num_expected_unidirectional_static_streams); 119 QuicSession(QuicConnection* connection, Visitor* owner, 120 const QuicConfig& config, 121 const ParsedQuicVersionVector& supported_versions, 122 QuicStreamCount num_expected_unidirectional_static_streams, 123 std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer); 124 QuicSession(const QuicSession&) = delete; 125 QuicSession& operator=(const QuicSession&) = delete; 126 127 ~QuicSession() override; 128 129 virtual void Initialize(); 130 131 // Return the reserved crypto stream as a constant pointer. 132 virtual const QuicCryptoStream* GetCryptoStream() const = 0; 133 134 // QuicConnectionVisitorInterface methods: 135 void OnStreamFrame(const QuicStreamFrame& frame) override; 136 void OnCryptoFrame(const QuicCryptoFrame& frame) override; 137 void OnRstStream(const QuicRstStreamFrame& frame) override; 138 void OnGoAway(const QuicGoAwayFrame& frame) override; 139 void OnMessageReceived(absl::string_view message) override; 140 void OnHandshakeDoneReceived() override; 141 void OnNewTokenReceived(absl::string_view token) override; 142 void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override; 143 void OnBlockedFrame(const QuicBlockedFrame& frame) override; 144 void OnConnectionClosed(const QuicConnectionCloseFrame& frame, 145 ConnectionCloseSource source) override; 146 void OnWriteBlocked() override; 147 void OnSuccessfulVersionNegotiation( 148 const ParsedQuicVersion& version) override; 149 void OnPacketReceived(const QuicSocketAddress& self_address, 150 const QuicSocketAddress& peer_address, 151 bool is_connectivity_probe) override; 152 void OnCanWrite() override; OnCongestionWindowChange(QuicTime)153 void OnCongestionWindowChange(QuicTime /*now*/) override {} OnConnectionMigration(AddressChangeType)154 void OnConnectionMigration(AddressChangeType /*type*/) override {} 155 // Adds a connection level WINDOW_UPDATE frame. 156 void OnAckNeedsRetransmittableFrame() override; 157 void SendAckFrequency(const QuicAckFrequencyFrame& frame) override; 158 void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override; 159 void SendRetireConnectionId(uint64_t sequence_number) override; 160 // Returns true if server_connection_id can be issued. If returns true, 161 // |visitor_| may establish a mapping from |server_connection_id| to this 162 // session, if that's not desired, 163 // OnServerConnectionIdRetired(server_connection_id) can be used to remove the 164 // mapping. 165 bool MaybeReserveConnectionId( 166 const QuicConnectionId& server_connection_id) override; 167 void OnServerConnectionIdRetired( 168 const QuicConnectionId& server_connection_id) override; 169 bool WillingAndAbleToWrite() const override; 170 std::string GetStreamsInfoForLogging() const override; 171 void OnPathDegrading() override; 172 void OnForwardProgressMadeAfterPathDegrading() override; 173 bool AllowSelfAddressChange() const override; 174 HandshakeState GetHandshakeState() const override; 175 bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override; 176 bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override; 177 void OnStopSendingFrame(const QuicStopSendingFrame& frame) override; 178 void OnPacketDecrypted(EncryptionLevel level) override; 179 void OnOneRttPacketAcknowledged() override; 180 void OnHandshakePacketSent() override; OnKeyUpdate(KeyUpdateReason)181 void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} 182 std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() 183 override; 184 std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override; BeforeConnectionCloseSent()185 void BeforeConnectionCloseSent() override {} 186 bool ValidateToken(absl::string_view token) override; 187 bool MaybeSendAddressToken() override; CreateContextForMultiPortPath(std::unique_ptr<MultiPortPathContextObserver>)188 void CreateContextForMultiPortPath( 189 std::unique_ptr<MultiPortPathContextObserver> /*context_observer*/) 190 override {} MigrateToMultiPortPath(std::unique_ptr<QuicPathValidationContext>)191 void MigrateToMultiPortPath( 192 std::unique_ptr<QuicPathValidationContext> /*context*/) override {} 193 void OnServerPreferredAddressAvailable( 194 const QuicSocketAddress& /*server_preferred_address*/) override; MaybeBundleOpportunistically()195 void MaybeBundleOpportunistically() override {} 196 QuicByteCount GetFlowControlSendWindowSize(QuicStreamId id) override; 197 198 // QuicStreamFrameDataProducer 199 WriteStreamDataResult WriteStreamData(QuicStreamId id, 200 QuicStreamOffset offset, 201 QuicByteCount data_length, 202 QuicDataWriter* writer) override; 203 bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset, 204 QuicByteCount data_length, 205 QuicDataWriter* writer) override; 206 207 // SessionNotifierInterface methods: 208 bool OnFrameAcked(const QuicFrame& frame, QuicTime::Delta ack_delay_time, 209 QuicTime receive_timestamp) override; 210 void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) override; 211 void OnFrameLost(const QuicFrame& frame) override; 212 bool RetransmitFrames(const QuicFrames& frames, 213 TransmissionType type) override; 214 bool IsFrameOutstanding(const QuicFrame& frame) const override; 215 bool HasUnackedCryptoData() const override; 216 bool HasUnackedStreamData() const override; 217 218 // QuicStreamIdManager::DelegateInterface 219 bool CanSendMaxStreams() override; 220 void SendMaxStreams(QuicStreamCount stream_count, 221 bool unidirectional) override; 222 223 // The default implementation does nothing. Subclasses should override if 224 // for example they queue up stream requests. OnCanCreateNewOutgoingStream(bool)225 virtual void OnCanCreateNewOutgoingStream(bool /*unidirectional*/) {} 226 227 // Called on every incoming packet. Passes |packet| through to |connection_|. 228 virtual void ProcessUdpPacket(const QuicSocketAddress& self_address, 229 const QuicSocketAddress& peer_address, 230 const QuicReceivedPacket& packet); 231 232 // Sends |message| as a QUIC DATAGRAM frame (QUIC MESSAGE frame in gQUIC). 233 // See <https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram> for 234 // more details. 235 // 236 // Returns a MessageResult struct which includes the status of the write 237 // operation and a message ID. The message ID (not sent on the wire) can be 238 // used to track the message; OnMessageAcked and OnMessageLost are called when 239 // a specific message gets acked or lost. 240 // 241 // If the write operation is successful, all of the slices in |message| are 242 // consumed, leaving them empty. If MESSAGE_STATUS_INTERNAL_ERROR is 243 // returned, the slices in question may or may not be consumed; it is no 244 // longer safe to access those. For all other status codes, |message| is kept 245 // intact. 246 // 247 // Note that SendMessage will fail with status = MESSAGE_STATUS_BLOCKED 248 // if the connection is congestion control blocked or the underlying socket is 249 // write blocked. In this case the caller can retry sending message again when 250 // connection becomes available, for example after getting OnCanWrite() 251 // callback. 252 // 253 // SendMessage flushes the current packet even it is not full; if the 254 // application needs to bundle other data in the same packet, consider using 255 // QuicConnection::ScopedPacketFlusher around the relevant write operations. 256 MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message); 257 258 // Same as above SendMessage, except caller can specify if the given |message| 259 // should be flushed even if the underlying connection is deemed unwritable. 260 MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message, 261 bool flush); 262 263 // Single-slice version of SendMessage(). Unlike the version above, this 264 // version always takes ownership of the slice. 265 MessageResult SendMessage(quiche::QuicheMemSlice message); 266 267 // Called when message with |message_id| gets acked. 268 virtual void OnMessageAcked(QuicMessageId message_id, 269 QuicTime receive_timestamp); 270 271 // Called when message with |message_id| is considered as lost. 272 virtual void OnMessageLost(QuicMessageId message_id); 273 274 // QuicControlFrameManager::DelegateInterface 275 // Close the connection on error. 276 void OnControlFrameManagerError(QuicErrorCode error_code, 277 std::string error_details) override; 278 // Called by control frame manager when it wants to write control frames to 279 // the peer. Returns true if |frame| is consumed, false otherwise. The frame 280 // will be sent in specified transmission |type|. 281 bool WriteControlFrame(const QuicFrame& frame, 282 TransmissionType type) override; 283 284 // Called to send RST_STREAM (and STOP_SENDING) and close stream. If stream 285 // |id| does not exist, just send RST_STREAM (and STOP_SENDING). 286 virtual void ResetStream(QuicStreamId id, QuicRstStreamErrorCode error); 287 288 // Called when the session wants to go away and not accept any new streams. 289 virtual void SendGoAway(QuicErrorCode error_code, const std::string& reason); 290 291 // Sends a BLOCKED frame. 292 virtual void SendBlocked(QuicStreamId id, QuicStreamOffset byte_offset); 293 294 // Sends a WINDOW_UPDATE frame. 295 virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset); 296 297 // Called by stream |stream_id| when it gets closed. 298 virtual void OnStreamClosed(QuicStreamId stream_id); 299 300 // Returns true if outgoing packets will be encrypted, even if the server 301 // hasn't confirmed the handshake yet. 302 virtual bool IsEncryptionEstablished() const; 303 304 // Returns true if 1RTT keys are available. 305 bool OneRttKeysAvailable() const; 306 307 // Called by the QuicCryptoStream when a new QuicConfig has been negotiated. 308 virtual void OnConfigNegotiated(); 309 310 // Called by the TLS handshaker when ALPS data is received. 311 // Returns an error message if an error has occurred, or nullopt otherwise. 312 virtual std::optional<std::string> OnAlpsData(const uint8_t* alps_data, 313 size_t alps_length); 314 315 // From HandshakerDelegateInterface 316 bool OnNewDecryptionKeyAvailable(EncryptionLevel level, 317 std::unique_ptr<QuicDecrypter> decrypter, 318 bool set_alternative_decrypter, 319 bool latch_once_used) override; 320 void OnNewEncryptionKeyAvailable( 321 EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override; 322 void SetDefaultEncryptionLevel(EncryptionLevel level) override; 323 void OnTlsHandshakeComplete() override; OnTlsHandshakeConfirmed()324 void OnTlsHandshakeConfirmed() override {} 325 void DiscardOldDecryptionKey(EncryptionLevel level) override; 326 void DiscardOldEncryptionKey(EncryptionLevel level) override; 327 void NeuterUnencryptedData() override; 328 void NeuterHandshakeData() override; 329 void OnZeroRttRejected(int reason) override; 330 bool FillTransportParameters(TransportParameters* params) override; 331 QuicErrorCode ProcessTransportParameters(const TransportParameters& params, 332 bool is_resumption, 333 std::string* error_details) override; 334 void OnHandshakeCallbackDone() override; 335 bool PacketFlusherAttached() const override; parsed_version()336 ParsedQuicVersion parsed_version() const override { return version(); } 337 void OnEncryptedClientHelloSent( 338 absl::string_view client_hello) const override; 339 void OnEncryptedClientHelloReceived( 340 absl::string_view client_hello) const override; 341 342 // Implement StreamDelegateInterface. 343 void OnStreamError(QuicErrorCode error_code, 344 std::string error_details) override; 345 void OnStreamError(QuicErrorCode error_code, 346 QuicIetfTransportErrorCodes ietf_error, 347 std::string error_details) override; 348 // Sets priority in the write blocked list. 349 void RegisterStreamPriority(QuicStreamId id, bool is_static, 350 const QuicStreamPriority& priority) override; 351 // Clears priority from the write blocked list. 352 void UnregisterStreamPriority(QuicStreamId id) override; 353 // Updates priority on the write blocked list. 354 void UpdateStreamPriority(QuicStreamId id, 355 const QuicStreamPriority& new_priority) override; 356 357 // Called by streams when they want to write data to the peer. 358 // Returns a pair with the number of bytes consumed from data, and a boolean 359 // indicating if the fin bit was consumed. This does not indicate the data 360 // has been sent on the wire: it may have been turned into a packet and queued 361 // if the socket was unexpectedly blocked. 362 QuicConsumedData WritevData(QuicStreamId id, size_t write_length, 363 QuicStreamOffset offset, StreamSendingState state, 364 TransmissionType type, 365 EncryptionLevel level) override; 366 367 size_t SendCryptoData(EncryptionLevel level, size_t write_length, 368 QuicStreamOffset offset, 369 TransmissionType type) override; 370 371 // Called by the QuicCryptoStream when a handshake message is sent. 372 virtual void OnCryptoHandshakeMessageSent( 373 const CryptoHandshakeMessage& message); 374 375 // Called by the QuicCryptoStream when a handshake message is received. 376 virtual void OnCryptoHandshakeMessageReceived( 377 const CryptoHandshakeMessage& message); 378 379 // Returns mutable config for this session. Returned config is owned 380 // by QuicSession. config()381 QuicConfig* config() { return &config_; } config()382 const QuicConfig* config() const { return &config_; } 383 384 // Returns true if the stream existed previously and has been closed. 385 // Returns false if the stream is still active or if the stream has 386 // not yet been created. 387 bool IsClosedStream(QuicStreamId id); 388 connection()389 QuicConnection* connection() { return connection_; } connection()390 const QuicConnection* connection() const { return connection_; } peer_address()391 const QuicSocketAddress& peer_address() const { 392 return connection_->peer_address(); 393 } self_address()394 const QuicSocketAddress& self_address() const { 395 return connection_->self_address(); 396 } connection_id()397 QuicConnectionId connection_id() const { 398 return connection_->connection_id(); 399 } 400 401 // Returns the number of currently open streams, excluding static streams, and 402 // never counting unfinished streams. 403 size_t GetNumActiveStreams() const; 404 405 // Add the stream to the session's write-blocked list because it is blocked by 406 // connection-level flow control but not by its own stream-level flow control. 407 // The stream will be given a chance to write when a connection-level 408 // WINDOW_UPDATE arrives. 409 virtual void MarkConnectionLevelWriteBlocked(QuicStreamId id); 410 411 // Called to close zombie stream |id|. 412 void MaybeCloseZombieStream(QuicStreamId id); 413 414 // Returns true if there is pending handshake data in the crypto stream. 415 // TODO(ianswett): Make this private or remove. 416 bool HasPendingHandshake() const; 417 418 // Returns true if the session has data to be sent, either queued in the 419 // connection, or in a write-blocked stream. 420 bool HasDataToWrite() const; 421 422 // Initiates a path validation on the path described in the given context, 423 // asynchronously calls |result_delegate| upon success or failure. 424 // The initiator should extend QuicPathValidationContext to provide the writer 425 // and ResultDelegate to react upon the validation result. 426 // Example implementations of these for path validation for connection 427 // migration could be: 428 // class QUICHE_EXPORT PathMigrationContext 429 // : public QuicPathValidationContext { 430 // public: 431 // PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer, 432 // const QuicSocketAddress& self_address, 433 // const QuicSocketAddress& peer_address) 434 // : QuicPathValidationContext(self_address, peer_address), 435 // alternative_writer_(std::move(writer)) {} 436 // 437 // QuicPacketWriter* WriterToUse() override { 438 // return alternative_writer_.get(); 439 // } 440 // 441 // QuicPacketWriter* ReleaseWriter() { 442 // return alternative_writer_.release(); 443 // } 444 // 445 // private: 446 // std::unique_ptr<QuicPacketWriter> alternative_writer_; 447 // }; 448 // 449 // class PathMigrationValidationResultDelegate 450 // : public QuicPathValidator::ResultDelegate { 451 // public: 452 // PathMigrationValidationResultDelegate(QuicConnection* connection) 453 // : QuicPathValidator::ResultDelegate(), connection_(connection) {} 454 // 455 // void OnPathValidationSuccess( 456 // std::unique_ptr<QuicPathValidationContext> context) override { 457 // // Do some work to prepare for migration. 458 // // ... 459 // 460 // // Actually migrate to the validated path. 461 // auto migration_context = std::unique_ptr<PathMigrationContext>( 462 // static_cast<PathMigrationContext*>(context.release())); 463 // connection_->MigratePath(migration_context->self_address(), 464 // migration_context->peer_address(), 465 // migration_context->ReleaseWriter(), 466 // /*owns_writer=*/true); 467 // 468 // // Post-migration actions 469 // // ... 470 // } 471 // 472 // void OnPathValidationFailure( 473 // std::unique_ptr<QuicPathValidationContext> /*context*/) override { 474 // // Handle validation failure. 475 // } 476 // 477 // private: 478 // QuicConnection* connection_; 479 // }; 480 void ValidatePath( 481 std::unique_ptr<QuicPathValidationContext> context, 482 std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate, 483 PathValidationReason reason); 484 485 // Return true if there is a path being validated. 486 bool HasPendingPathValidation() const; 487 488 // Switch to the path described in |context| without validating the path. 489 bool MigratePath(const QuicSocketAddress& self_address, 490 const QuicSocketAddress& peer_address, 491 QuicPacketWriter* writer, bool owns_writer); 492 493 // Returns the largest payload that will fit into a single MESSAGE frame. 494 // Because overhead can vary during a connection, this method should be 495 // checked for every message. 496 QuicPacketLength GetCurrentLargestMessagePayload() const; 497 498 // Returns the largest payload that will fit into a single MESSAGE frame at 499 // any point during the connection. This assumes the version and 500 // connection ID lengths do not change. 501 QuicPacketLength GetGuaranteedLargestMessagePayload() const; 502 transport_goaway_sent()503 bool transport_goaway_sent() const { return transport_goaway_sent_; } 504 transport_goaway_received()505 bool transport_goaway_received() const { return transport_goaway_received_; } 506 507 // Returns the Google QUIC error code error()508 QuicErrorCode error() const { return on_closed_frame_.quic_error_code; } 509 // The error code on the wire. For Google QUIC frames, this has the same 510 // value as `error()`. wire_error()511 uint64_t wire_error() const { return on_closed_frame_.wire_error_code; } error_details()512 const std::string& error_details() const { 513 return on_closed_frame_.error_details; 514 } transport_close_frame_type()515 uint64_t transport_close_frame_type() const { 516 return on_closed_frame_.transport_close_frame_type; 517 } close_type()518 QuicConnectionCloseType close_type() const { 519 return on_closed_frame_.close_type; 520 } 521 perspective()522 Perspective perspective() const { return perspective_; } 523 flow_controller()524 QuicFlowController* flow_controller() { return &flow_controller_; } 525 526 // Returns true if connection is flow controller blocked. 527 bool IsConnectionFlowControlBlocked() const; 528 529 // Returns true if any stream is flow controller blocked. 530 bool IsStreamFlowControlBlocked(); 531 532 size_t max_open_incoming_bidirectional_streams() const; 533 size_t max_open_incoming_unidirectional_streams() const; 534 535 size_t MaxAvailableBidirectionalStreams() const; 536 size_t MaxAvailableUnidirectionalStreams() const; 537 538 // Returns existing stream with id = |stream_id|. If no 539 // such stream exists, and |stream_id| is a peer-created stream id, 540 // then a new stream is created and returned. In all other cases, nullptr is 541 // returned. 542 // Caller does not own the returned stream. 543 QuicStream* GetOrCreateStream(const QuicStreamId stream_id); 544 545 // Mark a stream as draining. 546 void StreamDraining(QuicStreamId id, bool unidirectional); 547 548 // Returns true if this stream should yield writes to another blocked stream. 549 virtual bool ShouldYield(QuicStreamId stream_id); 550 551 // Clean up closed_streams_. 552 void CleanUpClosedStreams(); 553 supported_versions()554 const ParsedQuicVersionVector& supported_versions() const { 555 return supported_versions_; 556 } 557 558 QuicStreamId next_outgoing_bidirectional_stream_id() const; 559 QuicStreamId next_outgoing_unidirectional_stream_id() const; 560 561 // Return true if given stream is peer initiated. 562 bool IsIncomingStream(QuicStreamId id) const; 563 564 // Record errors when a connection is closed at the server side, should only 565 // be called from server's perspective. 566 // Noop if |error| is QUIC_NO_ERROR. 567 static void RecordConnectionCloseAtServer(QuicErrorCode error, 568 ConnectionCloseSource source); 569 transport_version()570 QuicTransportVersion transport_version() const { 571 return connection_->transport_version(); 572 } 573 version()574 ParsedQuicVersion version() const { return connection_->version(); } 575 is_configured()576 bool is_configured() const { return is_configured_; } 577 578 // Called to neuter crypto data of encryption |level|. 579 void NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level); 580 581 // Returns the ALPN values to negotiate on this session. GetAlpnsToOffer()582 virtual std::vector<std::string> GetAlpnsToOffer() const { 583 // TODO(vasilvv): this currently sets HTTP/3 by default. Switch all 584 // non-HTTP applications to appropriate ALPNs. 585 return std::vector<std::string>({AlpnForVersion(connection()->version())}); 586 } 587 588 // Provided a list of ALPNs offered by the client, selects an ALPN from the 589 // list, or alpns.end() if none of the ALPNs are acceptable. 590 virtual std::vector<absl::string_view>::const_iterator SelectAlpn( 591 const std::vector<absl::string_view>& alpns) const; 592 593 // Called when the ALPN of the connection is established for a connection that 594 // uses TLS handshake. 595 virtual void OnAlpnSelected(absl::string_view alpn); 596 597 // Called on clients by the crypto handshaker to provide application state 598 // necessary for sending application data in 0-RTT. The state provided here is 599 // the same state that was provided to the crypto handshaker in 600 // QuicCryptoStream::SetServerApplicationStateForResumption on a previous 601 // connection. Application protocols that require state to be carried over 602 // from the previous connection to support 0-RTT data must implement this 603 // method to ingest this state. For example, an HTTP/3 QuicSession would 604 // implement this function to process the remembered server SETTINGS and apply 605 // those SETTINGS to 0-RTT data. This function returns true if the application 606 // state has been successfully processed, and false if there was an error 607 // processing the cached state and the connection should be closed. ResumeApplicationState(ApplicationState *)608 virtual bool ResumeApplicationState(ApplicationState* /*cached_state*/) { 609 return true; 610 } 611 612 // Does actual work of sending RESET_STREAM, if the stream type allows. 613 // Also informs the connection so that pending stream frames can be flushed. 614 virtual void MaybeSendRstStreamFrame(QuicStreamId id, 615 QuicResetStreamError error, 616 QuicStreamOffset bytes_written); 617 618 // Sends a STOP_SENDING frame if the stream type allows. 619 virtual void MaybeSendStopSendingFrame(QuicStreamId id, 620 QuicResetStreamError error); 621 622 // Returns the encryption level to send application data. 623 EncryptionLevel GetEncryptionLevelToSendApplicationData() const; 624 user_agent_id()625 const std::optional<std::string> user_agent_id() const { 626 return user_agent_id_; 627 } 628 629 // TODO(wub): remove saving user-agent to QuicSession. SetUserAgentId(std::string user_agent_id)630 void SetUserAgentId(std::string user_agent_id) { 631 user_agent_id_ = std::move(user_agent_id); 632 connection()->OnUserAgentIdKnown(*user_agent_id_); 633 } 634 SetSourceAddressTokenToSend(absl::string_view token)635 void SetSourceAddressTokenToSend(absl::string_view token) { 636 connection()->SetSourceAddressTokenToSend(token); 637 } 638 GetClock()639 const QuicClock* GetClock() const { 640 return connection()->helper()->GetClock(); 641 } 642 liveness_testing_in_progress()643 bool liveness_testing_in_progress() const { 644 return liveness_testing_in_progress_; 645 } 646 GetSSLConfig()647 virtual QuicSSLConfig GetSSLConfig() const { return QuicSSLConfig(); } 648 649 // Start converting all pending streams to normal streams in the same order as 650 // they are created, which may need several event loops to finish. 651 void ProcessAllPendingStreams(); 652 client_original_supported_versions()653 const ParsedQuicVersionVector& client_original_supported_versions() const { 654 QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT); 655 return client_original_supported_versions_; 656 } set_client_original_supported_versions(const ParsedQuicVersionVector & client_original_supported_versions)657 void set_client_original_supported_versions( 658 const ParsedQuicVersionVector& client_original_supported_versions) { 659 QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT); 660 client_original_supported_versions_ = client_original_supported_versions; 661 } 662 663 // Controls whether the default datagram queue used by the session actually 664 // queues the datagram. If set to true, the datagrams in the default queue 665 // will be forcefully flushed, potentially bypassing congestion control and 666 // other limitations. SetForceFlushForDefaultQueue(bool force_flush)667 void SetForceFlushForDefaultQueue(bool force_flush) { 668 datagram_queue_.SetForceFlush(force_flush); 669 } 670 671 // Returns the total number of expired datagrams dropped in the default 672 // datagram queue. expired_datagrams_in_default_queue()673 uint64_t expired_datagrams_in_default_queue() const { 674 return datagram_queue_.expired_datagram_count(); 675 } 676 677 // Returns the total datagrams ever declared lost within the session. total_datagrams_lost()678 uint64_t total_datagrams_lost() const { return total_datagrams_lost_; } 679 680 // Find stream with |id|, returns nullptr if the stream does not exist or 681 // closed. static streams and zombie streams are not considered active 682 // streams. 683 QuicStream* GetActiveStream(QuicStreamId id) const; 684 685 // Called in the following event loop to reset 686 // |new_incoming_streams_in_current_loop_| and process any pending streams. 687 void OnStreamCountReset(); 688 689 // Returns the priority type used by the streams in the session. priority_type()690 QuicPriorityType priority_type() const { return QuicPriorityType::kHttp; } 691 692 protected: 693 using StreamMap = 694 absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>; 695 696 // Use a linked hash map for pending streams so that they will be processed in 697 // a FIFO order to avoid starvation. 698 using PendingStreamMap = 699 quiche::QuicheLinkedHashMap<QuicStreamId, std::unique_ptr<PendingStream>>; 700 701 using ClosedStreams = std::vector<std::unique_ptr<QuicStream>>; 702 703 using ZombieStreamMap = 704 absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>; 705 706 std::string on_closed_frame_string() const; 707 708 // Creates a new stream to handle a peer-initiated stream. 709 // Caller does not own the returned stream. 710 // Returns nullptr and does error handling if the stream can not be created. 711 virtual QuicStream* CreateIncomingStream(QuicStreamId id) = 0; 712 virtual QuicStream* CreateIncomingStream(PendingStream* pending) = 0; 713 714 // Return the reserved crypto stream. 715 virtual QuicCryptoStream* GetMutableCryptoStream() = 0; 716 717 // Adds |stream| to the stream map. 718 virtual void ActivateStream(std::unique_ptr<QuicStream> stream); 719 720 // Set transmission type of next sending packets. 721 void SetTransmissionType(TransmissionType type); 722 723 // Returns the stream ID for a new outgoing bidirectional/unidirectional 724 // stream, and increments the underlying counter. 725 QuicStreamId GetNextOutgoingBidirectionalStreamId(); 726 QuicStreamId GetNextOutgoingUnidirectionalStreamId(); 727 728 // Indicates whether the next outgoing bidirectional/unidirectional stream ID 729 // can be allocated or not. The test for version-99/IETF QUIC is whether it 730 // will exceed the maximum-stream-id or not. For non-version-99 (Google) QUIC 731 // it checks whether the next stream would exceed the limit on the number of 732 // open streams. 733 bool CanOpenNextOutgoingBidirectionalStream(); 734 bool CanOpenNextOutgoingUnidirectionalStream(); 735 736 // Returns the maximum bidirectional streams parameter sent with the handshake 737 // as a transport parameter, or in the most recent MAX_STREAMS frame. 738 QuicStreamCount GetAdvertisedMaxIncomingBidirectionalStreams() const; 739 740 // When a stream is closed locally, it may not yet know how many bytes the 741 // peer sent on that stream. 742 // When this data arrives (via stream frame w. FIN, trailing headers, or RST) 743 // this method is called, and correctly updates the connection level flow 744 // controller. 745 virtual void OnFinalByteOffsetReceived(QuicStreamId id, 746 QuicStreamOffset final_byte_offset); 747 748 // Returns true if a frame with the given type and id can be prcoessed by a 749 // PendingStream. However, the frame will always be processed by a QuicStream 750 // if one exists with the given stream_id. UsesPendingStreamForFrame(QuicFrameType,QuicStreamId)751 virtual bool UsesPendingStreamForFrame(QuicFrameType /*type*/, 752 QuicStreamId /*stream_id*/) const { 753 return false; 754 } 755 GetSpdyPriorityofStream(QuicStreamId stream_id)756 spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId stream_id) const { 757 return write_blocked_streams_->GetPriorityOfStream(stream_id) 758 .http() 759 .urgency; 760 } 761 pending_streams_size()762 size_t pending_streams_size() const { return pending_stream_map_.size(); } 763 closed_streams()764 ClosedStreams* closed_streams() { return &closed_streams_; } 765 766 void set_largest_peer_created_stream_id( 767 QuicStreamId largest_peer_created_stream_id); 768 write_blocked_streams()769 QuicWriteBlockedListInterface* write_blocked_streams() { 770 return write_blocked_streams_.get(); 771 } 772 773 // Returns true if the stream is still active. 774 bool IsOpenStream(QuicStreamId id); 775 776 // Returns true if the stream is a static stream. 777 bool IsStaticStream(QuicStreamId id) const; 778 779 // Close connection when receiving a frame for a locally-created nonexistent 780 // stream. 781 // Prerequisite: IsClosedStream(stream_id) == false 782 virtual void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id); 783 784 virtual bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id); 785 786 void InsertLocallyClosedStreamsHighestOffset(const QuicStreamId id, 787 QuicStreamOffset offset); 788 // If stream is a locally closed stream, this RST will update FIN offset. 789 // Otherwise stream is a preserved stream and the behavior of it depends on 790 // derived class's own implementation. 791 virtual void HandleRstOnValidNonexistentStream( 792 const QuicRstStreamFrame& frame); 793 794 // Returns a stateless reset token which will be included in the public reset 795 // packet. 796 virtual StatelessResetToken GetStatelessResetToken() const; 797 control_frame_manager()798 QuicControlFrameManager& control_frame_manager() { 799 return control_frame_manager_; 800 } 801 stream_id_manager()802 const LegacyQuicStreamIdManager& stream_id_manager() const { 803 return stream_id_manager_; 804 } 805 datagram_queue()806 QuicDatagramQueue* datagram_queue() { return &datagram_queue_; } 807 num_static_streams()808 size_t num_static_streams() const { return num_static_streams_; } 809 num_zombie_streams()810 size_t num_zombie_streams() const { return num_zombie_streams_; } 811 was_zero_rtt_rejected()812 bool was_zero_rtt_rejected() const { return was_zero_rtt_rejected_; } 813 num_outgoing_draining_streams()814 size_t num_outgoing_draining_streams() const { 815 return num_outgoing_draining_streams_; 816 } 817 num_draining_streams()818 size_t num_draining_streams() const { return num_draining_streams_; } 819 820 // How a pending stream is converted to a full QuicStream depends on subclass 821 // implementations. As the default value of max_streams_accepted_per_loop_ is 822 // kMaxQuicStreamCount and UsesPendingStreamForFrame() returns false, this 823 // method is not supposed to be called at all. ProcessReadUnidirectionalPendingStream(PendingStream *)824 virtual QuicStream* ProcessReadUnidirectionalPendingStream( 825 PendingStream* /*pending*/) { 826 QUICHE_BUG(received unexpected pending read unidirectional stream); 827 return nullptr; 828 } ProcessBidirectionalPendingStream(PendingStream *)829 virtual QuicStream* ProcessBidirectionalPendingStream( 830 PendingStream* /*pending*/) { 831 QUICHE_BUG(received unexpected pending bidirectional stream); 832 return nullptr; 833 } 834 835 // Called by applications to perform |action| on active streams. 836 // Stream iteration will be stopped if action returns false. 837 void PerformActionOnActiveStreams( 838 quiche::UnretainedCallback<bool(QuicStream*)> action); 839 void PerformActionOnActiveStreams( 840 quiche::UnretainedCallback<bool(QuicStream*)> action) const; 841 842 // Return the largest peer created stream id depending on directionality 843 // indicated by |unidirectional|. 844 QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const; 845 846 // Deletes the connection and sets it to nullptr, so calling it mulitiple 847 // times is safe. 848 void DeleteConnection(); 849 850 // Call SetPriority() on stream id |id| and return true if stream is active. 851 bool MaybeSetStreamPriority(QuicStreamId stream_id, 852 const QuicStreamPriority& priority); 853 SetLossDetectionTuner(std::unique_ptr<LossDetectionTunerInterface> tuner)854 void SetLossDetectionTuner( 855 std::unique_ptr<LossDetectionTunerInterface> tuner) { 856 connection()->SetLossDetectionTuner(std::move(tuner)); 857 } 858 ietf_streamid_manager()859 UberQuicStreamIdManager& ietf_streamid_manager() { 860 QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version())); 861 return ietf_streamid_manager_; 862 } 863 864 // Only called at a server session. Generate a CachedNetworkParameters that 865 // can be sent to the client as part of the address token, based on the latest 866 // bandwidth/rtt information. If return std::nullopt, address token will not 867 // contain the CachedNetworkParameters. 868 virtual std::optional<CachedNetworkParameters> GenerateCachedNetworkParameters()869 GenerateCachedNetworkParameters() const { 870 return std::nullopt; 871 } 872 873 // Debug helper for OnCanWrite. Check that after QuicStream::OnCanWrite(), 874 // if stream has buffered data and is not stream level flow control blocked, 875 // it has to be in the write blocked list. 876 virtual bool CheckStreamWriteBlocked(QuicStream* stream) const; 877 878 // Sets the limit on the maximum number of new streams that can be created in 879 // a single event loop. Any addition stream data will be stored in a 880 // PendingStream until a subsequent event loop. set_max_streams_accepted_per_loop(QuicStreamCount max_streams_accepted_per_loop)881 void set_max_streams_accepted_per_loop( 882 QuicStreamCount max_streams_accepted_per_loop) { 883 max_streams_accepted_per_loop_ = max_streams_accepted_per_loop; 884 } 885 886 private: 887 friend class test::QuicSessionPeer; 888 889 // Called in OnConfigNegotiated when we receive a new stream level flow 890 // control window in a negotiated config. Closes the connection if invalid. 891 void OnNewStreamFlowControlWindow(QuicStreamOffset new_window); 892 893 // Called in OnConfigNegotiated when we receive a new unidirectional stream 894 // flow control window in a negotiated config. 895 void OnNewStreamUnidirectionalFlowControlWindow(QuicStreamOffset new_window); 896 897 // Called in OnConfigNegotiated when we receive a new outgoing bidirectional 898 // stream flow control window in a negotiated config. 899 void OnNewStreamOutgoingBidirectionalFlowControlWindow( 900 QuicStreamOffset new_window); 901 902 // Called in OnConfigNegotiated when we receive a new incoming bidirectional 903 // stream flow control window in a negotiated config. 904 void OnNewStreamIncomingBidirectionalFlowControlWindow( 905 QuicStreamOffset new_window); 906 907 // Called in OnConfigNegotiated when we receive a new connection level flow 908 // control window in a negotiated config. Closes the connection if invalid. 909 void OnNewSessionFlowControlWindow(QuicStreamOffset new_window); 910 911 // Debug helper for |OnCanWrite()|, check that OnStreamWrite() makes 912 // forward progress. Returns false if busy loop detected. 913 bool CheckStreamNotBusyLooping(QuicStream* stream, 914 uint64_t previous_bytes_written, 915 bool previous_fin_sent); 916 917 // Called in OnConfigNegotiated for Finch trials to measure performance of 918 // starting with larger flow control receive windows. 919 void AdjustInitialFlowControlWindows(size_t stream_window); 920 921 // Find stream with |id|, returns nullptr if the stream does not exist or 922 // closed. 923 QuicStream* GetStream(QuicStreamId id) const; 924 925 // Can return NULL, e.g., if the stream has been closed before. 926 PendingStream* GetOrCreatePendingStream(QuicStreamId stream_id); 927 928 // Let streams and control frame managers retransmit lost data, returns true 929 // if all lost data is retransmitted. Returns false otherwise. 930 bool RetransmitLostData(); 931 932 // Returns true if stream data should be written. 933 bool CanWriteStreamData() const; 934 935 // Closes the pending stream |stream_id| before it has been created. 936 void ClosePendingStream(QuicStreamId stream_id); 937 938 // Whether the frame with given type and id should be feed to a pending 939 // stream. 940 bool ShouldProcessFrameByPendingStream(QuicFrameType type, 941 QuicStreamId id) const; 942 943 // Process the pending stream if possible. 944 // Returns true if more pending streams should be processed afterwards while 945 // iterating through all pending streams. 946 bool MaybeProcessPendingStream(PendingStream* pending); 947 948 // Creates or gets pending stream, feeds it with |frame|, and returns the 949 // pending stream. Can return NULL, e.g., if the stream ID is invalid. 950 PendingStream* PendingStreamOnStreamFrame(const QuicStreamFrame& frame); 951 952 // Creates or gets pending strea, feed it with |frame|, and closes the pending 953 // stream. 954 void PendingStreamOnRstStream(const QuicRstStreamFrame& frame); 955 956 // Creates or gets pending stream, feeds it with |frame|, and records the 957 // max_data in the pending stream. 958 void PendingStreamOnWindowUpdateFrame(const QuicWindowUpdateFrame& frame); 959 960 // Creates or gets pending stream, feeds it with |frame|, and records the 961 // ietf_error_code in the pending stream. 962 void PendingStreamOnStopSendingFrame(const QuicStopSendingFrame& frame); 963 964 // Processes the |pending| stream according to its stream type. 965 // If the pending stream has been converted to a normal stream, returns a 966 // pointer to the new stream; otherwise, returns nullptr. 967 QuicStream* ProcessPendingStream(PendingStream* pending); 968 969 bool ExceedsPerLoopStreamLimit() const; 970 971 // Keep track of highest received byte offset of locally closed streams, while 972 // waiting for a definitive final highest offset from the peer. 973 absl::flat_hash_map<QuicStreamId, QuicStreamOffset> 974 locally_closed_streams_highest_offset_; 975 976 QuicConnection* connection_; 977 978 // Store perspective on QuicSession during the constructor as it may be needed 979 // during our destructor when connection_ may have already been destroyed. 980 Perspective perspective_; 981 982 // May be null. 983 Visitor* visitor_; 984 985 // A list of streams which need to write more data. Stream register 986 // themselves in their constructor, and unregisterm themselves in their 987 // destructors, so the write blocked list must outlive all streams. 988 std::unique_ptr<QuicWriteBlockedList> write_blocked_streams_; 989 990 ClosedStreams closed_streams_; 991 992 QuicConfig config_; 993 994 // Map from StreamId to pointers to streams. Owns the streams. 995 StreamMap stream_map_; 996 997 // Map from StreamId to PendingStreams for peer-created unidirectional streams 998 // which are waiting for the first byte of payload to arrive. 999 PendingStreamMap pending_stream_map_; 1000 1001 // TODO(fayang): Consider moving LegacyQuicStreamIdManager into 1002 // UberQuicStreamIdManager. 1003 // Manages stream IDs for Google QUIC. 1004 LegacyQuicStreamIdManager stream_id_manager_; 1005 1006 // Manages stream IDs for version99/IETF QUIC 1007 UberQuicStreamIdManager ietf_streamid_manager_; 1008 1009 // A counter for streams which have sent and received FIN but waiting for 1010 // application to consume data. 1011 size_t num_draining_streams_; 1012 1013 // A counter for self initiated streams which have sent and received FIN but 1014 // waiting for application to consume data. 1015 size_t num_outgoing_draining_streams_; 1016 1017 // A counter for static streams which are in stream_map_. 1018 size_t num_static_streams_; 1019 1020 // A counter for streams which have done reading and writing, but are waiting 1021 // for acks. 1022 size_t num_zombie_streams_; 1023 1024 // Received information for a connection close. 1025 QuicConnectionCloseFrame on_closed_frame_; 1026 std::optional<ConnectionCloseSource> source_; 1027 1028 // Used for connection-level flow control. 1029 QuicFlowController flow_controller_; 1030 1031 // The stream id which was last popped in OnCanWrite, or 0, if not under the 1032 // call stack of OnCanWrite. 1033 QuicStreamId currently_writing_stream_id_; 1034 1035 // Whether a transport layer GOAWAY frame has been sent. 1036 // Such a frame only exists in Google QUIC, therefore |transport_goaway_sent_| 1037 // is always false when using IETF QUIC. 1038 bool transport_goaway_sent_; 1039 1040 // Whether a transport layer GOAWAY frame has been received. 1041 // Such a frame only exists in Google QUIC, therefore 1042 // |transport_goaway_received_| is always false when using IETF QUIC. 1043 bool transport_goaway_received_; 1044 1045 QuicControlFrameManager control_frame_manager_; 1046 1047 // Id of latest successfully sent message. 1048 QuicMessageId last_message_id_; 1049 1050 // The buffer used to queue the DATAGRAM frames. 1051 QuicDatagramQueue datagram_queue_; 1052 1053 // Total number of datagram frames declared lost within the session. 1054 uint64_t total_datagrams_lost_ = 0; 1055 1056 // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool 1057 // is not used here. 1058 // List of streams with pending retransmissions. 1059 quiche::QuicheLinkedHashMap<QuicStreamId, bool> 1060 streams_with_pending_retransmission_; 1061 1062 // Clean up closed_streams_ when this alarm fires. 1063 std::unique_ptr<QuicAlarm> closed_streams_clean_up_alarm_; 1064 1065 // Supported version list used by the crypto handshake only. Please note, this 1066 // list may be a superset of the connection framer's supported versions. 1067 ParsedQuicVersionVector supported_versions_; 1068 1069 // Only non-empty on the client after receiving a version negotiation packet, 1070 // contains the configured versions from the original session before version 1071 // negotiation was received. 1072 ParsedQuicVersionVector client_original_supported_versions_; 1073 1074 std::optional<std::string> user_agent_id_; 1075 1076 // Initialized to false. Set to true when the session has been properly 1077 // configured and is ready for general operation. 1078 bool is_configured_; 1079 1080 // Whether the session has received a 0-RTT rejection (QUIC+TLS only). 1081 bool was_zero_rtt_rejected_; 1082 1083 // This indicates a liveness testing is in progress, and push back the 1084 // creation of new outgoing bidirectional streams. 1085 bool liveness_testing_in_progress_; 1086 1087 // The counter for newly created non-static incoming streams in the current 1088 // event loop and gets reset for each event loop. 1089 QuicStreamCount new_incoming_streams_in_current_loop_ = 0u; 1090 // Default to max stream count so that there is no stream creation limit per 1091 // event loop. 1092 QuicStreamCount max_streams_accepted_per_loop_ = kMaxQuicStreamCount; 1093 std::unique_ptr<QuicAlarm> stream_count_reset_alarm_; 1094 }; 1095 1096 } // namespace quic 1097 1098 #endif // QUICHE_QUIC_CORE_QUIC_SESSION_H_ 1099