Refactor QUIC version downgrade prevention

This CL is the start of a series of CLs aimed at supporting draft-ietf-quic-version-negotiation. This CL refactors the Google QUIC version downgrade prevention transport parameter to better indicate that it is optional. This will make it easier to implement the IETF replacement and run both together during the transition period. This CL does not change any behavior, and is therefore not flag protected.

PiperOrigin-RevId: 408700446
diff --git a/quic/core/crypto/transport_parameters.cc b/quic/core/crypto/transport_parameters.cc
index fec6cc5..1ad7818 100644
--- a/quic/core/crypto/transport_parameters.cc
+++ b/quic/core/crypto/transport_parameters.cc
@@ -309,6 +309,38 @@
          "]";
 }
 
+TransportParameters::LegacyVersionInformation::LegacyVersionInformation()
+    : version(0) {}
+
+bool TransportParameters::LegacyVersionInformation::operator==(
+    const LegacyVersionInformation& rhs) const {
+  return version == rhs.version && supported_versions == rhs.supported_versions;
+}
+
+bool TransportParameters::LegacyVersionInformation::operator!=(
+    const LegacyVersionInformation& rhs) const {
+  return !(*this == rhs);
+}
+
+std::string TransportParameters::LegacyVersionInformation::ToString() const {
+  std::string rv =
+      absl::StrCat("legacy[version ", QuicVersionLabelToString(version));
+  if (!supported_versions.empty()) {
+    absl::StrAppend(&rv,
+                    " supported_versions " +
+                        QuicVersionLabelVectorToString(supported_versions));
+  }
+  absl::StrAppend(&rv, "]");
+  return rv;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const TransportParameters::LegacyVersionInformation&
+                             legacy_version_information) {
+  os << legacy_version_information.ToString();
+  return os;
+}
+
 std::ostream& operator<<(std::ostream& os, const TransportParameters& params) {
   os << params.ToString();
   return os;
@@ -321,12 +353,8 @@
   } else {
     rv += "Client";
   }
-  if (version != 0) {
-    rv += " version " + QuicVersionLabelToString(version);
-  }
-  if (!supported_versions.empty()) {
-    rv += " supported_versions " +
-          QuicVersionLabelVectorToString(supported_versions);
+  if (legacy_version_information.has_value()) {
+    rv += " " + legacy_version_information.value().ToString();
   }
   if (original_destination_connection_id.has_value()) {
     rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
@@ -403,12 +431,9 @@
 }
 
 TransportParameters::TransportParameters()
-    : version(0),
-      max_idle_timeout_ms(kMaxIdleTimeout),
-      max_udp_payload_size(kMaxPacketSize,
-                           kDefaultMaxPacketSizeTransportParam,
-                           kMinMaxPacketSizeTransportParam,
-                           kVarInt62MaxValue),
+    : max_idle_timeout_ms(kMaxIdleTimeout),
+      max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
+                           kMinMaxPacketSizeTransportParam, kVarInt62MaxValue),
       initial_max_data(kInitialMaxData),
       initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
       initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
@@ -416,16 +441,11 @@
       initial_max_streams_bidi(kInitialMaxStreamsBidi),
       initial_max_streams_uni(kInitialMaxStreamsUni),
       ack_delay_exponent(kAckDelayExponent,
-                         kDefaultAckDelayExponentTransportParam,
-                         0,
+                         kDefaultAckDelayExponentTransportParam, 0,
                          kMaxAckDelayExponentTransportParam),
