| // 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_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(); | |
| // 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) 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; | |
| private: | |
| struct StreamState { | |
| StreamState(); | |
| ~StreamState(); | |
| // Total number of bytes. | |
| QuicByteCount bytes_total; | |
| // Number of sent bytes. | |
| QuicByteCount bytes_sent; | |
| // Record of acked offsets. | |
| QuicIntervalSet<QuicStreamOffset> bytes_acked; | |
| // Data considered as lost and needs to be retransmitted. | |
| QuicIntervalSet<QuicStreamOffset> 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<QuicStreamId, StreamState>; | |
| 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; | |
| QuicDeque<QuicFrame> control_frames_; | |
| QuicLinkedHashMap<QuicControlFrameId, bool> 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<QuicStreamOffset> | |
| 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_ |