In QUIC, instead of looking up QuicConnection states, consult the session on whether the connection should be closed on STATELESS_RESET.

The new approach allows Chrome's connectivity probing manager to make decisions, which is consistent with other path determination logic for probing.

Client side change only. not protected.

PiperOrigin-RevId: 312556190
Change-Id: I0a295b84312b7c53bdf14c4c7940ce1f60609b09
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 1ef3cf7..0190967 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1596,9 +1596,9 @@
   // debug_visitor_.
   DCHECK(VersionHasIetfInvariantHeader(transport_version()));
   DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-  if (last_packet_destination_address_ != self_address()) {
+  if (!visitor_->ValidateStatelessReset(last_packet_destination_address_,
+                                        last_packet_source_address_)) {
     // This packet is received on a probing path. Do not close connection.
-    visitor_->OnStatelessResetForProbing();
     return;
   }
 
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index c1e95f3..9339fb0 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -131,8 +131,11 @@
   // bandwidth.  Returns true if data was sent, false otherwise.
   virtual bool SendProbingData() = 0;
 
-  // Called when stateless reset packet is received but is on a different path.
-  virtual void OnStatelessResetForProbing() = 0;
+  // Called when stateless reset packet is received. Returns true if the
+  // connection needs to be closed.
+  virtual bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& self_address,
+      const quic::QuicSocketAddress& peer_address) = 0;
 
   // Called when the connection experiences a change in congestion window.
   virtual void OnCongestionWindowChange(QuicTime now) = 0;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index fe94fcf..bb61130 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -7418,6 +7418,7 @@
                                                 kTestStatelessResetToken));
   std::unique_ptr<QuicReceivedPacket> received(
       ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, ValidateStatelessReset(_, _)).WillOnce(Return(true));
   EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
       .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
   connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
@@ -7426,33 +7427,6 @@
               IsError(QUIC_PUBLIC_RESET));
 }
 
-TEST_P(QuicConnectionTest, IetfStatelessResetOnProbingPath) {
-  if (!VersionHasIetfInvariantHeader(GetParam().version.transport_version)) {
-    return;
-  }
-  const QuicUint128 kTestStatelessResetToken = 1010101;
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedStatelessResetToken(&config,
-                                                 kTestStatelessResetToken);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  // Process a normal packet first to set the self address.
-  QuicReceivedPacket encrypted(nullptr, 0, QuicTime::Zero());
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, encrypted);
-
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
-                                                kTestStatelessResetToken));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*packet, QuicTime::Zero()));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-  EXPECT_CALL(visitor_, OnStatelessResetForProbing());
-  auto host = kSelfAddress.host();
-  QuicSocketAddress alternate_address(host, 80);
-  connection_.ProcessUdpPacket(alternate_address, kPeerAddress, *received);
-}
-
 TEST_P(QuicConnectionTest, GoAway) {
   if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
     // GoAway is not available in version 99.
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index 0aa3ae4..ae41efc 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -110,7 +110,11 @@
                         bool is_connectivity_probe) override;
   void OnCanWrite() override;
   bool SendProbingData() override;
-  void OnStatelessResetForProbing() override {}
+  bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& /*self_address*/,
+      const quic::QuicSocketAddress& /*peer_address*/) override {
+    return true;
+  }
   void OnCongestionWindowChange(QuicTime /*now*/) override {}
   void OnConnectionMigration(AddressChangeType /*type*/) override {}
   // Adds a connection level WINDOW_UPDATE frame.
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index 491b828..3c311a1 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -499,7 +499,10 @@
   MOCK_METHOD(void, OnWriteBlocked, (), (override));
   MOCK_METHOD(void, OnCanWrite, (), (override));
   MOCK_METHOD(bool, SendProbingData, (), (override));
-  MOCK_METHOD(void, OnStatelessResetForProbing, (), (override));
+  MOCK_METHOD(bool,
+              ValidateStatelessReset,
+              (const quic::QuicSocketAddress&, const quic::QuicSocketAddress&),
+              (override));
   MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
   MOCK_METHOD(void,
               OnConnectionMigration,
diff --git a/quic/test_tools/simulator/quic_endpoint.h b/quic/test_tools/simulator/quic_endpoint.h
index 9a3277b..dfc74ee 100644
--- a/quic/test_tools/simulator/quic_endpoint.h
+++ b/quic/test_tools/simulator/quic_endpoint.h
@@ -51,7 +51,11 @@
   void OnCryptoFrame(const QuicCryptoFrame& frame) override;
   void OnCanWrite() override;
   bool SendProbingData() override;
-  void OnStatelessResetForProbing() override {}
+  bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& /*self_address*/,
+      const quic::QuicSocketAddress& /*peer_address*/) override {
+    return true;
+  }
   bool WillingAndAbleToWrite() const override;
   bool ShouldKeepConnectionAlive() const override;