Deprecate --gfe2_restart_flag_quic_disable_legacy_version_encapsulation.

Code cleanup for Legacy Version Encapsulation in QUIC.

This was deprecated in cr/454650691 and cr/463115423. This is the code to clean
it after it has been deprecated by removing all the referecnces and dead code.

PiperOrigin-RevId: 481140681
diff --git a/build/source_list.bzl b/build/source_list.bzl
index 9ab0ba3..110f0da 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -307,7 +307,6 @@
     "quic/core/quic_interval.h",
     "quic/core/quic_interval_deque.h",
     "quic/core/quic_interval_set.h",
-    "quic/core/quic_legacy_version_encapsulator.h",
     "quic/core/quic_lru_cache.h",
     "quic/core/quic_mtu_discovery.h",
     "quic/core/quic_network_blackhole_detector.h",
@@ -636,7 +635,6 @@
     "quic/core/quic_flow_controller.cc",
     "quic/core/quic_framer.cc",
     "quic/core/quic_idle_network_detector.cc",
-    "quic/core/quic_legacy_version_encapsulator.cc",
     "quic/core/quic_mtu_discovery.cc",
     "quic/core/quic_network_blackhole_detector.cc",
     "quic/core/quic_packet_creator.cc",
@@ -1205,7 +1203,6 @@
     "quic/core/quic_interval_deque_test.cc",
     "quic/core/quic_interval_set_test.cc",
     "quic/core/quic_interval_test.cc",
-    "quic/core/quic_legacy_version_encapsulator_test.cc",
     "quic/core/quic_lru_cache_test.cc",
     "quic/core/quic_network_blackhole_detector_test.cc",
     "quic/core/quic_one_block_arena_test.cc",
diff --git a/build/source_list.gni b/build/source_list.gni
index 35107f0..94401df 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -307,7 +307,6 @@
     "src/quiche/quic/core/quic_interval.h",
     "src/quiche/quic/core/quic_interval_deque.h",
     "src/quiche/quic/core/quic_interval_set.h",
-    "src/quiche/quic/core/quic_legacy_version_encapsulator.h",
     "src/quiche/quic/core/quic_lru_cache.h",
     "src/quiche/quic/core/quic_mtu_discovery.h",
     "src/quiche/quic/core/quic_network_blackhole_detector.h",
@@ -636,7 +635,6 @@
     "src/quiche/quic/core/quic_flow_controller.cc",
     "src/quiche/quic/core/quic_framer.cc",
     "src/quiche/quic/core/quic_idle_network_detector.cc",
-    "src/quiche/quic/core/quic_legacy_version_encapsulator.cc",
     "src/quiche/quic/core/quic_mtu_discovery.cc",
     "src/quiche/quic/core/quic_network_blackhole_detector.cc",
     "src/quiche/quic/core/quic_packet_creator.cc",
@@ -1205,7 +1203,6 @@
     "src/quiche/quic/core/quic_interval_deque_test.cc",
     "src/quiche/quic/core/quic_interval_set_test.cc",
     "src/quiche/quic/core/quic_interval_test.cc",
-    "src/quiche/quic/core/quic_legacy_version_encapsulator_test.cc",
     "src/quiche/quic/core/quic_lru_cache_test.cc",
     "src/quiche/quic/core/quic_network_blackhole_detector_test.cc",
     "src/quiche/quic/core/quic_one_block_arena_test.cc",
diff --git a/build/source_list.json b/build/source_list.json
index a4394c8..599ccdd 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -306,7 +306,6 @@
     "quiche/quic/core/quic_interval.h",
     "quiche/quic/core/quic_interval_deque.h",
     "quiche/quic/core/quic_interval_set.h",
-    "quiche/quic/core/quic_legacy_version_encapsulator.h",
     "quiche/quic/core/quic_lru_cache.h",
     "quiche/quic/core/quic_mtu_discovery.h",
     "quiche/quic/core/quic_network_blackhole_detector.h",
@@ -635,7 +634,6 @@
     "quiche/quic/core/quic_flow_controller.cc",
     "quiche/quic/core/quic_framer.cc",
     "quiche/quic/core/quic_idle_network_detector.cc",
-    "quiche/quic/core/quic_legacy_version_encapsulator.cc",
     "quiche/quic/core/quic_mtu_discovery.cc",
     "quiche/quic/core/quic_network_blackhole_detector.cc",
     "quiche/quic/core/quic_packet_creator.cc",
@@ -1204,7 +1202,6 @@
     "quiche/quic/core/quic_interval_deque_test.cc",
     "quiche/quic/core/quic_interval_set_test.cc",
     "quiche/quic/core/quic_interval_test.cc",
-    "quiche/quic/core/quic_legacy_version_encapsulator_test.cc",
     "quiche/quic/core/quic_lru_cache_test.cc",
     "quiche/quic/core/quic_network_blackhole_detector_test.cc",
     "quiche/quic/core/quic_one_block_arena_test.cc",
diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h
index 7cfffd9..e64f3c8 100644
--- a/quiche/quic/core/crypto/crypto_protocol.h
+++ b/quiche/quic/core/crypto/crypto_protocol.h
@@ -31,7 +31,7 @@
 // "QNZR", "B2HI", "H2PR", "FIFO", "LIFO", "RRWS", "QNSP", "B2CL", "CHSP",
 // "BPTE", "ACKD", "AKD2", "AKD4", "MAD1", "MAD4", "MAD5", "ACD0", "ACKQ",
 // "TLPR", "CCS\0", "PDP4", "NCHP", "NBPE", "2RTO", "3RTO", "4RTO", "6RTO",
-// "PDP1", "PDP2", "PDP3", "PDP5"
+// "PDP1", "PDP2", "PDP3", "PDP5" "QLVE"
 
 // clang-format off
 const QuicTag kCHLO = TAG('C', 'H', 'L', 'O');   // Client hello
@@ -395,8 +395,6 @@
                                                  // flow control receive window.
 const QuicTag kUAID = TAG('U', 'A', 'I', 'D');   // Client's User Agent ID.
 const QuicTag kXLCT = TAG('X', 'L', 'C', 'T');   // Expected leaf certificate.
-const QuicTag kQLVE = TAG('Q', 'L', 'V', 'E');   // Legacy Version
-                                                 // Encapsulation.
 
 const QuicTag kQNZ2 = TAG('Q', 'N', 'Z', '2');   // Turn off QUIC crypto 0-RTT.
 
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index af39239..3fc79a9 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -6056,109 +6056,6 @@
   server_thread_->Resume();
 }
 
-TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
-  if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  if (!version_.HasLongHeaderLengths() ||
-      override_server_connection_id_length_ > -1) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
-  if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  if (!version_.HasLongHeaderLengths() ||
-      override_server_connection_id_length_ > -1) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  if (!version_.UsesTls()) {
-    // This test uses custom transport parameters to increase the size of the
-    // CHLO, and those are only supported with TLS.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  constexpr auto kCustomParameter =
-      static_cast<TransportParameters::TransportParameterId>(0xff34);
-  client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
-      std::string(2000, '?');
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
-  if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  if (!version_.HasLongHeaderLengths() ||
-      override_server_connection_id_length_ > -1) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    QuicVersionReservedForNegotiation());
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) {
-  if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  if (!version_.HasLongHeaderLengths() ||
-      override_server_connection_id_length_ > -1) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  SetPacketLossPercentage(30);
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  // Disable blackhole detection as this test is testing loss recovery.
-  client_extra_copts_.push_back(kNBHD);
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
 // Testing packet writer that makes a copy of the first sent packets before
 // sending them. Useful for tests that need access to sent packets.
 class CopyingPacketWriter : public PacketDroppingTestWriter {
diff --git a/quiche/quic/core/http/quic_spdy_client_session.cc b/quiche/quic/core/http/quic_spdy_client_session.cc
index 707281a..12bb511 100644
--- a/quiche/quic/core/http/quic_spdy_client_session.cc
+++ b/quiche/quic/core/http/quic_spdy_client_session.cc
@@ -36,14 +36,6 @@
 
 void QuicSpdyClientSession::Initialize() {
   crypto_stream_ = CreateQuicCryptoStream();
-  if (config()->HasClientRequestedIndependentOption(kQLVE,
-                                                    Perspective::IS_CLIENT)) {
-    if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-      QUIC_CODE_COUNT(quic_disable_legacy_version_encapsulation_client_init);
-    } else {
-      connection()->EnableLegacyVersionEncapsulation(server_id_.host());
-    }
-  }
   QuicSpdyClientSessionBase::Initialize();
 }
 
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index 0e71a7f..5c44172 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -32,7 +32,6 @@
 #include "quiche/quic/core/quic_connection_id.h"
 #include "quiche/quic/core/quic_constants.h"
 #include "quiche/quic/core/quic_error_codes.h"
-#include "quiche/quic/core/quic_legacy_version_encapsulator.h"
 #include "quiche/quic/core/quic_packet_creator.h"
 #include "quiche/quic/core/quic_packet_writer.h"
 #include "quiche/quic/core/quic_packets.h"
@@ -675,7 +674,8 @@
       GetQuicReloadableFlag(quic_connection_migration_use_new_cid_v2);
   if (config.HasReceivedMaxPacketSize()) {
     peer_max_packet_size_ = config.ReceivedMaxPacketSize();
-    MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+    packet_creator_.SetMaxPacketLength(
+        GetLimitedMaxPacketSize(packet_creator_.max_packet_length()));
   }
   if (config.HasReceivedMaxDatagramFrameSize()) {
     packet_creator_.SetMaxDatagramFrameSize(
@@ -698,31 +698,6 @@
   }
 }
 
-void QuicConnection::EnableLegacyVersionEncapsulation(
-    const std::string& server_name) {
-  if (perspective_ != Perspective::IS_CLIENT) {
-    QUIC_BUG(quic_bug_10511_1)
-        << "Cannot enable Legacy Version Encapsulation on the server";
-    return;
-  }
-  if (legacy_version_encapsulation_enabled_) {
-    QUIC_BUG(quic_bug_10511_2)
-        << "Do not call EnableLegacyVersionEncapsulation twice";
-    return;
-  }
-  if (!QuicHostnameUtils::IsValidSNI(server_name)) {
-    // Legacy Version Encapsulation is only used when SNI is transmitted.
-    QUIC_DLOG(INFO)
-        << "Refusing to use Legacy Version Encapsulation with invalid SNI \""
-        << server_name << "\"";
-    return;
-  }
-  QUIC_DLOG(INFO) << "Enabling Legacy Version Encapsulation with SNI \""
-                  << server_name << "\"";
-  legacy_version_encapsulation_enabled_ = true;
-  legacy_version_encapsulation_sni_ = server_name;
-}
-
 bool QuicConnection::MaybeTestLiveness() {
   QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
   if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
@@ -2441,29 +2416,6 @@
   }
 }
 
-void QuicConnection::MaybeActivateLegacyVersionEncapsulation() {
-  if (!legacy_version_encapsulation_enabled_) {
-    return;
-  }
-  QUICHE_DCHECK(!legacy_version_encapsulation_in_progress_);
-  QUIC_BUG_IF(quic_bug_12714_19, !packet_creator_.CanSetMaxPacketLength())
-      << "Cannot activate Legacy Version Encapsulation mid-packet";
-  QUIC_BUG_IF(quic_bug_12714_20, coalesced_packet_.length() != 0u)
-      << "Cannot activate Legacy Version Encapsulation mid-coalesced-packet";
-  legacy_version_encapsulation_in_progress_ = true;
-  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-void QuicConnection::MaybeDisactivateLegacyVersionEncapsulation() {
-  if (!legacy_version_encapsulation_in_progress_) {
-    return;
-  }
-  // Flush any remaining packet before disactivating encapsulation.
-  packet_creator_.FlushCurrentPacket();
-  QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
-  legacy_version_encapsulation_in_progress_ = false;
-  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-
 size_t QuicConnection::SendCryptoData(EncryptionLevel level,
                                       size_t write_length,
                                       QuicStreamOffset offset) {
@@ -2471,17 +2423,8 @@
     QUIC_BUG(quic_bug_10511_18) << "Attempt to send empty crypto frame";
     return 0;
   }
-  if (level == ENCRYPTION_INITIAL) {
-    MaybeActivateLegacyVersionEncapsulation();
-  }
-  size_t consumed_length;
-  {
-    ScopedPacketFlusher flusher(this);
-    consumed_length =
-        packet_creator_.ConsumeCryptoData(level, write_length, offset);
-  }  // Added scope ensures packets are flushed before continuing.
-  MaybeDisactivateLegacyVersionEncapsulation();
-  return consumed_length;
+  ScopedPacketFlusher flusher(this);
+  return packet_creator_.ConsumeCryptoData(level, write_length, offset);
 }
 
 QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
@@ -2493,10 +2436,6 @@
     return QuicConsumedData(0, false);
   }
 
