Project import generated by Copybara.

PiperOrigin-RevId: 248265360
Change-Id: Ib862f0deab43c6175c46799be27bb6d2589f610f
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index 85ae602..2675428 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -1640,7 +1640,11 @@
       client_->client()->client_session()->connection();
   QuicPacketHeader* header =
       QuicConnectionPeer::GetLastHeader(client_connection);
-  EXPECT_EQ(CONNECTION_ID_ABSENT, header->destination_connection_id_included);
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    EXPECT_EQ(CONNECTION_ID_ABSENT, header->destination_connection_id_included);
+  } else {
+    EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
+  }
 }
 
 TEST_P(EndToEndTestWithTls, 8ByteConnectionId) {
@@ -3753,7 +3757,6 @@
 TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
   // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
   // which has ZERO_RTT_PROTECTED encryption level.
-  SetQuicReloadableFlag(quic_fix_termination_packets, true);
   connect_to_server_on_initialize_ =
       negotiated_version_.transport_version <= QUIC_VERSION_43;
   ASSERT_TRUE(Initialize());
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index 47f3a63..8460c7d 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -511,10 +511,16 @@
   QuicFramerPeer::SetLastSerializedConnectionId(
       QuicConnectionPeer::GetFramer(connection_), connection_id);
   ParsedQuicVersionVector versions = SupportedVersions(GetParam());
+  QuicConnectionId destination_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId source_connection_id = connection_id;
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    destination_connection_id = connection_id;
+    source_connection_id = EmptyQuicConnectionId();
+  }
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      connection_id, EmptyQuicConnectionId(), false, false, 100, "data",
-      CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER,
-      &versions, Perspective::IS_SERVER));
+      destination_connection_id, source_connection_id, false, false, 100,
+      "data", CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT,
+      PACKET_4BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
   std::unique_ptr<QuicReceivedPacket> received(
       ConstructReceivedPacket(*packet, QuicTime::Zero()));
   // Change the last byte of the encrypted data.
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
index 6aa48b2..5eec97d 100644
--- a/quic/core/http/quic_spdy_session.cc
+++ b/quic/core/http/quic_spdy_session.cc
@@ -519,14 +519,13 @@
   return frame.size();
 }
 
-size_t QuicSpdySession::SendMaxHeaderListSize(size_t value) {
+void QuicSpdySession::SendMaxHeaderListSize(size_t value) {
   SpdySettingsIR settings_frame;
   settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, value);
 
   SpdySerializedFrame frame(spdy_framer_.SerializeFrame(settings_frame));
   headers_stream()->WriteOrBufferData(
       QuicStringPiece(frame.data(), frame.size()), false, nullptr);
-  return frame.size();
 }
 
 QpackEncoder* QuicSpdySession::qpack_encoder() {
@@ -563,7 +562,7 @@
 
 bool QuicSpdySession::UsesPendingStreams() const {
   DCHECK(VersionHasControlStreams(connection()->transport_version()));
-  return true;
+  return false;
 }
 
 size_t QuicSpdySession::WriteHeadersOnHeadersStreamImpl(
diff --git a/quic/core/http/quic_spdy_session.h b/quic/core/http/quic_spdy_session.h
index 65fa346..1935a2f 100644
--- a/quic/core/http/quic_spdy_session.h
+++ b/quic/core/http/quic_spdy_session.h
@@ -135,7 +135,7 @@
                                   spdy::SpdyHeaderBlock headers);
 
   // Sends SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame.
-  size_t SendMaxHeaderListSize(size_t value);
+  void SendMaxHeaderListSize(size_t value);
 
   QpackEncoder* qpack_encoder();
   QpackDecoder* qpack_decoder();
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 347a5f7..26ec153 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -421,7 +421,7 @@
   if (!VersionHasControlStreams(transport_version())) {
     return;
   }
-  EXPECT_TRUE(session_.UsesPendingStreams());
+  EXPECT_FALSE(session_.UsesPendingStreams());
 }
 
 TEST_P(QuicSpdySessionTestServer, PeerAddress) {
@@ -1602,7 +1602,7 @@
   if (!VersionHasControlStreams(transport_version())) {
     return;
   }
-  EXPECT_TRUE(session_.UsesPendingStreams());
+  EXPECT_FALSE(session_.UsesPendingStreams());
 }
 
 TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 6798f63..af388a9 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -346,8 +346,6 @@
       supports_release_time_(false),
       release_time_into_future_(QuicTime::Delta::Zero()),
       no_version_negotiation_(supported_versions.size() == 1),
