Add source connection ID parsing to QuicFramer::ProcessPacketDispatcher

This CL adds source connection ID parsing to ProcessPacketDispatcher when quic_do_not_override_connection_id is true. It also slightly refactors that function to remove the redundant destination_connection_id_length parameter and switches callers to use destination_connection_id.length() instead.

gfe-relnote: add source connection ID parsing, protected by disabled flag quic_do_not_override_connection_id
PiperOrigin-RevId: 250704987
Change-Id: I03b965250152175778d2bebbb0daf420d2c935a8
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index 5bf072d..0e6a71d 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -302,12 +302,11 @@
   }
   QUIC_RESTART_FLAG_COUNT(quic_no_framer_object_in_dispatcher);
   QuicPacketHeader header;
-  uint8_t destination_connection_id_length;
   std::string detailed_error;
   const QuicErrorCode error = QuicFramer::ProcessPacketDispatcher(
       packet, expected_server_connection_id_length_, &header.form,
       &header.version_flag, &last_version_label_,
-      &destination_connection_id_length, &header.destination_connection_id,
+      &header.destination_connection_id, &header.source_connection_id,
       &detailed_error);
   if (error != QUIC_NO_ERROR) {
     // Packet has framing error.
@@ -316,7 +315,7 @@
     return;
   }
   header.version = ParseQuicVersionLabel(last_version_label_);
