Index: net/quic/quic_server_session.cc |
diff --git a/net/quic/quic_server_session.cc b/net/quic/quic_server_session.cc |
index c7141e6568fb34e71e2ef8759b399bfd859833d5..5d0fef4ad15fa1a19e1bb833cece5f69b39a1f00 100644 |
--- a/net/quic/quic_server_session.cc |
+++ b/net/quic/quic_server_session.cc |
@@ -5,6 +5,7 @@ |
#include "net/quic/quic_server_session.h" |
#include "base/logging.h" |
+#include "net/quic/crypto/source_address_token.h" |
#include "net/quic/quic_connection.h" |
#include "net/quic/quic_flags.h" |
#include "net/quic/quic_spdy_server_stream.h" |
@@ -17,7 +18,9 @@ QuicServerSession::QuicServerSession( |
QuicConnection* connection, |
QuicServerSessionVisitor* visitor) |
: QuicSession(connection, config), |
- visitor_(visitor) {} |
+ visitor_(visitor), |
+ bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()), |
+ last_server_config_update_time_(QuicTime::Zero()) {} |
QuicServerSession::~QuicServerSession() {} |
@@ -60,6 +63,79 @@ void QuicServerSession::OnWriteBlocked() { |
visitor_->OnWriteBlocked(connection()); |
} |
+void QuicServerSession::OnCongestionWindowChange(QuicTime now) { |
+ if (connection()->version() <= QUIC_VERSION_21) { |
+ return; |
+ } |
+ |
+ // If not enough time has passed since the last time we sent an update to the |
+ // client, then return early. |
+ const QuicSentPacketManager& sent_packet_manager = |
+ connection()->sent_packet_manager(); |
+ int64 srtt_ms = |
+ sent_packet_manager.GetRttStats()->SmoothedRtt().ToMilliseconds(); |
+ int64 now_ms = now.Subtract(last_server_config_update_time_).ToMilliseconds(); |
+ if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) || |
+ now_ms < kMinIntervalBetweenServerConfigUpdatesMs) { |
+ return; |
+ } |
+ |
+ // If the bandwidth recorder does not have a valid estimate, return early. |
+ const QuicSustainedBandwidthRecorder& bandwidth_recorder = |
+ sent_packet_manager.SustainedBandwidthRecorder(); |
+ if (!bandwidth_recorder.HasEstimate()) { |
+ return; |
+ } |
+ |
+ // The bandwidth recorder has recorded at least one sustained bandwidth |
+ // estimate. Check that it's substantially different from the last one that |
+ // we sent to the client, and if so, send the new one. |
+ QuicBandwidth new_bandwidth_estimate = bandwidth_recorder.BandwidthEstimate(); |
+ |
+ int64 bandwidth_delta = |
+ std::abs(new_bandwidth_estimate.ToBitsPerSecond() - |
+ bandwidth_estimate_sent_to_client_.ToBitsPerSecond()); |
+ |
+ // Define "substantial" difference as a 50% increase or decrease from the |
+ // last estimate. |
+ bool substantial_difference = |
+ bandwidth_delta > |
+ 0.5 * bandwidth_estimate_sent_to_client_.ToBitsPerSecond(); |
+ if (!substantial_difference) { |
+ return; |
+ } |
+ |
+ bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate; |
+ DVLOG(1) << "Server: sending new bandwidth estimate (KBytes/s): " |
+ << bandwidth_estimate_sent_to_client_.ToKBytesPerSecond(); |
+ |
+ // Include max bandwidth in the update. |
+ QuicBandwidth max_bandwidth_estimate = |
+ bandwidth_recorder.MaxBandwidthEstimate(); |
+ int32 max_bandwidth_timestamp = bandwidth_recorder.MaxBandwidthTimestamp(); |
+ |
+ // Fill the proto before passing it to the crypto stream to send. |
+ CachedNetworkParameters cached_network_params; |
+ cached_network_params.set_bandwidth_estimate_bytes_per_second( |
+ bandwidth_estimate_sent_to_client_.ToBytesPerSecond()); |
+ cached_network_params.set_max_bandwidth_estimate_bytes_per_second( |
+ max_bandwidth_estimate.ToBytesPerSecond()); |
+ cached_network_params.set_max_bandwidth_timestamp_seconds( |
+ max_bandwidth_timestamp); |
+ cached_network_params.set_min_rtt_ms( |
+ sent_packet_manager.GetRttStats()->min_rtt().ToMilliseconds()); |
+ cached_network_params.set_previous_connection_state( |
+ bandwidth_recorder.EstimateRecordedDuringSlowStart() |
+ ? CachedNetworkParameters::SLOW_START |
+ : CachedNetworkParameters::CONGESTION_AVOIDANCE); |
+ if (!serving_region_.empty()) { |
+ cached_network_params.set_serving_region(serving_region_); |
+ } |
+ |
+ crypto_stream_->SendServerConfigUpdate(&cached_network_params); |
+ last_server_config_update_time_ = now; |
+} |
+ |
bool QuicServerSession::ShouldCreateIncomingDataStream(QuicStreamId id) { |
if (id % 2 == 0) { |
DVLOG(1) << "Invalid incoming even stream_id:" << id; |