Add retry_token to ReceivedPacketInfo. The token can be used later to extract cached network parameters.

PiperOrigin-RevId: 405479428
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index 02a0c8f..61f79dd 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -266,16 +266,15 @@
   QuicVersionLabel version_label;
   ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
   QuicConnectionId destination_connection_id, source_connection_id;
-  bool retry_token_present;
-  absl::string_view retry_token;
+  absl::optional<absl::string_view> retry_token;
   std::string detailed_error;
   const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
       QuicEncryptedPacket(legacy_version_encapsulation_inner_packet.data(),
                           legacy_version_encapsulation_inner_packet.length()),
       kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
   if (error != QUIC_NO_ERROR) {
     QUIC_DLOG(ERROR)
         << "Failed to parse Legacy Version Encapsulation inner packet:"
@@ -389,14 +388,12 @@
                        absl::string_view(packet.data(), packet.length()));
   ReceivedPacketInfo packet_info(self_address, peer_address, packet);
   std::string detailed_error;
-  bool retry_token_present;
-  absl::string_view retry_token;
   const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
       packet, expected_server_connection_id_length_, &packet_info.form,
       &packet_info.long_packet_type, &packet_info.version_flag,
       &packet_info.use_length_prefix, &packet_info.version_label,
       &packet_info.version, &packet_info.destination_connection_id,
-      &packet_info.source_connection_id, &retry_token_present, &retry_token,
+      &packet_info.source_connection_id, &packet_info.retry_token,
       &detailed_error);
   if (error != QUIC_NO_ERROR) {
     // Packet has framing error.
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index 2180962..276f59c 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -635,15 +635,14 @@
   QuicVersionLabel version_label;
   ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
   QuicConnectionId destination_connection_id, source_connection_id;
-  bool retry_token_present;
-  absl::string_view retry_token;
+  absl::optional<absl::string_view> retry_token;
   std::string detailed_error;
   const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
       QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
       kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
   ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
   EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
   EXPECT_TRUE(version_present);
@@ -651,7 +650,7 @@
   EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
   EXPECT_EQ(destination_connection_id, server_connection_id);
   EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
-  EXPECT_FALSE(retry_token_present);
+  EXPECT_FALSE(retry_token.has_value());
   EXPECT_TRUE(detailed_error.empty());
 
   // Processing the packet should create a new session.
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 4e0f639..7e78e64 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -6591,16 +6591,12 @@
 QuicErrorCode QuicFramer::ParsePublicHeaderDispatcher(
     const QuicEncryptedPacket& packet,
     uint8_t expected_destination_connection_id_length,
-    PacketHeaderFormat* format,
-    QuicLongHeaderType* long_packet_type,
-    bool* version_present,
-    bool* has_length_prefix,
-    QuicVersionLabel* version_label,
-    ParsedQuicVersion* parsed_version,
+    PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
+    bool* version_present, bool* has_length_prefix,
+    QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
     QuicConnectionId* destination_connection_id,
     QuicConnectionId* source_connection_id,
-    bool* retry_token_present,
-    absl::string_view* retry_token,
+    absl::optional<absl::string_view>* retry_token,
     std::string* detailed_error) {
   QuicDataReader reader(packet.data(), packet.length());
   if (reader.IsDoneReading()) {
@@ -6629,14 +6625,18 @@
   const bool ietf_format = QuicUtils::IsIetfPacketHeader(first_byte);
   uint8_t unused_first_byte;
   QuicVariableLengthIntegerLength retry_token_length_length;
+  absl::string_view maybe_retry_token;
   QuicErrorCode error_code = ParsePublicHeader(
       &reader, expected_destination_connection_id_length, ietf_format,
       &unused_first_byte, format, version_present, has_length_prefix,
       version_label, parsed_version, destination_connection_id,
       source_connection_id, long_packet_type, &retry_token_length_length,
-      retry_token, detailed_error);
-  *retry_token_present =
-      retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0;
+      &maybe_retry_token, detailed_error);
+  if (retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+    *retry_token = maybe_retry_token;
+  } else {
+    retry_token->reset();
+  }
   return error_code;
 }
 
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index b1fe416..2878888 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -453,16 +453,12 @@
   static QuicErrorCode ParsePublicHeaderDispatcher(
       const QuicEncryptedPacket& packet,
       uint8_t expected_destination_connection_id_length,
-      PacketHeaderFormat* format,
-      QuicLongHeaderType* long_packet_type,
-      bool* version_present,
-      bool* has_length_prefix,
-      QuicVersionLabel* version_label,
-      ParsedQuicVersion* parsed_version,
+      PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
+      bool* version_present, bool* has_length_prefix,
+      QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
       QuicConnectionId* destination_connection_id,
       QuicConnectionId* source_connection_id,
-      bool* retry_token_present,
-      absl::string_view* retry_token,
+      absl::optional<absl::string_view>* retry_token,
       std::string* detailed_error);
 
   // Serializes a packet containing |frames| into |buffer|.
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index f630867..28b7c20 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -1139,15 +1139,15 @@
   QuicConnectionId destination_connection_id, source_connection_id;
   QuicVersionLabel version_label;
   std::string detailed_error;
-  bool retry_token_present, use_length_prefix;
-  absl::string_view retry_token;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
   ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
   const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
       *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
-  EXPECT_FALSE(retry_token_present);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_FALSE(retry_token.has_value());
   EXPECT_FALSE(use_length_prefix);
   EXPECT_THAT(error_code, IsQuicNoError());
   EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
@@ -1204,17 +1204,17 @@
   QuicConnectionId destination_connection_id, source_connection_id;
   QuicVersionLabel version_label;
   std::string detailed_error;
-  bool retry_token_present, use_length_prefix;
-  absl::string_view retry_token;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
   ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
   const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
       *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
   EXPECT_THAT(error_code, IsQuicNoError());
   EXPECT_EQ("", detailed_error);
-  EXPECT_FALSE(retry_token_present);
+  EXPECT_FALSE(retry_token.has_value());
   EXPECT_FALSE(use_length_prefix);
   EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
   EXPECT_TRUE(version_flag);
@@ -1284,16 +1284,16 @@
   QuicConnectionId destination_connection_id, source_connection_id;
   QuicVersionLabel version_label = 0;
   std::string detailed_error = "";
-  bool retry_token_present, use_length_prefix;
-  absl::string_view retry_token;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
   ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
   const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
       encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
   EXPECT_THAT(error_code, IsQuicNoError());
-  EXPECT_FALSE(retry_token_present);
+  EXPECT_FALSE(retry_token.has_value());
   EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
             use_length_prefix);
   EXPECT_EQ("", detailed_error);