-      fix_termination_packets_(
-          GetQuicReloadableFlag(quic_fix_termination_packets)),
       send_ack_when_on_can_write_(false),
       retry_has_been_parsed_(false),
       validate_packet_number_post_decryption_(
@@ -816,25 +814,26 @@
 
 bool QuicConnection::OnUnauthenticatedPublicHeader(
     const QuicPacketHeader& header) {
-  if (header.destination_connection_id == connection_id_ ||
-      HasIncomingConnectionId(header.destination_connection_id)) {
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsRecipient(header, perspective_);
+
+  if (server_connection_id == connection_id_ ||
+      HasIncomingConnectionId(server_connection_id)) {
     return true;
   }
 
   if (PacketCanReplaceConnectionId(header, perspective_)) {
     QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
-                    << header.destination_connection_id << " instead of "
-                    << connection_id_;
+                    << server_connection_id << " instead of " << connection_id_;
     return true;
   }
 
   ++stats_.packets_dropped;
   QUIC_DLOG(INFO) << ENDPOINT
                   << "Ignoring packet from unexpected ConnectionId: "
-                  << header.destination_connection_id << " instead of "
-                  << connection_id_;
+                  << server_connection_id << " instead of " << connection_id_;
   if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnIncorrectConnectionId(header.destination_connection_id);
+    debug_visitor_->OnIncorrectConnectionId(server_connection_id);
   }
   // If this is a server, the dispatcher routes each packet to the
   // QuicConnection responsible for the packet's connection ID.  So if control
@@ -851,8 +850,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.
-  DCHECK(header.destination_connection_id == connection_id_ ||
-         HasIncomingConnectionId(header.destination_connection_id) ||
+  DCHECK(GetServerConnectionIdAsRecipient(header, perspective_) ==
+             connection_id_ ||
+         HasIncomingConnectionId(
+             GetServerConnectionIdAsRecipient(header, perspective_)) ||
          PacketCanReplaceConnectionId(header, perspective_));
 
   if (!packet_generator_.IsPendingPacketEmpty()) {
@@ -1480,7 +1481,8 @@
   }
 
   QUIC_DVLOG(1) << ENDPOINT << "Got packet " << last_header_.packet_number
-                << " for " << last_header_.destination_connection_id;
+                << " for "
+                << GetServerConnectionIdAsRecipient(last_header_, perspective_);
 
   QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
       << ENDPOINT << "Received a padded PING packet. is_probing: "
@@ -1489,7 +1491,8 @@
   if (perspective_ == Perspective::IS_CLIENT) {
     QUIC_DVLOG(1) << ENDPOINT
                   << "Received a speculative connectivity probing packet for "
-                  << last_header_.destination_connection_id
+                  << GetServerConnectionIdAsRecipient(last_header_,
+                                                      perspective_)
                   << " from ip:port: " << last_packet_source_address_.ToString()
                   << " to ip:port: "
                   << last_packet_destination_address_.ToString();
@@ -1500,7 +1503,8 @@
     // This node is not a client (is a server) AND the received packet was
     // connectivity-probing, send an appropriate response.
     QUIC_DVLOG(1) << ENDPOINT << "Received a connectivity probing packet for "
-                  << last_header_.destination_connection_id
+                  << GetServerConnectionIdAsRecipient(last_header_,
+                                                      perspective_)
                   << " from ip:port: " << last_packet_source_address_.ToString()
                   << " to ip:port: "
                   << last_packet_destination_address_.ToString();
@@ -3085,10 +3089,7 @@
 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error,
                                                const std::string& details) {
   QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet.";
-  if (fix_termination_packets_) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_fix_termination_packets);
-    SetDefaultEncryptionLevel(GetConnectionCloseEncryptionLevel());
-  }
+  SetDefaultEncryptionLevel(GetConnectionCloseEncryptionLevel());
   ClearQueuedPackets();
   // If there was a packet write error, write the smallest close possible.
   AckBundling ack_mode = (error == QUIC_PACKET_WRITE_ERROR) ? NO_ACK : SEND_ACK;
@@ -4008,7 +4009,6 @@
 }
 
 EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
-  DCHECK(fix_termination_packets_);
   if (perspective_ == Perspective::IS_CLIENT) {
     return encryption_level_;
   }
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 47816de..413a582 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -1503,9 +1503,6 @@
   // vector to improve performance since it is expected to be very small.
   std::vector<QuicConnectionId> incoming_connection_ids_;
 
-  // Latched value of quic_fix_termination_packets.
-  const bool fix_termination_packets_;
-
   // Indicates whether an ACK needs to be sent in OnCanWrite(). Only used when
   // deprecate_ack_bundling_mode is true.
   // TODO(fayang): Remove this when ACK sending logic is moved to received
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 82c493c..0bae7d5 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -1107,7 +1107,8 @@
     header.destination_connection_id = connection_id_;
     header.packet_number_length = packet_number_length_;
     header.destination_connection_id_included = connection_id_included_;
-    if (peer_framer_.transport_version() > QUIC_VERSION_43 &&
+    if ((peer_framer_.transport_version() > QUIC_VERSION_43 ||
+         GetQuicRestartFlag(quic_do_not_override_connection_id)) &&
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
     }
@@ -1116,10 +1117,14 @@
       header.version_flag = true;
       header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
       header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-      if (peer_framer_.perspective() == Perspective::IS_SERVER) {
-        header.source_connection_id = connection_id_;
-        header.source_connection_id_included = CONNECTION_ID_PRESENT;
-      }
+    }
+    if ((GetQuicRestartFlag(quic_do_not_override_connection_id) ||
+         (level == ENCRYPTION_INITIAL &&
+          peer_framer_.version().KnowsWhichDecrypterToUse())) &&
+        header.version_flag &&
+        peer_framer_.perspective() == Perspective::IS_SERVER) {
+      header.source_connection_id = connection_id_;
+      header.source_connection_id_included = CONNECTION_ID_PRESENT;
     }
     header.packet_number = QuicPacketNumber(number);
     QuicFrames frames;
@@ -1316,9 +1321,15 @@
     }
     // Set connection_id to peer's in memory representation as this data packet
     // is created by peer_framer.
