summaryrefslogtreecommitdiffstats
path: root/net/quic/quic_stream_sequencer.h
blob: 7677ad04e570eab3284bdd1444a34827bfecb2d1 (plain)
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
132
// 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 "base/basictypes.h"
#include "net/base/iovec.h"
#include "net/quic/quic_protocol.h"

using std::map;
using std::string;

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);
  QuicStreamSequencer(size_t max_frame_memory,
                      ReliableQuicStream* quic_stream);

  virtual ~QuicStreamSequencer();

  // Returns the expected value of OnStreamFrame for this frame.
  bool WillAcceptStreamFrame(const QuicStreamFrame& frame) const;

  // 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 either be buffered, and
  // this will return true, or it will be rejected and this will return false.
  bool 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;

  // 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() { return num_frames_received_; }

  int num_duplicate_frames_received() { 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.
  typedef map<QuicStreamOffset, string> FrameMap;

  // Stores buffered frames (maps from sequence number -> frame data as string).
  FrameMap frames_;

  // The maximum memory the sequencer can buffer.
  size_t max_frame_memory_;

  // 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_;
};

}  // namespace net

#endif  // NET_QUIC_QUIC_STREAM_SEQUENCER_H_