1 // Copyright (c) 2017 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_CORE_QUIC_STREAM_SEND_BUFFER_H_ 6 #define QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_ 7 8 #include "absl/types/span.h" 9 #include "quiche/quic/core/frames/quic_stream_frame.h" 10 #include "quiche/quic/core/quic_interval_deque.h" 11 #include "quiche/quic/core/quic_interval_set.h" 12 #include "quiche/quic/core/quic_types.h" 13 #include "quiche/common/platform/api/quiche_mem_slice.h" 14 #include "quiche/common/quiche_circular_deque.h" 15 16 namespace quic { 17 18 namespace test { 19 class QuicStreamSendBufferPeer; 20 class QuicStreamPeer; 21 } // namespace test 22 23 class QuicDataWriter; 24 25 // BufferedSlice comprises information of a piece of stream data stored in 26 // contiguous memory space. Please note, BufferedSlice is constructed when 27 // stream data is saved in send buffer and is removed when stream data is fully 28 // acked. It is move-only. 29 struct QUICHE_EXPORT BufferedSlice { 30 BufferedSlice(quiche::QuicheMemSlice mem_slice, QuicStreamOffset offset); 31 BufferedSlice(BufferedSlice&& other); 32 BufferedSlice& operator=(BufferedSlice&& other); 33 34 BufferedSlice(const BufferedSlice& other) = delete; 35 BufferedSlice& operator=(const BufferedSlice& other) = delete; 36 ~BufferedSlice(); 37 38 // Return an interval representing the offset and length. 39 QuicInterval<std::size_t> interval() const; 40 41 // Stream data of this data slice. 42 quiche::QuicheMemSlice slice; 43 // Location of this data slice in the stream. 44 QuicStreamOffset offset; 45 }; 46 47 struct QUICHE_EXPORT StreamPendingRetransmission { StreamPendingRetransmissionStreamPendingRetransmission48 constexpr StreamPendingRetransmission(QuicStreamOffset offset, 49 QuicByteCount length) 50 : offset(offset), length(length) {} 51 52 // Starting offset of this pending retransmission. 53 QuicStreamOffset offset; 54 // Length of this pending retransmission. 55 QuicByteCount length; 56 57 bool operator==(const StreamPendingRetransmission& other) const; 58 }; 59 60 // QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices 61 // are added to the tail of the list. Data slices are removed from the head of 62 // the list when they get fully acked. Stream data can be retrieved and acked 63 // across slice boundaries. 64 class QUICHE_EXPORT QuicStreamSendBuffer { 65 public: 66 explicit QuicStreamSendBuffer(quiche::QuicheBufferAllocator* allocator); 67 QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete; 68 QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete; 69 ~QuicStreamSendBuffer(); 70 71 // Save |data| to send buffer. 72 void SaveStreamData(absl::string_view data); 73 74 // Save |slice| to send buffer. 75 void SaveMemSlice(quiche::QuicheMemSlice slice); 76 77 // Save all slices in |span| to send buffer. Return total bytes saved. 78 QuicByteCount SaveMemSliceSpan(absl::Span<quiche::QuicheMemSlice> span); 79 80 // Called when |bytes_consumed| bytes has been consumed by the stream. 81 void OnStreamDataConsumed(size_t bytes_consumed); 82 83 // Write |data_length| of data starts at |offset|. 84 bool WriteStreamData(QuicStreamOffset offset, QuicByteCount data_length, 85 QuicDataWriter* writer); 86 87 // Called when data [offset, offset + data_length) is acked or removed as 88 // stream is canceled. Removes fully acked data slice from send buffer. Set 89 // |newly_acked_length|. Returns false if trying to ack unsent data. 90 bool OnStreamDataAcked(QuicStreamOffset offset, QuicByteCount data_length, 91 QuicByteCount* newly_acked_length); 92 93 // Called when data [offset, offset + data_length) is considered as lost. 94 void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length); 95 96 // Called when data [offset, offset + length) was retransmitted. 97 void OnStreamDataRetransmitted(QuicStreamOffset offset, 98 QuicByteCount data_length); 99 100 // Returns true if there is pending retransmissions. 101 bool HasPendingRetransmission() const; 102 103 // Returns next pending retransmissions. 104 StreamPendingRetransmission NextPendingRetransmission() const; 105 106 // Returns true if data [offset, offset + data_length) is outstanding and 107 // waiting to be acked. Returns false otherwise. 108 bool IsStreamDataOutstanding(QuicStreamOffset offset, 109 QuicByteCount data_length) const; 110 111 // Number of data slices in send buffer. 112 size_t size() const; 113 stream_offset()114 QuicStreamOffset stream_offset() const { return stream_offset_; } 115 stream_bytes_written()116 uint64_t stream_bytes_written() const { return stream_bytes_written_; } 117 stream_bytes_outstanding()118 uint64_t stream_bytes_outstanding() const { 119 return stream_bytes_outstanding_; 120 } 121 bytes_acked()122 const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const { 123 return bytes_acked_; 124 } 125 pending_retransmissions()126 const QuicIntervalSet<QuicStreamOffset>& pending_retransmissions() const { 127 return pending_retransmissions_; 128 } 129 130 private: 131 friend class test::QuicStreamSendBufferPeer; 132 friend class test::QuicStreamPeer; 133 134 // Called when data within offset [start, end) gets acked. Frees fully 135 // acked buffered slices if any. Returns false if the corresponding data does 136 // not exist or has been acked. 137 bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end); 138 139 // Cleanup empty slices in order from buffered_slices_. 140 void CleanUpBufferedSlices(); 141 142 // |current_end_offset_| stores the end offset of the current slice to ensure 143 // data isn't being written out of order when using the |interval_deque_|. 144 QuicStreamOffset current_end_offset_; 145 QuicIntervalDeque<BufferedSlice> interval_deque_; 146 147 // Offset of next inserted byte. 148 QuicStreamOffset stream_offset_; 149 150 quiche::QuicheBufferAllocator* allocator_; 151 152 // Bytes that have been consumed by the stream. 153 uint64_t stream_bytes_written_; 154 155 // Bytes that have been consumed and are waiting to be acked. 156 uint64_t stream_bytes_outstanding_; 157 158 // Offsets of data that has been acked. 159 QuicIntervalSet<QuicStreamOffset> bytes_acked_; 160 161 // Data considered as lost and needs to be retransmitted. 162 QuicIntervalSet<QuicStreamOffset> pending_retransmissions_; 163 164 // Index of slice which contains data waiting to be written for the first 165 // time. -1 if send buffer is empty or all data has been written. 166 int32_t write_index_; 167 }; 168 169 } // namespace quic 170 171 #endif // QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_ 172