Support LengthPrefixedConnectionIds in v99

This CL adds support for the invariants change from draft-22. It introduces a new parsing method QuicFramer::ParsePublicHeader which can parse both old and new formats, and uses it for v99 and also for all versions when gfe2_reloadable_flag_quic_use_parse_public_header is true.

gfe-relnote: change v99 encoding, protected by disabled v99 flag and by gfe2_reloadable_flag_quic_use_parse_public_header.
PiperOrigin-RevId: 260871822
Change-Id: I680d12141b2731401a818ed335af03e7c5365219
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index c6ee816..7522703 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -228,11 +228,25 @@
                        QuicStringPiece(packet.data(), packet.length()));
   ReceivedPacketInfo packet_info(self_address, peer_address, packet);
   std::string detailed_error;
-  const QuicErrorCode error = QuicFramer::ProcessPacketDispatcher(
-      packet, expected_server_connection_id_length_, &packet_info.form,
-      &packet_info.version_flag, &packet_info.version_label,
-      &packet_info.destination_connection_id, &packet_info.source_connection_id,
-      &detailed_error);
+  QuicErrorCode error;
+  if (!GetQuicReloadableFlag(quic_use_parse_public_header)) {
+    error = QuicFramer::ProcessPacketDispatcher(
+        packet, expected_server_connection_id_length_, &packet_info.form,
+        &packet_info.version_flag, &packet_info.version_label,
+        &packet_info.destination_connection_id,
+        &packet_info.source_connection_id, &detailed_error);
+  } else {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_use_parse_public_header);
+    bool retry_token_present;
+    QuicStringPiece retry_token;
+    error = QuicFramer::ParsePublicHeaderDispatcher(
+        packet, expected_server_connection_id_length_, &packet_info.form,
+        &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);
+  }
   if (error != QUIC_NO_ERROR) {
     // Packet has framing error.
     SetLastError(error);
@@ -319,7 +333,8 @@
                       << " to time-wait list.";
       StatelesslyTerminateConnection(
           server_connection_id, packet_info.form, packet_info.version_flag,
-          packet_info.version, QUIC_HANDSHAKE_FAILED, "Reject connection",
+          packet_info.use_length_prefix, packet_info.version,
+          QUIC_HANDSHAKE_FAILED, "Reject connection",
           quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
 
       DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
@@ -396,9 +411,12 @@
             packet_info.source_connection_id;
         time_wait_list_manager()->SendVersionNegotiationPacket(
             server_connection_id, client_connection_id,
-            packet_info.form != GOOGLE_QUIC_PACKET, GetSupportedVersions(),
-            packet_info.self_address, packet_info.peer_address,
-            GetPerPacketContext());
+            packet_info.form != GOOGLE_QUIC_PACKET,
+            packet_info.form != GOOGLE_QUIC_PACKET &&
+                !QuicVersionLabelUses4BitConnectionIdLength(
+                    packet_info.version_label),
+            GetSupportedVersions(), packet_info.self_address,
+            packet_info.peer_address, GetPerPacketContext());
       }
       return true;
     }
@@ -454,7 +472,8 @@
       QUIC_CODE_COUNT(quic_reject_fate_time_wait);
       StatelesslyTerminateConnection(
           server_connection_id, packet_info->form, packet_info->version_flag,
-          packet_info->version, QUIC_HANDSHAKE_FAILED, "Reject connection",
+          packet_info->use_length_prefix, packet_info->version,
+          QUIC_HANDSHAKE_FAILED, "Reject connection",
           quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
 
       DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
@@ -521,7 +540,9 @@
           VersionHasIetfInvariantHeader(connection->transport_version())
               ? IETF_QUIC_LONG_HEADER_PACKET
               : GOOGLE_QUIC_PACKET,
-          /*version_flag=*/true, connection->version(), QUIC_HANDSHAKE_FAILED,
+          /*version_flag=*/true,
+          connection->version().HasLengthPrefixedConnectionIds(),
+          connection->version(), QUIC_HANDSHAKE_FAILED,
           "Connection is closed by server before handshake confirmed",
           // Although it is our intention to send termination packets, the
           // |action| argument is not used by this call to
@@ -665,6 +686,7 @@
     QuicConnectionId server_connection_id,
     PacketHeaderFormat format,
     bool version_flag,
+    bool use_length_prefix,
     ParsedQuicVersion version,
     QuicErrorCode error_code,
     const std::string& error_details,
@@ -707,7 +729,7 @@
   std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
   termination_packets.push_back(QuicFramer::BuildVersionNegotiationPacket(
       server_connection_id, EmptyQuicConnectionId(),
-      /*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
+      /*ietf_quic=*/format != GOOGLE_QUIC_PACKET, use_length_prefix,
       /*versions=*/{}));
   time_wait_list_manager()->AddConnectionIdToTimeWait(
       server_connection_id, /*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
@@ -728,8 +750,10 @@
       server_connection_id,
       early_arrived_packets.ietf_quic ? IETF_QUIC_LONG_HEADER_PACKET
                                       : GOOGLE_QUIC_PACKET,
-      /*version_flag=*/true, early_arrived_packets.version,
-      QUIC_HANDSHAKE_FAILED, "Packets buffered for too long",
+      /*version_flag=*/true,
+      early_arrived_packets.version.HasLengthPrefixedConnectionIds(),
+      early_arrived_packets.version, QUIC_HANDSHAKE_FAILED,
+      "Packets buffered for too long",
       quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
 }
 
@@ -820,7 +844,8 @@
     QUIC_CODE_COUNT(quic_reject_stop_accepting_new_connections);
     StatelesslyTerminateConnection(
         packet_info->destination_connection_id, packet_info->form,
-        /*version_flag=*/true, packet_info->version, QUIC_HANDSHAKE_FAILED,
+        /*version_flag=*/true, packet_info->use_length_prefix,
+        packet_info->version, QUIC_HANDSHAKE_FAILED,
         "Stop accepting new connections",
         quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
     // Time wait list will reject the packet correspondingly.