-    header.destination_connection_id = connection_id_;
-    header.packet_number_length = packet_number_length_;
-    header.destination_connection_id_included = connection_id_included_;
+    if (GetQuicRestartFlag(quic_do_not_override_connection_id) &&
+        peer_framer_.perspective() == Perspective::IS_SERVER) {
+      header.source_connection_id = connection_id_;
+      header.source_connection_id_included = connection_id_included_;
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    } else {
+      header.destination_connection_id = connection_id_;
+      header.destination_connection_id_included = connection_id_included_;
+    }
     if (peer_framer_.transport_version() > QUIC_VERSION_43 &&
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
@@ -1331,6 +1342,7 @@
         }
       }
     }
+    header.packet_number_length = packet_number_length_;
     header.packet_number = QuicPacketNumber(number);
 
     QuicFrames frames;
@@ -1357,13 +1369,22 @@
     QuicPacketHeader header;
     // Set connection_id to peer's in memory representation as this connection
     // close packet is created by peer_framer.
-    header.destination_connection_id = connection_id_;
-    header.packet_number = QuicPacketNumber(number);
-    if (peer_framer_.transport_version() > QUIC_VERSION_43 &&
+    if (GetQuicRestartFlag(quic_do_not_override_connection_id) &&
         peer_framer_.perspective() == Perspective::IS_SERVER) {
+      header.source_connection_id = connection_id_;
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      if (peer_framer_.transport_version() <= QUIC_VERSION_43) {
+        header.source_connection_id_included = CONNECTION_ID_PRESENT;
+      }
+    } else {
+      header.destination_connection_id = connection_id_;
+      if (peer_framer_.transport_version() > QUIC_VERSION_43) {
+        header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      }
     }
 
+    header.packet_number = QuicPacketNumber(number);
+
     QuicConnectionCloseFrame qccf(QUIC_PEER_GOING_AWAY);
     if (peer_framer_.transport_version() == QUIC_VERSION_99) {
       // Default close-type is Google QUIC. If doing IETF/V99 then
@@ -6764,8 +6785,12 @@
   // Now force another packet.  The connection should transition into
   // NEGOTIATED_VERSION state and tell the packet creator to StopSendingVersion.
   QuicPacketHeader header;
-  header.destination_connection_id = connection_id_;
   header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    header.destination_connection_id = connection_id_;
+  } else {
+    header.source_connection_id = connection_id_;
+  }
   header.packet_number = QuicPacketNumber(12);
   header.version_flag = false;
   QuicFrames frames;
@@ -6865,9 +6890,18 @@
 TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
   // Construct a packet with stream frame and connection close frame.
   QuicPacketHeader header;
-  header.destination_connection_id = connection_id_;
-  if (peer_framer_.transport_version() > QUIC_VERSION_43) {
+  if (GetQuicRestartFlag(quic_do_not_override_connection_id) &&
+      peer_framer_.perspective() == Perspective::IS_SERVER) {
+    header.source_connection_id = connection_id_;
     header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    if (peer_framer_.transport_version() <= QUIC_VERSION_43) {
+      header.source_connection_id_included = CONNECTION_ID_PRESENT;
+    }
+  } else {
+    header.destination_connection_id = connection_id_;
+    if (peer_framer_.transport_version() > QUIC_VERSION_43) {
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    }
   }
   header.packet_number = QuicPacketNumber(1);
   header.version_flag = false;
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index eedb45a..9633053 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -1570,7 +1570,8 @@
     const QuicPacketHeader& header) {
   DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
 
-  QuicVersionNegotiationPacket packet(header.destination_connection_id);
+  QuicVersionNegotiationPacket packet(
+      GetServerConnectionIdAsRecipient(header, perspective_));
   // Try reading at least once to raise error if the packet is invalid.
   do {
     QuicVersionLabel version_label;
@@ -1982,7 +1983,8 @@
 
 bool QuicFramer::ProcessPublicResetPacket(QuicDataReader* reader,
                                           const QuicPacketHeader& header) {
-  QuicPublicResetPacket packet(header.destination_connection_id);
+  QuicPublicResetPacket packet(
+      GetServerConnectionIdAsRecipient(header, perspective_));
 
   std::unique_ptr<CryptoHandshakeMessage> reset(
       CryptoFramer::ParseMessage(reader->ReadRemainingPayload()));
@@ -2061,8 +2063,15 @@
     DCHECK_EQ(Perspective::IS_SERVER, perspective_);
     public_flags |= PACKET_PUBLIC_FLAGS_NONCE;
   }
-  DCHECK_EQ(CONNECTION_ID_ABSENT, header.source_connection_id_included);
-  switch (header.destination_connection_id_included) {
+
+  QuicConnectionId connection_id =
+      GetServerConnectionIdAsSender(header, perspective_);
+  QuicConnectionIdIncluded connection_id_included =
+      GetServerConnectionIdIncludedAsSender(header, perspective_);
+  DCHECK_EQ(CONNECTION_ID_ABSENT,
+            GetClientConnectionIdIncludedAsSender(header, perspective_));
+
+  switch (connection_id_included) {
     case CONNECTION_ID_ABSENT:
       if (!writer->WriteUInt8(public_flags |
                               PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
@@ -2071,10 +2080,9 @@
       break;
     case CONNECTION_ID_PRESENT:
       QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(
-          header.destination_connection_id, transport_version()))
+          connection_id, transport_version()))
           << "AppendPacketHeader: attempted to use connection ID "
-          << header.destination_connection_id
-          << " which is invalid with version "
+          << connection_id << " which is invalid with version "
           << QuicVersionToString(transport_version());
 
       public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
@@ -2082,12 +2090,12 @@
         public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD;
       }
       if (!writer->WriteUInt8(public_flags) ||
-          !writer->WriteConnectionId(header.destination_connection_id)) {
+          !writer->WriteConnectionId(connection_id)) {
         return false;
       }
       break;
   }
-  last_serialized_connection_id_ = header.destination_connection_id;
+  last_serialized_connection_id_ = connection_id;
 
   if (header.version_flag) {
     DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
@@ -2153,10 +2161,12 @@
                                         QuicDataWriter* writer,
                                         size_t* length_field_offset) {
   QUIC_DVLOG(1) << ENDPOINT << "Appending IETF header: " << header;
-  QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(
-      header.destination_connection_id, transport_version()))
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsSender(header, perspective_);
+  QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(server_connection_id,
+                                                        transport_version()))
       << "AppendIetfPacketHeader: attempted to use connection ID "
-      << header.destination_connection_id << " which is invalid with version "
+      << server_connection_id << " which is invalid with version "
       << QuicVersionToString(transport_version());
   if (!AppendIetfHeaderTypeByte(header, writer)) {
     return false;
@@ -2184,7 +2194,7 @@
     return false;
   }
 
-  last_serialized_connection_id_ = header.destination_connection_id;
+  last_serialized_connection_id_ = server_connection_id;
 
   if (QuicVersionHasLongHeaderLengths(transport_version()) &&
       header.version_flag) {
@@ -2307,18 +2317,26 @@
     return false;
   }
 
+  QuicConnectionId* header_connection_id = &header->destination_connection_id;
+  QuicConnectionIdIncluded* header_connection_id_included =
+      &header->destination_connection_id_included;
+  if (perspective_ == Perspective::IS_CLIENT &&
+      GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    header_connection_id = &header->source_connection_id;
+    header_connection_id_included = &header->source_connection_id_included;
+  }
   switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) {
     case PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID:
-      if (!reader->ReadConnectionId(&header->destination_connection_id,
+      if (!reader->ReadConnectionId(header_connection_id,
                                     kQuicDefaultConnectionIdLength)) {
         set_detailed_error("Unable to read ConnectionId.");
         return false;
       }
-      header->destination_connection_id_included = CONNECTION_ID_PRESENT;
+      *header_connection_id_included = CONNECTION_ID_PRESENT;
       break;
     case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID:
-      header->destination_connection_id_included = CONNECTION_ID_ABSENT;
-      header->destination_connection_id = last_serialized_connection_id_;
+      *header_connection_id_included = CONNECTION_ID_ABSENT;
+      *header_connection_id = last_serialized_connection_id_;
       break;
   }
 
@@ -2679,13 +2697,21 @@
     return false;
   }
 
-  if (header->source_connection_id_included == CONNECTION_ID_PRESENT) {
-    // Set destination connection ID to source connection ID.
-    DCHECK_EQ(EmptyQuicConnectionId(), header->destination_connection_id);
-    header->destination_connection_id = header->source_connection_id;
-  } else if (header->destination_connection_id_included ==
-             CONNECTION_ID_ABSENT) {
-    header->destination_connection_id = last_serialized_connection_id_;
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    if (header->source_connection_id_included == CONNECTION_ID_PRESENT) {
+      // Set destination connection ID to source connection ID.
+      DCHECK_EQ(EmptyQuicConnectionId(), header->destination_connection_id);
+      header->destination_connection_id = header->source_connection_id;
+    } else if (header->destination_connection_id_included ==
+               CONNECTION_ID_ABSENT) {
+      header->destination_connection_id = last_serialized_connection_id_;
+    }
+  } else {
+    QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 5, 5);
+    if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
+      DCHECK_EQ(EmptyQuicConnectionId(), header->source_connection_id);
+      header->source_connection_id = last_serialized_connection_id_;
+    }
   }
 
   return true;
