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