1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_QUIC_QUIC_STREAM_SEQUENCER_H_
#define NET_QUIC_QUIC_STREAM_SEQUENCER_H_
#include <map>
#include <string>
#include "base/basictypes.h"
#include "net/base/iovec.h"
#include "net/quic/quic_protocol.h"
namespace net {
namespace test {
class QuicStreamSequencerPeer;
} // namespace test
class QuicSession;
class ReliableQuicStream;
// Buffers frames until we have something which can be passed
// up to the next layer.
// TOOD(alyssar) add some checks for overflow attempts [1, 256,] [2, 256]
class NET_EXPORT_PRIVATE QuicStreamSequencer {
public:
explicit QuicStreamSequencer(ReliableQuicStream* quic_stream);
virtual ~QuicStreamSequencer();
// If the frame is the next one we need in order to process in-order data,
// ProcessData will be immediately called on the stream until all buffered
// data is processed or the stream fails to consume data. Any unconsumed
// data will be buffered. If the frame is not the next in line, it will be
// buffered.
void OnStreamFrame(const QuicStreamFrame& frame);
// Once data is buffered, it's up to the stream to read it when the stream
// can handle more data. The following three functions make that possible.
// Fills in up to iov_len iovecs with the next readable regions. Returns the
// number of iovs used. Non-destructive of the underlying data.
int GetReadableRegions(iovec* iov, size_t iov_len);
// Copies the data into the iov_len buffers provided. Returns the number of
// bytes read. Any buffered data no longer in use will be released.
int Readv(const struct iovec* iov, size_t iov_len);
// Returns true if the sequncer has bytes available for reading.
bool HasBytesToRead() const;
// Returns true if the sequencer has delivered the fin.
bool IsClosed() const;
// Returns true if the sequencer has received this frame before.
bool IsDuplicate(const QuicStreamFrame& frame) const;
// Returns true if |frame| contains data which overlaps buffered data
// (indicating an invalid stream frame has been received).
bool FrameOverlapsBufferedData(const QuicStreamFrame& frame) const;
// Calls |ProcessRawData| on |stream_| for each buffered frame that may
// be processed.
void FlushBufferedFrames();
// Blocks processing of frames until |FlushBufferedFrames| is called.
void SetBlockedUntilFlush();
size_t num_bytes_buffered() const { return num_bytes_buffered_; }
QuicStreamOffset num_bytes_consumed() const { return num_bytes_consumed_; }
int num_frames_received() const { return num_frames_received_; }
int num_duplicate_frames_received() const {
return num_duplicate_frames_received_;
}
private:
friend class test::QuicStreamSequencerPeer;
// Wait until we've seen 'offset' bytes, and then terminate the stream.
void CloseStreamAtOffset(QuicStreamOffset offset);
// If we've received a FIN and have processed all remaining data, then inform
// the stream of FIN, and clear buffers.
bool MaybeCloseStream();
// Called whenever bytes are consumed by the stream. Updates
// num_bytes_consumed_ and num_bytes_buffered_.
void RecordBytesConsumed(size_t bytes_consumed);
// The stream which owns this sequencer.
ReliableQuicStream* stream_;
// The last data consumed by the stream.
QuicStreamOffset num_bytes_consumed_;
// TODO(alyssar) use something better than strings.
// TODO(rjshade): In future we may support retransmission of partial stream
// frames, in which case we will have to allow receipt of overlapping frames.
// Maybe write new frames into a ring buffer, and keep track of consumed
// bytes, and gaps.
typedef std::map<QuicStreamOffset, std::string> FrameMap;
// Stores buffered frames (maps from sequence number -> frame data as string).
FrameMap buffered_frames_;
// The offset, if any, we got a stream termination for. When this many bytes
// have been processed, the sequencer will be closed.
QuicStreamOffset close_offset_;
// If true, the sequencer is blocked from passing data to the stream and will
// buffer all new incoming data until FlushBufferedFrames is called.
bool blocked_;
// Tracks how many bytes the sequencer has buffered.
size_t num_bytes_buffered_;
// Count of the number of frames received.
int num_frames_received_;
// Count of the number of duplicate frames received.
int num_duplicate_frames_received_;
DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencer);
};
} // namespace net
#endif // NET_QUIC_QUIC_STREAM_SEQUENCER_H_
|