@@ -4318,7 +4344,6 @@
   QuicDecrypter* decrypter = decrypter_[level].get();
   QuicDecrypter* alternative_decrypter = nullptr;
   if (version().KnowsWhichDecrypterToUse()) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_v44_disable_trial_decryption);
     if (header.form == GOOGLE_QUIC_PACKET) {
       QUIC_BUG << "Attempted to decrypt GOOGLE_QUIC_PACKET with a version that "
                   "knows which decrypter to use";
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 96f335c..e83fd1b 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -1069,8 +1069,12 @@
   EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
   EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    EXPECT_EQ(FramerTestConnectionId(),
+              visitor_.header_->destination_connection_id);
+  } else {
+    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);
@@ -5726,6 +5730,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -5737,7 +5742,7 @@
   // clang-format off
   unsigned char packet[kMaxOutgoingPacketSize] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -5814,6 +5819,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -5828,7 +5834,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -5957,6 +5963,7 @@
 }
 
 TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -5969,7 +5976,7 @@
   // clang-format off
   unsigned char packet[kMaxOutgoingPacketSize] = {
     // public flags (8 byte connection_id and 4 byte packet number)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -6046,6 +6053,7 @@
 }
 
 TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -6058,7 +6066,7 @@
   // clang-format off
   unsigned char packet[kMaxOutgoingPacketSize] = {
     // public flags (8 byte connection_id and 2 byte packet number)
-    0x18,
+    0x1C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -6135,6 +6143,7 @@
 }
 
 TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -6147,7 +6156,7 @@
   // clang-format off
   unsigned char packet[kMaxOutgoingPacketSize] = {
     // public flags (8 byte connection_id and 1 byte packet number)
-    0x08,
+    0x0C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -6224,6 +6233,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildStreamFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -6241,7 +6251,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -6475,6 +6485,7 @@
     // CRYPTO frames aren't supported prior to v46.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -6622,6 +6633,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -6637,7 +6649,7 @@
   // clang-format off
   unsigned char packet[] = {
       // public flags (8 byte connection_id)
-      0x28,
+      0x2C,
       // connection_id
       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
       // packet number
@@ -6738,6 +6750,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -6752,7 +6765,7 @@
   // clang-format off
   unsigned char packet[] = {
       // public flags (8 byte connection_id)
-      0x28,
+      0x2C,
       // connection_id
       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
       // packet number
@@ -6854,6 +6867,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -6873,7 +6887,7 @@
   // clang-format off
   unsigned char packet[] = {
       // public flags (8 byte connection_id)
-      0x28,
+      0x2C,
       // connection_id
       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
       // packet number
@@ -7044,6 +7058,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -7065,7 +7080,7 @@
   // clang-format off
   unsigned char packet[] = {
       // public flags (8 byte connection_id)
-      0x28,
+      0x2C,
       // connection_id
       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
       // packet number
@@ -7451,6 +7466,7 @@
   if (version_.transport_version > QUIC_VERSION_43) {
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -7465,7 +7481,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -7488,6 +7504,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -7506,7 +7523,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -7604,6 +7621,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildCloseFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -7626,7 +7644,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -7732,6 +7750,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -7752,7 +7771,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -7974,6 +7993,7 @@
     // Versions other than 99 do not have ApplicationClose
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8024,6 +8044,7 @@
     // Versions other than 99 do not have this frame.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8101,6 +8122,7 @@
     // This frame type is not supported in version 99.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8117,7 +8139,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -8208,6 +8230,7 @@
     // This frame type is not supported in version 99.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8224,7 +8247,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -8394,6 +8417,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8409,7 +8433,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -8501,6 +8525,7 @@
     // This frame is available only in this version.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8545,6 +8570,7 @@
     // This frame is available only in this version.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8584,6 +8610,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildBlockedPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8607,7 +8634,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -8683,6 +8710,7 @@
 }
 
 TEST_P(QuicFramerTest, BuildPingPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8694,7 +8722,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -8763,6 +8791,7 @@
   if (framer_.transport_version() <= QUIC_VERSION_44) {
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8854,6 +8883,7 @@
 // Test that the connectivity probing packet is serialized correctly as a
 // padded PING packet.
 TEST_P(QuicFramerTest, BuildConnectivityProbingPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -8863,7 +8893,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -9201,6 +9231,7 @@
 
 // Test that the MTU discovery packet is serialized correctly as a PING packet.
 TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -9212,7 +9243,7 @@
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
-    0x28,
+    0x2C,
     // connection_id
     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
     // packet number
@@ -11322,6 +11353,7 @@
     // This frame is only for version 99.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -11422,6 +11454,7 @@
     // This frame is only for version 99.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
@@ -12484,6 +12517,7 @@
     // This frame is only for version 99.
     return;
   }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketHeader header;
   header.destination_connection_id = FramerTestConnectionId();
   header.reset_flag = false;
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index dddc8e7..0ffcc37 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -114,7 +114,7 @@
   max_packet_length_ = length;
   max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
   QUIC_BUG_IF(max_plaintext_size_ - PacketHeaderSize() <
-              MinPlaintextPacketSize())
+              MinPlaintextPacketSize(framer_->version()))
       << "Attempted to set max packet length too small";
 }
 
@@ -466,8 +466,8 @@
     QUIC_BUG << "AppendStreamFrame failed";
     return;
   }
-  if (plaintext_bytes_written < MinPlaintextPacketSize() &&
-      !writer.WritePaddingBytes(MinPlaintextPacketSize() -
+  if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
+      !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
                                 plaintext_bytes_written)) {
     QUIC_BUG << "Unable to add padding bytes";
     return;
@@ -735,9 +735,32 @@
                           nullptr, 0, false, false);
 }
 
+QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    return connection_id_;
+  }
+  QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 1, 5);
+  if (framer_->perspective() == Perspective::IS_SERVER) {
+    return EmptyQuicConnectionId();
+  }
+  return connection_id_;
+}
+
+QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    return connection_id_;
+  }
+  QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 6, 6);
+  if (framer_->perspective() == Perspective::IS_CLIENT) {
+    return EmptyQuicConnectionId();
+  }
+  return connection_id_;
+}
+
 QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
     const {
-  if (framer_->transport_version() > QUIC_VERSION_43) {
+  if (framer_->transport_version() > QUIC_VERSION_43 ||
+      GetQuicRestartFlag(quic_do_not_override_connection_id)) {
     // Packets sent by client always include destination connection ID, and
     // those sent by the server do not include destination connection ID.
     return framer_->perspective() == Perspective::IS_CLIENT
@@ -753,6 +776,11 @@
   if (HasIetfLongHeader() && framer_->perspective() == Perspective::IS_SERVER) {
     return CONNECTION_ID_PRESENT;
   }
+  if (GetQuicRestartFlag(quic_do_not_override_connection_id) &&
+      framer_->perspective() == Perspective::IS_SERVER) {
+    QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 2, 5);
+    return connection_id_included_;
+  }
   return CONNECTION_ID_ABSENT;
 }
 
@@ -761,7 +789,8 @@
   DCHECK(QuicUtils::IsConnectionIdValidForVersion(connection_id_,
                                                   transport_version()));
   return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
-             ? static_cast<QuicConnectionIdLength>(connection_id_.length())
+             ? static_cast<QuicConnectionIdLength>(
+                   GetDestinationConnectionId().length())
              : PACKET_0BYTE_CONNECTION_ID;
 }
 
