Add a method in QuicConnection to be called when the client successfully migrate itself after probing. Client change only and not in use. PiperOrigin-RevId: 316923865 Change-Id: Ibb3f94073f0f05ecba5b9fc070e7586565c1dd0f
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index b22dc96..9901afa 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -976,6 +976,17 @@ } } +void QuicConnection::OnSuccessfulMigrationAfterProbing() { + DCHECK_EQ(perspective_, Perspective::IS_CLIENT); + if (IsPathDegrading()) { + // If path was previously degrading, and migration is successful after + // probing, restart the path degrading and blackhole detection. + OnForwardProgressMade(); + } + // TODO(b/159074035): notify SentPacketManger with RTT sample from probing and + // reset cwnd if this is a successful network migration. +} + void QuicConnection::OnTransportParametersSent( const TransportParameters& transport_parameters) const { if (debug_visitor_ != nullptr) {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index 5cc257d..118e9c4 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -965,6 +965,9 @@ // Called when version is considered negotiated. void OnSuccessfulVersionNegotiation(); + // Called when self migration succeeds after probing. + void OnSuccessfulMigrationAfterProbing(); + // Called for QUIC+TLS versions when we send transport parameters. void OnTransportParametersSent( const TransportParameters& transport_parameters) const;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 1385425..db402c7 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -50,7 +50,6 @@ using testing::AnyNumber; using testing::AtLeast; using testing::DoAll; -using testing::Exactly; using testing::Ge; using testing::IgnoreResult; using testing::InSequence; @@ -9231,6 +9230,103 @@ sizeof(challenge_data))); } +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(_)); + set_perspective(Perspective::IS_CLIENT); + EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective()); + + // Clear direct_peer_address and effective_peer_address. + QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress()); + QuicConnectionPeer::SetEffectivePeerAddress(&connection_, + QuicSocketAddress()); + EXPECT_FALSE(connection_.effective_peer_address().IsInitialized()); + + EXPECT_TRUE(connection_.connected()); + EXPECT_CALL(visitor_, ShouldKeepConnectionAlive()) + .WillRepeatedly(Return(true)); + EXPECT_FALSE(connection_.PathDegradingDetectionInProgress()); + EXPECT_FALSE(connection_.IsPathDegrading()); + EXPECT_FALSE(connection_.GetPingAlarm()->IsSet()); + + if (QuicVersionUsesCryptoFrames(connection_.transport_version())) { + EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber()); + } else { + EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); + } + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, + kPeerAddress); + EXPECT_EQ(kPeerAddress, connection_.peer_address()); + EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); + + // Send data and verify the path degrading detection is set. + const char data[] = "data"; + size_t data_size = strlen(data); + QuicStreamOffset offset = 0; + connection_.SendStreamDataWithString(1, data, offset, NO_FIN); + offset += data_size; + + // Verify the path degrading detection is in progress. + EXPECT_TRUE(connection_.PathDegradingDetectionInProgress()); + EXPECT_FALSE(connection_.IsPathDegrading()); + QuicTime ddl = connection_.GetBlackholeDetectorAlarm()->deadline(); + + // Simulate the firing of path degrading. + clock_.AdvanceTime(ddl - clock_.ApproximateNow()); + EXPECT_CALL(visitor_, OnPathDegrading()).Times(1); + connection_.PathDegradingTimeout(); + 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_); + 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()) { + 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); + + std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket(); + std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket( + QuicEncryptedPacket(probing_packet->encrypted_buffer, + probing_packet->encrypted_length), + clock_.Now())); + uint64_t num_probing_received = + connection_.GetStats().num_connectivity_probing_received; + ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received); + + EXPECT_EQ(num_probing_received + 1, + connection_.GetStats().num_connectivity_probing_received); + 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_.OnSuccessfulMigrationAfterProbing(); + EXPECT_FALSE(connection_.IsPathDegrading()); + EXPECT_TRUE(connection_.PathDegradingDetectionInProgress()); +} + // Regression test for b/110259444 TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));