Do not synthesize and verify source connection id for QuicPacketHeader generated from short header packet.

Protected by FLAGS_quic_reloadable_flag_quic_do_not_synthesize_source_cid_for_short_header.

PiperOrigin-RevId: 360981332
Change-Id: Ie6d918738d76936f0f2758ce07171dfe526671ff
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index f7cb8f4..0bdc1bf 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1007,10 +1007,16 @@
     framer_.set_drop_incoming_retry_packets(true);
   }
 
+  bool skip_server_connection_id_validation =
+      framer_.do_not_synthesize_source_cid_for_short_header() &&
+      perspective_ == Perspective::IS_CLIENT &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+
   QuicConnectionId server_connection_id =
       GetServerConnectionIdAsRecipient(header, perspective_);
 
-  if (server_connection_id != server_connection_id_ &&
+  if (!skip_server_connection_id_validation &&
+      server_connection_id != server_connection_id_ &&
       !HasIncomingConnectionId(server_connection_id)) {
     if (PacketCanReplaceConnectionId(header, perspective_)) {
       QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
@@ -1038,6 +1044,14 @@
     return true;
   }
 
+  if (framer_.do_not_synthesize_source_cid_for_short_header() &&
+      perspective_ == Perspective::IS_SERVER &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(
+        quic_do_not_synthesize_source_cid_for_short_header, 3, 3);
+    return true;
+  }
+
   QuicConnectionId client_connection_id =
       GetClientConnectionIdAsRecipient(header, perspective_);
 
@@ -1069,7 +1083,10 @@
   // Check that any public reset packet with a different connection ID that was
   // routed to this QuicConnection has been redirected before control reaches
   // here.
-  QUICHE_DCHECK(GetServerConnectionIdAsRecipient(header, perspective_) ==
+  QUICHE_DCHECK((framer_.do_not_synthesize_source_cid_for_short_header() &&
+                 perspective_ == Perspective::IS_CLIENT &&
+                 header.form == IETF_QUIC_SHORT_HEADER_PACKET) ||
+                GetServerConnectionIdAsRecipient(header, perspective_) ==
                     server_connection_id_ ||
                 HasIncomingConnectionId(
                     GetServerConnectionIdAsRecipient(header, perspective_)) ||
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 83b2a65..7f4f82d 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -33,6 +33,7 @@
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t051, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_do_not_synthesize_source_cid_for_short_header, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_dont_defer_sending, true)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_alps_client, false)
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index e7565f6..2c20a44 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -433,6 +433,10 @@
   version_ = supported_versions_[0];
   QUICHE_DCHECK(version_.IsKnown())
       << ParsedQuicVersionVectorToString(supported_versions_);
+  if (do_not_synthesize_source_cid_for_short_header_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(
+        quic_do_not_synthesize_source_cid_for_short_header, 1, 3);
+  }
 }
 
 QuicFramer::~QuicFramer() {}
@@ -2701,14 +2705,28 @@
 }
 
 bool QuicFramer::ValidateReceivedConnectionIds(const QuicPacketHeader& header) {
-  if (!QuicUtils::IsConnectionIdValidForVersion(
+  bool skip_server_connection_id_validation =
+      do_not_synthesize_source_cid_for_short_header_ &&
+      perspective_ == Perspective::IS_CLIENT &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+  if (!skip_server_connection_id_validation &&
+      !QuicUtils::IsConnectionIdValidForVersion(
           GetServerConnectionIdAsRecipient(header, perspective_),
           transport_version())) {
     set_detailed_error("Received server connection ID with invalid length.");
     return false;
   }
 
-  if (version_.SupportsClientConnectionIds() &&
+  bool skip_client_connection_id_validation =
+      do_not_synthesize_source_cid_for_short_header_ &&
+      perspective_ == Perspective::IS_SERVER &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+  if (skip_client_connection_id_validation) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(
+        quic_do_not_synthesize_source_cid_for_short_header, 2, 3);
+  }
+  if (!skip_client_connection_id_validation &&
+      version_.SupportsClientConnectionIds() &&
       !QuicUtils::IsConnectionIdValidForVersion(
           GetClientConnectionIdAsRecipient(header, perspective_),
           transport_version())) {
@@ -2743,7 +2761,8 @@
     header->destination_connection_id_included = CONNECTION_ID_PRESENT;
     header->source_connection_id_included =
         header->version_flag ? CONNECTION_ID_PRESENT : CONNECTION_ID_ABSENT;
-    if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
+    if (!do_not_synthesize_source_cid_for_short_header_ &&
+        header->source_connection_id_included == CONNECTION_ID_ABSENT) {
       QUICHE_DCHECK(header->source_connection_id.IsEmpty());
       if (perspective_ == Perspective::IS_CLIENT) {
         header->source_connection_id = last_serialized_server_connection_id_;
@@ -2838,10 +2857,12 @@
       set_detailed_error("Client connection ID not supported in this version.");
       return false;
     }
-    if (perspective_ == Perspective::IS_CLIENT) {
-      header->source_connection_id = last_serialized_server_connection_id_;
-    } else {
-      header->source_connection_id = last_serialized_client_connection_id_;
+    if (!do_not_synthesize_source_cid_for_short_header_) {
+      if (perspective_ == Perspective::IS_CLIENT) {
+        header->source_connection_id = last_serialized_server_connection_id_;
+      } else {
+        header->source_connection_id = last_serialized_client_connection_id_;
+      }
     }
   }
 
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index fe395ce..5362718 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -709,6 +709,10 @@
     drop_incoming_retry_packets_ = drop_incoming_retry_packets;
   }
 
+  bool do_not_synthesize_source_cid_for_short_header() const {
+    return do_not_synthesize_source_cid_for_short_header_;
+  }
+
  private:
   friend class test::QuicFramerPeer;
 
@@ -1168,6 +1172,11 @@
   bool reject_unexpected_ietf_frame_types_ =
       GetQuicReloadableFlag(quic_reject_unexpected_ietf_frame_types);
 
+  // Indicates whether source connection ID should be synthesized when read
+  // short header packet.
+  const bool do_not_synthesize_source_cid_for_short_header_ =
+      GetQuicReloadableFlag(quic_do_not_synthesize_source_cid_for_short_header);
+
   // The length in bytes of the last packet number written to an IETF-framed
   // packet.
   size_t last_written_packet_number_length_;
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 02201b3..1ecd036 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -1476,7 +1476,9 @@
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(FramerTestConnectionId(),
             visitor_.header_->destination_connection_id);
-  EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+  if (!framer_.do_not_synthesize_source_cid_for_short_header()) {
+    EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+  }
 }
 
 // In short header packets from client to server, the client connection ID
@@ -1510,7 +1512,9 @@
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(FramerTestConnectionId(),
             visitor_.header_->destination_connection_id);
-  EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+  if (!framer_.do_not_synthesize_source_cid_for_short_header()) {
+    EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+  }
 }
 
 TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
@@ -1560,7 +1564,9 @@
   EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
   EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
   ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(), visitor_.header_->source_connection_id);
+  if (!framer_.do_not_synthesize_source_cid_for_short_header()) {
+    EXPECT_EQ(FramerTestConnectionId(), visitor_.header_->source_connection_id);
+  }
   EXPECT_FALSE(visitor_.header_->reset_flag);
   EXPECT_FALSE(visitor_.header_->version_flag);
   EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);