@@ -769,7 +798,8 @@
   DCHECK(QuicUtils::IsConnectionIdValidForVersion(connection_id_,
                                                   transport_version()));
   return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
-             ? static_cast<QuicConnectionIdLength>(connection_id_.length())
+             ? static_cast<QuicConnectionIdLength>(
+                   GetSourceConnectionId().length())
              : PACKET_0BYTE_CONNECTION_ID;
 }
 
@@ -820,10 +850,10 @@
 }
 
 void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
-  header->destination_connection_id = connection_id_;
+  header->destination_connection_id = GetDestinationConnectionId();
   header->destination_connection_id_included =
       GetDestinationConnectionIdIncluded();
-  header->source_connection_id = connection_id_;
+  header->source_connection_id = GetSourceConnectionId();
   header->source_connection_id_included = GetSourceConnectionIdIncluded();
   header->reset_flag = false;
   header->version_flag = IncludeVersionInHeader();
@@ -931,9 +961,11 @@
   if (framer_->version().HasHeaderProtection()) {
     size_t frame_bytes = PacketSize() - PacketHeaderSize();
 
-    if (frame_bytes + pending_padding_bytes_ < MinPlaintextPacketSize() &&
+    if (frame_bytes + pending_padding_bytes_ <
+            MinPlaintextPacketSize(framer_->version()) &&
         !needs_full_padding_) {
-      extra_padding_bytes = MinPlaintextPacketSize() - frame_bytes;
+      extra_padding_bytes =
+          MinPlaintextPacketSize(framer_->version()) - frame_bytes;
     }
   }
 
@@ -1063,8 +1095,9 @@
          packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
 }
 
