Index: net/quic/quic_flow_controller.cc |
diff --git a/net/quic/quic_flow_controller.cc b/net/quic/quic_flow_controller.cc |
deleted file mode 100644 |
index f88acb67a40bf1a2d6342d79325620ad0af970fa..0000000000000000000000000000000000000000 |
--- a/net/quic/quic_flow_controller.cc |
+++ /dev/null |
@@ -1,254 +0,0 @@ |
-// Copyright 2014 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. |
- |
-#include "net/quic/quic_flow_controller.h" |
- |
-#include "base/strings/stringprintf.h" |
-#include "net/quic/quic_bug_tracker.h" |
-#include "net/quic/quic_connection.h" |
-#include "net/quic/quic_flags.h" |
-#include "net/quic/quic_protocol.h" |
- |
-namespace net { |
- |
-#define ENDPOINT \ |
- (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") |
- |
-QuicFlowController::QuicFlowController(QuicConnection* connection, |
- QuicStreamId id, |
- Perspective perspective, |
- QuicStreamOffset send_window_offset, |
- QuicStreamOffset receive_window_offset, |
- bool should_auto_tune_receive_window) |
- : connection_(connection), |
- id_(id), |
- perspective_(perspective), |
- bytes_sent_(0), |
- send_window_offset_(send_window_offset), |
- bytes_consumed_(0), |
- highest_received_byte_offset_(0), |
- receive_window_offset_(receive_window_offset), |
- receive_window_size_(receive_window_offset), |
- auto_tune_receive_window_(should_auto_tune_receive_window), |
- last_blocked_send_window_offset_(0), |
- prev_window_update_time_(QuicTime::Zero()) { |
- receive_window_size_limit_ = (id_ == kConnectionLevelId) |
- ? kSessionReceiveWindowLimit |
- : kStreamReceiveWindowLimit; |
- |
- DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_ |
- << ", setting initial receive window offset to: " |
- << receive_window_offset_ |
- << ", max receive window to: " << receive_window_size_ |
- << ", max receive window limit to: " << receive_window_size_limit_ |
- << ", setting send window offset to: " << send_window_offset_; |
-} |
- |
-void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) { |
- bytes_consumed_ += bytes_consumed; |
- DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_; |
- |
- MaybeSendWindowUpdate(); |
-} |
- |
-bool QuicFlowController::UpdateHighestReceivedOffset( |
- QuicStreamOffset new_offset) { |
- // Only update if offset has increased. |
- if (new_offset <= highest_received_byte_offset_) { |
- return false; |
- } |
- |
- DVLOG(1) << ENDPOINT << "Stream " << id_ |
- << " highest byte offset increased from: " |
- << highest_received_byte_offset_ << " to " << new_offset; |
- highest_received_byte_offset_ = new_offset; |
- return true; |
-} |
- |
-void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) { |
- if (bytes_sent_ + bytes_sent > send_window_offset_) { |
- QUIC_BUG << ENDPOINT << "Stream " << id_ << " Trying to send an extra " |
- << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_ |
- << ", and send_window_offset_ = " << send_window_offset_; |
- bytes_sent_ = send_window_offset_; |
- |
- // This is an error on our side, close the connection as soon as possible. |
- connection_->CloseConnection( |
- QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, |
- base::StringPrintf( |
- "%llu bytes over send window offset", |
- static_cast<unsigned long long>(send_window_offset_ - |
- (bytes_sent_ + bytes_sent))) |
- .c_str(), |
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
- return; |
- } |
- |
- bytes_sent_ += bytes_sent; |
- DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_; |
-} |
- |
-bool QuicFlowController::FlowControlViolation() { |
- if (highest_received_byte_offset_ > receive_window_offset_) { |
- LOG(ERROR) << ENDPOINT << "Flow control violation on stream " << id_ |
- << ", receive window offset: " << receive_window_offset_ |
- << ", highest received byte offset: " |
- << highest_received_byte_offset_; |
- return true; |
- } |
- return false; |
-} |
- |
-void QuicFlowController::MaybeIncreaseMaxWindowSize() { |
- // Core of receive window auto tuning. This method should be called before a |
- // WINDOW_UPDATE frame is sent. Ideally, window updates should occur close to |
- // once per RTT. If a window update happens much faster than RTT, it implies |
- // that the flow control window is imposing a bottleneck. To prevent this, |
- // this method will increase the receive window size (subject to a reasonable |
- // upper bound). For simplicity this algorithm is deliberately asymmetric, in |
- // that it may increase window size but never decreases. |
- |
- // Keep track of timing between successive window updates. |
- QuicTime now = connection_->clock()->ApproximateNow(); |
- QuicTime prev = prev_window_update_time_; |
- prev_window_update_time_ = now; |
- if (!prev.IsInitialized()) { |
- DVLOG(1) << ENDPOINT << "first window update for stream " << id_; |
- return; |
- } |
- |
- if (!auto_tune_receive_window_) { |
- return; |
- } |
- |
- // Get outbound RTT. |
- QuicTime::Delta rtt = |
- connection_->sent_packet_manager().GetRttStats()->smoothed_rtt(); |
- if (rtt.IsZero()) { |
- DVLOG(1) << ENDPOINT << "rtt zero for stream " << id_; |
- return; |
- } |
- |
- // Now we can compare timing of window updates with RTT. |
- QuicTime::Delta since_last = now - prev; |
- QuicTime::Delta two_rtt = 2 * rtt; |
- |
- if (since_last >= two_rtt) { |
- // If interval between window updates is sufficiently large, there |
- // is no need to increase receive_window_size_. |
- return; |
- } |
- |
- QuicByteCount old_window = receive_window_size_; |
- receive_window_size_ *= 2; |
- receive_window_size_ = |
- std::min(receive_window_size_, receive_window_size_limit_); |
- |
- if (receive_window_size_ > old_window) { |
- DVLOG(1) << ENDPOINT << "New max window increase for stream " << id_ |
- << " after " << since_last.ToMicroseconds() << " us, and RTT is " |
- << rtt.ToMicroseconds() |
- << "us. max wndw: " << receive_window_size_; |
- } else { |
- // TODO(ckrasic) - add a varz to track this (?). |
- DVLOG(1) << ENDPOINT << "Max window at limit for stream " << id_ |
- << " after " << since_last.ToMicroseconds() << " us, and RTT is " |
- << rtt.ToMicroseconds() |
- << "us. Limit size: " << receive_window_size_; |
- } |
-} |
- |
-QuicByteCount QuicFlowController::WindowUpdateThreshold() { |
- return receive_window_size_ / 2; |
-} |
- |
-void QuicFlowController::MaybeSendWindowUpdate() { |
- // Send WindowUpdate to increase receive window if |
- // (receive window offset - consumed bytes) < (max window / 2). |
- // This is behaviour copied from SPDY. |
- DCHECK_LE(bytes_consumed_, receive_window_offset_); |
- QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_; |
- QuicByteCount threshold = WindowUpdateThreshold(); |
- |
- if (available_window >= threshold) { |
- DVLOG(1) << ENDPOINT << "Not sending WindowUpdate for stream " << id_ |
- << ", available window: " << available_window |
- << " >= threshold: " << threshold; |
- return; |
- } |
- |
- MaybeIncreaseMaxWindowSize(); |
- |
- // Update our receive window. |
- receive_window_offset_ += (receive_window_size_ - available_window); |
- |
- DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_ |
- << ", consumed bytes: " << bytes_consumed_ |
- << ", available window: " << available_window |
- << ", and threshold: " << threshold |
- << ", and receive window size: " << receive_window_size_ |
- << ". New receive window offset is: " << receive_window_offset_; |
- |
- // Inform the peer of our new receive window. |
- connection_->SendWindowUpdate(id_, receive_window_offset_); |
-} |
- |
-void QuicFlowController::MaybeSendBlocked() { |
- if (SendWindowSize() == 0 && |
- last_blocked_send_window_offset_ < send_window_offset_) { |
- DVLOG(1) << ENDPOINT << "Stream " << id_ << " is flow control blocked. " |
- << "Send window: " << SendWindowSize() |
- << ", bytes sent: " << bytes_sent_ |
- << ", send limit: " << send_window_offset_; |
- // The entire send_window has been consumed, we are now flow control |
- // blocked. |
- connection_->SendBlocked(id_); |
- |
- // Keep track of when we last sent a BLOCKED frame so that we only send one |
- // at a given send offset. |
- last_blocked_send_window_offset_ = send_window_offset_; |
- } |
-} |
- |
-bool QuicFlowController::UpdateSendWindowOffset( |
- QuicStreamOffset new_send_window_offset) { |
- // Only update if send window has increased. |
- if (new_send_window_offset <= send_window_offset_) { |
- return false; |
- } |
- |
- DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for stream " << id_ |
- << " with new offset " << new_send_window_offset |
- << " current offset: " << send_window_offset_ |
- << " bytes_sent: " << bytes_sent_; |
- |
- const bool blocked = IsBlocked(); |
- send_window_offset_ = new_send_window_offset; |
- return blocked; |
-} |
- |
-bool QuicFlowController::IsBlocked() const { |
- return SendWindowSize() == 0; |
-} |
- |
-uint64_t QuicFlowController::SendWindowSize() const { |
- if (bytes_sent_ > send_window_offset_) { |
- return 0; |
- } |
- return send_window_offset_ - bytes_sent_; |
-} |
- |
-void QuicFlowController::UpdateReceiveWindowSize(QuicStreamOffset size) { |
- DVLOG(1) << ENDPOINT << "UpdateReceiveWindowSize for stream " << id_ << ": " |
- << size; |
- if (receive_window_size_ != receive_window_offset_) { |
- QUIC_BUG << "receive_window_size_:" << receive_window_size_ |
- << " != receive_window_offset:" << receive_window_offset_; |
- return; |
- } |
- receive_window_size_ = size; |
- receive_window_offset_ = size; |
-} |
- |
-} // namespace net |