blob: 7cecf4de70ae43fd55f3aacf21b30addfb39270c [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
84 // Fill in one iovec with the next unread region for the quic spdy stream.
85 // Returns false if no readable region is available.
86 bool PrefetchNextRegion(iovec* iov);
87
88 // Copies the data into the iov_len buffers provided. Returns the number of
89 // bytes read. Any buffered data no longer in use will be released.
90 // TODO(rch): remove this method and instead implement it as a helper method
91 // based on GetReadableRegions and MarkConsumed.
92 int Readv(const struct iovec* iov, size_t iov_len);
93
94 // Consumes |num_bytes| data. Used in conjunction with |GetReadableRegions|
95 // to do zero-copy reads.
96 void MarkConsumed(size_t num_bytes);
97
98 // Appends all of the readable data to |buffer| and marks all of the appended
99 // data as consumed.
vasilvvc48c8712019-03-11 13:38:16 -0700100 void Read(std::string* buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101
102 // Returns true if the sequncer has bytes available for reading.
103 bool HasBytesToRead() const;
104
105 // Number of bytes available to read.
106 size_t ReadableBytes() const;
107
108 // Returns true if the sequencer has delivered the fin.
109 bool IsClosed() const;
110
111 // Calls |OnDataAvailable| on |stream_| if there is buffered data that can
112 // be processed, and causes |OnDataAvailable| to be called as new data
113 // arrives.
114 void SetUnblocked();
115
116 // Blocks processing of frames until |SetUnblocked| is called.
117 void SetBlockedUntilFlush();
118
119 // Sets the sequencer to discard all incoming data itself and not call
120 // |stream_->OnDataAvailable()|. |stream_->OnFinRead()| will be called
121 // automatically when the FIN is consumed (which may be immediately).
122 void StopReading();
123
124 // Free the memory of underlying buffer.
125 void ReleaseBuffer();
126
127 // Free the memory of underlying buffer when no bytes remain in it.
128 void ReleaseBufferIfEmpty();
129
130 // Number of bytes in the buffer right now.
131 size_t NumBytesBuffered() const;
132
133 // Number of bytes has been consumed.
134 QuicStreamOffset NumBytesConsumed() const;
135
136 QuicStreamOffset close_offset() const { return close_offset_; }
137
138 int num_frames_received() const { return num_frames_received_; }
139
140 int num_duplicate_frames_received() const {
141 return num_duplicate_frames_received_;
142 }
143
144 bool ignore_read_data() const { return ignore_read_data_; }
145
146 void set_level_triggered(bool level_triggered) {
147 level_triggered_ = level_triggered;
148 }
149
150 bool level_triggered() const { return level_triggered_; }
151
152 void set_stream(StreamInterface* stream) { stream_ = stream; }
153
154 // Returns string describing internal state.
vasilvvc48c8712019-03-11 13:38:16 -0700155 const std::string DebugString() const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500156
157 private:
158 friend class test::QuicStreamSequencerPeer;
159
160 // Deletes and records as consumed any buffered data that is now in-sequence.
161 // (To be called only after StopReading has been called.)
162 void FlushBufferedFrames();
163
164 // Wait until we've seen 'offset' bytes, and then terminate the stream.
165 void CloseStreamAtOffset(QuicStreamOffset offset);
166
167 // If we've received a FIN and have processed all remaining data, then inform
168 // the stream of FIN, and clear buffers.
169 bool MaybeCloseStream();
170
171 // Shared implementation between OnStreamFrame and OnCryptoFrame.
172 void OnFrameData(QuicStreamOffset byte_offset,
173 size_t data_len,
174 const char* data_buffer);
175
176 // The stream which owns this sequencer.
177 StreamInterface* stream_;
178
179 // Stores received data in offset order.
180 QuicStreamSequencerBuffer buffered_frames_;
181
182 // The offset, if any, we got a stream termination for. When this many bytes
183 // have been processed, the sequencer will be closed.
184 QuicStreamOffset close_offset_;
185
186 // If true, the sequencer is blocked from passing data to the stream and will
187 // buffer all new incoming data until FlushBufferedFrames is called.
188 bool blocked_;
189
190 // Count of the number of frames received.
191 int num_frames_received_;
192
193 // Count of the number of duplicate frames received.
194 int num_duplicate_frames_received_;
195
196 // If true, all incoming data will be discarded.
197 bool ignore_read_data_;
198
199 // If false, only call OnDataAvailable() when it becomes newly unblocked.
200 // Otherwise, call OnDataAvailable() when number of readable bytes changes.
201 bool level_triggered_;
202
203 // Latched value of quic_stop_reading_when_level_triggered flag. When true,
204 // the sequencer will discard incoming data (but not FIN bits) after
205 // StopReading is called, even in level_triggered_ mode.
206 const bool stop_reading_when_level_triggered_;
207};
208
209} // namespace quic
210
211#endif // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_