@@ -1312,14 +1312,14 @@
   QuicConnectionId destination_connection_id, source_connection_id;
   QuicVersionLabel version_label = 0;
   std::string detailed_error = "";
-  bool retry_token_present, use_length_prefix;
-  absl::string_view retry_token;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
   ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
   const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
       encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
   EXPECT_EQ(error_code, QUIC_INVALID_PACKET_HEADER);
   EXPECT_EQ(detailed_error, "Invalid flags.");
 }
@@ -14495,14 +14495,13 @@
   ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
   QuicConnectionId destination_connection_id = TestConnectionId(1);
   QuicConnectionId source_connection_id = TestConnectionId(2);
-  bool retry_token_present = true;
-  absl::string_view retry_token;
+  absl::optional<absl::string_view> retry_token;
   std::string detailed_error = "foobar";
   QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
       encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
   EXPECT_THAT(header_parse_result, IsQuicNoError());
   EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
   EXPECT_TRUE(version_present);
@@ -14510,7 +14509,7 @@
   EXPECT_EQ(0xcabadaba, version_label);
   EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
   EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-  EXPECT_FALSE(retry_token_present);
+  EXPECT_FALSE(retry_token.has_value());
   EXPECT_EQ("", detailed_error);
 }
 
@@ -14574,14 +14573,13 @@
   ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
   QuicConnectionId destination_connection_id = TestConnectionId(1);
   QuicConnectionId source_connection_id = TestConnectionId(2);
-  bool retry_token_present = true;
-  absl::string_view retry_token;
+  absl::optional<absl::string_view> retry_token;
   std::string detailed_error = "foobar";
   QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
       encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
       &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token_present,
-      &retry_token, &detailed_error);
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
   EXPECT_THAT(header_parse_result, IsQuicNoError());
   EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
   EXPECT_TRUE(version_present);
diff --git a/quic/core/quic_legacy_version_encapsulator_test.cc b/quic/core/quic_legacy_version_encapsulator_test.cc
index 2f74d3a..b0e11a3 100644
--- a/quic/core/quic_legacy_version_encapsulator_test.cc
+++ b/quic/core/quic_legacy_version_encapsulator_test.cc
@@ -41,15 +41,14 @@
     QuicVersionLabel version_label;
     ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
     QuicConnectionId destination_connection_id, source_connection_id;