-  if (destination_connection_id_length !=
+  if (header.destination_connection_id.length() !=
           expected_server_connection_id_length_ &&
       !should_update_expected_server_connection_id_length_ &&
       !QuicUtils::VariableLengthConnectionIdAllowedForVersion(
@@ -326,7 +325,8 @@
     return;
   }
   if (should_update_expected_server_connection_id_length_) {
-    expected_server_connection_id_length_ = destination_connection_id_length;
+    expected_server_connection_id_length_ =
+        header.destination_connection_id.length();
   }
   // TODO(fayang): Instead of passing in QuicPacketHeader, pass format,
   // version_flag, version and destination_connection_id. Combine
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 328e453..6048133 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -6056,28 +6056,30 @@
 // static
 QuicErrorCode QuicFramer::ProcessPacketDispatcher(
     const QuicEncryptedPacket& packet,
-    uint8_t expected_connection_id_length,
+    uint8_t expected_destination_connection_id_length,
     PacketHeaderFormat* format,
     bool* version_flag,
     QuicVersionLabel* version_label,
-    uint8_t* destination_connection_id_length,
     QuicConnectionId* destination_connection_id,
+    QuicConnectionId* source_connection_id,
     std::string* detailed_error) {
   QuicDataReader reader(packet.data(), packet.length());
 
+  *source_connection_id = EmptyQuicConnectionId();
   uint8_t first_byte;
   if (!reader.ReadBytes(&first_byte, 1)) {
     *detailed_error = "Unable to read first byte.";
     return QUIC_INVALID_PACKET_HEADER;
   }
+  uint8_t destination_connection_id_length = 0, source_connection_id_length = 0;
   if (!QuicUtils::IsIetfPacketHeader(first_byte)) {
     *format = GOOGLE_QUIC_PACKET;
     *version_flag = (first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
-    *destination_connection_id_length =
+    destination_connection_id_length =
         first_byte & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
-    if (*destination_connection_id_length == 0 ||
+    if (destination_connection_id_length == 0 ||
         !reader.ReadConnectionId(destination_connection_id,
-                                 *destination_connection_id_length)) {
+                                 destination_connection_id_length)) {
       *detailed_error = "Unable to read ConnectionId.";
       return QUIC_INVALID_PACKET_HEADER;
     }
@@ -6099,26 +6101,34 @@
     }
     // Set should_update_expected_server_connection_id_length to true to bypass
     // connection ID lengths validation.
-    uint8_t unused_source_connection_id_length = 0;
     uint8_t unused_expected_server_connection_id_length = 0;
     if (!ProcessAndValidateIetfConnectionIdLength(
             &reader, ParseQuicVersionLabel(*version_label),
             Perspective::IS_SERVER,
             /*should_update_expected_server_connection_id_length=*/true,
             &unused_expected_server_connection_id_length,
-            destination_connection_id_length,
-            &unused_source_connection_id_length, detailed_error)) {
+            &destination_connection_id_length, &source_connection_id_length,
+            detailed_error)) {
       return QUIC_INVALID_PACKET_HEADER;
     }
   } else {
-    // For short header packets, expected_connection_id_length is used to
-    // determine the destination_connection_id_length.
-    *destination_connection_id_length = expected_connection_id_length;
+    // For short header packets, expected_destination_connection_id_length
+    // is used to determine the destination_connection_id_length.
+    destination_connection_id_length =
+        expected_destination_connection_id_length;
+    DCHECK_EQ(0, source_connection_id_length);
   }
   // Read destination connection ID.
   if (!reader.ReadConnectionId(destination_connection_id,
-                               *destination_connection_id_length)) {
-    *detailed_error = "Unable to read Destination ConnectionId.";
+                               destination_connection_id_length)) {
+    *detailed_error = "Unable to read destination connection ID.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+  // Read source connection ID.
+  if (GetQuicRestartFlag(quic_do_not_override_connection_id) &&
+      !reader.ReadConnectionId(source_connection_id,
+                               source_connection_id_length)) {
+    *detailed_error = "Unable to read source connection ID.";
     return QUIC_INVALID_PACKET_HEADER;
   }
   return QUIC_NO_ERROR;
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index e6eecf1..992f370 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -374,18 +374,18 @@
       QuicVariableLengthIntegerLength length_length);
 
   // Lightweight parsing of |packet| and populates |format|, |version_flag|,
-  // |version_label|, |destination_connection_id_length|,
-  // |destination_connection_id| and |detailed_error|. Please note,
-  // |expected_connection_id_length| is only used to determine IETF short header
-  // packet's destination connection ID length.
+  // |version_label|, |destination_connection_id|, |source_connection_id| and
+  // |detailed_error|. Please note, |expected_destination_connection_id_length|
+  // is only used to determine IETF short header packet's destination
+  // connection ID length.
   static QuicErrorCode ProcessPacketDispatcher(
       const QuicEncryptedPacket& packet,
-      uint8_t expected_connection_id_length,
+      uint8_t expected_destination_connection_id_length,
       PacketHeaderFormat* format,
       bool* version_flag,
       QuicVersionLabel* version_label,
-      uint8_t* destination_connection_id_length,
       QuicConnectionId* destination_connection_id,
+      QuicConnectionId* source_connection_id,
       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 048cf95..5cc8470 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -909,19 +909,19 @@
 
   PacketHeaderFormat format;
   bool version_flag;
-  uint8_t destination_connection_id_length;
-  QuicConnectionId destination_connection_id;
+  QuicConnectionId destination_connection_id, source_connection_id;
   QuicVersionLabel version_label;
   std::string detailed_error;
-  EXPECT_EQ(QUIC_NO_ERROR, QuicFramer::ProcessPacketDispatcher(
-                               *encrypted, kQuicDefaultConnectionIdLength,
-                               &format, &version_flag, &version_label,
-                               &destination_connection_id_length,
-                               &destination_connection_id, &detailed_error));
+  EXPECT_EQ(QUIC_NO_ERROR,
+            QuicFramer::ProcessPacketDispatcher(
+                *encrypted, kQuicDefaultConnectionIdLength, &format,
+                &version_flag, &version_label, &destination_connection_id,
+                &source_connection_id, &detailed_error));
   EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
   EXPECT_FALSE(version_flag);
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id_length);
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
   EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
 }
 
 TEST_P(QuicFramerTest, LongPacketHeader) {
@@ -987,19 +987,68 @@
 
   PacketHeaderFormat format;
   bool version_flag;
-  uint8_t destination_connection_id_length;
-  QuicConnectionId destination_connection_id;
+  QuicConnectionId destination_connection_id, source_connection_id;
   QuicVersionLabel version_label;
   std::string detailed_error;
-  EXPECT_EQ(QUIC_NO_ERROR, QuicFramer::ProcessPacketDispatcher(
-                               *encrypted, kQuicDefaultConnectionIdLength,
-                               &format, &version_flag, &version_label,
-                               &destination_connection_id_length,
-                               &destination_connection_id, &detailed_error));
+  EXPECT_EQ(QUIC_NO_ERROR,
+            QuicFramer::ProcessPacketDispatcher(
+                *encrypted, kQuicDefaultConnectionIdLength, &format,
+                &version_flag, &version_label, &destination_connection_id,
+                &source_connection_id, &detailed_error));
   EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
   EXPECT_TRUE(version_flag);
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id_length);
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
   EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+}