-size_t QuicPacketCreator::MinPlaintextPacketSize() const {
-  if (!framer_->version().HasHeaderProtection()) {
+size_t QuicPacketCreator::MinPlaintextPacketSize(
+    const ParsedQuicVersion& version) {
+  if (!version.HasHeaderProtection()) {
     return 0;
   }
   // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
diff --git a/quic/core/quic_packet_creator.h b/quic/core/quic_packet_creator.h
index bceeae9..6e1f7a2 100644
--- a/quic/core/quic_packet_creator.h
+++ b/quic/core/quic_packet_creator.h
@@ -210,6 +210,12 @@
   // Returns a dummy packet that is valid but contains no useful information.
   static SerializedPacket NoPacket();
 
+  // Returns the destination connection ID to send over the wire.
+  QuicConnectionId GetDestinationConnectionId() const;
+
+  // Returns the source connection ID to send over the wire.
+  QuicConnectionId GetSourceConnectionId() const;
+
   // Returns length of destination connection ID to send over the wire.
   QuicConnectionIdLength GetDestinationConnectionIdLength() const;
 
@@ -283,7 +289,7 @@
   }
 
   // Returns the minimum size that the plaintext of a packet must be.
-  size_t MinPlaintextPacketSize() const;
+  static size_t MinPlaintextPacketSize(const ParsedQuicVersion& version);
 
  private:
   friend class test::QuicPacketCreatorPeer;
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index 637960f..f87715b 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -653,7 +653,8 @@
   const size_t overhead =
       GetPacketHeaderOverhead(client_framer_.transport_version()) +
       GetEncryptionOverhead();
-  for (size_t i = overhead + creator_.MinPlaintextPacketSize();
+  for (size_t i = overhead + QuicPacketCreator::MinPlaintextPacketSize(
+                                 client_framer_.version());
        i < overhead + 100; ++i) {
     SCOPED_TRACE(i);
     creator_.SetMaxPacketLength(i);
@@ -1862,6 +1863,16 @@
   DeleteFrames(&frames_);
 }
 
+TEST_P(QuicPacketCreatorTest, GetConnectionId) {
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+    EXPECT_EQ(TestConnectionId(2), creator_.GetSourceConnectionId());
+    return;
+  }
+  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
index 1d66439..705142a 100644
--- a/quic/core/quic_packet_generator_test.cc
+++ b/quic/core/quic_packet_generator_test.cc
@@ -650,6 +650,9 @@
     // frames, so the expected packet length differs slightly.
     expected_packet_length = 28;
   }
+  if (framer_.version().HasHeaderProtection()) {
+    expected_packet_length = 29;
+  }
   EXPECT_EQ(expected_packet_length, packets_[0].encrypted_length);
 }
 
diff --git a/quic/core/quic_packets.cc b/quic/core/quic_packets.cc
index 9b2cb09..3732af3 100644
--- a/quic/core/quic_packets.cc
+++ b/quic/core/quic_packets.cc
@@ -16,6 +16,47 @@
 
 namespace quic {
 
+QuicConnectionId GetServerConnectionIdAsRecipient(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_SERVER ||
+      !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    return header.destination_connection_id;
+  }
+  return header.source_connection_id;
+}
+
+QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
+                                               Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT ||
+      !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    return header.destination_connection_id;
+  }
+  QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 3, 5);
+  return header.source_connection_id;
+}
+
+QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT ||
+      !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    return header.destination_connection_id_included;
+  }
+  QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 4, 5);
+  return header.source_connection_id_included;
+}
+
+QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT ||
+      !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    return header.source_connection_id_included;
+  }
+  return header.destination_connection_id_included;
+}
+
 QuicConnectionIdLength GetIncludedConnectionIdLength(
     QuicConnectionId connection_id,
     QuicConnectionIdIncluded connection_id_included) {
@@ -74,7 +115,13 @@
     return kPacketHeaderTypeSize + destination_connection_id_length +
            packet_number_length;
   }