-  if (packet_creator_.encryption_level() == ENCRYPTION_INITIAL &&
-      QuicUtils::IsCryptoStreamId(transport_version(), id)) {
-    MaybeActivateLegacyVersionEncapsulation();
-  }
   if (perspective_ == Perspective::IS_SERVER &&
       version().CanSendCoalescedPackets() && !IsHandshakeConfirmed()) {
     if (in_on_retransmission_time_out_ &&
@@ -2514,20 +2453,14 @@
       sent_packet_manager_.RetransmitDataOfSpaceIfAny(HANDSHAKE_DATA);
     }
   }
-  QuicConsumedData consumed_data(0, false);
-  {
-    // Opportunistically bundle an ack with every outgoing packet.
-    // Particularly, we want to bundle with handshake packets since we don't
-    // know which decrypter will be used on an ack packet following a handshake
-    // packet (a handshake packet from client to server could result in a REJ or
-    // a SHLO from the server, leading to two different decrypters at the
-    // server.)
-    ScopedPacketFlusher flusher(this);
-    consumed_data =
-        packet_creator_.ConsumeData(id, write_length, offset, state);
-  }  // Added scope ensures packets are flushed before continuing.
-  MaybeDisactivateLegacyVersionEncapsulation();
-  return consumed_data;
+  // Opportunistically bundle an ack with every outgoing packet.
+  // Particularly, we want to bundle with handshake packets since we don't
+  // know which decrypter will be used on an ack packet following a handshake
+  // packet (a handshake packet from client to server could result in a REJ or
+  // a SHLO from the server, leading to two different decrypters at the
+  // server.)
+  ScopedPacketFlusher flusher(this);
+  return packet_creator_.ConsumeData(id, write_length, offset, state);
 }
 
 bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
@@ -2707,28 +2640,6 @@
   return info;
 }
 
-void QuicConnection::MaybeUpdatePacketCreatorMaxPacketLengthAndPadding() {
-  QuicByteCount max_packet_length = GetLimitedMaxPacketSize(long_term_mtu_);
-  if (legacy_version_encapsulation_in_progress_) {
-    QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
-    const QuicByteCount minimum_overhead =
-        QuicLegacyVersionEncapsulator::GetMinimumOverhead(
-            legacy_version_encapsulation_sni_);
-    if (max_packet_length < minimum_overhead) {
-      QUIC_BUG(quic_bug_10511_20)
-          << "Cannot apply Legacy Version Encapsulation overhead because "
-          << "max_packet_length " << max_packet_length << " < minimum_overhead "
-          << minimum_overhead;
-      legacy_version_encapsulation_in_progress_ = false;
-      legacy_version_encapsulation_enabled_ = false;
-      MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-      return;
-    }
-    max_packet_length -= minimum_overhead;
-  }
-  packet_creator_.SetMaxPacketLength(max_packet_length);
-}
-
 void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
                                       const QuicSocketAddress& peer_address,
                                       const QuicReceivedPacket& packet) {
@@ -3488,49 +3399,6 @@
         result = writer_->Flush();
       }
       break;
-    case LEGACY_VERSION_ENCAPSULATE: {
-      QUICHE_DCHECK(!is_mtu_discovery);
-      QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-      QUICHE_DCHECK_EQ(packet->encryption_level, ENCRYPTION_INITIAL);
-      QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
-      QUICHE_DCHECK(legacy_version_encapsulation_in_progress_);
-      QuicPacketLength encapsulated_length =
-          QuicLegacyVersionEncapsulator::Encapsulate(
-              legacy_version_encapsulation_sni_,
-              absl::string_view(packet->encrypted_buffer,
-                                packet->encrypted_length),
-              default_path_.server_connection_id, framer_.creation_time(),
-              GetLimitedMaxPacketSize(long_term_mtu_),
-              const_cast<char*>(packet->encrypted_buffer));
-      if (encapsulated_length != 0) {
-        stats_.sent_legacy_version_encapsulated_packets++;
-        packet->encrypted_length = encapsulated_length;
-        encrypted_length = encapsulated_length;
-        QUIC_DVLOG(2)
-            << ENDPOINT
-            << "Successfully performed Legacy Version Encapsulation on "
-            << packet->encryption_level << " packet number " << packet_number
-            << " of length " << encrypted_length << ": " << std::endl
-            << quiche::QuicheTextUtils::HexDump(absl::string_view(
-                   packet->encrypted_buffer, encrypted_length));
-      } else {
-        QUIC_BUG(quic_bug_10511_24)
-            << ENDPOINT << "Failed to perform Legacy Version Encapsulation on "
-            << packet->encryption_level << " packet number " << packet_number
-            << " of length " << encrypted_length;
-      }
-      if (!buffered_packets_.empty() || HandleWriteBlocked()) {
-        // Buffer the packet.
-        buffered_packets_.emplace_back(*packet, self_address(),
-                                       send_to_address);
-      } else {  // Send the packet to the writer.
-        // writer_->WritePacket transfers buffer ownership back to the writer.
-        packet->release_encrypted_buffer = nullptr;
-        result = writer_->WritePacket(packet->encrypted_buffer,
-                                      encrypted_length, self_address().host(),
-                                      send_to_address, per_packet_options_);
-      }
-    } break;
     default:
       QUICHE_DCHECK(false);
       break;
@@ -4673,7 +4541,7 @@
 void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
   long_term_mtu_ = length;
   stats_.max_egress_mtu = std::max(stats_.max_egress_mtu, long_term_mtu_);