-      max_ack_delay(kMaxAckDelay,
-                    kDefaultMaxAckDelayTransportParam,
-                    0,
+      max_ack_delay(kMaxAckDelay, kDefaultMaxAckDelayTransportParam, 0,
                     kMaxMaxAckDelayTransportParam),
-      min_ack_delay_us(kMinAckDelay,
-                       0,
-                       0,
+      min_ack_delay_us(kMinAckDelay, 0, 0,
                        kMaxMaxAckDelayTransportParam * kNumMicrosPerMilli),
       disable_active_migration(false),
       active_connection_id_limit(kActiveConnectionIdLimit,
@@ -443,8 +463,7 @@
 
 TransportParameters::TransportParameters(const TransportParameters& other)
     : perspective(other.perspective),
-      version(other.version),
-      supported_versions(other.supported_versions),
+      legacy_version_information(other.legacy_version_information),
       original_destination_connection_id(
           other.original_destination_connection_id),
       max_idle_timeout_ms(other.max_idle_timeout_ms),
@@ -478,8 +497,8 @@
 }
 
 bool TransportParameters::operator==(const TransportParameters& rhs) const {
-  if (!(perspective == rhs.perspective && version == rhs.version &&
-        supported_versions == rhs.supported_versions &&
+  if (!(perspective == rhs.perspective &&
+        legacy_version_information == rhs.legacy_version_information &&
         original_destination_connection_id ==
             rhs.original_destination_connection_id &&
         max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
@@ -616,8 +635,10 @@
         << "Not serializing invalid transport parameters: " << error_details;
     return false;
   }
-  if (in.version == 0 || (in.perspective == Perspective::IS_SERVER &&
-                          in.supported_versions.empty())) {
+  if (!in.legacy_version_information.has_value() ||
+      in.legacy_version_information.value().version == 0 ||
+      (in.perspective == Perspective::IS_SERVER &&
+       in.legacy_version_information.value().supported_versions.empty())) {
     QUIC_BUG(missing versions) << "Refusing to serialize without versions";
     return false;
   }
@@ -714,9 +735,13 @@
     max_transport_param_length += in.user_agent_id.value().length();
   }
   // Google-specific version extension.
-  max_transport_param_length +=
-      sizeof(in.version) + 1 /* versions length */ +
-      in.supported_versions.size() * sizeof(QuicVersionLabel);
+  if (in.legacy_version_information.has_value()) {
+    max_transport_param_length +=
+        sizeof(in.legacy_version_information.value().version) +
+        1 /* versions length */ +
+        in.legacy_version_information.value().supported_versions.size() *
+            sizeof(QuicVersionLabel);
+  }
 
   // Add a random GREASE transport parameter, as defined in the
   // "Reserved Transport Parameters" section of RFC 9000.
@@ -1051,30 +1076,38 @@
       } break;
       // Google-specific version extension.
       case TransportParameters::kGoogleQuicVersion: {
+        if (!in.legacy_version_information.has_value()) {
+          break;
+        }
         static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
                       "bad length");
-        uint64_t google_version_length = sizeof(in.version);
+        uint64_t google_version_length =
+            sizeof(in.legacy_version_information.value().version);
         if (in.perspective == Perspective::IS_SERVER) {
           google_version_length +=
               /* versions length */ sizeof(uint8_t) +
-              sizeof(QuicVersionLabel) * in.supported_versions.size();
+              sizeof(QuicVersionLabel) * in.legacy_version_information.value()
+                                             .supported_versions.size();
         }
         if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
             !writer.WriteVarInt62(
                 /* transport parameter length */ google_version_length) ||
-            !writer.WriteUInt32(in.version)) {
+            !writer.WriteUInt32(
+                in.legacy_version_information.value().version)) {
           QUIC_BUG(Failed to write Google version extension)
               << "Failed to write Google version extension for " << in;
           return false;
         }
         if (in.perspective == Perspective::IS_SERVER) {
           if (!writer.WriteUInt8(sizeof(QuicVersionLabel) *
-                                 in.supported_versions.size())) {
+                                 in.legacy_version_information.value()
+                                     .supported_versions.size())) {
             QUIC_BUG(Failed to write versions length)
                 << "Failed to write versions length for " << in;
             return false;
           }
-          for (QuicVersionLabel version_label : in.supported_versions) {
+          for (QuicVersionLabel version_label :
+               in.legacy_version_information.value().supported_versions) {
             if (!writer.WriteUInt32(version_label)) {
               QUIC_BUG(Failed to write supported version)
                   << "Failed to write supported version for " << in;
@@ -1377,7 +1410,12 @@
         out->key_update_not_yet_supported = true;
         break;
       case TransportParameters::kGoogleQuicVersion: {
-        if (!value_reader.ReadUInt32(&out->version)) {
+        if (!out->legacy_version_information.has_value()) {
+          out->legacy_version_information =
+              TransportParameters::LegacyVersionInformation();
+        }
+        if (!value_reader.ReadUInt32(
+                &out->legacy_version_information.value().version)) {
           *error_details = "Failed to read Google version extension version";
           return false;
         }
@@ -1394,7 +1432,8 @@
               *error_details = "Failed to parse Google supported version";
               return false;
             }
-            out->supported_versions.push_back(version);
+            out->legacy_version_information.value()
+                .supported_versions.push_back(version);
           }
         }
       } break;
diff --git a/quic/core/crypto/transport_parameters.h b/quic/core/crypto/transport_parameters.h
index b6ecb69..1d66ee9 100644
--- a/quic/core/crypto/transport_parameters.h
+++ b/quic/core/crypto/transport_parameters.h
@@ -110,6 +110,38 @@
         const TransportParameters& params);
   };
 
+  // LegacyVersionInformation represents the Google QUIC downgrade prevention
+  // mechanism ported to QUIC+TLS. It is exchanged using transport parameter ID
+  // 0x4752 and will eventually be deprecated in favor of
+  // draft-ietf-quic-version-negotiation.
+  struct QUIC_EXPORT_PRIVATE LegacyVersionInformation {
+    LegacyVersionInformation();
+    LegacyVersionInformation(const LegacyVersionInformation& other) = default;
+    LegacyVersionInformation& operator=(const LegacyVersionInformation& other) =
+        default;
+    LegacyVersionInformation& operator=(LegacyVersionInformation&& other) =
+        default;
+    LegacyVersionInformation(LegacyVersionInformation&& other) = default;
+    ~LegacyVersionInformation() = default;
+    bool operator==(const LegacyVersionInformation& rhs) const;
+    bool operator!=(const LegacyVersionInformation& rhs) const;
+    // When sent by the client, |version| is the initial version offered by the
+    // client (before any version negotiation packets) for this connection. When
+    // sent by the server, |version| is the version that is in use.
+    QuicVersionLabel version;
+
+    // When sent by the server, |supported_versions| contains a list of all
+    // versions that the server would send in a version negotiation packet. When
+    // sent by the client, this is empty.
+    QuicVersionLabelVector supported_versions;
+
+    // Allows easily logging.
+    std::string ToString() const;
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const LegacyVersionInformation& legacy_version_information);
+  };
+
   TransportParameters();
   TransportParameters(const TransportParameters& other);
   ~TransportParameters();
@@ -122,15 +154,8 @@
   // the encrypted_extensions handshake message.
   Perspective perspective;
 
-  // When Perspective::IS_CLIENT, |version| is the initial version offered by
-  // the client (before any version negotiation packets) for this connection.
-  // When Perspective::IS_SERVER, |version| is the version that is in use.
-  QuicVersionLabel version;
-
-  // |supported_versions| contains a list of all versions that the server would
-  // send in a version negotiation packet. It is not used if |perspective ==
-  // Perspective::IS_CLIENT|.
-  QuicVersionLabelVector supported_versions;
+  // Google QUIC downgrade prevention mechanism sent over QUIC+TLS.
+  absl::optional<LegacyVersionInformation> legacy_version_information;
 
   // The value of the Destination Connection ID field from the first
   // Initial packet sent by the client.
diff --git a/quic/core/crypto/transport_parameters_test.cc b/quic/core/crypto/transport_parameters_test.cc
index 05ada68..4ba0500 100644
--- a/quic/core/crypto/transport_parameters_test.cc
+++ b/quic/core/crypto/transport_parameters_test.cc
@@ -99,6 +99,22 @@
       preferred_address);
 }
 
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformationClient() {
+  TransportParameters::LegacyVersionInformation legacy_version_information;
+  legacy_version_information.version = kFakeVersionLabel;
+  return legacy_version_information;
+}
+
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformationServer() {
+  TransportParameters::LegacyVersionInformation legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
+  return legacy_version_information;
+}
+
 QuicTagVector CreateFakeGoogleConnectionOptions() {
   return {kALPN, MakeQuicTag('E', 'F', 'G', 0x00),
           MakeQuicTag('H', 'I', 'J', 0xff)};
@@ -145,8 +161,10 @@
   EXPECT_FALSE(orig_params == new_params);
   EXPECT_TRUE(orig_params != new_params);
   new_params.perspective = Perspective::IS_CLIENT;
-  orig_params.version = kFakeVersionLabel;
-  new_params.version = kFakeVersionLabel;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  new_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
   orig_params.disable_active_migration = true;
   new_params.disable_active_migration = true;
   EXPECT_EQ(orig_params, new_params);
@@ -154,13 +172,16 @@
   EXPECT_FALSE(orig_params != new_params);
 
   // Test comparison on vectors.
-  orig_params.supported_versions.push_back(kFakeVersionLabel);
-  new_params.supported_versions.push_back(kFakeVersionLabel2);
+  orig_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel);
+  new_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel2);
   EXPECT_NE(orig_params, new_params);
   EXPECT_FALSE(orig_params == new_params);
   EXPECT_TRUE(orig_params != new_params);
