In quicconnection, revert to a previously validated mtu after a delay equivalent to the duration of three ptos. protected by --gfe2_reloadable_flag_quic_revert_mtu_after_two_ptos.
PiperOrigin-RevId: 323411817
Change-Id: I1972673c2e75677fcffad3a45d9e0087e8fc6fc2
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index df6c5c2..9a74a33 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -2721,7 +2721,7 @@
<< ", previous_validated_mtu_:" << previous_validated_mtu_
<< ", max_packet_length():" << max_packet_length()
<< ", is_mtu_discovery:" << is_mtu_discovery;
- if (ShouldIgnoreWriteError()) {
+ if (MaybeRevertToPreviousMtu()) {
return true;
}
@@ -2752,7 +2752,8 @@
// because either both detections are inactive when sending last packet
// or this connection just gets out of quiescence.
blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
- GetNetworkBlackholeDeadline());
+ GetNetworkBlackholeDeadline(),
+ GetPathMtuReductionDeadline());
}
idle_network_detector_.OnPacketSent(packet_send_time);
}
@@ -2824,7 +2825,7 @@
return;
}
- if (IsWriteError(result.status) && !ShouldIgnoreWriteError()) {
+ if (IsWriteError(result.status) && !MaybeRevertToPreviousMtu()) {
OnWriteError(result.error_code);
}
}
@@ -2854,7 +2855,22 @@
return false;
}
-bool QuicConnection::ShouldIgnoreWriteError() {
+QuicTime QuicConnection::GetPathMtuReductionDeadline() const {
+ if (!blackhole_detector_.revert_mtu_after_two_ptos()) {
+ return QuicTime::Zero();
+ }
+ if (previous_validated_mtu_ == 0) {
+ return QuicTime::Zero();
+ }
+ QuicTime::Delta delay = sent_packet_manager_.GetMtuReductionDelay(
+ num_rtos_for_blackhole_detection_);
+ if (delay.IsZero()) {
+ return QuicTime::Zero();
+ }
+ return clock_->ApproximateNow() + delay;
+}
+
+bool QuicConnection::MaybeRevertToPreviousMtu() {
if (previous_validated_mtu_ == 0) {
return false;
}
@@ -4489,7 +4505,8 @@
if (sent_packet_manager_.HasInFlightPackets()) {
// Restart detections if forward progress has been made.
blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
- GetNetworkBlackholeDeadline());
+ GetNetworkBlackholeDeadline(),
+ GetPathMtuReductionDeadline());
} else {
// Stop detections in quiecense.
blackhole_detector_.StopDetection();
@@ -4639,6 +4656,15 @@
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
}
+void QuicConnection::OnPathMtuReductionDetected() {
+ DCHECK(blackhole_detector_.revert_mtu_after_two_ptos());
+ if (MaybeRevertToPreviousMtu()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_revert_mtu_after_two_ptos, 1, 2);
+ } else {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_revert_mtu_after_two_ptos, 2, 2);
+ }
+}
+
void QuicConnection::OnHandshakeTimeout() {
const QuicTime::Delta duration =
clock_->ApproximateNow() - stats_.connection_creation_time;
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 36ef402..9439adf 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -612,6 +612,7 @@
// QuicNetworkBlackholeDetector::Delegate
void OnPathDegradingDetected() override;
void OnBlackholeDetected() override;
+ void OnPathMtuReductionDetected() override;
// QuicIdleNetworkDetector::Delegate
void OnHandshakeTimeout() override;
@@ -1292,10 +1293,12 @@
// |supports_release_time_| is false.
QuicTime CalculatePacketSentTime();
- // We've got a packet write error, should we ignore it?
- // NOTE: This is not a const function - if return true, the max packet size is
- // reverted to a previous(smaller) value to avoid write errors in the future.
- bool ShouldIgnoreWriteError();
+ // If we have a previously validate MTU value, e.g. due to a write error,
+ // revert to it and disable MTU discovery.
+ // Return true iff we reverted to a previously validate MTU.
+ bool MaybeRevertToPreviousMtu();
+
+ QuicTime GetPathMtuReductionDeadline() const;
// Returns path degrading deadline. QuicTime::Zero() means no path degrading
// detection is needed.
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 59f12bb..ac301c2 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -932,6 +932,11 @@
.IsInitialized();
}
+ bool PathMtuReductionDetectionInProgress() {
+ return QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(this)
+ .IsInitialized();
+ }
+
void SetMaxTailLossProbes(size_t max_tail_loss_probes) {
QuicSentPacketManagerPeer::SetMaxTailLossProbes(
QuicConnectionPeer::GetSentPacketManager(this), max_tail_loss_probes);
@@ -5434,6 +5439,32 @@
ConstructAckFrame(creator_->packet_number(), second_probe_packet_number);
ProcessAckPacket(&third_ack);
EXPECT_EQ(third_probe_size, connection_.max_packet_length());
+
+ SendStreamDataToPeer(3, "$", stream_offset++, NO_FIN, nullptr);
+ if (!GetQuicReloadableFlag(quic_revert_mtu_after_two_ptos)) {
+ EXPECT_FALSE(connection_.PathMtuReductionDetectionInProgress());
+ return;
+ }
+
+ EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
+
+ if (connection_.PathDegradingDetectionInProgress() &&
+ QuicConnectionPeer::GetPathDegradingDeadline(&connection_) <
+ QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
+ &connection_)) {
+ // Fire path degrading alarm first.
+ connection_.PathDegradingTimeout();
+ }
+
+ // Verify the max packet size has not reduced.
+ EXPECT_EQ(third_probe_size, connection_.max_packet_length());
+
+ // Fire alarm to get path mtu reduction callback called.
+ EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
+ connection_.GetBlackholeDetectorAlarm()->Fire();
+
+ // Verify the max packet size has reduced to the previous value.
+ EXPECT_EQ(probe_size, connection_.max_packet_length());
}
// Tests whether MTU discovery works when the writer has a limit on how large a
diff --git a/quic/core/quic_network_blackhole_detector.cc b/quic/core/quic_network_blackhole_detector.cc
index 9206ae4..02e3308 100644
--- a/quic/core/quic_network_blackhole_detector.cc
+++ b/quic/core/quic_network_blackhole_detector.cc
@@ -30,45 +30,128 @@
QuicConnectionArena* arena,
QuicAlarmFactory* alarm_factory)
: delegate_(delegate),
- path_degrading_deadline_(QuicTime::Zero()),
- blackhole_deadline_(QuicTime::Zero()),
alarm_(
alarm_factory->CreateAlarm(arena->New<AlarmDelegate>(this), arena)) {}
void QuicNetworkBlackholeDetector::OnAlarm() {
- if (path_degrading_deadline_.IsInitialized()) {
- path_degrading_deadline_ = QuicTime::Zero();
- delegate_->OnPathDegradingDetected();
- // Switch to blackhole detection mode.
- alarm_->Update(blackhole_deadline_, kAlarmGranularity);
+ if (!revert_mtu_after_two_ptos_) {
+ if (path_degrading_deadline_.IsInitialized()) {
+ path_degrading_deadline_ = QuicTime::Zero();
+ delegate_->OnPathDegradingDetected();
+ // Switch to blackhole detection mode.
+ alarm_->Update(blackhole_deadline_, kAlarmGranularity);
+ return;
+ }
+ if (blackhole_deadline_.IsInitialized()) {
+ blackhole_deadline_ = QuicTime::Zero();
+ delegate_->OnBlackholeDetected();
+ }
return;
}
- if (blackhole_deadline_.IsInitialized()) {
+
+ QuicTime next_deadline = GetEarliestDeadline();
+ if (!next_deadline.IsInitialized()) {
+ QUIC_BUG << "BlackholeDetector alarm fired unexpectedly";
+ return;
+ }
+
+ QUIC_DLOG(INFO) << "BlackholeDetector alarm firing. next_deadline:"
+ << next_deadline
+ << ", path_degrading_deadline_:" << path_degrading_deadline_
+ << ", path_mtu_reduction_deadline_:"
+ << path_mtu_reduction_deadline_
+ << ", blackhole_deadline_:" << blackhole_deadline_;
+ if (path_degrading_deadline_ == next_deadline) {
+ path_degrading_deadline_ = QuicTime::Zero();
+ delegate_->OnPathDegradingDetected();
+ }
+
+ if (path_mtu_reduction_deadline_ == next_deadline) {
+ path_mtu_reduction_deadline_ = QuicTime::Zero();
+ delegate_->OnPathMtuReductionDetected();
+ }
+
+ if (blackhole_deadline_ == next_deadline) {
blackhole_deadline_ = QuicTime::Zero();
delegate_->OnBlackholeDetected();
}
+
+ UpdateAlarm();
}
void QuicNetworkBlackholeDetector::StopDetection() {
alarm_->Cancel();
path_degrading_deadline_ = QuicTime::Zero();
blackhole_deadline_ = QuicTime::Zero();
+ path_mtu_reduction_deadline_ = QuicTime::Zero();
}
void QuicNetworkBlackholeDetector::RestartDetection(
QuicTime path_degrading_deadline,
- QuicTime blackhole_deadline) {
+ QuicTime blackhole_deadline,
+ QuicTime path_mtu_reduction_deadline) {
path_degrading_deadline_ = path_degrading_deadline;
blackhole_deadline_ = blackhole_deadline;
- QUIC_BUG_IF(path_degrading_deadline_.IsInitialized() &&
- blackhole_deadline_.IsInitialized() &&
- path_degrading_deadline_ > blackhole_deadline_)
- << "Path degrading timeout is later than blackhole detection timeout";
- alarm_->Update(path_degrading_deadline_, kAlarmGranularity);
- if (alarm_->IsSet()) {
- return;
+ path_mtu_reduction_deadline_ = path_mtu_reduction_deadline;
+
+ if (!revert_mtu_after_two_ptos_) {
+ QUIC_BUG_IF(path_degrading_deadline_.IsInitialized() &&
+ blackhole_deadline_.IsInitialized() &&
+ path_degrading_deadline_ > blackhole_deadline_)
+ << "Path degrading timeout is later than blackhole detection timeout";
+ } else {
+ QUIC_BUG_IF(blackhole_deadline_.IsInitialized() &&
+ blackhole_deadline_ != GetLastDeadline())
+ << "Blackhole detection deadline should be the last deadline.";
}
- alarm_->Update(blackhole_deadline_, kAlarmGranularity);
+
+ if (!revert_mtu_after_two_ptos_) {
+ alarm_->Update(path_degrading_deadline_, kAlarmGranularity);
+ if (alarm_->IsSet()) {
+ return;
+ }
+ alarm_->Update(blackhole_deadline_, kAlarmGranularity);
+ } else {
+ UpdateAlarm();
+ }
+}
+
+QuicTime QuicNetworkBlackholeDetector::GetEarliestDeadline() const {
+ DCHECK(revert_mtu_after_two_ptos_);
+
+ QuicTime result = QuicTime::Zero();
+ for (QuicTime t : {path_degrading_deadline_, blackhole_deadline_,
+ path_mtu_reduction_deadline_}) {
+ if (!t.IsInitialized()) {
+ continue;
+ }
+
+ if (!result.IsInitialized() || t < result) {
+ result = t;
+ }
+ }
+
+ return result;
+}
+
+QuicTime QuicNetworkBlackholeDetector::GetLastDeadline() const {
+ DCHECK(revert_mtu_after_two_ptos_);
+ return std::max({path_degrading_deadline_, blackhole_deadline_,
+ path_mtu_reduction_deadline_});
+}
+
+void QuicNetworkBlackholeDetector::UpdateAlarm() const {
+ DCHECK(revert_mtu_after_two_ptos_);
+
+ QuicTime next_deadline = GetEarliestDeadline();
+
+ QUIC_DLOG(INFO) << "Updating alarm. next_deadline:" << next_deadline
+ << ", path_degrading_deadline_:" << path_degrading_deadline_
+ << ", path_mtu_reduction_deadline_:"
+ << path_mtu_reduction_deadline_
+ << ", blackhole_deadline_:" << blackhole_deadline_;
+
+ alarm_->Update(next_deadline, kAlarmGranularity);
}
bool QuicNetworkBlackholeDetector::IsDetectionInProgress() const {
diff --git a/quic/core/quic_network_blackhole_detector.h b/quic/core/quic_network_blackhole_detector.h
index b839d42..77c5c59 100644
--- a/quic/core/quic_network_blackhole_detector.h
+++ b/quic/core/quic_network_blackhole_detector.h
@@ -10,6 +10,7 @@
#include "net/third_party/quiche/src/quic/core/quic_one_block_arena.h"
#include "net/third_party/quiche/src/quic/core/quic_time.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
namespace quic {
@@ -34,6 +35,9 @@
// Called when the path blackhole alarm fires.
virtual void OnBlackholeDetected() = 0;
+
+ // Called when the path mtu reduction alarm fires.
+ virtual void OnPathMtuReductionDetected() = 0;
};
QuicNetworkBlackholeDetector(Delegate* delegate,
@@ -43,11 +47,12 @@
// Called to stop all detections.
void StopDetection();
- // Called to restart path degrading or/and blackhole detections. Please note,
- // if both deadlines are set, |blackhole_deadline| must be later than
- // |path_degrading_deadline|.
+ // Called to restart path degrading, path mtu reduction and blackhole
+ // detections. Please note, if |blackhole_deadline| is set, it must be the
+ // furthest in the future of all deadlines.
void RestartDetection(QuicTime path_degrading_deadline,
- QuicTime blackhole_deadline);
+ QuicTime blackhole_deadline,
+ QuicTime path_mtu_reduction_deadline);
// Called when |alarm_| fires.
void OnAlarm();
@@ -55,18 +60,32 @@
// Returns true if |alarm_| is set.
bool IsDetectionInProgress() const;
+ bool revert_mtu_after_two_ptos() const { return revert_mtu_after_two_ptos_; }
+
private:
friend class test::QuicConnectionPeer;
friend class test::QuicNetworkBlackholeDetectorPeer;
+ QuicTime GetEarliestDeadline() const;
+ QuicTime GetLastDeadline() const;
+
+ // Update alarm to the next deadline.
+ void UpdateAlarm() const;
+
Delegate* delegate_; // Not owned.
+ const bool revert_mtu_after_two_ptos_ =
+ GetQuicReloadableFlag(quic_revert_mtu_after_two_ptos);
+
// Time that Delegate::OnPathDegrading will be called. 0 means no path
// degrading detection is in progress.
- QuicTime path_degrading_deadline_;
+ QuicTime path_degrading_deadline_ = QuicTime::Zero();
// Time that Delegate::OnBlackholeDetected will be called. 0 means no
// blackhole detection is in progress.
- QuicTime blackhole_deadline_;
+ QuicTime blackhole_deadline_ = QuicTime::Zero();
+ // Time that Delegate::OnPathMtuReductionDetected will be called. 0 means no
+ // path mtu reduction detection is in progress.
+ QuicTime path_mtu_reduction_deadline_ = QuicTime::Zero();
QuicArenaScopedPtr<QuicAlarm> alarm_;
};
diff --git a/quic/core/quic_network_blackhole_detector_test.cc b/quic/core/quic_network_blackhole_detector_test.cc
index 0178887..3f6f747 100644
--- a/quic/core/quic_network_blackhole_detector_test.cc
+++ b/quic/core/quic_network_blackhole_detector_test.cc
@@ -23,9 +23,11 @@
public:
MOCK_METHOD(void, OnPathDegradingDetected, (), (override));
MOCK_METHOD(void, OnBlackholeDetected, (), (override));
+ MOCK_METHOD(void, OnPathMtuReductionDetected, (), (override));
};
const size_t kPathDegradingDelayInSeconds = 5;
+const size_t kPathMtuReductionDelayInSeconds = 7;
const size_t kBlackholeDelayInSeconds = 10;
class QuicNetworkBlackholeDetectorTest : public QuicTest {
@@ -36,12 +38,20 @@
QuicNetworkBlackholeDetectorPeer::GetAlarm(&detector_))),
path_degrading_delay_(
QuicTime::Delta::FromSeconds(kPathDegradingDelayInSeconds)),
+ path_mtu_reduction_delay_(
+ QuicTime::Delta::FromSeconds(kPathMtuReductionDelayInSeconds)),
blackhole_delay_(
QuicTime::Delta::FromSeconds(kBlackholeDelayInSeconds)) {
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
protected:
+ void RestartDetection() {
+ detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
+ clock_.Now() + blackhole_delay_,
+ clock_.Now() + path_mtu_reduction_delay_);
+ }
+
testing::StrictMock<MockDelegate> delegate_;
QuicConnectionArena arena_;
MockAlarmFactory alarm_factory_;
@@ -51,14 +61,14 @@
MockAlarmFactory::TestAlarm* alarm_;
MockClock clock_;
const QuicTime::Delta path_degrading_delay_;
+ const QuicTime::Delta path_mtu_reduction_delay_;
const QuicTime::Delta blackhole_delay_;
};
TEST_F(QuicNetworkBlackholeDetectorTest, StartAndFire) {
EXPECT_FALSE(detector_.IsDetectionInProgress());
- detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
- clock_.Now() + blackhole_delay_);
+ RestartDetection();
EXPECT_TRUE(detector_.IsDetectionInProgress());
EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
@@ -66,25 +76,48 @@
clock_.AdvanceTime(path_degrading_delay_);
EXPECT_CALL(delegate_, OnPathDegradingDetected());
alarm_->Fire();
+
+ if (!detector_.revert_mtu_after_two_ptos()) {
+ // Verify blackhole detection is still in progress.
+ EXPECT_TRUE(detector_.IsDetectionInProgress());
+ EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_degrading_delay_,
+ alarm_->deadline());
+
+ // Fire blackhole detection alarm.
+ clock_.AdvanceTime(blackhole_delay_ - path_degrading_delay_);
+ EXPECT_CALL(delegate_, OnBlackholeDetected());
+ alarm_->Fire();
+ EXPECT_FALSE(detector_.IsDetectionInProgress());
+ return;
+ }
+
+ // Verify path mtu reduction detection is still in progress.
+ EXPECT_TRUE(detector_.IsDetectionInProgress());
+ EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
+ alarm_->deadline());
+
+ // Fire path mtu reduction detection alarm.
+ clock_.AdvanceTime(path_mtu_reduction_delay_ - path_degrading_delay_);
+ EXPECT_CALL(delegate_, OnPathMtuReductionDetected());
+ alarm_->Fire();
+
// Verify blackhole detection is still in progress.
EXPECT_TRUE(detector_.IsDetectionInProgress());
- EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_degrading_delay_,
+ EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_mtu_reduction_delay_,
alarm_->deadline());
// Fire blackhole detection alarm.
- clock_.AdvanceTime(blackhole_delay_ - path_degrading_delay_);
+ clock_.AdvanceTime(blackhole_delay_ - path_mtu_reduction_delay_);
EXPECT_CALL(delegate_, OnBlackholeDetected());
alarm_->Fire();
EXPECT_FALSE(detector_.IsDetectionInProgress());
}
TEST_F(QuicNetworkBlackholeDetectorTest, RestartAndStop) {
- detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
- clock_.Now() + blackhole_delay_);
+ RestartDetection();
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
- clock_.Now() + blackhole_delay_);
+ RestartDetection();
EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
detector_.StopDetection();
@@ -93,8 +126,7 @@
TEST_F(QuicNetworkBlackholeDetectorTest, PathDegradingFiresAndRestart) {
EXPECT_FALSE(detector_.IsDetectionInProgress());
- detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
- clock_.Now() + blackhole_delay_);
+ RestartDetection();
EXPECT_TRUE(detector_.IsDetectionInProgress());
EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
@@ -102,15 +134,22 @@
clock_.AdvanceTime(path_degrading_delay_);
EXPECT_CALL(delegate_, OnPathDegradingDetected());
alarm_->Fire();
- // Verify blackhole detection is still in progress.
- EXPECT_TRUE(detector_.IsDetectionInProgress());
- EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_degrading_delay_,
- alarm_->deadline());
+
+ if (!detector_.revert_mtu_after_two_ptos()) {
+ // Verify blackhole detection is still in progress.
+ EXPECT_TRUE(detector_.IsDetectionInProgress());
+ EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_degrading_delay_,
+ alarm_->deadline());
+ } else {
+ // Verify path mtu reduction detection is still in progress.
+ EXPECT_TRUE(detector_.IsDetectionInProgress());
+ EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
+ alarm_->deadline());
+ }
// After 100ms, restart detections on forward progress.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
- detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
- clock_.Now() + blackhole_delay_);
+ RestartDetection();
// Verify alarm is armed based on path degrading deadline.
EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
}
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc
index 2848137..ededb87 100644
--- a/quic/core/quic_sent_packet_manager.cc
+++ b/quic/core/quic_sent_packet_manager.cc
@@ -1167,6 +1167,11 @@
max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
}
+QuicTime::Delta QuicSentPacketManager::GetMtuReductionDelay(
+ int8_t num_rtos_for_blackhole_detection) const {
+ return GetNetworkBlackholeDelay(num_rtos_for_blackhole_detection / 2);
+}
+
const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
const {
// This is equivalent to the TailLossProbeDelay, but slightly more aggressive
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h
index 310cd1a..4e6cab1 100644
--- a/quic/core/quic_sent_packet_manager.h
+++ b/quic/core/quic_sent_packet_manager.h
@@ -215,6 +215,11 @@
const QuicTime::Delta GetNetworkBlackholeDelay(
int8_t num_rtos_for_blackhole_detection) const;
+ // Returns the delay before reducing max packet size. This delay is guranteed
+ // to be smaller than the network blackhole delay.
+ QuicTime::Delta GetMtuReductionDelay(
+ int8_t num_rtos_for_blackhole_detection) const;
+
const RttStats* GetRttStats() const { return &rtt_stats_; }
// Returns the estimated bandwidth calculated by the congestion algorithm.
diff --git a/quic/test_tools/quic_connection_peer.cc b/quic/test_tools/quic_connection_peer.cc
index 7192797..5fb31a5 100644
--- a/quic/test_tools/quic_connection_peer.cc
+++ b/quic/test_tools/quic_connection_peer.cc
@@ -356,6 +356,12 @@
}
// static
+QuicTime QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
+ QuicConnection* connection) {
+ return connection->blackhole_detector_.path_mtu_reduction_deadline_;
+}
+
+// static
QuicAlarm* QuicConnectionPeer::GetIdleNetworkDetectorAlarm(
QuicConnection* connection) {
return connection->idle_network_detector_.alarm_.get();
diff --git a/quic/test_tools/quic_connection_peer.h b/quic/test_tools/quic_connection_peer.h
index 258d953..8f3a78c 100644
--- a/quic/test_tools/quic_connection_peer.h
+++ b/quic/test_tools/quic_connection_peer.h
@@ -141,6 +141,9 @@
static QuicTime GetBlackholeDetectionDeadline(QuicConnection* connection);
+ static QuicTime GetPathMtuReductionDetectionDeadline(
+ QuicConnection* connection);
+
static QuicAlarm* GetIdleNetworkDetectorAlarm(QuicConnection* connection);
static void SetServerConnectionId(