In quic client connection, reset rtt and cwnd after successfully migrate to a new IP address if using IETF version.
To code merger: in the two call sites of QuicConnection::OnSuccessfulMigration()
OnConnectionMigrationProbeSucceeded() and OnPortMigrationProbeSucceeded(), pass false in the former caller and true in the latter caller.
client side change only.
PiperOrigin-RevId: 358208758
Change-Id: I63dd3dc8b06dec3c3d1922bbe9d4d064de31f00a
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 5b35138..81a15ad 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1088,7 +1088,7 @@
}
}
-void QuicConnection::OnSuccessfulMigration() {
+void QuicConnection::OnSuccessfulMigration(bool is_port_change) {
QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
if (IsPathDegrading()) {
// If path was previously degrading, and migration is successful after
@@ -1100,8 +1100,10 @@
// Reset alternative path state even if it is still under validation.
alternative_path_.Clear();
}
- // TODO(b/159074035): notify SentPacketManger with RTT sample from probing and
- // reset cwnd if this is a successful network migration.
+ // TODO(b/159074035): notify SentPacketManger with RTT sample from probing.
+ if (version().HasIetfQuicFrames() && !is_port_change) {
+ sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+ }
}
void QuicConnection::OnTransportParametersSent(
@@ -5780,10 +5782,15 @@
if (!connected_) {
return;
}
+ const bool is_port_change =
+ QuicUtils::DetermineAddressChangeType(default_path_.self_address,
+ self_address) == PORT_CHANGE &&
+ QuicUtils::DetermineAddressChangeType(default_path_.peer_address,
+ peer_address) == PORT_CHANGE;
SetSelfAddress(self_address);
UpdatePeerAddress(peer_address);
SetQuicPacketWriter(writer, owns_writer);
- OnSuccessfulMigration();
+ OnSuccessfulMigration(is_port_change);
}
std::vector<QuicConnectionId> QuicConnection::GetActiveServerConnectionIds()
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 47a295a..ab111e5 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -1095,7 +1095,7 @@
void OnSuccessfulVersionNegotiation();
// Called when self migration succeeds after probing.
- void OnSuccessfulMigration();
+ void OnSuccessfulMigration(bool is_port_change);
// Called for QUIC+TLS versions when we send transport parameters.
void OnTransportParametersSent(
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 74534df..910af57 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -699,6 +699,8 @@
.Times(AnyNumber());
EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+ EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
+ .Times(AnyNumber());
EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
EXPECT_CALL(visitor_, OnPacketDecrypted(_)).Times(AnyNumber());
@@ -8594,12 +8596,6 @@
TEST_P(QuicConnectionTest,
RestartPathDegradingDetectionAfterMigrationWithProbe) {
- // TODO(b/150095484): add test coverage for IETF to verify that client takes
- // PATH RESPONSE with peer address change as correct validation on the new
- // path.
- if (GetParam().version.HasIetfQuicFrames()) {
- return;
- }
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
PathProbeTestInit(Perspective::IS_CLIENT);
@@ -8622,24 +8618,21 @@
EXPECT_TRUE(connection_.IsPathDegrading());
EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- // Simulate path degrading handling by sending a probe on an alternet path.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
- connection_.SendConnectivityProbingPacket(&probing_writer,
- connection_.peer_address());
- // Verify that path degrading detection is not reset.
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
- // Simulate successful path degrading handling by receiving probe response.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
if (!GetParam().version.HasIetfQuicFrames()) {
+ // Simulate path degrading handling by sending a probe on an alternet path.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
+ connection_.SendConnectivityProbingPacket(&probing_writer,
+ connection_.peer_address());
+ // Verify that path degrading detection is not reset.
+ EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+ // Simulate successful path degrading handling by receiving probe response.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
EXPECT_CALL(visitor_,
OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
.Times(1);
- } else {
- EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
- }
const QuicSocketAddress kNewSelfAddress =
QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
@@ -8657,14 +8650,46 @@
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
EXPECT_TRUE(connection_.IsPathDegrading());
+ }
// Verify new path degrading detection is activated.
EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
- connection_.OnSuccessfulMigration();
+ connection_.OnSuccessfulMigration(/*is_port_change*/ true);
EXPECT_FALSE(connection_.IsPathDegrading());
EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
}
+TEST_P(QuicConnectionTest, ClientsResetCwndAfterConnectionMigration) {
+ if (!GetParam().version.HasIetfQuicFrames()) {
+ return;
+ }
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ PathProbeTestInit(Perspective::IS_CLIENT);
+ EXPECT_EQ(kSelfAddress, connection_.self_address());
+
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+ QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+ rtt_stats->set_initial_rtt(default_init_rtt * 2);
+ EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+ QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
+ EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
+ QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
+ EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+ const SendAlgorithmInterface* send_algorithm = manager_->GetSendAlgorithm();
+
+ // Migrate to a new address with different IP.
+ const QuicSocketAddress kNewSelfAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+ TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+ connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+ &new_writer, false);
+ EXPECT_EQ(default_init_rtt, manager_->GetRttStats()->initial_rtt());
+ EXPECT_EQ(0u, manager_->GetConsecutiveRtoCount());
+ EXPECT_EQ(0u, manager_->GetConsecutiveTlpCount());
+ EXPECT_NE(send_algorithm, manager_->GetSendAlgorithm());
+}
+
// Regression test for b/110259444
TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));