OLD | NEW |
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(QuicVersion version, | 16 QuicFlowController::QuicFlowController(QuicVersion version, |
17 QuicStreamId id, | 17 QuicStreamId id, |
18 bool is_server, | 18 bool is_server, |
19 uint64 send_window_offset, | 19 uint64 send_window_offset, |
20 uint64 receive_window_offset, | 20 uint64 receive_window_offset, |
21 uint64 max_receive_window) | 21 uint64 max_receive_window) |
22 : id_(id), | 22 : id_(id), |
23 is_enabled_(true), | 23 is_enabled_(true), |
24 is_server_(is_server), | 24 is_server_(is_server), |
25 bytes_consumed_(0), | 25 bytes_consumed_(0), |
26 bytes_buffered_(0), | 26 highest_received_byte_offset_(0), |
27 bytes_sent_(0), | 27 bytes_sent_(0), |
28 send_window_offset_(send_window_offset), | 28 send_window_offset_(send_window_offset), |
29 receive_window_offset_(receive_window_offset), | 29 receive_window_offset_(receive_window_offset), |
30 max_receive_window_(max_receive_window), | 30 max_receive_window_(max_receive_window), |
31 last_blocked_send_window_offset_(0) { | 31 last_blocked_send_window_offset_(0) { |
32 DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_ | 32 DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_ |
33 << ", setting initial receive window offset to: " | 33 << ", setting initial receive window offset to: " |
34 << receive_window_offset_ | 34 << receive_window_offset_ |
35 << ", max receive window to: " | 35 << ", max receive window to: " |
36 << max_receive_window_ | 36 << max_receive_window_ |
37 << ", setting send window offset to: " << send_window_offset_; | 37 << ", setting send window offset to: " << send_window_offset_; |
38 if (version < QUIC_VERSION_17) { | 38 if (version < QUIC_VERSION_17) { |
39 DVLOG(1) << ENDPOINT << "Disabling QuicFlowController for stream " << id_ | 39 DVLOG(1) << ENDPOINT << "Disabling QuicFlowController for stream " << id_ |
40 << ", QUIC version " << version; | 40 << ", QUIC version " << version; |
41 Disable(); | 41 Disable(); |
42 } | 42 } |
43 } | 43 } |
44 | 44 |
45 void QuicFlowController::AddBytesConsumed(uint64 bytes_consumed) { | 45 void QuicFlowController::AddBytesConsumed(uint64 bytes_consumed) { |
46 if (!IsEnabled()) { | 46 if (!IsEnabled()) { |
47 return; | 47 return; |
48 } | 48 } |
49 | 49 |
50 bytes_consumed_ += bytes_consumed; | 50 bytes_consumed_ += bytes_consumed; |
51 DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_; | 51 DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_; |
52 } | 52 } |
53 | 53 |
54 void QuicFlowController::AddBytesBuffered(uint64 bytes_buffered) { | 54 bool QuicFlowController::UpdateHighestReceivedOffset(uint64 new_offset) { |
55 if (!IsEnabled()) { | 55 if (!IsEnabled()) { |
56 return; | 56 return false; |
57 } | 57 } |
58 | 58 |
59 bytes_buffered_ += bytes_buffered; | 59 // Only update if offset has increased. |
60 DVLOG(1) << ENDPOINT << "Stream " << id_ << " buffered: " << bytes_buffered_; | 60 if (new_offset <= highest_received_byte_offset_) { |
61 } | 61 return false; |
62 | |
63 void QuicFlowController::RemoveBytesBuffered(uint64 bytes_buffered) { | |
64 if (!IsEnabled()) { | |
65 return; | |
66 } | 62 } |
67 | 63 |
68 if (bytes_buffered_ < bytes_buffered) { | 64 DVLOG(1) << ENDPOINT << "Stream " << id_ |
69 LOG(DFATAL) << "Trying to remove " << bytes_buffered << " bytes, when only " | 65 << " highest byte offset increased from: " |
70 << bytes_buffered_ << " bytes are buffered"; | 66 << highest_received_byte_offset_ << " to " << new_offset; |
71 bytes_buffered_ = 0; | 67 highest_received_byte_offset_ = new_offset; |
72 return; | 68 return true; |
73 } | |
74 | |
75 bytes_buffered_ -= bytes_buffered; | |
76 DVLOG(1) << ENDPOINT << "Stream " << id_ << " buffered: " << bytes_buffered_; | |
77 } | 69 } |
78 | 70 |
79 void QuicFlowController::AddBytesSent(uint64 bytes_sent) { | 71 void QuicFlowController::AddBytesSent(uint64 bytes_sent) { |
80 if (!IsEnabled()) { | 72 if (!IsEnabled()) { |
81 return; | 73 return; |
82 } | 74 } |
83 | 75 |
84 if (bytes_sent_ + bytes_sent > send_window_offset_) { | 76 if (bytes_sent_ + bytes_sent > send_window_offset_) { |
85 LOG(DFATAL) << ENDPOINT << "Stream " << id_ << " Trying to send an extra " | 77 LOG(DFATAL) << ENDPOINT << "Stream " << id_ << " Trying to send an extra " |
86 << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_ | 78 << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_ |
87 << ", and send_window_offset_ = " << send_window_offset_; | 79 << ", and send_window_offset_ = " << send_window_offset_; |
88 bytes_sent_ = send_window_offset_; | 80 bytes_sent_ = send_window_offset_; |
89 return; | 81 return; |
90 } | 82 } |
91 | 83 |
92 bytes_sent_ += bytes_sent; | 84 bytes_sent_ += bytes_sent; |
93 DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_; | 85 DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_; |
94 } | 86 } |
95 | 87 |
96 bool QuicFlowController::FlowControlViolation() { | 88 bool QuicFlowController::FlowControlViolation() { |
97 if (!IsEnabled()) { | 89 if (!IsEnabled()) { |
98 return false; | 90 return false; |
99 } | 91 } |
100 | 92 |
101 if (receive_window_offset_ < TotalReceivedBytes()) { | 93 if (highest_received_byte_offset_ > receive_window_offset_) { |
102 LOG(ERROR) | 94 LOG(ERROR) << ENDPOINT << "Flow control violation on stream " |
103 << ENDPOINT << "Flow control violation on stream " << id_ | 95 << id_ << ", receive window offset: " |
104 << ", receive window: " << receive_window_offset_ | 96 << receive_window_offset_ |
105 << ", bytes received: " << TotalReceivedBytes(); | 97 << ", highest received byte offset: " |
106 | 98 << highest_received_byte_offset_; |
107 return true; | 99 return true; |
108 } | 100 } |
109 return false; | 101 return false; |
110 } | 102 } |
111 | 103 |
112 void QuicFlowController::MaybeSendWindowUpdate(QuicConnection* connection) { | 104 void QuicFlowController::MaybeSendWindowUpdate(QuicConnection* connection) { |
113 if (!IsEnabled()) { | 105 if (!IsEnabled()) { |
114 return; | 106 return; |
115 } | 107 } |
116 | 108 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 return IsEnabled() && SendWindowSize() == 0; | 186 return IsEnabled() && SendWindowSize() == 0; |
195 } | 187 } |
196 | 188 |
197 uint64 QuicFlowController::SendWindowSize() const { | 189 uint64 QuicFlowController::SendWindowSize() const { |
198 if (bytes_sent_ > send_window_offset_) { | 190 if (bytes_sent_ > send_window_offset_) { |
199 return 0; | 191 return 0; |
200 } | 192 } |
201 return send_window_offset_ - bytes_sent_; | 193 return send_window_offset_ - bytes_sent_; |
202 } | 194 } |
203 | 195 |
204 uint64 QuicFlowController::TotalReceivedBytes() const { | |
205 return bytes_consumed_ + bytes_buffered_; | |
206 } | |
207 | |
208 } // namespace net | 196 } // namespace net |
OLD | NEW |