-  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+  packet_creator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length));
 }
 
 bool QuicConnection::HasQueuedData() const {
@@ -6162,10 +6030,6 @@
   if (ShouldDiscardPacket(encryption_level)) {
     return DISCARD;
   }
-  if (legacy_version_encapsulation_in_progress_) {
-    QUICHE_DCHECK(!is_mtu_discovery);
-    return LEGACY_VERSION_ENCAPSULATE;
-  }
   if (version().CanSendCoalescedPackets() && !coalescing_done_ &&
       !is_mtu_discovery) {
     if (!IsHandshakeConfirmed()) {
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index 578de98..36e9bbf 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -1167,10 +1167,6 @@
 
   virtual void OnUserAgentIdKnown(const std::string& user_agent_id);
 
-  // Enables Legacy Version Encapsulation using |server_name| as SNI.
-  // Can only be set if this is a client connection.
-  void EnableLegacyVersionEncapsulation(const std::string& server_name);
-
   // If now is close to idle timeout, returns true and sends a connectivity
   // probing packet to test the connection for liveness. Otherwise, returns
   // false.
@@ -1822,13 +1818,6 @@
   // Returns string which contains undecryptable packets information.
   std::string UndecryptablePacketsInfo() const;
 
-  // Sets the max packet length on the packet creator if needed.
-  void MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-
-  // Sets internal state to enable or disable Legacy Version Encapsulation.
-  void MaybeActivateLegacyVersionEncapsulation();
-  void MaybeDisactivateLegacyVersionEncapsulation();
-
   // For Google Quic, if the current packet is connectivity probing packet, call
   // session OnPacketReceived() which eventually sends connectivity probing
   // response on server side. And no-op on client side. And for both Google Quic
@@ -2223,13 +2212,6 @@
   const bool default_enable_5rto_blackhole_detection_ =
       GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2);
 
-  // Whether the Legacy Version Encapsulation feature is enabled.
-  bool legacy_version_encapsulation_enabled_ = false;
-  // Whether we are in the middle of sending a packet using Legacy Version
-  // Encapsulation.
-  bool legacy_version_encapsulation_in_progress_ = false;
-  // SNI to send when using Legacy Version Encapsulation.
-  std::string legacy_version_encapsulation_sni_;
   // True if next packet is intended to consume remaining space in the
   // coalescer.
   bool fill_coalesced_packet_ = false;
diff --git a/quiche/quic/core/quic_connection_stats.cc b/quiche/quic/core/quic_connection_stats.cc
index 105d957..b5561eb 100644
--- a/quiche/quic/core/quic_connection_stats.cc
+++ b/quiche/quic/core/quic_connection_stats.cc
@@ -55,8 +55,6 @@
   os << " num_coalesced_packets_processed: "
      << s.num_coalesced_packets_processed;
   os << " num_ack_aggregation_epochs: " << s.num_ack_aggregation_epochs;
-  os << " sent_legacy_version_encapsulated_packets: "
-     << s.sent_legacy_version_encapsulated_packets;
   os << " key_update_count: " << s.key_update_count;
   os << " num_failed_authentication_packets_received: "
      << s.num_failed_authentication_packets_received;
diff --git a/quiche/quic/core/quic_connection_stats.h b/quiche/quic/core/quic_connection_stats.h
index 2d25495..bf21073 100644
--- a/quiche/quic/core/quic_connection_stats.h
+++ b/quiche/quic/core/quic_connection_stats.h
@@ -170,10 +170,6 @@
   // Max consecutive retransmission timeout before making forward progress.
   size_t max_consecutive_rto_with_forward_progress = 0;
 
-  // Number of sent packets that were encapsulated using Legacy Version
-  // Encapsulation.
-  QuicPacketCount sent_legacy_version_encapsulated_packets = 0;
-
   // Number of times when the connection tries to send data but gets throttled
   // by amplification factor.
   size_t num_amplification_throttling = 0;
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 608d306..ee2a090 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -9994,49 +9994,6 @@
   EXPECT_QUIC_BUG(test_body(), "SerializeCoalescedPacket failed.");
 }
 
-TEST_P(QuicConnectionTest, LegacyVersionEncapsulation) {
-  connection_.EnableLegacyVersionEncapsulation("test.example.org");
-
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
-
-  // Our TestPacketWriter normally parses the sent packet using the version
-  // from the connection, so here we need to tell it to use the encapsulation
-  // version, and reset the initial decrypter for that version.
-  writer_->framer()->SetSupportedVersions(
-      SupportedVersions(LegacyVersionForEncapsulation()));
-  writer_->framer()->framer()->SetInitialObfuscators(
-      connection_.connection_id());
-
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendCryptoDataWithString("TEST_CRYPTO_DATA", /*offset=*/0);
-  }
-
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  // Verify that the packet is fully padded.
-  EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
-
-  // Check that the connection stats show Legacy Version Encapsulation was used.
-  EXPECT_GT(connection_.GetStats().sent_legacy_version_encapsulated_packets,
-            0u);
-
-  // Verify that the sent packet was in fact encapsulated, and check header.
-  const QuicPacketHeader& encapsulated_header = writer_->last_packet_header();
-  EXPECT_TRUE(encapsulated_header.version_flag);
-  EXPECT_EQ(encapsulated_header.version, LegacyVersionForEncapsulation());
-  EXPECT_EQ(encapsulated_header.destination_connection_id,
-            connection_.connection_id());
-
-  // Encapsulated packet should contain a stream frame for the crypto stream,
-  // optionally padding, and nothing else.
-  EXPECT_EQ(0u, writer_->crypto_frames().size());
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(writer_->frame_count(), writer_->framer()->padding_frames().size() +
-                                        writer_->stream_frames().size());
-}
-
 TEST_P(QuicConnectionTest, ClientReceivedHandshakeDone) {
   if (!connection_.version().UsesTls()) {
     return;
diff --git a/quiche/quic/core/quic_dispatcher.cc b/quiche/quic/core/quic_dispatcher.cc
index 63fa567..e82ddce 100644
--- a/quiche/quic/core/quic_dispatcher.cc
+++ b/quiche/quic/core/quic_dispatcher.cc
@@ -212,7 +212,7 @@
 // Class which extracts the ALPN and SNI from a QUIC_CRYPTO CHLO packet.
 class ChloAlpnSniExtractor : public ChloExtractor::Delegate {
  public:
-  void OnChlo(QuicTransportVersion version,
+  void OnChlo(QuicTransportVersion /*version*/,
               QuicConnectionId /*server_connection_id*/,
               const CryptoHandshakeMessage& chlo) override {
     absl::string_view alpn_value;
@@ -227,12 +227,6 @@
     if (chlo.GetStringPiece(quic::kUAID, &uaid_value)) {
       uaid_ = std::string(uaid_value);
     }
-    if (version == LegacyVersionForEncapsulation().transport_version) {
-      absl::string_view qlve_value;
-      if (chlo.GetStringPiece(kQLVE, &qlve_value)) {
-        legacy_version_encapsulation_inner_packet_ = std::string(qlve_value);
-      }
-    }
   }
 
   std::string&& ConsumeAlpn() { return std::move(alpn_); }
@@ -241,91 +235,12 @@
 
   std::string&& ConsumeUaid() { return std::move(uaid_); }
 
-  std::string&& ConsumeLegacyVersionEncapsulationInnerPacket() {
-    return std::move(legacy_version_encapsulation_inner_packet_);
-  }
-
  private:
   std::string alpn_;
   std::string sni_;
   std::string uaid_;
-  std::string legacy_version_encapsulation_inner_packet_;
 };
 
-bool MaybeHandleLegacyVersionEncapsulation(
-    QuicDispatcher* dispatcher,
-    std::string legacy_version_encapsulation_inner_packet,
-    const ReceivedPacketInfo& packet_info) {
-  QUICHE_DCHECK(!GetQuicRestartFlag(quic_disable_legacy_version_encapsulation));
-  if (legacy_version_encapsulation_inner_packet.empty()) {
-    // This CHLO did not contain the Legacy Version Encapsulation tag.
-    return false;
-  }
-  PacketHeaderFormat format;
-  QuicLongHeaderType long_packet_type;
-  bool version_present;
-  bool has_length_prefix;
-  QuicVersionLabel version_label;
-  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-  QuicConnectionId destination_connection_id, source_connection_id;
-  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,
-      &detailed_error);
-  if (error != QUIC_NO_ERROR) {
-    QUIC_DLOG(ERROR)
-        << "Failed to parse Legacy Version Encapsulation inner packet:"
-        << detailed_error;
-    return false;
-  }
-  if (destination_connection_id != packet_info.destination_connection_id) {
-    // We enforce that the inner and outer connection IDs match to make sure
-    // this never impacts routing of packets.
-    QUIC_DLOG(ERROR) << "Ignoring Legacy Version Encapsulation packet "
-                        "with mismatched connection ID "
-                     << destination_connection_id << " vs "
-                     << packet_info.destination_connection_id;
-    return false;
-  }
-  if (legacy_version_encapsulation_inner_packet.length() >=
-      packet_info.packet.length()) {
-    QUIC_BUG(quic_bug_10287_2)
-        << "Inner packet cannot be larger than outer "
-        << legacy_version_encapsulation_inner_packet.length() << " vs "
-        << packet_info.packet.length();
-    return false;
-  }
-
-  QUIC_DVLOG(1) << "Extracted a Legacy Version Encapsulation "
-                << legacy_version_encapsulation_inner_packet.length()
-                << " byte packet of version " << parsed_version;
-
-  // Append zeroes to the end of the packet. This will ensure that
-  // we use the right number of bytes for calculating anti-amplification
-  // limits. Note that this only works for long headers of versions that carry
-  // long header lengths, since they'll ignore any trailing zeroes. We still
-  // do this for all packets to ensure version negotiation works.
-  legacy_version_encapsulation_inner_packet.append(
-      packet_info.packet.length() -
-          legacy_version_encapsulation_inner_packet.length(),
-      0x00);
-
-  // Process the inner packet as if it had been received by itself.
-  QuicReceivedPacket received_encapsulated_packet(
-      legacy_version_encapsulation_inner_packet.data(),
-      legacy_version_encapsulation_inner_packet.length(),
-      packet_info.packet.receipt_time());
-  dispatcher->ProcessPacket(packet_info.self_address, packet_info.peer_address,
-                            received_encapsulated_packet);
-  QUIC_CODE_COUNT(quic_legacy_version_encapsulation_decapsulated);
-  return true;
-}
-
 }  // namespace
 
 QuicDispatcher::QuicDispatcher(
@@ -594,29 +509,6 @@
   auto it = reference_counted_session_map_.find(server_connection_id);
   if (it != reference_counted_session_map_.end()) {
     QUICHE_DCHECK(!buffered_packets_.HasBufferedPackets(server_connection_id));
-    if (packet_info.version_flag &&
-        packet_info.version != it->second->version() &&
-        packet_info.version == LegacyVersionForEncapsulation()) {
-      // This packet is using the Legacy Version Encapsulation version but the
-      // corresponding session isn't, attempt extraction of inner packet.
-      if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-        QUIC_CODE_COUNT(
-            quic_disable_legacy_version_encapsulation_dispatch_packet);
-      } else {
-        ChloAlpnSniExtractor alpn_extractor;
-        if (ChloExtractor::Extract(packet_info.packet, packet_info.version,
-                                   config_->create_session_tag_indicators(),
-                                   &alpn_extractor,
-                                   server_connection_id.length())) {
-          if (MaybeHandleLegacyVersionEncapsulation(
-                  this,
-                  alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket(),
-                  packet_info)) {
-            return true;
-          }
-        }
-      }
-    }
     it->second->ProcessUdpPacket(packet_info.self_address,
                                  packet_info.peer_address, packet_info.packet);
     return true;
@@ -740,22 +632,6 @@
       fate = ValidityChecksOnFullChlo(*packet_info, *parsed_chlo);
 
       if (fate == kFateProcess) {
-        QUICHE_DCHECK(
-            parsed_chlo->legacy_version_encapsulation_inner_packet.empty() ||
-            !packet_info->version.UsesTls());
-        if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-          if (!parsed_chlo->legacy_version_encapsulation_inner_packet.empty()) {
-            QUIC_CODE_COUNT(
-                quic_disable_legacy_version_encapsulation_process_header);
-          }
-        } else {
-          if (MaybeHandleLegacyVersionEncapsulation(
-                  this, parsed_chlo->legacy_version_encapsulation_inner_packet,
-                  *packet_info)) {
-            return;
-          }
-        }
-
         ProcessChlo(*std::move(parsed_chlo), packet_info);
         return;
       }
@@ -882,8 +758,6 @@
   }
 
   ParsedClientHello& parsed_chlo = result.parsed_chlo.emplace();
