1 // Copyright (c) 2018 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 #ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_ 6 #define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_ 7 8 #include "absl/container/flat_hash_map.h" 9 #include "quiche/quic/core/quic_interval_set.h" 10 #include "quiche/quic/core/session_notifier_interface.h" 11 #include "quiche/quic/platform/api/quic_test.h" 12 #include "quiche/common/quiche_circular_deque.h" 13 #include "quiche/common/quiche_linked_hash_map.h" 14 15 namespace quic { 16 17 class QuicConnection; 18 19 namespace test { 20 21 // SimpleSessionNotifier implements the basic functionalities of a session, and 22 // it manages stream data and control frames. 23 class SimpleSessionNotifier : public SessionNotifierInterface { 24 public: 25 explicit SimpleSessionNotifier(QuicConnection* connection); 26 ~SimpleSessionNotifier() override; 27 28 // Tries to write stream data and returns data consumed. 29 QuicConsumedData WriteOrBufferData(QuicStreamId id, QuicByteCount data_length, 30 StreamSendingState state); 31 QuicConsumedData WriteOrBufferData(QuicStreamId id, QuicByteCount data_length, 32 StreamSendingState state, 33 TransmissionType transmission_type); 34 35 // Tries to write RST_STREAM_FRAME. 36 void WriteOrBufferRstStream(QuicStreamId id, QuicRstStreamErrorCode error, 37 QuicStreamOffset bytes_written); 38 39 // Tries to write WINDOW_UPDATE. 40 void WriteOrBufferWindowUpate(QuicStreamId id, QuicStreamOffset byte_offset); 41 42 // Tries to write PING. 43 void WriteOrBufferPing(); 44 45 // Tries to write ACK_FREQUENCY. 46 void WriteOrBufferAckFrequency( 47 const QuicAckFrequencyFrame& ack_frequency_frame); 48 49 // Tries to write CRYPTO data and returns the number of bytes written. 50 size_t WriteCryptoData(EncryptionLevel level, QuicByteCount data_length, 51 QuicStreamOffset offset); 52 53 // Neuters unencrypted data of crypto stream. 54 void NeuterUnencryptedData(); 55 56 // Called when connection_ becomes writable. 57 void OnCanWrite(); 58 59 // Called to reset stream. 60 void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error); 61 62 // Returns true if there are 1) unsent control frames and stream data, or 2) 63 // lost control frames and stream data. 64 bool WillingToWrite() const; 65 66 // Number of sent stream bytes. Please note, this does not count 67 // retransmissions. 68 QuicByteCount StreamBytesSent() const; 69 70 // Number of stream bytes waiting to be sent for the first time. 71 QuicByteCount StreamBytesToSend() const; 72 73 // Returns true if there is any stream data waiting to be sent for the first 74 // time. 75 bool HasBufferedStreamData() const; 76 77 // Returns true if stream |id| has any outstanding data. 78 bool StreamIsWaitingForAcks(QuicStreamId id) const; 79 80 // SessionNotifierInterface methods: 81 bool OnFrameAcked(const QuicFrame& frame, QuicTime::Delta ack_delay_time, 82 QuicTime receive_timestamp) override; OnStreamFrameRetransmitted(const QuicStreamFrame &)83 void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {} 84 void OnFrameLost(const QuicFrame& frame) override; 85 bool RetransmitFrames(const QuicFrames& frames, 86 TransmissionType type) override; 87 bool IsFrameOutstanding(const QuicFrame& frame) const override; 88 bool HasUnackedCryptoData() const override; 89 bool HasUnackedStreamData() const override; 90 bool HasLostStreamData() const; 91 92 private: 93 struct StreamState { 94 StreamState(); 95 ~StreamState(); 96 97 // Total number of bytes. 98 QuicByteCount bytes_total; 99 // Number of sent bytes. 100 QuicByteCount bytes_sent; 101 // Record of acked offsets. 102 QuicIntervalSet<QuicStreamOffset> bytes_acked; 103 // Data considered as lost and needs to be retransmitted. 104 QuicIntervalSet<QuicStreamOffset> pending_retransmissions; 105 106 bool fin_buffered; 107 bool fin_sent; 108 bool fin_outstanding; 109 bool fin_lost; 110 }; 111 112 friend std::ostream& operator<<(std::ostream& os, const StreamState& s); 113 114 using StreamMap = absl::flat_hash_map<QuicStreamId, StreamState>; 115 116 void OnStreamDataConsumed(QuicStreamId id, QuicStreamOffset offset, 117 QuicByteCount data_length, bool fin); 118 119 bool OnControlFrameAcked(const QuicFrame& frame); 120 121 void OnControlFrameLost(const QuicFrame& frame); 122 123 bool RetransmitLostControlFrames(); 124 125 bool RetransmitLostCryptoData(); 126 127 bool RetransmitLostStreamData(); 128 129 bool WriteBufferedControlFrames(); 130 131 bool WriteBufferedCryptoData(); 132 133 bool IsControlFrameOutstanding(const QuicFrame& frame) const; 134 135 bool HasBufferedControlFrames() const; 136 137 bool StreamHasBufferedData(QuicStreamId id) const; 138 139 quiche::QuicheCircularDeque<QuicFrame> control_frames_; 140 141 quiche::QuicheLinkedHashMap<QuicControlFrameId, bool> lost_control_frames_; 142 143 // Id of latest saved control frame. 0 if no control frame has been saved. 144 QuicControlFrameId last_control_frame_id_; 145 146 // The control frame at the 0th index of control_frames_. 147 QuicControlFrameId least_unacked_; 148 149 // ID of the least unsent control frame. 150 QuicControlFrameId least_unsent_; 151 152 StreamMap stream_map_; 153 154 // Transferred crypto bytes according to encryption levels. 155 QuicIntervalSet<QuicStreamOffset> 156 crypto_bytes_transferred_[NUM_ENCRYPTION_LEVELS]; 157 158 StreamState crypto_state_[NUM_ENCRYPTION_LEVELS]; 159 160 QuicConnection* connection_; 161 }; 162 163 } // namespace test 164 165 } // namespace quic 166 167 #endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_ 168