Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: net/quic/quic_flow_controller.cc

Issue 968233004: Land Recent QUIC Changes until 03/02/2015. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cleanup
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_flow_controller.h ('k') | net/quic/quic_flow_controller_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/quic_flow_controller.h" 5 #include "net/quic/quic_flow_controller.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "net/quic/quic_connection.h" 8 #include "net/quic/quic_connection.h"
9 #include "net/quic/quic_flags.h" 9 #include "net/quic/quic_flags.h"
10 #include "net/quic/quic_protocol.h" 10 #include "net/quic/quic_protocol.h"
11 11
12 namespace net { 12 namespace net {
13 13
14 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") 14 #define ENDPOINT (is_server_ ? "Server: " : " Client: ")
15 15
16 QuicFlowController::QuicFlowController(QuicConnection* connection, 16 QuicFlowController::QuicFlowController(QuicConnection* connection,
17 QuicStreamId id, 17 QuicStreamId id,
18 bool is_server, 18 bool is_server,
19 QuicStreamOffset send_window_offset, 19 QuicStreamOffset send_window_offset,
20 QuicStreamOffset receive_window_offset, 20 QuicStreamOffset receive_window_offset,
21 QuicByteCount max_receive_window) 21 QuicByteCount max_receive_window)
22 : connection_(connection), 22 : connection_(connection),
23 id_(id), 23 id_(id),
24 is_enabled_(true),
25 is_server_(is_server), 24 is_server_(is_server),
26 bytes_consumed_(0), 25 bytes_consumed_(0),
27 highest_received_byte_offset_(0), 26 highest_received_byte_offset_(0),
28 bytes_sent_(0), 27 bytes_sent_(0),
29 send_window_offset_(send_window_offset), 28 send_window_offset_(send_window_offset),
30 receive_window_offset_(receive_window_offset), 29 receive_window_offset_(receive_window_offset),
31 max_receive_window_(max_receive_window), 30 max_receive_window_(max_receive_window),
32 last_blocked_send_window_offset_(0) { 31 last_blocked_send_window_offset_(0) {
33 DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_ 32 DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_
34 << ", setting initial receive window offset to: " 33 << ", setting initial receive window offset to: "
35 << receive_window_offset_ 34 << receive_window_offset_
36 << ", max receive window to: " 35 << ", max receive window to: "
37 << max_receive_window_ 36 << max_receive_window_
38 << ", setting send window offset to: " << send_window_offset_; 37 << ", setting send window offset to: " << send_window_offset_;
39 } 38 }
40 39
41 void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) { 40 void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) {
42 if (!IsEnabled()) {
43 return;
44 }
45
46 bytes_consumed_ += bytes_consumed; 41 bytes_consumed_ += bytes_consumed;
47 DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_; 42 DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_;
48 43
49 MaybeSendWindowUpdate(); 44 MaybeSendWindowUpdate();
50 } 45 }
51 46
52 bool QuicFlowController::UpdateHighestReceivedOffset( 47 bool QuicFlowController::UpdateHighestReceivedOffset(
53 QuicStreamOffset new_offset) { 48 QuicStreamOffset new_offset) {
54 if (!IsEnabled()) {
55 return false;
56 }
57
58 // Only update if offset has increased. 49 // Only update if offset has increased.
59 if (new_offset <= highest_received_byte_offset_) { 50 if (new_offset <= highest_received_byte_offset_) {
60 return false; 51 return false;
61 } 52 }
62 53
63 DVLOG(1) << ENDPOINT << "Stream " << id_ 54 DVLOG(1) << ENDPOINT << "Stream " << id_
64 << " highest byte offset increased from: " 55 << " highest byte offset increased from: "
65 << highest_received_byte_offset_ << " to " << new_offset; 56 << highest_received_byte_offset_ << " to " << new_offset;
66 highest_received_byte_offset_ = new_offset; 57 highest_received_byte_offset_ = new_offset;
67 return true; 58 return true;
68 } 59 }
69 60
70 void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) { 61 void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
71 if (!IsEnabled()) {
72 return;
73 }
74
75 if (bytes_sent_ + bytes_sent > send_window_offset_) { 62 if (bytes_sent_ + bytes_sent > send_window_offset_) {
76 LOG(DFATAL) << ENDPOINT << "Stream " << id_ << " Trying to send an extra " 63 LOG(DFATAL) << ENDPOINT << "Stream " << id_ << " Trying to send an extra "
77 << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_ 64 << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_
78 << ", and send_window_offset_ = " << send_window_offset_; 65 << ", and send_window_offset_ = " << send_window_offset_;
79 bytes_sent_ = send_window_offset_; 66 bytes_sent_ = send_window_offset_;
80 67
81 // This is an error on our side, close the connection as soon as possible. 68 // This is an error on our side, close the connection as soon as possible.
82 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA); 69 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
83 return; 70 return;
84 } 71 }
85 72
86 bytes_sent_ += bytes_sent; 73 bytes_sent_ += bytes_sent;
87 DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_; 74 DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_;
88 } 75 }
89 76
90 bool QuicFlowController::FlowControlViolation() { 77 bool QuicFlowController::FlowControlViolation() {
91 if (!IsEnabled()) {
92 return false;
93 }
94
95 if (highest_received_byte_offset_ > receive_window_offset_) { 78 if (highest_received_byte_offset_ > receive_window_offset_) {
96 LOG(ERROR) << ENDPOINT << "Flow control violation on stream " 79 LOG(ERROR) << ENDPOINT << "Flow control violation on stream "
97 << id_ << ", receive window offset: " 80 << id_ << ", receive window offset: "
98 << receive_window_offset_ 81 << receive_window_offset_
99 << ", highest received byte offset: " 82 << ", highest received byte offset: "
100 << highest_received_byte_offset_; 83 << highest_received_byte_offset_;
101 return true; 84 return true;
102 } 85 }
103 return false; 86 return false;
104 } 87 }
105 88
106 void QuicFlowController::MaybeSendWindowUpdate() { 89 void QuicFlowController::MaybeSendWindowUpdate() {
107 if (!IsEnabled()) {
108 return;
109 }
110
111 // Send WindowUpdate to increase receive window if 90 // Send WindowUpdate to increase receive window if
112 // (receive window offset - consumed bytes) < (max window / 2). 91 // (receive window offset - consumed bytes) < (max window / 2).
113 // This is behaviour copied from SPDY. 92 // This is behaviour copied from SPDY.
114 DCHECK_LT(bytes_consumed_, receive_window_offset_); 93 DCHECK_LT(bytes_consumed_, receive_window_offset_);
115 QuicStreamOffset consumed_window = receive_window_offset_ - bytes_consumed_; 94 QuicStreamOffset consumed_window = receive_window_offset_ - bytes_consumed_;
116 QuicByteCount threshold = (max_receive_window_ / 2); 95 QuicByteCount threshold = (max_receive_window_ / 2);
117 96
118 if (consumed_window < threshold) { 97 if (consumed_window < threshold) {
119 // Update our receive window. 98 // Update our receive window.
120 receive_window_offset_ += (max_receive_window_ - consumed_window); 99 receive_window_offset_ += (max_receive_window_ - consumed_window);
121 100
122 DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_ 101 DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_
123 << ", consumed bytes: " << bytes_consumed_ 102 << ", consumed bytes: " << bytes_consumed_
124 << ", consumed window: " << consumed_window 103 << ", consumed window: " << consumed_window
125 << ", and threshold: " << threshold 104 << ", and threshold: " << threshold
126 << ", and max recvw: " << max_receive_window_ 105 << ", and max recvw: " << max_receive_window_
127 << ". New receive window offset is: " << receive_window_offset_; 106 << ". New receive window offset is: " << receive_window_offset_;
128 107
129 // Inform the peer of our new receive window. 108 // Inform the peer of our new receive window.
130 connection_->SendWindowUpdate(id_, receive_window_offset_); 109 connection_->SendWindowUpdate(id_, receive_window_offset_);
131 } 110 }
132 } 111 }
133 112
134 void QuicFlowController::MaybeSendBlocked() { 113 void QuicFlowController::MaybeSendBlocked() {
135 if (!IsEnabled()) {
136 return;
137 }
138
139 if (SendWindowSize() == 0 && 114 if (SendWindowSize() == 0 &&
140 last_blocked_send_window_offset_ < send_window_offset_) { 115 last_blocked_send_window_offset_ < send_window_offset_) {
141 DVLOG(1) << ENDPOINT << "Stream " << id_ << " is flow control blocked. " 116 DVLOG(1) << ENDPOINT << "Stream " << id_ << " is flow control blocked. "
142 << "Send window: " << SendWindowSize() 117 << "Send window: " << SendWindowSize()
143 << ", bytes sent: " << bytes_sent_ 118 << ", bytes sent: " << bytes_sent_
144 << ", send limit: " << send_window_offset_; 119 << ", send limit: " << send_window_offset_;
145 // The entire send_window has been consumed, we are now flow control 120 // The entire send_window has been consumed, we are now flow control
146 // blocked. 121 // blocked.
147 connection_->SendBlocked(id_); 122 connection_->SendBlocked(id_);
148 123
149 // Keep track of when we last sent a BLOCKED frame so that we only send one 124 // Keep track of when we last sent a BLOCKED frame so that we only send one
150 // at a given send offset. 125 // at a given send offset.
151 last_blocked_send_window_offset_ = send_window_offset_; 126 last_blocked_send_window_offset_ = send_window_offset_;
152 } 127 }
153 } 128 }
154 129
155 bool QuicFlowController::UpdateSendWindowOffset( 130 bool QuicFlowController::UpdateSendWindowOffset(
156 QuicStreamOffset new_send_window_offset) { 131 QuicStreamOffset new_send_window_offset) {
157 if (!IsEnabled()) {
158 return false;
159 }
160
161 // Only update if send window has increased. 132 // Only update if send window has increased.
162 if (new_send_window_offset <= send_window_offset_) { 133 if (new_send_window_offset <= send_window_offset_) {
163 return false; 134 return false;
164 } 135 }
165 136
166 DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for stream " << id_ 137 DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for stream " << id_
167 << " with new offset " << new_send_window_offset 138 << " with new offset " << new_send_window_offset
168 << " current offset: " << send_window_offset_ 139 << " current offset: " << send_window_offset_
169 << " bytes_sent: " << bytes_sent_; 140 << " bytes_sent: " << bytes_sent_;
170 141
171 const bool blocked = IsBlocked(); 142 const bool blocked = IsBlocked();
172 send_window_offset_ = new_send_window_offset; 143 send_window_offset_ = new_send_window_offset;
173 return blocked; 144 return blocked;
174 } 145 }
175 146
176 void QuicFlowController::Disable() {
177 is_enabled_ = false;
178 }
179
180 bool QuicFlowController::IsEnabled() const {
181 return is_enabled_;
182 }
183
184 bool QuicFlowController::IsBlocked() const { 147 bool QuicFlowController::IsBlocked() const {
185 return IsEnabled() && SendWindowSize() == 0; 148 return SendWindowSize() == 0;
186 } 149 }
187 150
188 uint64 QuicFlowController::SendWindowSize() const { 151 uint64 QuicFlowController::SendWindowSize() const {
189 if (bytes_sent_ > send_window_offset_) { 152 if (bytes_sent_ > send_window_offset_) {
190 return 0; 153 return 0;
191 } 154 }
192 return send_window_offset_ - bytes_sent_; 155 return send_window_offset_ - bytes_sent_;
193 } 156 }
194 157
195 } // namespace net 158 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_flow_controller.h ('k') | net/quic/quic_flow_controller_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698