-  parsed_chlo.legacy_version_encapsulation_inner_packet =
-      alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket();
   parsed_chlo.sni = alpn_extractor.ConsumeSni();
   parsed_chlo.uaid = alpn_extractor.ConsumeUaid();
   parsed_chlo.alpns = {alpn_extractor.ConsumeAlpn()};
diff --git a/quiche/quic/core/quic_dispatcher_test.cc b/quiche/quic/core/quic_dispatcher_test.cc
index 0447586..ed5ea0c 100644
--- a/quiche/quic/core/quic_dispatcher_test.cc
+++ b/quiche/quic/core/quic_dispatcher_test.cc
@@ -677,73 +677,6 @@
                                 /*long_connection_id=*/true);
 }
 
-TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
-  if (GetQuicRestartFlag(quic_disable_legacy_version_encapsulation)) {
-    return;
-  }
-  if (!version_.HasLongHeaderLengths()) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    return;
-  }
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicConnectionId server_connection_id = TestConnectionId();
-  QuicConfig client_config = DefaultQuicConfig();
-  client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
-      GetFirstFlightOfPackets(version_, client_config, server_connection_id);
-  ASSERT_EQ(packets.size(), 1u);
-
-  // Validate that Legacy Version Encapsulation is actually being used by
-  // checking the version of the packet before processing it.
-  PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
-  QuicLongHeaderType long_packet_type;
-  bool version_present;
-  bool has_length_prefix;
-  QuicVersionLabel version_label;
-  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-  QuicConnectionId destination_connection_id, source_connection_id;
-  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,
-      &detailed_error);
-  ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
-  EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
-  EXPECT_TRUE(version_present);
-  EXPECT_FALSE(has_length_prefix);
-  EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
-  EXPECT_EQ(destination_connection_id, server_connection_id);
-  EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
-  EXPECT_FALSE(retry_token.has_value());
-  EXPECT_TRUE(detailed_error.empty());
-
-  // Processing the packet should create a new session.
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(server_connection_id, _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, server_connection_id, client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(2);
-
-  ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
-                        server_connection_id);
-  EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-
-  // Processing the same packet a second time should also be routed by the
-  // dispatcher to the right connection (we expect ProcessUdpPacket to be
-  // called twice, see the EXPECT_CALL above).
-  ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
-                        server_connection_id);
-}
-
 TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
   QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
 
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h
index d8e8cd8..20f5594 100644
--- a/quiche/quic/core/quic_flags_list.h
+++ b/quiche/quic/core/quic_flags_list.h
@@ -19,8 +19,6 @@
 QUIC_FLAG(quic_restart_flag_quic_testonly_default_true, true)
 // If trrue, early return before write control frame in OnCanWrite() if the connection is already closed.
 QUIC_FLAG(quic_reloadable_flag_quic_no_write_control_frame_upon_connection_close, true)
