Commit d372280b authored by Zhongyi Shi's avatar Zhongyi Shi Committed by Commit Bot

Landing Recent QUIC changes until 1:12 PM, Jan 19, 2018 UTC-8

No Flag update.

Some changes to quic_connection_test, including:
1) fix stream offset to make it increases monotonically.
2) Refactor out SendRstStream.
Merge internal change: 182410984
https://chromium-review.googlesource.com/c/chromium/src/+/879753/

relnote: Stores SpdyHeaderBlocks directly in QuicClientPromisedInfo,
rather than holding them via unique_ptr. No functional change.
Merge internal change: 182114281
https://chromium-review.googlesource.com/c/chromium/src/+/879841/

relnote: Add two new QUIC connection options to experiment with different
max ack delay behaviors, one that ignores ack delay and one that sets the
default to 25ms instead of 0ms.
Protected by quic_reloadable_flag_quic_max_ack_delay.
Merge internal change: 182103603
https://chromium-review.googlesource.com/c/chromium/src/+/879435

Change-Id: If84cf1ae1eb3609380e95a24aefd9d87b555f40e
Reviewed-on: https://chromium-review.googlesource.com/883778
Commit-Queue: Zhongyi Shi <zhongyi@chromium.org>
Reviewed-by: default avatarRyan Hamilton <rch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532038}
parent da9945e1
...@@ -30,7 +30,8 @@ RttStats::RttStats() ...@@ -30,7 +30,8 @@ RttStats::RttStats()
previous_srtt_(QuicTime::Delta::Zero()), previous_srtt_(QuicTime::Delta::Zero()),
mean_deviation_(QuicTime::Delta::Zero()), mean_deviation_(QuicTime::Delta::Zero()),
initial_rtt_us_(kInitialRttMs * kNumMicrosPerMilli), initial_rtt_us_(kInitialRttMs * kNumMicrosPerMilli),
max_ack_delay_(QuicTime::Delta::Zero()) {} max_ack_delay_(QuicTime::Delta::Zero()),
ignore_max_ack_delay_(false) {}
void RttStats::ExpireSmoothedMetrics() { void RttStats::ExpireSmoothedMetrics() {
mean_deviation_ = std::max( mean_deviation_ = std::max(
...@@ -62,6 +63,9 @@ void RttStats::UpdateRtt(QuicTime::Delta send_delta, ...@@ -62,6 +63,9 @@ void RttStats::UpdateRtt(QuicTime::Delta send_delta,
QuicTime::Delta rtt_sample(send_delta); QuicTime::Delta rtt_sample(send_delta);
previous_srtt_ = smoothed_rtt_; previous_srtt_ = smoothed_rtt_;
if (ignore_max_ack_delay_) {
ack_delay = QuicTime::Delta::Zero();
}
// Correct for ack_delay if information received from the peer results in a // Correct for ack_delay if information received from the peer results in a
// an RTT sample at least as large as min_rtt. Otherwise, only use the // an RTT sample at least as large as min_rtt. Otherwise, only use the
// send_delta. // send_delta.
......
...@@ -70,6 +70,17 @@ class QUIC_EXPORT_PRIVATE RttStats { ...@@ -70,6 +70,17 @@ class QUIC_EXPORT_PRIVATE RttStats {
QuicTime::Delta max_ack_delay() const { return max_ack_delay_; } QuicTime::Delta max_ack_delay() const { return max_ack_delay_; }
bool ignore_max_ack_delay() const { return ignore_max_ack_delay_; }
void set_ignore_max_ack_delay(bool ignore_max_ack_delay) {
ignore_max_ack_delay_ = ignore_max_ack_delay;
}
void set_initial_max_ack_delay(QuicTime::Delta initial_max_ack_delay) {
DCHECK(max_ack_delay_.IsZero());
max_ack_delay_ = std::max(max_ack_delay_, initial_max_ack_delay);
}
private: private:
friend class test::RttStatsPeer; friend class test::RttStatsPeer;
...@@ -85,6 +96,8 @@ class QUIC_EXPORT_PRIVATE RttStats { ...@@ -85,6 +96,8 @@ class QUIC_EXPORT_PRIVATE RttStats {
// The maximum ack delay observed over the connection after excluding ack // The maximum ack delay observed over the connection after excluding ack
// delays that were too large to be included in an RTT measurement. // delays that were too large to be included in an RTT measurement.
QuicTime::Delta max_ack_delay_; QuicTime::Delta max_ack_delay_;
// Whether to ignore the peer's max ack delay.
bool ignore_max_ack_delay_;
DISALLOW_COPY_AND_ASSIGN(RttStats); DISALLOW_COPY_AND_ASSIGN(RttStats);
}; };
......
...@@ -72,6 +72,7 @@ TEST_F(RttStatsTest, SmoothedRttMaxAckDelay) { ...@@ -72,6 +72,7 @@ TEST_F(RttStatsTest, SmoothedRttMaxAckDelay) {
QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero()); QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt()); EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt()); EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.max_ack_delay());
// Verify that large erroneous ack_delay does not change Smoothed RTT. // Verify that large erroneous ack_delay does not change Smoothed RTT.
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
QuicTime::Delta::FromMilliseconds(300), QuicTime::Delta::FromMilliseconds(300),
...@@ -79,6 +80,39 @@ TEST_F(RttStatsTest, SmoothedRttMaxAckDelay) { ...@@ -79,6 +80,39 @@ TEST_F(RttStatsTest, SmoothedRttMaxAckDelay) {
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt()); EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500), EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
rtt_stats_.smoothed_rtt()); rtt_stats_.smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.max_ack_delay());
}
TEST_F(RttStatsTest, SmoothedRttIgnoreAckDelay) {
SetQuicReloadableFlag(quic_max_ack_delay, true);
rtt_stats_.set_ignore_max_ack_delay(true);
// Verify that ack_delay is ignored in the first measurement.
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
QuicTime::Delta::FromMilliseconds(100),
QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.max_ack_delay());
// Verify that a plausible ack delay increases the max ack delay.
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
QuicTime::Delta::FromMilliseconds(100),
QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.max_ack_delay());
// Verify that Smoothed RTT includes max ack delay if it's reasonable.
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
// Verify that large erroneous ack_delay does not change Smoothed RTT.
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
QuicTime::Delta::FromMilliseconds(300),
QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
rtt_stats_.smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.max_ack_delay());
} }
// Ensure that the potential rounding artifacts in EWMA calculation do not cause // Ensure that the potential rounding artifacts in EWMA calculation do not cause
......
...@@ -123,6 +123,8 @@ const QuicTag kMIN4 = TAG('M', 'I', 'N', '4'); // Min CWND of 4 packets, ...@@ -123,6 +123,8 @@ const QuicTag kMIN4 = TAG('M', 'I', 'N', '4'); // Min CWND of 4 packets,
// with a min rate of 1 BDP. // with a min rate of 1 BDP.
const QuicTag kTLPR = TAG('T', 'L', 'P', 'R'); // Tail loss probe delay of const QuicTag kTLPR = TAG('T', 'L', 'P', 'R'); // Tail loss probe delay of
// 0.5RTT. // 0.5RTT.
const QuicTag kMAD0 = TAG('M', 'A', 'D', '0'); // Ignore ack delay
const QuicTag kMAD1 = TAG('M', 'A', 'D', '1'); // 25ms initial max ack delay
const QuicTag kACKD = TAG('A', 'C', 'K', 'D'); // Ack decimation style acking. const QuicTag kACKD = TAG('A', 'C', 'K', 'D'); // Ack decimation style acking.
const QuicTag kAKD2 = TAG('A', 'K', 'D', '2'); // Ack decimation tolerating const QuicTag kAKD2 = TAG('A', 'K', 'D', '2'); // Ack decimation tolerating
// out of order packets. // out of order packets.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "net/quic/core/spdy_utils.h" #include "net/quic/core/spdy_utils.h"
#include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/spdy/core/spdy_protocol.h" #include "net/spdy/core/spdy_protocol.h"
using std::string; using std::string;
...@@ -64,11 +65,11 @@ void QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) { ...@@ -64,11 +65,11 @@ void QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) {
Reset(QUIC_UNAUTHORIZED_PROMISE_URL); Reset(QUIC_UNAUTHORIZED_PROMISE_URL);
return; return;
} }
request_headers_.reset(new SpdyHeaderBlock(headers.Clone())); request_headers_ = headers.Clone();
} }
void QuicClientPromisedInfo::OnResponseHeaders(const SpdyHeaderBlock& headers) { void QuicClientPromisedInfo::OnResponseHeaders(const SpdyHeaderBlock& headers) {
response_headers_.reset(new SpdyHeaderBlock(headers.Clone())); response_headers_ = QuicMakeUnique<SpdyHeaderBlock>(headers.Clone());
if (client_request_delegate_) { if (client_request_delegate_) {
// We already have a client request waiting. // We already have a client request waiting.
FinalValidation(); FinalValidation();
...@@ -86,7 +87,7 @@ void QuicClientPromisedInfo::Reset(QuicRstStreamErrorCode error_code) { ...@@ -86,7 +87,7 @@ void QuicClientPromisedInfo::Reset(QuicRstStreamErrorCode error_code) {
QuicAsyncStatus QuicClientPromisedInfo::FinalValidation() { QuicAsyncStatus QuicClientPromisedInfo::FinalValidation() {
if (!client_request_delegate_->CheckVary( if (!client_request_delegate_->CheckVary(
*client_request_headers_, *request_headers_, *response_headers_)) { client_request_headers_, request_headers_, *response_headers_)) {
Reset(QUIC_PROMISE_VARY_MISMATCH); Reset(QUIC_PROMISE_VARY_MISMATCH);
return QUIC_FAILURE; return QUIC_FAILURE;
} }
...@@ -124,8 +125,8 @@ QuicAsyncStatus QuicClientPromisedInfo::HandleClientRequest( ...@@ -124,8 +125,8 @@ QuicAsyncStatus QuicClientPromisedInfo::HandleClientRequest(
} }
client_request_delegate_ = delegate; client_request_delegate_ = delegate;
client_request_headers_.reset(new SpdyHeaderBlock(request_headers.Clone())); client_request_headers_ = request_headers.Clone();
if (!response_headers_) { if (response_headers_ == nullptr) {
return QUIC_PENDING; return QUIC_PENDING;
} }
return FinalValidation(); return FinalValidation();
......
...@@ -66,10 +66,12 @@ class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo ...@@ -66,10 +66,12 @@ class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
// validation requires the response headers (for the actual Vary // validation requires the response headers (for the actual Vary
// field list), the promise headers (taking the role of the "cached" // field list), the promise headers (taking the role of the "cached"
// request), and the client request headers. // request), and the client request headers.
SpdyHeaderBlock* request_headers() { return request_headers_.get(); } SpdyHeaderBlock* request_headers() { return &request_headers_; }
SpdyHeaderBlock* response_headers() { return response_headers_.get(); } SpdyHeaderBlock* response_headers() { return response_headers_.get(); }
// After validation, client will use this to access the pushed stream.
QuicStreamId id() const { return id_; } QuicStreamId id() const { return id_; }
const std::string url() const { return url_; } const std::string url() const { return url_; }
...@@ -95,13 +97,13 @@ class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo ...@@ -95,13 +97,13 @@ class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
QuicSpdyClientSessionBase* session_; QuicSpdyClientSessionBase* session_;
QuicStreamId id_; QuicStreamId id_;
std::string url_; std::string url_;
std::unique_ptr<SpdyHeaderBlock> request_headers_; SpdyHeaderBlock request_headers_;
std::unique_ptr<SpdyHeaderBlock> response_headers_; std::unique_ptr<SpdyHeaderBlock> response_headers_;
std::unique_ptr<SpdyHeaderBlock> client_request_headers_; SpdyHeaderBlock client_request_headers_;
QuicClientPushPromiseIndex::Delegate* client_request_delegate_; QuicClientPushPromiseIndex::Delegate* client_request_delegate_;
// The promise will commit suicide eventually if it is not claimed // The promise will commit suicide eventually if it is not claimed by a GET
// by a GET first. // first.
std::unique_ptr<QuicAlarm> cleanup_alarm_; std::unique_ptr<QuicAlarm> cleanup_alarm_;
DISALLOW_COPY_AND_ASSIGN(QuicClientPromisedInfo); DISALLOW_COPY_AND_ASSIGN(QuicClientPromisedInfo);
......
This diff is collapsed.
...@@ -179,3 +179,7 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_min_rtt_ack_delay, false) ...@@ -179,3 +179,7 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_min_rtt_ack_delay, false)
QUIC_FLAG(bool, QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_use_control_frame_manager, FLAGS_quic_reloadable_flag_quic_use_control_frame_manager,
false) false)
// When true, allows two connection options to run experiments with using max
// ack delay as described in QUIC IETF.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_max_ack_delay, false)
...@@ -103,6 +103,18 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { ...@@ -103,6 +103,18 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
std::min(kMaxInitialRoundTripTimeUs, std::min(kMaxInitialRoundTripTimeUs,
config.GetInitialRoundTripTimeUsToSend()))); config.GetInitialRoundTripTimeUsToSend())));
} }
if (GetQuicReloadableFlag(quic_max_ack_delay) &&
config.HasClientSentConnectionOption(kMAD0, perspective_)) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_max_ack_delay, 1, 2);
rtt_stats_.set_ignore_max_ack_delay(true);
}
if (GetQuicReloadableFlag(quic_max_ack_delay) &&
config.HasClientSentConnectionOption(kMAD1, perspective_)) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_max_ack_delay, 2, 2);
rtt_stats_.set_initial_max_ack_delay(
QuicTime::Delta::FromMilliseconds(kMaxDelayedAckTimeMs));
}
// Configure congestion control. // Configure congestion control.
if (config.HasClientRequestedIndependentOption(kTBBR, perspective_)) { if (config.HasClientRequestedIndependentOption(kTBBR, perspective_)) {
SetSendAlgorithm(kBBR); SetSendAlgorithm(kBBR);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment