| 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 |