-// If true, QUIC Legacy Version Encapsulation will be disabled.
-QUIC_FLAG(quic_restart_flag_quic_disable_legacy_version_encapsulation, true)
 // If true, QUIC will default enable MTU discovery at server, with a target of 1450 bytes.
 QUIC_FLAG(quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
 // If true, QuicConnectionContext will track the decrypted payload and the offset of the current frame, for debugging.
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator.cc b/quiche/quic/core/quic_legacy_version_encapsulator.cc
deleted file mode 100644
index d2c6082..0000000
--- a/quiche/quic/core/quic_legacy_version_encapsulator.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2020 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 "quiche/quic/core/quic_legacy_version_encapsulator.h"
-
-#include "quiche/quic/core/crypto/crypto_handshake_message.h"
-#include "quiche/quic/core/crypto/crypto_protocol.h"
-#include "quiche/quic/core/quic_utils.h"
-#include "quiche/quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicLegacyVersionEncapsulator::QuicLegacyVersionEncapsulator(
-    QuicPacketBuffer packet_buffer)
-    : packet_buffer_(packet_buffer) {}
-
-QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}
-
-// static
-QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
-    absl::string_view sni) {
-  // The number 52 is the sum of:
-  // - Flags (1 byte)
-  // - Server Connection ID (8 bytes)
-  // - Version (4 bytes)
-  // - Packet Number (1 byte)
-  // - Message Authentication Hash (12 bytes)
-  // - Frame Type (1 byte)
-  // - Stream ID (1 byte)
-  // - ClientHello tag (4 bytes)
-  // - ClientHello num tags (2 bytes)
-  // - Padding (2 bytes)
-  // - SNI tag (4 bytes)
-  // - SNI end offset (4 bytes)
-  // - QLVE tag (4 bytes)
-  // - QLVE end offset (4 bytes)
-  return 52 + sni.length();
-}
-
-QuicPacketBuffer QuicLegacyVersionEncapsulator::GetPacketBuffer() {
-  return packet_buffer_;
-}
-
-void QuicLegacyVersionEncapsulator::OnSerializedPacket(
-    SerializedPacket serialized_packet) {
-  if (encrypted_length_ != 0) {
-    unrecoverable_failure_encountered_ = true;
-    QUIC_BUG(quic_bug_10615_1) << "OnSerializedPacket called twice";
-    return;
-  }
-  if (serialized_packet.encrypted_length == 0) {
-    unrecoverable_failure_encountered_ = true;
-    QUIC_BUG(quic_bug_10615_2) << "OnSerializedPacket called with empty packet";
-    return;
-  }
-  encrypted_length_ = serialized_packet.encrypted_length;
-}
-
-void QuicLegacyVersionEncapsulator::OnUnrecoverableError(
-    QuicErrorCode error, const std::string& error_details) {
-  unrecoverable_failure_encountered_ = true;
-  QUIC_BUG(quic_bug_10615_3) << "QuicLegacyVersionEncapsulator received error "
-                             << error << ": " << error_details;
-}
-
-bool QuicLegacyVersionEncapsulator::ShouldGeneratePacket(
-    HasRetransmittableData /*retransmittable*/, IsHandshake /*handshake*/) {
-  return true;
-}
-
-const QuicFrames
-QuicLegacyVersionEncapsulator::MaybeBundleAckOpportunistically() {
-  // We do not want to ever include any ACKs here, return an empty array.
-  return QuicFrames();
-}
-
-SerializedPacketFate QuicLegacyVersionEncapsulator::GetSerializedPacketFate(
-    bool /*is_mtu_discovery*/, EncryptionLevel /*encryption_level*/) {
-  return SEND_TO_WRITER;
-}
-
-// static
-QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate(
-    absl::string_view sni, absl::string_view inner_packet,
-    const QuicConnectionId& server_connection_id, QuicTime creation_time,
-    QuicByteCount outer_max_packet_length, char* out) {
-  if (outer_max_packet_length > kMaxOutgoingPacketSize) {
-    outer_max_packet_length = kMaxOutgoingPacketSize;
-  }
-  CryptoHandshakeMessage outer_chlo;
-  outer_chlo.set_tag(kCHLO);
-  outer_chlo.SetStringPiece(kSNI, sni);
-  outer_chlo.SetStringPiece(kQLVE, inner_packet);
-  const QuicData& serialized_outer_chlo = outer_chlo.GetSerialized();
-  QUICHE_DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
-  QUICHE_DCHECK(LegacyVersionForEncapsulation().UsesQuicCrypto());
-  QuicStreamFrame outer_stream_frame(
-      QuicUtils::GetCryptoStreamId(
-          LegacyVersionForEncapsulation().transport_version),
-      /*fin=*/false,
-      /*offset=*/0, serialized_outer_chlo.AsStringPiece());
-  QuicFramer outer_framer(
-      ParsedQuicVersionVector{LegacyVersionForEncapsulation()}, creation_time,
-      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
-  outer_framer.SetInitialObfuscators(server_connection_id);
-  char outer_encrypted_packet[kMaxOutgoingPacketSize];
-  QuicPacketBuffer outer_packet_buffer(outer_encrypted_packet, nullptr);
-  QuicLegacyVersionEncapsulator creator_delegate(outer_packet_buffer);
-  QuicPacketCreator outer_creator(server_connection_id, &outer_framer,
-                                  &creator_delegate);
-  outer_creator.SetMaxPacketLength(outer_max_packet_length);
-  outer_creator.set_encryption_level(ENCRYPTION_INITIAL);
-  outer_creator.SetTransmissionType(NOT_RETRANSMISSION);
-  if (!outer_creator.AddPaddedSavedFrame(QuicFrame(outer_stream_frame),
-                                         NOT_RETRANSMISSION)) {
-    QUIC_BUG(quic_bug_10615_4)
-        << "Failed to add Legacy Version Encapsulation stream frame "
-           "(max packet length is "
-        << outer_creator.max_packet_length() << ") " << outer_stream_frame;
-    return 0;
-  }
-  outer_creator.FlushCurrentPacket();
-  const QuicPacketLength encrypted_length = creator_delegate.encrypted_length_;
-  if (creator_delegate.unrecoverable_failure_encountered_ ||
-      encrypted_length == 0) {
-    QUIC_BUG(quic_bug_10615_5)
-        << "Failed to perform Legacy Version Encapsulation of "
-        << inner_packet.length() << " bytes";
-    return 0;
-  }
-  if (encrypted_length > kMaxOutgoingPacketSize) {
-    QUIC_BUG(quic_bug_10615_6)
-        << "Legacy Version Encapsulation outer creator generated a "
-           "packet with unexpected length "
-        << encrypted_length;
-    return 0;
-  }
-
-  QUIC_DLOG(INFO) << "Successfully performed Legacy Version Encapsulation from "
-                  << inner_packet.length() << " bytes to " << encrypted_length;
-
-  // Replace our current packet with the encapsulated one.
-  memcpy(out, outer_encrypted_packet, encrypted_length);
-  return encrypted_length;
-}
-
-}  // namespace quic
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator.h b/quiche/quic/core/quic_legacy_version_encapsulator.h
deleted file mode 100644
index bc96725..0000000
--- a/quiche/quic/core/quic_legacy_version_encapsulator.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2020 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.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
-
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/quic_packet_creator.h"
-#include "quiche/quic/core/quic_packets.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicLegacyVersionEncapsulator is responsible for encapsulation of packets
-// using Legacy Version Encapsulation.
-
-class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator
-    : public QuicPacketCreator::DelegateInterface {
- public:
-  // Encapsulates |inner_packet| into a new encapsulated packet that uses a
-  // CHLO of version LegacyVersionForEncapsulation() with server name |sni|
-  // exposed and using |server_connection_id|. The packet will be padded up to
-  // |outer_max_packet_length| bytes if necessary. On failure, returns 0. On
-  // success, returns the length of the outer encapsulated packet, and copies
-  // the contents of the encapsulated packet to |out|. |out| must point to a
-  // valid memory buffer capable of holding kMaxOutgoingPacketSize bytes.
-  static QuicPacketLength Encapsulate(
-      absl::string_view sni, absl::string_view inner_packet,
-      const QuicConnectionId& server_connection_id, QuicTime creation_time,
-      QuicByteCount outer_max_packet_length, char* out);
-
-  // Returns the number of bytes of minimum overhead caused by Legacy Version
-  // Encapsulation, based on the length of the provided server name |sni|.
-  // The overhead may be higher due to extra padding added.
-  static QuicByteCount GetMinimumOverhead(absl::string_view sni);
-
-  // Overrides for QuicPacketCreator::DelegateInterface.
-  QuicPacketBuffer GetPacketBuffer() override;
-  void OnSerializedPacket(SerializedPacket serialized_packet) override;
-  void OnUnrecoverableError(QuicErrorCode error,
-                            const std::string& error_details) override;
-  bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
-                            IsHandshake handshake) override;
-  const QuicFrames MaybeBundleAckOpportunistically() override;
-  SerializedPacketFate GetSerializedPacketFate(
-      bool is_mtu_discovery, EncryptionLevel encryption_level) override;
-
-  ~QuicLegacyVersionEncapsulator() override;
-
- private:
-  explicit QuicLegacyVersionEncapsulator(QuicPacketBuffer packet_buffer);
-
-  // Disallow copy, move and assignment.
-  QuicLegacyVersionEncapsulator(const QuicLegacyVersionEncapsulator&) = delete;
-  QuicLegacyVersionEncapsulator(QuicLegacyVersionEncapsulator&&) = delete;
-  QuicLegacyVersionEncapsulator& operator=(
-      const QuicLegacyVersionEncapsulator&) = delete;
-  QuicLegacyVersionEncapsulator& operator=(QuicLegacyVersionEncapsulator&&) =
-      delete;
-
-  QuicPacketBuffer packet_buffer_;
-  QuicPacketLength encrypted_length_ = 0;
-  bool unrecoverable_failure_encountered_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator_test.cc b/quiche/quic/core/quic_legacy_version_encapsulator_test.cc
deleted file mode 100644
index 928386d..0000000
--- a/quiche/quic/core/quic_legacy_version_encapsulator_test.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2020 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 "quiche/quic/core/quic_legacy_version_encapsulator.h"
-
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/platform/api/quic_expect_bug.h"
-#include "quiche/quic/platform/api/quic_test.h"
-#include "quiche/quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicLegacyVersionEncapsulatorTest
-    : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  QuicLegacyVersionEncapsulatorTest()
-      : version_(GetParam()),
-        sni_("test.example.org"),
-        server_connection_id_(TestConnectionId()),
-        outer_max_packet_length_(kMaxOutgoingPacketSize),
-        encapsulated_length_(0) {}
-
-  void Encapsulate(const std::string& inner_packet) {
-    encapsulated_length_ = QuicLegacyVersionEncapsulator::Encapsulate(
-        sni_, inner_packet, server_connection_id_, QuicTime::Zero(),
-        outer_max_packet_length_, outer_buffer_);
-  }
-
-  void CheckEncapsulation() {
-    ASSERT_NE(encapsulated_length_, 0u);
-    ASSERT_EQ(encapsulated_length_, outer_max_packet_length_);
-    // Verify that the encapsulated packet parses as encapsulated.
-    PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
-    QuicLongHeaderType long_packet_type;
-    bool version_present;
-    bool has_length_prefix;
-    QuicVersionLabel version_label;
-    ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-    QuicConnectionId destination_connection_id, source_connection_id;
-    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,
-        &detailed_error);
-    ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
-    EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
-    EXPECT_TRUE(version_present);
-    EXPECT_FALSE(has_length_prefix);
-    EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
-    EXPECT_EQ(destination_connection_id, server_connection_id_);
-    EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
-    EXPECT_FALSE(retry_token.has_value());
-    EXPECT_TRUE(detailed_error.empty());
-  }
-
-  QuicByteCount Overhead() {
-    return QuicLegacyVersionEncapsulator::GetMinimumOverhead(sni_);
-  }
-
-  ParsedQuicVersion version_;
-  std::string sni_;
-  QuicConnectionId server_connection_id_;
-  QuicByteCount outer_max_packet_length_;
-  char outer_buffer_[kMaxOutgoingPacketSize];
-  QuicPacketLength encapsulated_length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicLegacyVersionEncapsulatorTests,
-                         QuicLegacyVersionEncapsulatorTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, Simple) {
-  Encapsulate("TEST_INNER_PACKET");
-  CheckEncapsulation();
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, TooBig) {
-  std::string inner_packet(kMaxOutgoingPacketSize, '?');
-  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
-  ASSERT_EQ(encapsulated_length_, 0u);
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, BarelyFits) {
-  QuicByteCount inner_size = kMaxOutgoingPacketSize - Overhead();
-  std::string inner_packet(inner_size, '?');
-  Encapsulate(inner_packet);
-  CheckEncapsulation();
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, DoesNotQuiteFit) {
-  QuicByteCount inner_size = 1 + kMaxOutgoingPacketSize - Overhead();
-  std::string inner_packet(inner_size, '?');
-  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
-  ASSERT_EQ(encapsulated_length_, 0u);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_creator.cc b/quiche/quic/core/quic_packet_creator.cc
index 6f29e52..ad4e785 100644
--- a/quiche/quic/core/quic_packet_creator.cc
+++ b/quiche/quic/core/quic_packet_creator.cc
@@ -1881,9 +1881,8 @@
     return;
   }
 