+
+TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) {
+  if (framer_.transport_version() <= QUIC_VERSION_43) {
+    // This test requires an IETF long header.
+    return;
+  }
+  SetQuicRestartFlag(quic_do_not_override_connection_id, true);
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  const unsigned char type_byte =
+      framer_.transport_version() == QUIC_VERSION_44 ? 0xFC : 0xD3;
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type ZERO_RTT_PROTECTED and
+    // 4-byte packet number)
+    type_byte,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x55,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  bool version_flag = false;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label = 0;
+  std::string detailed_error = "";
+  EXPECT_EQ(QUIC_NO_ERROR,
+            QuicFramer::ProcessPacketDispatcher(
+                encrypted, kQuicDefaultConnectionIdLength, &format,
+                &version_flag, &version_label, &destination_connection_id,
+                &source_connection_id, &detailed_error));
+  EXPECT_EQ("", detailed_error);
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_flag);
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(FramerTestConnectionIdPlusOne(), source_connection_id);
 }
 
 TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
@@ -13409,8 +13458,7 @@
 
   PacketHeaderFormat format;
   bool version_flag;
-  uint8_t destination_connection_id_length;
-  QuicConnectionId destination_connection_id;
+  QuicConnectionId destination_connection_id, source_connection_id;
   QuicVersionLabel version_label;
   std::string detailed_error;
   EXPECT_EQ(QUIC_NO_ERROR,
@@ -13418,22 +13466,24 @@
                 QuicEncryptedPacket(AsChars(long_header_packet),
                                     QUIC_ARRAYSIZE(long_header_packet)),
                 kQuicDefaultConnectionIdLength, &format, &version_flag,
-                &version_label, &destination_connection_id_length,
-                &destination_connection_id, &detailed_error));
+                &version_label, &destination_connection_id,
+                &source_connection_id, &detailed_error));
   EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
   EXPECT_TRUE(version_flag);
-  EXPECT_EQ(9, destination_connection_id_length);
+  EXPECT_EQ(9, destination_connection_id.length());
   EXPECT_EQ(FramerTestConnectionIdNineBytes(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
 
-  EXPECT_EQ(QUIC_NO_ERROR,
-            QuicFramer::ProcessPacketDispatcher(
-                short_header_encrypted, 9, &format, &version_flag,
-                &version_label, &destination_connection_id_length,
-                &destination_connection_id, &detailed_error));
+  EXPECT_EQ(
+      QUIC_NO_ERROR,
+      QuicFramer::ProcessPacketDispatcher(
+          short_header_encrypted, 9, &format, &version_flag, &version_label,
+          &destination_connection_id, &source_connection_id, &detailed_error));
   EXPECT_EQ(IETF_QUIC_SHORT_HEADER_PACKET, format);
   EXPECT_FALSE(version_flag);
-  EXPECT_EQ(9, destination_connection_id_length);
+  EXPECT_EQ(9, destination_connection_id.length());
   EXPECT_EQ(FramerTestConnectionIdNineBytes(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
 }
 
 TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) {