Allow copy constructor of TransportParameters.

gfe-relnote: unused code. not protected.
PiperOrigin-RevId: 305522294
Change-Id: Ic954d44bf127b2aea85313a164f20d203693be44
diff --git a/quic/core/crypto/transport_parameters.cc b/quic/core/crypto/transport_parameters.cc
index 4cefcdd..4a6a0c7 100644
--- a/quic/core/crypto/transport_parameters.cc
+++ b/quic/core/crypto/transport_parameters.cc
@@ -7,9 +7,11 @@
 #include <cstdint>
 #include <cstring>
 #include <forward_list>
+#include <memory>
 #include <utility>
 
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
 #include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
 #include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
 #include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
@@ -413,9 +415,42 @@
       max_datagram_frame_size(kMaxDatagramFrameSize)
 // Important note: any new transport parameters must be added
 // to TransportParameters::AreValid, SerializeTransportParameters and
-// ParseTransportParameters.
+// ParseTransportParameters, TransportParameters's custom copy constructor, and
+// TransportParametersTest.CopyConstructor.
 {}
 
+TransportParameters::TransportParameters(const TransportParameters& other)
+    : perspective(other.perspective),
+      version(other.version),
+      supported_versions(other.supported_versions),
+      original_connection_id(other.original_connection_id),
+      idle_timeout_milliseconds(other.idle_timeout_milliseconds),
+      stateless_reset_token(other.stateless_reset_token),
+      max_packet_size(other.max_packet_size),
+      initial_max_data(other.initial_max_data),
+      initial_max_stream_data_bidi_local(
+          other.initial_max_stream_data_bidi_local),
+      initial_max_stream_data_bidi_remote(
+          other.initial_max_stream_data_bidi_remote),
+      initial_max_stream_data_uni(other.initial_max_stream_data_uni),
+      initial_max_streams_bidi(other.initial_max_streams_bidi),
+      initial_max_streams_uni(other.initial_max_streams_uni),
+      ack_delay_exponent(other.ack_delay_exponent),
+      max_ack_delay(other.max_ack_delay),
+      disable_migration(other.disable_migration),
+      active_connection_id_limit(other.active_connection_id_limit),
+      max_datagram_frame_size(other.max_datagram_frame_size),
+      custom_parameters(other.custom_parameters) {
+  if (other.preferred_address) {
+    preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
+        *other.preferred_address);
+  }
+  if (other.google_quic_params) {
+    google_quic_params =
+        std::make_unique<CryptoHandshakeMessage>(*other.google_quic_params);
+  }
+}
+
 bool TransportParameters::AreValid(std::string* error_details) const {
   DCHECK(perspective == Perspective::IS_CLIENT ||
          perspective == Perspective::IS_SERVER);
diff --git a/quic/core/crypto/transport_parameters.h b/quic/core/crypto/transport_parameters.h
index 831caec..e4737c2 100644
--- a/quic/core/crypto/transport_parameters.h
+++ b/quic/core/crypto/transport_parameters.h
@@ -35,7 +35,6 @@
    public:
     // Forbid constructing and copying apart from TransportParameters.
     IntegerParameter() = delete;
-    IntegerParameter(const IntegerParameter&) = delete;
     IntegerParameter& operator=(const IntegerParameter&) = delete;
     // Sets the value of this transport parameter.
     void set_value(uint64_t value);
@@ -67,6 +66,8 @@
                      uint64_t default_value,
                      uint64_t min_value,
                      uint64_t max_value);
+    IntegerParameter(const IntegerParameter& other) = default;
+    IntegerParameter(IntegerParameter&& other) = default;
     // Human-readable string representation.
     std::string ToString(bool for_use_in_list) const;
 
@@ -88,6 +89,8 @@
   // send to clients.
   struct QUIC_EXPORT_PRIVATE PreferredAddress {
     PreferredAddress();
+    PreferredAddress(const PreferredAddress& other) = default;
+    PreferredAddress(PreferredAddress&& other) = default;
     ~PreferredAddress();
 
     QuicSocketAddress ipv4_socket_address;
@@ -103,6 +106,7 @@
   };
 
   TransportParameters();
+  TransportParameters(const TransportParameters& other);
   ~TransportParameters();
 
   // Represents the sender of the transport parameters. When |perspective| is
diff --git a/quic/core/crypto/transport_parameters_test.cc b/quic/core/crypto/transport_parameters_test.cc
index bbcba74..51e5145 100644
--- a/quic/core/crypto/transport_parameters_test.cc
+++ b/quic/core/crypto/transport_parameters_test.cc
@@ -125,6 +125,77 @@
                          ::testing::ValuesIn(AllSupportedTlsVersions()),
                          ::testing::PrintToStringParamName());
 
+TEST_P(TransportParametersTest, CopyConstructor) {
+  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.original_connection_id = CreateFakeOriginalConnectionId();
+  orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.stateless_reset_token = CreateFakeStatelessResetToken();
+  orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kFakeAckDelayExponent);
+  orig_params.max_ack_delay.set_value(kFakeMaxAckDelay);
+  orig_params.disable_migration = kFakeDisableMigration;
+  orig_params.preferred_address = CreateFakePreferredAddress();
+  orig_params.active_connection_id_limit.set_value(
+      kFakeActiveConnectionIdLimit);
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  TransportParameters new_params(orig_params);
+  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]);
+  EXPECT_EQ(CreateFakeOriginalConnectionId(),
+            new_params.original_connection_id);
+  EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
+            new_params.idle_timeout_milliseconds.value());
+  EXPECT_EQ(CreateFakeStatelessResetToken(), new_params.stateless_reset_token);
+  EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
+  EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
+            new_params.initial_max_stream_data_bidi_local.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
+            new_params.initial_max_stream_data_bidi_remote.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataUni,
+            new_params.initial_max_stream_data_uni.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsBidi,
+            new_params.initial_max_streams_bidi.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsUni,
+            new_params.initial_max_streams_uni.value());
+  EXPECT_EQ(kFakeAckDelayExponent, new_params.ack_delay_exponent.value());
+  EXPECT_EQ(kFakeMaxAckDelay, new_params.max_ack_delay.value());
+  EXPECT_EQ(kFakeDisableMigration, new_params.disable_migration);
+  ASSERT_NE(nullptr, new_params.preferred_address.get());
+  EXPECT_EQ(CreateFakeV4SocketAddress(),
+            new_params.preferred_address->ipv4_socket_address);
+  EXPECT_EQ(CreateFakeV6SocketAddress(),
+            new_params.preferred_address->ipv6_socket_address);
+  EXPECT_EQ(CreateFakePreferredConnectionId(),
+            new_params.preferred_address->connection_id);
+  EXPECT_EQ(CreateFakePreferredStatelessResetToken(),
+            new_params.preferred_address->stateless_reset_token);
+  EXPECT_EQ(kFakeActiveConnectionIdLimit,
+            new_params.active_connection_id_limit.value());
+  EXPECT_THAT(
+      new_params.custom_parameters,
+      UnorderedElementsAre(Pair(kCustomParameter1, kCustomParameter1Value),
+                           Pair(kCustomParameter2, kCustomParameter2Value)));
+}
+
 TEST_P(TransportParametersTest, RoundTripClient) {
   TransportParameters orig_params;
   orig_params.perspective = Perspective::IS_CLIENT;