-  if (packet_.fate == COALESCE || packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
-    // Do not add full padding if the packet is going to be coalesced or
-    // encapsulated.
+  if (packet_.fate == COALESCE) {
+    // Do not add full padding if the packet is going to be coalesced.
     needs_full_padding_ = false;
   }
 
diff --git a/quiche/quic/core/quic_types.cc b/quiche/quic/core/quic_types.cc
index 6e74dd7..46b2fc2 100644
--- a/quiche/quic/core/quic_types.cc
+++ b/quiche/quic/core/quic_types.cc
@@ -297,7 +297,6 @@
     RETURN_STRING_LITERAL(COALESCE);
     RETURN_STRING_LITERAL(BUFFER);
     RETURN_STRING_LITERAL(SEND_TO_WRITER);
-    RETURN_STRING_LITERAL(LEGACY_VERSION_ENCAPSULATE);
   }
   return absl::StrCat("Unknown(", static_cast<int>(fate), ")");
 }
@@ -419,8 +418,6 @@
 
 bool operator==(const ParsedClientHello& a, const ParsedClientHello& b) {
   return a.sni == b.sni && a.uaid == b.uaid && a.alpns == b.alpns &&
-         a.legacy_version_encapsulation_inner_packet ==
-             b.legacy_version_encapsulation_inner_packet &&
          a.retry_token == b.retry_token &&
          a.resumption_attempted == b.resumption_attempted &&
          a.early_data_attempted == b.early_data_attempted;
@@ -430,9 +427,7 @@
                          const ParsedClientHello& parsed_chlo) {
   os << "{ sni:" << parsed_chlo.sni << ", uaid:" << parsed_chlo.uaid
      << ", alpns:" << quiche::PrintElements(parsed_chlo.alpns)
-     << ", len(retry_token):" << parsed_chlo.retry_token.size()
-     << ", len(inner_packet):"
-     << parsed_chlo.legacy_version_encapsulation_inner_packet.size() << " }";
+     << ", len(retry_token):" << parsed_chlo.retry_token.size() << " }";
   return os;
 }
 