+  // Google QUIC versions <= 43 can only carry one connection ID.
+  DCHECK(destination_connection_id_length == 0 ||
+         source_connection_id_length == 0);
+  DCHECK(source_connection_id_length == 0 ||
+         GetQuicRestartFlag(quic_do_not_override_connection_id));
   return kPublicFlagsSize + destination_connection_id_length +
+         source_connection_id_length +
          (include_version ? kQuicVersionSize : 0) + packet_number_length +
          (include_diversification_nonce ? kDiversificationNonceSize : 0);
 }
diff --git a/quic/core/quic_packets.h b/quic/core/quic_packets.h
index 3ced31f..d3c2600 100644
--- a/quic/core/quic_packets.h
+++ b/quic/core/quic_packets.h
@@ -32,6 +32,32 @@
 class QuicPacket;
 struct QuicPacketHeader;
 
+// Returns the destination connection ID of |header| when |perspective| is
+// server, and the source connection ID when |perspective| is client.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetServerConnectionIdAsRecipient(const QuicPacketHeader& header,
+                                 Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// client, and the source connection ID when |perspective| is server.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetServerConnectionIdAsSender(const QuicPacketHeader& header,
+                              Perspective perspective);
+
+// Returns the destination connection ID included of |header| when |perspective|
+// is client, and the source connection ID included when |perspective| is
+// server.
+QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
+GetServerConnectionIdIncludedAsSender(const QuicPacketHeader& header,
+                                      Perspective perspective);
+
+// Returns the destination connection ID included of |header| when |perspective|
+// is server, and the source connection ID included when |perspective| is
+// client.
+QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
+GetClientConnectionIdIncludedAsSender(const QuicPacketHeader& header,
+                                      Perspective perspective);
+
 // Number of connection ID bytes that are actually included over the wire.
 QUIC_EXPORT_PRIVATE QuicConnectionIdLength
 GetIncludedConnectionIdLength(QuicConnectionId connection_id,
diff --git a/quic/core/quic_packets_test.cc b/quic/core/quic_packets_test.cc
new file mode 100644
index 0000000..9ea369e
--- /dev/null
+++ b/quic/core/quic_packets_test.cc
@@ -0,0 +1,91 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+QuicPacketHeader CreateFakePacketHeader() {
+  QuicPacketHeader header;
+  header.destination_connection_id = TestConnectionId(1);
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id = TestConnectionId(2);
+  header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  return header;
+}
+
+class QuicPacketsTest : public QuicTest {};
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdAsRecipient) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    EXPECT_EQ(TestConnectionId(1),
+              GetServerConnectionIdAsRecipient(header, Perspective::IS_SERVER));
+    EXPECT_EQ(TestConnectionId(1),
+              GetServerConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
+    return;
+  }
+
+  EXPECT_EQ(TestConnectionId(1),
+            GetServerConnectionIdAsRecipient(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(2),
+            GetServerConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    EXPECT_EQ(TestConnectionId(1),
+              GetServerConnectionIdAsSender(header, Perspective::IS_SERVER));
+    EXPECT_EQ(TestConnectionId(1),
+              GetServerConnectionIdAsSender(header, Perspective::IS_CLIENT));
+    return;
+  }
+
+  EXPECT_EQ(TestConnectionId(2),
+            GetServerConnectionIdAsSender(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(1),
+            GetServerConnectionIdAsSender(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdIncludedAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
+                                         header, Perspective::IS_SERVER));
+    EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
+                                         header, Perspective::IS_CLIENT));
+    return;
+  }
+
+  EXPECT_EQ(CONNECTION_ID_ABSENT, GetServerConnectionIdIncludedAsSender(
+                                      header, Perspective::IS_SERVER));
+  EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
+                                       header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetClientConnectionIdIncludedAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+    EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
+                                        header, Perspective::IS_SERVER));
+    EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
+                                        header, Perspective::IS_CLIENT));
+    return;
+  }
+
+  EXPECT_EQ(CONNECTION_ID_PRESENT, GetClientConnectionIdIncludedAsSender(
+                                       header, Perspective::IS_SERVER));
+  EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
+                                      header, Perspective::IS_CLIENT));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index a27b77c..a1f4d8e 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -38,9 +38,7 @@
 }
 
 bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
-  return (GetQuicReloadableFlag(quic_v44_disable_trial_decryption) &&
-          transport_version >= QUIC_VERSION_44) ||
-         transport_version == QUIC_VERSION_99 ||
+  return transport_version >= QUIC_VERSION_47 ||
          handshake_protocol == PROTOCOL_TLS1_3;
 }
 
@@ -50,14 +48,7 @@
 }
 
 bool ParsedQuicVersion::HasHeaderProtection() const {
-  // Header protection support hasn't landed yet, so right now no version
-  // supports header protection. When support for header protection lands, this
-  // check will be revised to return true for versions that support header
-  // protection (i.e. transport_version == QUIC_VERSION_99).
-  //
-  // Returning false right now allows code to land in chromium that needs to be
-  // on only when header protection is supported.
-  return false;
+  return transport_version == QUIC_VERSION_99;
 }
 
 bool ParsedQuicVersion::SupportsRetry() const {
@@ -440,6 +431,7 @@
   SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
   SetQuicRestartFlag(quic_allow_variable_length_connection_id_for_negotiation,
                      true);
+  SetQuicRestartFlag(quic_do_not_override_connection_id, true);
 }
 
 void QuicEnableVersion(ParsedQuicVersion parsed_version) {