xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
6 #define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
7 
8 #include <cstddef>
9 #include <map>
10 #include <string>
11 
12 #include "quiche/quic/core/quic_packets.h"
13 #include "quiche/quic/core/quic_stream_sequencer_buffer.h"
14 #include "quiche/quic/core/quic_types.h"
15 #include "quiche/quic/platform/api/quic_export.h"
16 
17 namespace quic {
18 
19 namespace test {
20 class QuicStreamSequencerPeer;
21 }  // namespace test
22 
23 // Buffers frames until we have something which can be passed
24 // up to the next layer.
25 class QUICHE_EXPORT QuicStreamSequencer final {
26  public:
27   // Interface that thie Sequencer uses to communicate with the Stream.
28   class QUICHE_EXPORT StreamInterface {
29    public:
30     virtual ~StreamInterface() = default;
31 
32     // Called when new data is available to be read from the sequencer.
33     virtual void OnDataAvailable() = 0;
34     // Called when the end of the stream has been read.
35     virtual void OnFinRead() = 0;
36     // Called when bytes have been consumed from the sequencer.
37     virtual void AddBytesConsumed(QuicByteCount bytes) = 0;
38     // Called when an error has occurred which should result in the stream
39     // being reset.
40     virtual void ResetWithError(QuicResetStreamError error) = 0;
41     // Called when an error has occurred which should result in the connection
42     // being closed.
43     virtual void OnUnrecoverableError(QuicErrorCode error,
44                                       const std::string& details) = 0;
45     // Called when an error has occurred which should result in the connection
46     // being closed, specifying the wire error code |ietf_error| explicitly.
47     virtual void OnUnrecoverableError(QuicErrorCode error,
48                                       QuicIetfTransportErrorCodes ietf_error,
49                                       const std::string& details) = 0;
50     // Returns the stream id of this stream.
51     virtual QuicStreamId id() const = 0;
52 
53     // Returns the QUIC version being used by this stream.
54     virtual ParsedQuicVersion version() const = 0;
55   };
56 
57   explicit QuicStreamSequencer(StreamInterface* quic_stream);
58   QuicStreamSequencer(const QuicStreamSequencer&) = delete;
59   QuicStreamSequencer(QuicStreamSequencer&&) = default;
60   QuicStreamSequencer& operator=(const QuicStreamSequencer&) = delete;
61   QuicStreamSequencer& operator=(QuicStreamSequencer&&) = default;
62   ~QuicStreamSequencer();
63 
64   // If the frame is the next one we need in order to process in-order data,
65   // ProcessData will be immediately called on the stream until all buffered
66   // data is processed or the stream fails to consume data.  Any unconsumed
67   // data will be buffered. If the frame is not the next in line, it will be
68   // buffered.
69   void OnStreamFrame(const QuicStreamFrame& frame);
70 
71   // If the frame is the next one we need in order to process in-order data,
72   // ProcessData will be immediately called on the crypto stream until all
73   // buffered data is processed or the crypto stream fails to consume data. Any
74   // unconsumed data will be buffered. If the frame is not the next in line, it
75   // will be buffered.
76   void OnCryptoFrame(const QuicCryptoFrame& frame);
77 
78   // Once data is buffered, it's up to the stream to read it when the stream
79   // can handle more data.  The following three functions make that possible.
80 
81   // Fills in up to iov_len iovecs with the next readable regions.  Returns the
82   // number of iovs used.  Non-destructive of the underlying data.
83   int GetReadableRegions(iovec* iov, size_t iov_len) const;
84 
85   // Fills in one iovec with the next readable region.  Returns false if there
86   // is no readable region available.
87   bool GetReadableRegion(iovec* iov) const;
88 
89   // Fills in one iovec with the region starting at |offset| and returns true.
90   // Returns false if no readable region is available, either because data has
91   // not been received yet or has already been consumed.
92   bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
93 
94   // Copies the data into the iov_len buffers provided.  Returns the number of
95   // bytes read.  Any buffered data no longer in use will be released.
96   // TODO(rch): remove this method and instead implement it as a helper method
97   // based on GetReadableRegions and MarkConsumed.
98   size_t Readv(const struct iovec* iov, size_t iov_len);
99 
100   // Consumes |num_bytes| data.  Used in conjunction with |GetReadableRegions|
101   // to do zero-copy reads.
102   void MarkConsumed(size_t num_bytes);
103 
104   // Appends all of the readable data to |buffer| and marks all of the appended
105   // data as consumed.
106   void Read(std::string* buffer);
107 
108   // Returns true if the sequncer has bytes available for reading.
109   bool HasBytesToRead() const;
110 
111   // Number of bytes available to read.
112   size_t ReadableBytes() const;
113 
114   // Returns true if the sequencer has delivered the fin.
115   bool IsClosed() const;
116 
117   // Calls |OnDataAvailable| on |stream_| if there is buffered data that can
118   // be processed, and causes |OnDataAvailable| to be called as new data
119   // arrives.
120   void SetUnblocked();
121 
122   // Blocks processing of frames until |SetUnblocked| is called.
123   void SetBlockedUntilFlush();
124 
125   // Sets the sequencer to discard all incoming data itself and not call
126   // |stream_->OnDataAvailable()|.  |stream_->OnFinRead()| will be called
127   // automatically when the FIN is consumed (which may be immediately).
128   void StopReading();
129 
130   // Free the memory of underlying buffer.
131   void ReleaseBuffer();
132 
133   // Free the memory of underlying buffer when no bytes remain in it.
134   void ReleaseBufferIfEmpty();
135 
136   // Number of bytes in the buffer right now.
137   size_t NumBytesBuffered() const;
138 
139   // Number of bytes has been consumed.
140   QuicStreamOffset NumBytesConsumed() const;
141 
142   // Returns true if all of the data within the stream up until the FIN is
143   // available.
144   bool IsAllDataAvailable() const;
145 
close_offset()146   QuicStreamOffset close_offset() const { return close_offset_; }
147 
num_frames_received()148   int num_frames_received() const { return num_frames_received_; }
149 
num_duplicate_frames_received()150   int num_duplicate_frames_received() const {
151     return num_duplicate_frames_received_;
152   }
153 
ignore_read_data()154   bool ignore_read_data() const { return ignore_read_data_; }
155 
set_level_triggered(bool level_triggered)156   void set_level_triggered(bool level_triggered) {
157     level_triggered_ = level_triggered;
158   }
159 
level_triggered()160   bool level_triggered() const { return level_triggered_; }
161 
set_stream(StreamInterface * stream)162   void set_stream(StreamInterface* stream) { stream_ = stream; }
163 
164   // Returns string describing internal state.
165   std::string DebugString() const;
166 
167  private:
168   friend class test::QuicStreamSequencerPeer;
169 
170   // Deletes and records as consumed any buffered data that is now in-sequence.
171   // (To be called only after StopReading has been called.)
172   void FlushBufferedFrames();
173 
174   // Wait until we've seen 'offset' bytes, and then terminate the stream.
175   // Returns true if |stream_| is still available to receive data, and false if
176   // |stream_| is reset.
177   bool CloseStreamAtOffset(QuicStreamOffset offset);
178 
179   // If we've received a FIN and have processed all remaining data, then inform
180   // the stream of FIN, and clear buffers.
181   void MaybeCloseStream();
182 
183   // Shared implementation between OnStreamFrame and OnCryptoFrame.
184   void OnFrameData(QuicStreamOffset byte_offset, size_t data_len,
185                    const char* data_buffer);
186 
187   // The stream which owns this sequencer.
188   StreamInterface* stream_;
189 
190   // Stores received data in offset order.
191   QuicStreamSequencerBuffer buffered_frames_;
192 
193   // The highest offset that is received so far.
194   QuicStreamOffset highest_offset_;
195 
196   // The offset, if any, we got a stream termination for.  When this many bytes
197   // have been processed, the sequencer will be closed.
198   QuicStreamOffset close_offset_;
199 
200   // If true, the sequencer is blocked from passing data to the stream and will
201   // buffer all new incoming data until FlushBufferedFrames is called.
202   bool blocked_;
203 
204   // Count of the number of frames received.
205   int num_frames_received_;
206 
207   // Count of the number of duplicate frames received.
208   int num_duplicate_frames_received_;
209 
210   // If true, all incoming data will be discarded.
211   bool ignore_read_data_;
212 
213   // If false, only call OnDataAvailable() when it becomes newly unblocked.
214   // Otherwise, call OnDataAvailable() when number of readable bytes changes.
215   bool level_triggered_;
216 };
217 
218 }  // namespace quic
219 
220 #endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
221