diff --git a/quiche/quic/core/quic_types.h b/quiche/quic/core/quic_types.h
index ffaf6c6..1496625 100644
--- a/quiche/quic/core/quic_types.h
+++ b/quiche/quic/core/quic_types.h
@@ -710,8 +710,6 @@
   COALESCE,                    // Try to coalesce packet.
   BUFFER,                      // Buffer packet in buffered_packets_.
   SEND_TO_WRITER,              // Send packet to writer.
-  LEGACY_VERSION_ENCAPSULATE,  // Perform Legacy Version Encapsulation on this
-                               // packet.
 };
 
 QUIC_EXPORT_PRIVATE std::string SerializedPacketFateToString(
@@ -848,7 +846,6 @@
   std::string sni;                 // QUIC crypto and TLS.
   std::string uaid;                // QUIC crypto only.
   std::vector<std::string> alpns;  // QUIC crypto and TLS.
-  std::string legacy_version_encapsulation_inner_packet;  // QUIC crypto only.
   // The unvalidated retry token from the last received packet of a potentially
   // multi-packet client hello. TLS only.
   std::string retry_token;
diff --git a/quiche/quic/core/quic_versions.cc b/quiche/quic/core/quic_versions.cc
index cc9065b..89b58b5 100644
--- a/quiche/quic/core/quic_versions.cc
+++ b/quiche/quic/core/quic_versions.cc
@@ -631,10 +631,6 @@
   return ParsedQuicVersion::ReservedForNegotiation();
 }
 
-ParsedQuicVersion LegacyVersionForEncapsulation() {
-  return ParsedQuicVersion::Q043();
-}
-
 std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
   if (parsed_version == ParsedQuicVersion::V2Draft01()) {
     return "h3";
diff --git a/quiche/quic/core/quic_versions.h b/quiche/quic/core/quic_versions.h
index 39f8642..374db5d 100644
--- a/quiche/quic/core/quic_versions.h
+++ b/quiche/quic/core/quic_versions.h
@@ -383,10 +383,6 @@
 
 QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();
 
-// Outer version used when encapsulating other packets using the Legacy Version
-// Encapsulation feature.
-QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation();
-
 QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                              const ParsedQuicVersion& version);