-    bool retry_token_present;
-    absl::string_view retry_token;
+    absl::optional<absl::string_view> retry_token;
     std::string detailed_error;
     const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
         QuicEncryptedPacket(outer_buffer_, encapsulated_length_),
         kQuicDefaultConnectionIdLength, &format, &long_packet_type,
         &version_present, &has_length_prefix, &version_label, &parsed_version,
-        &destination_connection_id, &source_connection_id, &retry_token_present,
-        &retry_token, &detailed_error);
+        &destination_connection_id, &source_connection_id, &retry_token,
+        &detailed_error);
     ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
     EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
     EXPECT_TRUE(version_present);
@@ -57,7 +56,7 @@
     EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
     EXPECT_EQ(destination_connection_id, server_connection_id_);
     EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
-    EXPECT_FALSE(retry_token_present);
+    EXPECT_FALSE(retry_token.has_value());
     EXPECT_TRUE(detailed_error.empty());
   }
 
diff --git a/quic/core/quic_packets.h b/quic/core/quic_packets.h
index a3fc59d..c79e5a5 100644
--- a/quic/core/quic_packets.h
+++ b/quic/core/quic_packets.h
@@ -455,6 +455,7 @@
   ParsedQuicVersion version;
   QuicConnectionId destination_connection_id;
   QuicConnectionId source_connection_id;
+  absl::optional<absl::string_view> retry_token;
 };
 
 }  // namespace quic
diff --git a/quic/core/tls_chlo_extractor_test.cc b/quic/core/tls_chlo_extractor_test.cc
index f5a6e85..8b5ee42 100644
--- a/quic/core/tls_chlo_extractor_test.cc
+++ b/quic/core/tls_chlo_extractor_test.cc
@@ -30,16 +30,14 @@
           QuicSocketAddress(TestPeerIPAddress(), kTestPort),
           QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packet);
       std::string detailed_error;
-      bool retry_token_present;
-      absl::string_view retry_token;
+      absl::optional<absl::string_view> retry_token;
       const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
           *packet, /*expected_destination_connection_id_length=*/0,
           &packet_info.form, &packet_info.long_packet_type,
           &packet_info.version_flag, &packet_info.use_length_prefix,
           &packet_info.version_label, &packet_info.version,
           &packet_info.destination_connection_id,
-          &packet_info.source_connection_id, &retry_token_present, &retry_token,
-          &detailed_error);
+          &packet_info.source_connection_id, &retry_token, &detailed_error);
       ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
       tls_chlo_extractor_.IngestPacket(packet_info.version, packet_info.packet);
     }
@@ -127,15 +125,14 @@
       QuicSocketAddress(TestPeerIPAddress(), kTestPort),
       QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packets_[0]);
   std::string detailed_error;
-  bool retry_token_present;
-  absl::string_view retry_token;
+  absl::optional<absl::string_view> retry_token;
   const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
       *packets_[0], /*expected_destination_connection_id_length=*/0,
       &packet_info.form, &packet_info.long_packet_type,
       &packet_info.version_flag, &packet_info.use_length_prefix,
       &packet_info.version_label, &packet_info.version,
       &packet_info.destination_connection_id, &packet_info.source_connection_id,
-      &retry_token_present, &retry_token, &detailed_error);
+      &retry_token, &detailed_error);
   ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
   other_extractor.IngestPacket(packet_info.version, packet_info.packet);
   // Remove the first packet from the list.
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc
index 9a7fd85..da095dc 100644
--- a/quic/test_tools/quic_test_utils.cc
+++ b/quic/test_tools/quic_test_utils.cc
@@ -1583,18 +1583,18 @@
   QuicEncryptedPacket encrypted_packet(packet_bytes, packet_length);
   PacketHeaderFormat format;
   QuicLongHeaderType long_packet_type;
-  bool version_present, has_length_prefix, retry_token_present;
+  bool version_present, has_length_prefix;
   QuicVersionLabel version_label;
   ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
   QuicConnectionId destination_connection_id, source_connection_id;
-  absl::string_view retry_token;
+  absl::optional<absl::string_view> retry_token;
   std::string detailed_error;
   QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
       encrypted_packet,
       /*expected_destination_connection_id_length=*/0, &format,
       &long_packet_type, &version_present, &has_length_prefix, &version_label,
       &parsed_version, &destination_connection_id, &source_connection_id,
-      &retry_token_present, &retry_token, &detailed_error);
+      &retry_token, &detailed_error);
   if (error != QUIC_NO_ERROR) {
     QUIC_BUG(quic_bug_10256_9) << "Failed to parse packet: " << detailed_error;
     return false;