-  new_params.supported_versions.pop_back();
-  new_params.supported_versions.push_back(kFakeVersionLabel);
+  new_params.legacy_version_information.value().supported_versions.pop_back();
+  new_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel);
   orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
   new_params.stateless_reset_token = CreateStatelessResetTokenForTest();
   EXPECT_EQ(orig_params, new_params);
@@ -219,9 +240,8 @@
 TEST_P(TransportParametersTest, CopyConstructor) {
   TransportParameters orig_params;
   orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.version = kFakeVersionLabel;
-  orig_params.supported_versions.push_back(kFakeVersionLabel);
-  orig_params.supported_versions.push_back(kFakeVersionLabel2);
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
   orig_params.original_destination_connection_id =
       CreateFakeOriginalDestinationConnectionId();
   orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
@@ -260,7 +280,8 @@
 TEST_P(TransportParametersTest, RoundTripClient) {
   TransportParameters orig_params;
   orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.version = kFakeVersionLabel;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
   orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
   orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
   orig_params.initial_max_data.set_value(kFakeInitialMaxData);
@@ -308,9 +329,8 @@
 TEST_P(TransportParametersTest, RoundTripServer) {
   TransportParameters orig_params;
   orig_params.perspective = Perspective::IS_SERVER;
-  orig_params.version = kFakeVersionLabel;
-  orig_params.supported_versions.push_back(kFakeVersionLabel);
-  orig_params.supported_versions.push_back(kFakeVersionLabel2);
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationServer();
   orig_params.original_destination_connection_id =
       CreateFakeOriginalDestinationConnectionId();
   orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
@@ -446,7 +466,8 @@
 TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
   TransportParameters orig_params;
   orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.version = kFakeVersionLabel;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
   orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
   orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
   orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
@@ -552,8 +573,11 @@
       << error_details;
   EXPECT_TRUE(error_details.empty());
   EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
-  EXPECT_EQ(kFakeVersionLabel, new_params.version);
-  EXPECT_TRUE(new_params.supported_versions.empty());
+  ASSERT_TRUE(new_params.legacy_version_information.has_value());
+  EXPECT_EQ(kFakeVersionLabel,
+            new_params.legacy_version_information.value().version);
+  EXPECT_TRUE(
+      new_params.legacy_version_information.value().supported_versions.empty());
   EXPECT_FALSE(new_params.original_destination_connection_id.has_value());
   EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
             new_params.max_idle_timeout_ms.value());
@@ -803,10 +827,18 @@
       << error_details;
   EXPECT_TRUE(error_details.empty());
   EXPECT_EQ(Perspective::IS_SERVER, new_params.perspective);
-  EXPECT_EQ(kFakeVersionLabel, new_params.version);
-  EXPECT_EQ(2u, new_params.supported_versions.size());
-  EXPECT_EQ(kFakeVersionLabel, new_params.supported_versions[0]);
-  EXPECT_EQ(kFakeVersionLabel2, new_params.supported_versions[1]);
+  ASSERT_TRUE(new_params.legacy_version_information.has_value());
+  EXPECT_EQ(kFakeVersionLabel,
+            new_params.legacy_version_information.value().version);
+  ASSERT_EQ(
+      2u,
+      new_params.legacy_version_information.value().supported_versions.size());
+  EXPECT_EQ(
+      kFakeVersionLabel,
+      new_params.legacy_version_information.value().supported_versions[0]);
+  EXPECT_EQ(
+      kFakeVersionLabel2,
+      new_params.legacy_version_information.value().supported_versions[1]);
   ASSERT_TRUE(new_params.original_destination_connection_id.has_value());
   EXPECT_EQ(CreateFakeOriginalDestinationConnectionId(),
             new_params.original_destination_connection_id.value());
@@ -927,7 +959,8 @@
   std::string custom_value(70000, '?');
   TransportParameters orig_params;
   orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.version = kFakeVersionLabel;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
   orig_params.custom_parameters[kCustomParameter1] = custom_value;
 
   std::vector<uint8_t> serialized;
@@ -947,7 +980,8 @@
 TEST_P(TransportParametersTest, SerializationOrderIsRandom) {
   TransportParameters orig_params;
   orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.version = kFakeVersionLabel;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
   orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
   orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
   orig_params.initial_max_data.set_value(kFakeInitialMaxData);
@@ -994,9 +1028,8 @@
  protected:
   void SetUp() override {
     original_params_.perspective = Perspective::IS_SERVER;
-    original_params_.version = kFakeVersionLabel;
-    original_params_.supported_versions.push_back(kFakeVersionLabel);
-    original_params_.supported_versions.push_back(kFakeVersionLabel2);
+    original_params_.legacy_version_information =
+        CreateFakeLegacyVersionInformationServer();
     original_params_.original_destination_connection_id =
         CreateFakeOriginalDestinationConnectionId();
     original_params_.max_idle_timeout_ms.set_value(
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index 2717db0..b2abf33 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -221,7 +221,9 @@
 bool TlsClientHandshaker::SetTransportParameters() {
   TransportParameters params;
   params.perspective = Perspective::IS_CLIENT;
-  params.version =
+  params.legacy_version_information =
+      TransportParameters::LegacyVersionInformation();
+  params.legacy_version_information.value().version =
       CreateQuicVersionLabel(session()->supported_versions().front());
 
   if (!handshaker_delegate()->FillTransportParameters(&params)) {
@@ -268,22 +270,31 @@
 
   // When interoperating with non-Google implementations that do not send
   // the version extension, set it to what we expect.
-  if (received_transport_params_->version == 0) {
-    received_transport_params_->version =
+  if (!received_transport_params_->legacy_version_information.has_value()) {
+    received_transport_params_->legacy_version_information =
+        TransportParameters::LegacyVersionInformation();
+  }
+  if (received_transport_params_->legacy_version_information.value().version ==
+      0) {
+    received_transport_params_->legacy_version_information.value().version =
         CreateQuicVersionLabel(session()->connection()->version());
   }
-  if (received_transport_params_->supported_versions.empty()) {
-    received_transport_params_->supported_versions.push_back(
-        received_transport_params_->version);
+  if (received_transport_params_->legacy_version_information.value()
+          .supported_versions.empty()) {
+    received_transport_params_->legacy_version_information.value()
+        .supported_versions.push_back(
+            received_transport_params_->legacy_version_information.value()
+                .version);
   }
 
-  if (received_transport_params_->version !=
+  if (received_transport_params_->legacy_version_information.value().version !=
       CreateQuicVersionLabel(session()->connection()->version())) {
     *error_details = "Version mismatch detected";
     return false;
   }
   if (CryptoUtils::ValidateServerHelloVersions(
-          received_transport_params_->supported_versions,
+          received_transport_params_->legacy_version_information.value()
+              .supported_versions,
           session()->connection()->server_supported_versions(),
           error_details) != QUIC_NO_ERROR ||
       handshaker_delegate()->ProcessTransportParameters(
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index 49bd5a0..a36f97d 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -502,14 +502,19 @@
 
   // When interoperating with non-Google implementations that do not send
   // the version extension, set it to what we expect.
-  if (client_params.version == 0) {
-    client_params.version =
+  if (!client_params.legacy_version_information.has_value()) {
+    client_params.legacy_version_information =
+        TransportParameters::LegacyVersionInformation();
+  }
+  if (client_params.legacy_version_information.value().version == 0) {
+    client_params.legacy_version_information.value().version =
         CreateQuicVersionLabel(session()->connection()->version());
   }
 
   if (CryptoUtils::ValidateClientHelloVersion(
-          client_params.version, session()->connection()->version(),
-          session()->supported_versions(), error_details) != QUIC_NO_ERROR ||
+          client_params.legacy_version_information.value().version,
+          session()->connection()->version(), session()->supported_versions(),
+          error_details) != QUIC_NO_ERROR ||
       handshaker_delegate()->ProcessTransportParameters(
           client_params, /* is_resumption = */ false, error_details) !=
           QUIC_NO_ERROR) {
@@ -531,9 +536,11 @@
 
   TransportParameters server_params;
   server_params.perspective = Perspective::IS_SERVER;
-  server_params.supported_versions =
+  server_params.legacy_version_information =
+      TransportParameters::LegacyVersionInformation();
+  server_params.legacy_version_information.value().supported_versions =
       CreateQuicVersionLabelVector(session()->supported_versions());
-  server_params.version =
+  server_params.legacy_version_information.value().version =
       CreateQuicVersionLabel(session()->connection()->version());
 
   if (!handshaker_delegate()->FillTransportParameters(&server_params)) {