// Copyright (c) 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_ #define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_ #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_interval_set.h" #include "net/third_party/quiche/src/quic/core/session_notifier_interface.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" namespace quic { class QuicConnection; namespace test { // SimpleSessionNotifier implements the basic functionalities of a session, and // it manages stream data and control frames. class SimpleSessionNotifier : public SessionNotifierInterface { public: explicit SimpleSessionNotifier(QuicConnection* connection); ~SimpleSessionNotifier() override; // Tries to write stream data and returns data consumed. QuicConsumedData WriteOrBufferData(QuicStreamId id, QuicByteCount data_length, StreamSendingState state); // Tries to write RST_STREAM_FRAME. void WriteOrBufferRstStream(QuicStreamId id, QuicRstStreamErrorCode error, QuicStreamOffset bytes_written); // Tries to write PING. void WriteOrBufferPing(); // Tries to write CRYPTO data and returns the number of bytes written. size_t WriteCryptoData(EncryptionLevel level, QuicByteCount data_length, QuicStreamOffset offset); // Neuters unencrypted data of crypto stream. void NeuterUnencryptedData(); // Called when connection_ becomes writable. void OnCanWrite(); // Called to reset stream. void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error); // Returns true if there are 1) unsent control frames and stream data, or 2) // lost control frames and stream data. bool WillingToWrite() const; // Number of sent stream bytes. Please note, this does not count // retransmissions. QuicByteCount StreamBytesSent() const; // Number of stream bytes waiting to be sent for the first time. QuicByteCount StreamBytesToSend() const; // Returns true if there is any stream data waiting to be sent for the first // time. bool HasBufferedStreamData() const; // Returns true if stream |id| has any outstanding data. bool StreamIsWaitingForAcks(QuicStreamId id) const; // SessionNotifierInterface methods: bool OnFrameAcked(const QuicFrame& frame, QuicTime::Delta ack_delay_time, QuicTime receive_timestamp) override; void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {} void OnFrameLost(const QuicFrame& frame) override; void RetransmitFrames(const QuicFrames& frames, TransmissionType type) override; bool IsFrameOutstanding(const QuicFrame& frame) const override; bool HasUnackedCryptoData() const override; bool HasUnackedStreamData() const override; private: struct StreamState { StreamState(); ~StreamState(); // Total number of bytes. QuicByteCount bytes_total; // Number of sent bytes. QuicByteCount bytes_sent; // Record of acked offsets. QuicIntervalSet bytes_acked; // Data considered as lost and needs to be retransmitted. QuicIntervalSet pending_retransmissions; bool fin_buffered; bool fin_sent; bool fin_outstanding; bool fin_lost; }; friend std::ostream& operator<<(std::ostream& os, const StreamState& s); using StreamMap = QuicUnorderedMap; void OnStreamDataConsumed(QuicStreamId id, QuicStreamOffset offset, QuicByteCount data_length, bool fin); bool OnControlFrameAcked(const QuicFrame& frame); void OnControlFrameLost(const QuicFrame& frame); bool RetransmitLostControlFrames(); bool RetransmitLostCryptoData(); bool RetransmitLostStreamData(); bool WriteBufferedControlFrames(); bool IsControlFrameOutstanding(const QuicFrame& frame) const; bool HasBufferedControlFrames() const; bool HasLostStreamData() const; bool StreamHasBufferedData(QuicStreamId id) const; QuicCircularDeque control_frames_; QuicLinkedHashMap lost_control_frames_; // Id of latest saved control frame. 0 if no control frame has been saved. QuicControlFrameId last_control_frame_id_; // The control frame at the 0th index of control_frames_. QuicControlFrameId least_unacked_; // ID of the least unsent control frame. QuicControlFrameId least_unsent_; StreamMap stream_map_; // Transferred crypto bytes according to encryption levels. QuicIntervalSet crypto_bytes_transferred_[NUM_ENCRYPTION_LEVELS]; StreamState crypto_state_[NUM_ENCRYPTION_LEVELS]; QuicConnection* connection_; }; } // namespace test } // namespace quic #endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_