1// Copyright 2014 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_FLOW_CONTROLLER_H_
6#define NET_QUIC_QUIC_FLOW_CONTROLLER_H_
7
8#include "base/basictypes.h"
9#include "net/base/net_export.h"
10#include "net/quic/quic_protocol.h"
11
12namespace net {
13
14namespace test {
15class QuicFlowControllerPeer;
16}  // namespace test
17
18class QuicConnection;
19
20const QuicStreamId kConnectionLevelId = 0;
21
22// QuicFlowController allows a QUIC stream or connection to perform flow
23// control. The stream/connection owns a QuicFlowController which keeps track of
24// bytes sent/received, can tell the owner if it is flow control blocked, and
25// can send WINDOW_UPDATE or BLOCKED frames when needed.
26class NET_EXPORT_PRIVATE QuicFlowController {
27 public:
28  QuicFlowController(QuicConnection* connection,
29                     QuicStreamId id,
30                     bool is_server,
31                     uint64 send_window_offset,
32                     uint64 receive_window_offset,
33                     uint64 max_receive_window);
34  ~QuicFlowController() {}
35
36  // Called when we see a new highest received byte offset from the peer, either
37  // via a data frame or a RST.
38  // Returns true if this call changes highest_received_byte_offset_, and false
39  // in the case where |new_offset| is <= highest_received_byte_offset_.
40  bool UpdateHighestReceivedOffset(uint64 new_offset);
41
42  // Called when bytes received from the peer are consumed locally. This may
43  // trigger the sending of a WINDOW_UPDATE frame using |connection|.
44  void AddBytesConsumed(uint64 bytes_consumed);
45
46  // Called when bytes are sent to the peer.
47  void AddBytesSent(uint64 bytes_sent);
48
49  // Set a new send window offset.
50  // Returns true if this increases send_window_offset_ and is now blocked.
51  bool UpdateSendWindowOffset(uint64 new_send_window_offset);
52
53  // Returns the current available send window.
54  uint64 SendWindowSize() const;
55
56  // Send a BLOCKED frame if appropriate.
57  void MaybeSendBlocked();
58
59  // Disable flow control.
60  void Disable();
61
62  // Returns true if flow control is enabled.
63  bool IsEnabled() const;
64
65  // Returns true if flow control send limits have been reached.
66  bool IsBlocked() const;
67
68  // Returns true if flow control receive limits have been violated by the peer.
69  bool FlowControlViolation();
70
71  uint64 bytes_consumed() const { return bytes_consumed_; }
72
73  uint64 highest_received_byte_offset() const {
74    return highest_received_byte_offset_;
75  }
76
77 private:
78  friend class test::QuicFlowControllerPeer;
79
80  // Send a WINDOW_UPDATE frame if appropriate.
81  void MaybeSendWindowUpdate();
82
83  // The parent connection, used to send connection close on flow control
84  // violation, and WINDOW_UPDATE and BLOCKED frames when appropriate.
85  // Not owned.
86  QuicConnection* connection_;
87
88  // ID of stream this flow controller belongs to. This can be 0 if this is a
89  // connection level flow controller.
90  QuicStreamId id_;
91
92  // True if flow control is enabled.
93  bool is_enabled_;
94
95  // True if this is owned by a server.
96  bool is_server_;
97
98  // Track number of bytes received from the peer, which have been consumed
99  // locally.
100  uint64 bytes_consumed_;
101
102  // The highest byte offset we have seen from the peer. This could be the
103  // highest offset in a data frame, or a final value in a RST.
104  uint64 highest_received_byte_offset_;
105
106  // Tracks number of bytes sent to the peer.
107  uint64 bytes_sent_;
108
109  // The absolute offset in the outgoing byte stream. If this offset is reached
110  // then we become flow control blocked until we receive a WINDOW_UPDATE.
111  uint64 send_window_offset_;
112
113  // The absolute offset in the incoming byte stream. The peer should never send
114  // us bytes which are beyond this offset.
115  uint64 receive_window_offset_;
116
117  // Largest size the receive window can grow to.
118  uint64 max_receive_window_;
119
120  // Keep track of the last time we sent a BLOCKED frame. We should only send
121  // another when the number of bytes we have sent has changed.
122  uint64 last_blocked_send_window_offset_;
123
124  DISALLOW_COPY_AND_ASSIGN(QuicFlowController);
125};
126
127}  // namespace net
128
129#endif  // NET_QUIC_QUIC_FLOW_CONTROLLER_H_
130