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