• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/crypto/transport_parameters.h"
6 
7 #include <cstdint>
8 #include <cstring>
9 #include <forward_list>
10 #include <memory>
11 #include <utility>
12 
13 #include "absl/strings/escaping.h"
14 #include "absl/strings/str_cat.h"
15 #include "absl/strings/string_view.h"
16 #include "openssl/digest.h"
17 #include "openssl/sha.h"
18 #include "quiche/quic/core/quic_connection_id.h"
19 #include "quiche/quic/core/quic_data_reader.h"
20 #include "quiche/quic/core/quic_data_writer.h"
21 #include "quiche/quic/core/quic_types.h"
22 #include "quiche/quic/core/quic_utils.h"
23 #include "quiche/quic/core/quic_versions.h"
24 #include "quiche/quic/platform/api/quic_bug_tracker.h"
25 #include "quiche/quic/platform/api/quic_flag_utils.h"
26 #include "quiche/quic/platform/api/quic_ip_address.h"
27 
28 namespace quic {
29 
30 // Values of the TransportParameterId enum as defined in the
31 // "Transport Parameter Encoding" section of draft-ietf-quic-transport.
32 // When parameters are encoded, one of these enum values is used to indicate
33 // which parameter is encoded. The supported draft version is noted in
34 // transport_parameters.h.
35 enum TransportParameters::TransportParameterId : uint64_t {
36   kOriginalDestinationConnectionId = 0,
37   kMaxIdleTimeout = 1,
38   kStatelessResetToken = 2,
39   kMaxPacketSize = 3,
40   kInitialMaxData = 4,
41   kInitialMaxStreamDataBidiLocal = 5,
42   kInitialMaxStreamDataBidiRemote = 6,
43   kInitialMaxStreamDataUni = 7,
44   kInitialMaxStreamsBidi = 8,
45   kInitialMaxStreamsUni = 9,
46   kAckDelayExponent = 0xa,
47   kMaxAckDelay = 0xb,
48   kDisableActiveMigration = 0xc,
49   kPreferredAddress = 0xd,
50   kActiveConnectionIdLimit = 0xe,
51   kInitialSourceConnectionId = 0xf,
52   kRetrySourceConnectionId = 0x10,
53 
54   kMaxDatagramFrameSize = 0x20,
55 
56   kGoogleHandshakeMessage = 0x26ab,
57 
58   kInitialRoundTripTime = 0x3127,
59   kGoogleConnectionOptions = 0x3128,
60   // 0x3129 was used to convey the user agent string.
61   // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
62   // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
63   // 0x4751 was used for non-standard Google-specific parameters encoded as a
64   // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
65   kGoogleQuicVersion =
66       0x4752,  // Used to transmit version and supported_versions.
67 
68   kMinAckDelay = 0xDE1A,           // draft-iyengar-quic-delayed-ack.
69   kVersionInformation = 0xFF73DB,  // draft-ietf-quic-version-negotiation.
70 };
71 
72 namespace {
73 
74 constexpr QuicVersionLabel kReservedVersionMask = 0x0f0f0f0f;
75 constexpr QuicVersionLabel kReservedVersionBits = 0x0a0a0a0a;
76 
77 // The following constants define minimum and maximum allowed values for some of
78 // the parameters. These come from the "Transport Parameter Definitions"
79 // section of draft-ietf-quic-transport.
80 constexpr uint64_t kMinMaxPacketSizeTransportParam = 1200;
81 constexpr uint64_t kMaxAckDelayExponentTransportParam = 20;
82 constexpr uint64_t kDefaultAckDelayExponentTransportParam = 3;
83 constexpr uint64_t kMaxMaxAckDelayTransportParam = 16383;
84 constexpr uint64_t kDefaultMaxAckDelayTransportParam = 25;
85 constexpr uint64_t kMinActiveConnectionIdLimitTransportParam = 2;
86 constexpr uint64_t kDefaultActiveConnectionIdLimitTransportParam = 2;
87 
TransportParameterIdToString(TransportParameters::TransportParameterId param_id)88 std::string TransportParameterIdToString(
89     TransportParameters::TransportParameterId param_id) {
90   switch (param_id) {
91     case TransportParameters::kOriginalDestinationConnectionId:
92       return "original_destination_connection_id";
93     case TransportParameters::kMaxIdleTimeout:
94       return "max_idle_timeout";
95     case TransportParameters::kStatelessResetToken:
96       return "stateless_reset_token";
97     case TransportParameters::kMaxPacketSize:
98       return "max_udp_payload_size";
99     case TransportParameters::kInitialMaxData:
100       return "initial_max_data";
101     case TransportParameters::kInitialMaxStreamDataBidiLocal:
102       return "initial_max_stream_data_bidi_local";
103     case TransportParameters::kInitialMaxStreamDataBidiRemote:
104       return "initial_max_stream_data_bidi_remote";
105     case TransportParameters::kInitialMaxStreamDataUni:
106       return "initial_max_stream_data_uni";
107     case TransportParameters::kInitialMaxStreamsBidi:
108       return "initial_max_streams_bidi";
109     case TransportParameters::kInitialMaxStreamsUni:
110       return "initial_max_streams_uni";
111     case TransportParameters::kAckDelayExponent:
112       return "ack_delay_exponent";
113     case TransportParameters::kMaxAckDelay:
114       return "max_ack_delay";
115     case TransportParameters::kDisableActiveMigration:
116       return "disable_active_migration";
117     case TransportParameters::kPreferredAddress:
118       return "preferred_address";
119     case TransportParameters::kActiveConnectionIdLimit:
120       return "active_connection_id_limit";
121     case TransportParameters::kInitialSourceConnectionId:
122       return "initial_source_connection_id";
123     case TransportParameters::kRetrySourceConnectionId:
124       return "retry_source_connection_id";
125     case TransportParameters::kMaxDatagramFrameSize:
126       return "max_datagram_frame_size";
127     case TransportParameters::kGoogleHandshakeMessage:
128       return "google_handshake_message";
129     case TransportParameters::kInitialRoundTripTime:
130       return "initial_round_trip_time";
131     case TransportParameters::kGoogleConnectionOptions:
132       return "google_connection_options";
133     case TransportParameters::kGoogleQuicVersion:
134       return "google-version";
135     case TransportParameters::kMinAckDelay:
136       return "min_ack_delay_us";
137     case TransportParameters::kVersionInformation:
138       return "version_information";
139   }
140   return absl::StrCat("Unknown(", param_id, ")");
141 }
142 
TransportParameterIdIsKnown(TransportParameters::TransportParameterId param_id)143 bool TransportParameterIdIsKnown(
144     TransportParameters::TransportParameterId param_id) {
145   switch (param_id) {
146     case TransportParameters::kOriginalDestinationConnectionId:
147     case TransportParameters::kMaxIdleTimeout:
148     case TransportParameters::kStatelessResetToken:
149     case TransportParameters::kMaxPacketSize:
150     case TransportParameters::kInitialMaxData:
151     case TransportParameters::kInitialMaxStreamDataBidiLocal:
152     case TransportParameters::kInitialMaxStreamDataBidiRemote:
153     case TransportParameters::kInitialMaxStreamDataUni:
154     case TransportParameters::kInitialMaxStreamsBidi:
155     case TransportParameters::kInitialMaxStreamsUni:
156     case TransportParameters::kAckDelayExponent:
157     case TransportParameters::kMaxAckDelay:
158     case TransportParameters::kDisableActiveMigration:
159     case TransportParameters::kPreferredAddress:
160     case TransportParameters::kActiveConnectionIdLimit:
161     case TransportParameters::kInitialSourceConnectionId:
162     case TransportParameters::kRetrySourceConnectionId:
163     case TransportParameters::kMaxDatagramFrameSize:
164     case TransportParameters::kGoogleHandshakeMessage:
165     case TransportParameters::kInitialRoundTripTime:
166     case TransportParameters::kGoogleConnectionOptions:
167     case TransportParameters::kGoogleQuicVersion:
168     case TransportParameters::kMinAckDelay:
169     case TransportParameters::kVersionInformation:
170       return true;
171   }
172   return false;
173 }
174 
175 }  // namespace
176 
IntegerParameter(TransportParameters::TransportParameterId param_id,uint64_t default_value,uint64_t min_value,uint64_t max_value)177 TransportParameters::IntegerParameter::IntegerParameter(
178     TransportParameters::TransportParameterId param_id, uint64_t default_value,
179     uint64_t min_value, uint64_t max_value)
180     : param_id_(param_id),
181       value_(default_value),
182       default_value_(default_value),
183       min_value_(min_value),
184       max_value_(max_value),
185       has_been_read_(false) {
186   QUICHE_DCHECK_LE(min_value, default_value);
187   QUICHE_DCHECK_LE(default_value, max_value);
188   QUICHE_DCHECK_LE(max_value, quiche::kVarInt62MaxValue);
189 }
190 
IntegerParameter(TransportParameters::TransportParameterId param_id)191 TransportParameters::IntegerParameter::IntegerParameter(
192     TransportParameters::TransportParameterId param_id)
193     : TransportParameters::IntegerParameter::IntegerParameter(
194           param_id, 0, 0, quiche::kVarInt62MaxValue) {}
195 
set_value(uint64_t value)196 void TransportParameters::IntegerParameter::set_value(uint64_t value) {
197   value_ = value;
198 }
199 
value() const200 uint64_t TransportParameters::IntegerParameter::value() const { return value_; }
201 
IsValid() const202 bool TransportParameters::IntegerParameter::IsValid() const {
203   return min_value_ <= value_ && value_ <= max_value_;
204 }
205 
Write(QuicDataWriter * writer) const206 bool TransportParameters::IntegerParameter::Write(
207     QuicDataWriter* writer) const {
208   QUICHE_DCHECK(IsValid());
209   if (value_ == default_value_) {
210     // Do not write if the value is default.
211     return true;
212   }
213   if (!writer->WriteVarInt62(param_id_)) {
214     QUIC_BUG(quic_bug_10743_1) << "Failed to write param_id for " << *this;
215     return false;
216   }
217   const quiche::QuicheVariableLengthIntegerLength value_length =
218       QuicDataWriter::GetVarInt62Len(value_);
219   if (!writer->WriteVarInt62(value_length)) {
220     QUIC_BUG(quic_bug_10743_2) << "Failed to write value_length for " << *this;
221     return false;
222   }
223   if (!writer->WriteVarInt62WithForcedLength(value_, value_length)) {
224     QUIC_BUG(quic_bug_10743_3) << "Failed to write value for " << *this;
225     return false;
226   }
227   return true;
228 }
229 
Read(QuicDataReader * reader,std::string * error_details)230 bool TransportParameters::IntegerParameter::Read(QuicDataReader* reader,
231                                                  std::string* error_details) {
232   if (has_been_read_) {
233     *error_details =
234         "Received a second " + TransportParameterIdToString(param_id_);
235     return false;
236   }
237   has_been_read_ = true;
238 
239   if (!reader->ReadVarInt62(&value_)) {
240     *error_details =
241         "Failed to parse value for " + TransportParameterIdToString(param_id_);
242     return false;
243   }
244   if (!reader->IsDoneReading()) {
245     *error_details =
246         absl::StrCat("Received unexpected ", reader->BytesRemaining(),
247                      " bytes after parsing ", this->ToString(false));
248     return false;
249   }
250   return true;
251 }
252 
ToString(bool for_use_in_list) const253 std::string TransportParameters::IntegerParameter::ToString(
254     bool for_use_in_list) const {
255   if (for_use_in_list && value_ == default_value_) {
256     return "";
257   }
258   std::string rv = for_use_in_list ? " " : "";
259   absl::StrAppend(&rv, TransportParameterIdToString(param_id_), " ", value_);
260   if (!IsValid()) {
261     rv += " (Invalid)";
262   }
263   return rv;
264 }
265 
operator <<(std::ostream & os,const TransportParameters::IntegerParameter & param)266 std::ostream& operator<<(std::ostream& os,
267                          const TransportParameters::IntegerParameter& param) {
268   os << param.ToString(/*for_use_in_list=*/false);
269   return os;
270 }
271 
PreferredAddress()272 TransportParameters::PreferredAddress::PreferredAddress()
273     : ipv4_socket_address(QuicIpAddress::Any4(), 0),
274       ipv6_socket_address(QuicIpAddress::Any6(), 0),
275       connection_id(EmptyQuicConnectionId()),
276       stateless_reset_token(kStatelessResetTokenLength, 0) {}
277 
~PreferredAddress()278 TransportParameters::PreferredAddress::~PreferredAddress() {}
279 
operator ==(const PreferredAddress & rhs) const280 bool TransportParameters::PreferredAddress::operator==(
281     const PreferredAddress& rhs) const {
282   return ipv4_socket_address == rhs.ipv4_socket_address &&
283          ipv6_socket_address == rhs.ipv6_socket_address &&
284          connection_id == rhs.connection_id &&
285          stateless_reset_token == rhs.stateless_reset_token;
286 }
287 
operator !=(const PreferredAddress & rhs) const288 bool TransportParameters::PreferredAddress::operator!=(
289     const PreferredAddress& rhs) const {
290   return !(*this == rhs);
291 }
292 
operator <<(std::ostream & os,const TransportParameters::PreferredAddress & preferred_address)293 std::ostream& operator<<(
294     std::ostream& os,
295     const TransportParameters::PreferredAddress& preferred_address) {
296   os << preferred_address.ToString();
297   return os;
298 }
299 
ToString() const300 std::string TransportParameters::PreferredAddress::ToString() const {
301   return "[" + ipv4_socket_address.ToString() + " " +
302          ipv6_socket_address.ToString() + " connection_id " +
303          connection_id.ToString() + " stateless_reset_token " +
304          absl::BytesToHexString(absl::string_view(
305              reinterpret_cast<const char*>(stateless_reset_token.data()),
306              stateless_reset_token.size())) +
307          "]";
308 }
309 
LegacyVersionInformation()310 TransportParameters::LegacyVersionInformation::LegacyVersionInformation()
311     : version(0) {}
312 
operator ==(const LegacyVersionInformation & rhs) const313 bool TransportParameters::LegacyVersionInformation::operator==(
314     const LegacyVersionInformation& rhs) const {
315   return version == rhs.version && supported_versions == rhs.supported_versions;
316 }
317 
operator !=(const LegacyVersionInformation & rhs) const318 bool TransportParameters::LegacyVersionInformation::operator!=(
319     const LegacyVersionInformation& rhs) const {
320   return !(*this == rhs);
321 }
322 
ToString() const323 std::string TransportParameters::LegacyVersionInformation::ToString() const {
324   std::string rv =
325       absl::StrCat("legacy[version ", QuicVersionLabelToString(version));
326   if (!supported_versions.empty()) {
327     absl::StrAppend(&rv,
328                     " supported_versions " +
329                         QuicVersionLabelVectorToString(supported_versions));
330   }
331   absl::StrAppend(&rv, "]");
332   return rv;
333 }
334 
operator <<(std::ostream & os,const TransportParameters::LegacyVersionInformation & legacy_version_information)335 std::ostream& operator<<(std::ostream& os,
336                          const TransportParameters::LegacyVersionInformation&
337                              legacy_version_information) {
338   os << legacy_version_information.ToString();
339   return os;
340 }
341 
VersionInformation()342 TransportParameters::VersionInformation::VersionInformation()
343     : chosen_version(0) {}
344 
operator ==(const VersionInformation & rhs) const345 bool TransportParameters::VersionInformation::operator==(
346     const VersionInformation& rhs) const {
347   return chosen_version == rhs.chosen_version &&
348          other_versions == rhs.other_versions;
349 }
350 
operator !=(const VersionInformation & rhs) const351 bool TransportParameters::VersionInformation::operator!=(
352     const VersionInformation& rhs) const {
353   return !(*this == rhs);
354 }
355 
ToString() const356 std::string TransportParameters::VersionInformation::ToString() const {
357   std::string rv = absl::StrCat("[chosen_version ",
358                                 QuicVersionLabelToString(chosen_version));
359   if (!other_versions.empty()) {
360     absl::StrAppend(&rv, " other_versions " +
361                              QuicVersionLabelVectorToString(other_versions));
362   }
363   absl::StrAppend(&rv, "]");
364   return rv;
365 }
366 
operator <<(std::ostream & os,const TransportParameters::VersionInformation & version_information)367 std::ostream& operator<<(
368     std::ostream& os,
369     const TransportParameters::VersionInformation& version_information) {
370   os << version_information.ToString();
371   return os;
372 }
373 
operator <<(std::ostream & os,const TransportParameters & params)374 std::ostream& operator<<(std::ostream& os, const TransportParameters& params) {
375   os << params.ToString();
376   return os;
377 }
378 
ToString() const379 std::string TransportParameters::ToString() const {
380   std::string rv = "[";
381   if (perspective == Perspective::IS_SERVER) {
382     rv += "Server";
383   } else {
384     rv += "Client";
385   }
386   if (legacy_version_information.has_value()) {
387     rv += " " + legacy_version_information.value().ToString();
388   }
389   if (version_information.has_value()) {
390     rv += " " + version_information.value().ToString();
391   }
392   if (original_destination_connection_id.has_value()) {
393     rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
394           " " + original_destination_connection_id.value().ToString();
395   }
396   rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
397   if (!stateless_reset_token.empty()) {
398     rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
399           absl::BytesToHexString(absl::string_view(
400               reinterpret_cast<const char*>(stateless_reset_token.data()),
401               stateless_reset_token.size()));
402   }
403   rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
404   rv += initial_max_data.ToString(/*for_use_in_list=*/true);
405   rv += initial_max_stream_data_bidi_local.ToString(/*for_use_in_list=*/true);
406   rv += initial_max_stream_data_bidi_remote.ToString(/*for_use_in_list=*/true);
407   rv += initial_max_stream_data_uni.ToString(/*for_use_in_list=*/true);
408   rv += initial_max_streams_bidi.ToString(/*for_use_in_list=*/true);
409   rv += initial_max_streams_uni.ToString(/*for_use_in_list=*/true);
410   rv += ack_delay_exponent.ToString(/*for_use_in_list=*/true);
411   rv += max_ack_delay.ToString(/*for_use_in_list=*/true);
412   rv += min_ack_delay_us.ToString(/*for_use_in_list=*/true);
413   if (disable_active_migration) {
414     rv += " " + TransportParameterIdToString(kDisableActiveMigration);
415   }
416   if (preferred_address) {
417     rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
418           preferred_address->ToString();
419   }
420   rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
421   if (initial_source_connection_id.has_value()) {
422     rv += " " + TransportParameterIdToString(kInitialSourceConnectionId) + " " +
423           initial_source_connection_id.value().ToString();
424   }
425   if (retry_source_connection_id.has_value()) {
426     rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
427           retry_source_connection_id.value().ToString();
428   }
429   rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true);
430   if (google_handshake_message.has_value()) {
431     absl::StrAppend(&rv, " ",
432                     TransportParameterIdToString(kGoogleHandshakeMessage),
433                     " length: ", google_handshake_message.value().length());
434   }
435   rv += initial_round_trip_time_us.ToString(/*for_use_in_list=*/true);
436   if (google_connection_options.has_value()) {
437     rv += " " + TransportParameterIdToString(kGoogleConnectionOptions) + " ";
438     bool first = true;
439     for (const QuicTag& connection_option : google_connection_options.value()) {
440       if (first) {
441         first = false;
442       } else {
443         rv += ",";
444       }
445       rv += QuicTagToString(connection_option);
446     }
447   }
448   for (const auto& kv : custom_parameters) {
449     absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
450                     "=");
451     static constexpr size_t kMaxPrintableLength = 32;
452     if (kv.second.length() <= kMaxPrintableLength) {
453       rv += absl::BytesToHexString(kv.second);
454     } else {
455       absl::string_view truncated(kv.second.data(), kMaxPrintableLength);
456       rv += absl::StrCat(absl::BytesToHexString(truncated), "...(length ",
457                          kv.second.length(), ")");
458     }
459   }
460   rv += "]";
461   return rv;
462 }
463 
TransportParameters()464 TransportParameters::TransportParameters()
465     : max_idle_timeout_ms(kMaxIdleTimeout),
466       max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
467                            kMinMaxPacketSizeTransportParam,
468                            quiche::kVarInt62MaxValue),
469       initial_max_data(kInitialMaxData),
470       initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
471       initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
472       initial_max_stream_data_uni(kInitialMaxStreamDataUni),
473       initial_max_streams_bidi(kInitialMaxStreamsBidi),
474       initial_max_streams_uni(kInitialMaxStreamsUni),
475       ack_delay_exponent(kAckDelayExponent,
476                          kDefaultAckDelayExponentTransportParam, 0,
477                          kMaxAckDelayExponentTransportParam),
478       max_ack_delay(kMaxAckDelay, kDefaultMaxAckDelayTransportParam, 0,
479                     kMaxMaxAckDelayTransportParam),
480       min_ack_delay_us(kMinAckDelay, 0, 0,
481                        kMaxMaxAckDelayTransportParam * kNumMicrosPerMilli),
482       disable_active_migration(false),
483       active_connection_id_limit(kActiveConnectionIdLimit,
484                                  kDefaultActiveConnectionIdLimitTransportParam,
485                                  kMinActiveConnectionIdLimitTransportParam,
486                                  quiche::kVarInt62MaxValue),
487       max_datagram_frame_size(kMaxDatagramFrameSize),
488       initial_round_trip_time_us(kInitialRoundTripTime)
489 // Important note: any new transport parameters must be added
490 // to TransportParameters::AreValid, SerializeTransportParameters and
491 // ParseTransportParameters, TransportParameters's custom copy constructor, the
492 // operator==, and TransportParametersTest.Comparator.
493 {}
494 
TransportParameters(const TransportParameters & other)495 TransportParameters::TransportParameters(const TransportParameters& other)
496     : perspective(other.perspective),
497       legacy_version_information(other.legacy_version_information),
498       version_information(other.version_information),
499       original_destination_connection_id(
500           other.original_destination_connection_id),
501       max_idle_timeout_ms(other.max_idle_timeout_ms),
502       stateless_reset_token(other.stateless_reset_token),
503       max_udp_payload_size(other.max_udp_payload_size),
504       initial_max_data(other.initial_max_data),
505       initial_max_stream_data_bidi_local(
506           other.initial_max_stream_data_bidi_local),
507       initial_max_stream_data_bidi_remote(
508           other.initial_max_stream_data_bidi_remote),
509       initial_max_stream_data_uni(other.initial_max_stream_data_uni),
510       initial_max_streams_bidi(other.initial_max_streams_bidi),
511       initial_max_streams_uni(other.initial_max_streams_uni),
512       ack_delay_exponent(other.ack_delay_exponent),
513       max_ack_delay(other.max_ack_delay),
514       min_ack_delay_us(other.min_ack_delay_us),
515       disable_active_migration(other.disable_active_migration),
516       active_connection_id_limit(other.active_connection_id_limit),
517       initial_source_connection_id(other.initial_source_connection_id),
518       retry_source_connection_id(other.retry_source_connection_id),
519       max_datagram_frame_size(other.max_datagram_frame_size),
520       initial_round_trip_time_us(other.initial_round_trip_time_us),
521       google_handshake_message(other.google_handshake_message),
522       google_connection_options(other.google_connection_options),
523       custom_parameters(other.custom_parameters) {
524   if (other.preferred_address) {
525     preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
526         *other.preferred_address);
527   }
528 }
529 
operator ==(const TransportParameters & rhs) const530 bool TransportParameters::operator==(const TransportParameters& rhs) const {
531   if (!(perspective == rhs.perspective &&
532         legacy_version_information == rhs.legacy_version_information &&
533         version_information == rhs.version_information &&
534         original_destination_connection_id ==
535             rhs.original_destination_connection_id &&
536         max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
537         stateless_reset_token == rhs.stateless_reset_token &&
538         max_udp_payload_size.value() == rhs.max_udp_payload_size.value() &&
539         initial_max_data.value() == rhs.initial_max_data.value() &&
540         initial_max_stream_data_bidi_local.value() ==
541             rhs.initial_max_stream_data_bidi_local.value() &&
542         initial_max_stream_data_bidi_remote.value() ==
543             rhs.initial_max_stream_data_bidi_remote.value() &&
544         initial_max_stream_data_uni.value() ==
545             rhs.initial_max_stream_data_uni.value() &&
546         initial_max_streams_bidi.value() ==
547             rhs.initial_max_streams_bidi.value() &&
548         initial_max_streams_uni.value() ==
549             rhs.initial_max_streams_uni.value() &&
550         ack_delay_exponent.value() == rhs.ack_delay_exponent.value() &&
551         max_ack_delay.value() == rhs.max_ack_delay.value() &&
552         min_ack_delay_us.value() == rhs.min_ack_delay_us.value() &&
553         disable_active_migration == rhs.disable_active_migration &&
554         active_connection_id_limit.value() ==
555             rhs.active_connection_id_limit.value() &&
556         initial_source_connection_id == rhs.initial_source_connection_id &&
557         retry_source_connection_id == rhs.retry_source_connection_id &&
558         max_datagram_frame_size.value() ==
559             rhs.max_datagram_frame_size.value() &&
560         initial_round_trip_time_us.value() ==
561             rhs.initial_round_trip_time_us.value() &&
562         google_handshake_message == rhs.google_handshake_message &&
563         google_connection_options == rhs.google_connection_options &&
564         custom_parameters == rhs.custom_parameters)) {
565     return false;
566   }
567 
568   if ((!preferred_address && rhs.preferred_address) ||
569       (preferred_address && !rhs.preferred_address)) {
570     return false;
571   }
572   if (preferred_address && rhs.preferred_address &&
573       *preferred_address != *rhs.preferred_address) {
574     return false;
575   }
576 
577   return true;
578 }
579 
operator !=(const TransportParameters & rhs) const580 bool TransportParameters::operator!=(const TransportParameters& rhs) const {
581   return !(*this == rhs);
582 }
583 
AreValid(std::string * error_details) const584 bool TransportParameters::AreValid(std::string* error_details) const {
585   QUICHE_DCHECK(perspective == Perspective::IS_CLIENT ||
586                 perspective == Perspective::IS_SERVER);
587   if (perspective == Perspective::IS_CLIENT && !stateless_reset_token.empty()) {
588     *error_details = "Client cannot send stateless reset token";
589     return false;
590   }
591   if (perspective == Perspective::IS_CLIENT &&
592       original_destination_connection_id.has_value()) {
593     *error_details = "Client cannot send original_destination_connection_id";
594     return false;
595   }
596   if (!stateless_reset_token.empty() &&
597       stateless_reset_token.size() != kStatelessResetTokenLength) {
598     *error_details = absl::StrCat("Stateless reset token has bad length ",
599                                   stateless_reset_token.size());
600     return false;
601   }
602   if (perspective == Perspective::IS_CLIENT && preferred_address) {
603     *error_details = "Client cannot send preferred address";
604     return false;
605   }
606   if (preferred_address && preferred_address->stateless_reset_token.size() !=
607                                kStatelessResetTokenLength) {
608     *error_details =
609         absl::StrCat("Preferred address stateless reset token has bad length ",
610                      preferred_address->stateless_reset_token.size());
611     return false;
612   }
613   if (preferred_address &&
614       (!preferred_address->ipv4_socket_address.host().IsIPv4() ||
615        !preferred_address->ipv6_socket_address.host().IsIPv6())) {
616     QUIC_BUG(quic_bug_10743_4) << "Preferred address family failure";
617     *error_details = "Internal preferred address family failure";
618     return false;
619   }
620   if (perspective == Perspective::IS_CLIENT &&
621       retry_source_connection_id.has_value()) {
622     *error_details = "Client cannot send retry_source_connection_id";
623     return false;
624   }
625   for (const auto& kv : custom_parameters) {
626     if (TransportParameterIdIsKnown(kv.first)) {
627       *error_details = absl::StrCat("Using custom_parameters with known ID ",
628                                     TransportParameterIdToString(kv.first),
629                                     " is not allowed");
630       return false;
631     }
632   }
633   if (perspective == Perspective::IS_SERVER &&
634       google_handshake_message.has_value()) {
635     *error_details = "Server cannot send google_handshake_message";
636     return false;
637   }
638   if (perspective == Perspective::IS_SERVER &&
639       initial_round_trip_time_us.value() > 0) {
640     *error_details = "Server cannot send initial round trip time";
641     return false;
642   }
643   if (version_information.has_value()) {
644     const QuicVersionLabel& chosen_version =
645         version_information.value().chosen_version;
646     const QuicVersionLabelVector& other_versions =
647         version_information.value().other_versions;
648     if (chosen_version == 0) {
649       *error_details = "Invalid chosen version";
650       return false;
651     }
652     if (perspective == Perspective::IS_CLIENT &&
653         std::find(other_versions.begin(), other_versions.end(),
654                   chosen_version) == other_versions.end()) {
655       // When sent by the client, chosen_version needs to be present in
656       // other_versions because other_versions lists the compatible versions and
657       // the chosen version is part of that list. When sent by the server,
658       // other_version contains the list of fully-deployed versions which is
659       // generally equal to the list of supported versions but can slightly
660       // differ during removal of versions across a server fleet. See
661       // draft-ietf-quic-version-negotiation for details.
662       *error_details = "Client chosen version not in other versions";
663       return false;
664     }
665   }
666   const bool ok =
667       max_idle_timeout_ms.IsValid() && max_udp_payload_size.IsValid() &&
668       initial_max_data.IsValid() &&
669       initial_max_stream_data_bidi_local.IsValid() &&
670       initial_max_stream_data_bidi_remote.IsValid() &&
671       initial_max_stream_data_uni.IsValid() &&
672       initial_max_streams_bidi.IsValid() && initial_max_streams_uni.IsValid() &&
673       ack_delay_exponent.IsValid() && max_ack_delay.IsValid() &&
674       min_ack_delay_us.IsValid() && active_connection_id_limit.IsValid() &&
675       max_datagram_frame_size.IsValid() && initial_round_trip_time_us.IsValid();
676   if (!ok) {
677     *error_details = "Invalid transport parameters " + this->ToString();
678   }
679   return ok;
680 }
681 
682 TransportParameters::~TransportParameters() = default;
683 
SerializeTransportParameters(const TransportParameters & in,std::vector<uint8_t> * out)684 bool SerializeTransportParameters(const TransportParameters& in,
685                                   std::vector<uint8_t>* out) {
686   std::string error_details;
687   if (!in.AreValid(&error_details)) {
688     QUIC_BUG(invalid transport parameters)
689         << "Not serializing invalid transport parameters: " << error_details;
690     return false;
691   }
692   if (!in.legacy_version_information.has_value() ||
693       in.legacy_version_information.value().version == 0 ||
694       (in.perspective == Perspective::IS_SERVER &&
695        in.legacy_version_information.value().supported_versions.empty())) {
696     QUIC_BUG(missing versions) << "Refusing to serialize without versions";
697     return false;
698   }
699   TransportParameters::ParameterMap custom_parameters = in.custom_parameters;
700   for (const auto& kv : custom_parameters) {
701     if (kv.first % 31 == 27) {
702       // See the "Reserved Transport Parameters" section of RFC 9000.
703       QUIC_BUG(custom_parameters with GREASE)
704           << "Serializing custom_parameters with GREASE ID " << kv.first
705           << " is not allowed";
706       return false;
707     }
708   }
709 
710   // Maximum length of the GREASE transport parameter (see below).
711   static constexpr size_t kMaxGreaseLength = 16;
712 
713   // Empirically transport parameters generally fit within 128 bytes, but we
714   // need to allocate the size up front. Integer transport parameters
715   // have a maximum encoded length of 24 bytes (3 variable length integers),
716   // other transport parameters have a length of 16 + the maximum value length.
717   static constexpr size_t kTypeAndValueLength = 2 * sizeof(uint64_t);
718   static constexpr size_t kIntegerParameterLength =
719       kTypeAndValueLength + sizeof(uint64_t);
720   static constexpr size_t kStatelessResetParameterLength =
721       kTypeAndValueLength + 16 /* stateless reset token length */;
722   static constexpr size_t kConnectionIdParameterLength =
723       kTypeAndValueLength + 255 /* maximum connection ID length */;
724   static constexpr size_t kPreferredAddressParameterLength =
725       kTypeAndValueLength + 4 /*IPv4 address */ + 2 /* IPv4 port */ +
726       16 /* IPv6 address */ + 1 /* Connection ID length */ +
727       255 /* maximum connection ID length */ + 16 /* stateless reset token */;
728   static constexpr size_t kKnownTransportParamLength =
729       kConnectionIdParameterLength +      // original_destination_connection_id
730       kIntegerParameterLength +           // max_idle_timeout
731       kStatelessResetParameterLength +    // stateless_reset_token
732       kIntegerParameterLength +           // max_udp_payload_size
733       kIntegerParameterLength +           // initial_max_data
734       kIntegerParameterLength +           // initial_max_stream_data_bidi_local
735       kIntegerParameterLength +           // initial_max_stream_data_bidi_remote
736       kIntegerParameterLength +           // initial_max_stream_data_uni
737       kIntegerParameterLength +           // initial_max_streams_bidi
738       kIntegerParameterLength +           // initial_max_streams_uni
739       kIntegerParameterLength +           // ack_delay_exponent
740       kIntegerParameterLength +           // max_ack_delay
741       kIntegerParameterLength +           // min_ack_delay_us
742       kTypeAndValueLength +               // disable_active_migration
743       kPreferredAddressParameterLength +  // preferred_address
744       kIntegerParameterLength +           // active_connection_id_limit
745       kConnectionIdParameterLength +      // initial_source_connection_id
746       kConnectionIdParameterLength +      // retry_source_connection_id
747       kIntegerParameterLength +           // max_datagram_frame_size
748       kIntegerParameterLength +           // initial_round_trip_time_us
749       kTypeAndValueLength +               // google_handshake_message
750       kTypeAndValueLength +               // google_connection_options
751       kTypeAndValueLength;                // google-version
752 
753   std::vector<TransportParameters::TransportParameterId> parameter_ids = {
754       TransportParameters::kOriginalDestinationConnectionId,
755       TransportParameters::kMaxIdleTimeout,
756       TransportParameters::kStatelessResetToken,
757       TransportParameters::kMaxPacketSize,
758       TransportParameters::kInitialMaxData,
759       TransportParameters::kInitialMaxStreamDataBidiLocal,
760       TransportParameters::kInitialMaxStreamDataBidiRemote,
761       TransportParameters::kInitialMaxStreamDataUni,
762       TransportParameters::kInitialMaxStreamsBidi,
763       TransportParameters::kInitialMaxStreamsUni,
764       TransportParameters::kAckDelayExponent,
765       TransportParameters::kMaxAckDelay,
766       TransportParameters::kMinAckDelay,
767       TransportParameters::kActiveConnectionIdLimit,
768       TransportParameters::kMaxDatagramFrameSize,
769       TransportParameters::kGoogleHandshakeMessage,
770       TransportParameters::kInitialRoundTripTime,
771       TransportParameters::kDisableActiveMigration,
772       TransportParameters::kPreferredAddress,
773       TransportParameters::kInitialSourceConnectionId,
774       TransportParameters::kRetrySourceConnectionId,
775       TransportParameters::kGoogleConnectionOptions,
776       TransportParameters::kGoogleQuicVersion,
777       TransportParameters::kVersionInformation,
778   };
779 
780   size_t max_transport_param_length = kKnownTransportParamLength;
781   // google_connection_options.
782   if (in.google_connection_options.has_value()) {
783     max_transport_param_length +=
784         in.google_connection_options.value().size() * sizeof(QuicTag);
785   }
786   // Google-specific version extension.
787   if (in.legacy_version_information.has_value()) {
788     max_transport_param_length +=
789         sizeof(in.legacy_version_information.value().version) +
790         1 /* versions length */ +
791         in.legacy_version_information.value().supported_versions.size() *
792             sizeof(QuicVersionLabel);
793   }
794   // version_information.
795   if (in.version_information.has_value()) {
796     max_transport_param_length +=
797         sizeof(in.version_information.value().chosen_version) +
798         // Add one for the added GREASE version.
799         (in.version_information.value().other_versions.size() + 1) *
800             sizeof(QuicVersionLabel);
801   }
802   // google_handshake_message.
803   if (in.google_handshake_message.has_value()) {
804     max_transport_param_length += in.google_handshake_message.value().length();
805   }
806 
807   // Add a random GREASE transport parameter, as defined in the
808   // "Reserved Transport Parameters" section of RFC 9000.
809   // This forces receivers to support unexpected input.
810   QuicRandom* random = QuicRandom::GetInstance();
811   // Transport parameter identifiers are 62 bits long so we need to
812   // ensure that the output of the computation below fits in 62 bits.
813   uint64_t grease_id64 = random->RandUint64() % ((1ULL << 62) - 31);
814   // Make sure grease_id % 31 == 27. Note that this is not uniformely
815   // distributed but is acceptable since no security depends on this
816   // randomness.
817   grease_id64 = (grease_id64 / 31) * 31 + 27;
818   TransportParameters::TransportParameterId grease_id =
819       static_cast<TransportParameters::TransportParameterId>(grease_id64);
820   const size_t grease_length = random->RandUint64() % kMaxGreaseLength;
821   QUICHE_DCHECK_GE(kMaxGreaseLength, grease_length);
822   char grease_contents[kMaxGreaseLength];
823   random->RandBytes(grease_contents, grease_length);
824   custom_parameters[grease_id] = std::string(grease_contents, grease_length);
825 
826   // Custom parameters.
827   for (const auto& kv : custom_parameters) {
828     max_transport_param_length += kTypeAndValueLength + kv.second.length();
829     parameter_ids.push_back(kv.first);
830   }
831 
832   // Randomize order of sent transport parameters by walking the array
833   // backwards and swapping each element with a random earlier one.
834   for (size_t i = parameter_ids.size() - 1; i > 0; i--) {
835     std::swap(parameter_ids[i],
836               parameter_ids[random->InsecureRandUint64() % (i + 1)]);
837   }
838 
839   out->resize(max_transport_param_length);
840   QuicDataWriter writer(out->size(), reinterpret_cast<char*>(out->data()));
841 
842   for (TransportParameters::TransportParameterId parameter_id : parameter_ids) {
843     switch (parameter_id) {
844       // original_destination_connection_id
845       case TransportParameters::kOriginalDestinationConnectionId: {
846         if (in.original_destination_connection_id.has_value()) {
847           QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
848           QuicConnectionId original_destination_connection_id =
849               in.original_destination_connection_id.value();
850           if (!writer.WriteVarInt62(
851                   TransportParameters::kOriginalDestinationConnectionId) ||
852               !writer.WriteStringPieceVarInt62(absl::string_view(
853                   original_destination_connection_id.data(),
854                   original_destination_connection_id.length()))) {
855             QUIC_BUG(Failed to write original_destination_connection_id)
856                 << "Failed to write original_destination_connection_id "
857                 << original_destination_connection_id << " for " << in;
858             return false;
859           }
860         }
861       } break;
862       // max_idle_timeout
863       case TransportParameters::kMaxIdleTimeout: {
864         if (!in.max_idle_timeout_ms.Write(&writer)) {
865           QUIC_BUG(Failed to write idle_timeout)
866               << "Failed to write idle_timeout for " << in;
867           return false;
868         }
869       } break;
870       // stateless_reset_token
871       case TransportParameters::kStatelessResetToken: {
872         if (!in.stateless_reset_token.empty()) {
873           QUICHE_DCHECK_EQ(kStatelessResetTokenLength,
874                            in.stateless_reset_token.size());
875           QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
876           if (!writer.WriteVarInt62(
877                   TransportParameters::kStatelessResetToken) ||
878               !writer.WriteStringPieceVarInt62(
879                   absl::string_view(reinterpret_cast<const char*>(
880                                         in.stateless_reset_token.data()),
881                                     in.stateless_reset_token.size()))) {
882             QUIC_BUG(Failed to write stateless_reset_token)
883                 << "Failed to write stateless_reset_token of length "
884                 << in.stateless_reset_token.size() << " for " << in;
885             return false;
886           }
887         }
888       } break;
889       // max_udp_payload_size
890       case TransportParameters::kMaxPacketSize: {
891         if (!in.max_udp_payload_size.Write(&writer)) {
892           QUIC_BUG(Failed to write max_udp_payload_size)
893               << "Failed to write max_udp_payload_size for " << in;
894           return false;
895         }
896       } break;
897       // initial_max_data
898       case TransportParameters::kInitialMaxData: {
899         if (!in.initial_max_data.Write(&writer)) {
900           QUIC_BUG(Failed to write initial_max_data)
901               << "Failed to write initial_max_data for " << in;
902           return false;
903         }
904       } break;
905       // initial_max_stream_data_bidi_local
906       case TransportParameters::kInitialMaxStreamDataBidiLocal: {
907         if (!in.initial_max_stream_data_bidi_local.Write(&writer)) {
908           QUIC_BUG(Failed to write initial_max_stream_data_bidi_local)
909               << "Failed to write initial_max_stream_data_bidi_local for "
910               << in;
911           return false;
912         }
913       } break;
914       // initial_max_stream_data_bidi_remote
915       case TransportParameters::kInitialMaxStreamDataBidiRemote: {
916         if (!in.initial_max_stream_data_bidi_remote.Write(&writer)) {
917           QUIC_BUG(Failed to write initial_max_stream_data_bidi_remote)
918               << "Failed to write initial_max_stream_data_bidi_remote for "
919               << in;
920           return false;
921         }
922       } break;
923       // initial_max_stream_data_uni
924       case TransportParameters::kInitialMaxStreamDataUni: {
925         if (!in.initial_max_stream_data_uni.Write(&writer)) {
926           QUIC_BUG(Failed to write initial_max_stream_data_uni)
927               << "Failed to write initial_max_stream_data_uni for " << in;
928           return false;
929         }
930       } break;
931       // initial_max_streams_bidi
932       case TransportParameters::kInitialMaxStreamsBidi: {
933         if (!in.initial_max_streams_bidi.Write(&writer)) {
934           QUIC_BUG(Failed to write initial_max_streams_bidi)
935               << "Failed to write initial_max_streams_bidi for " << in;
936           return false;
937         }
938       } break;
939       // initial_max_streams_uni
940       case TransportParameters::kInitialMaxStreamsUni: {
941         if (!in.initial_max_streams_uni.Write(&writer)) {
942           QUIC_BUG(Failed to write initial_max_streams_uni)
943               << "Failed to write initial_max_streams_uni for " << in;
944           return false;
945         }
946       } break;
947       // ack_delay_exponent
948       case TransportParameters::kAckDelayExponent: {
949         if (!in.ack_delay_exponent.Write(&writer)) {
950           QUIC_BUG(Failed to write ack_delay_exponent)
951               << "Failed to write ack_delay_exponent for " << in;
952           return false;
953         }
954       } break;
955       // max_ack_delay
956       case TransportParameters::kMaxAckDelay: {
957         if (!in.max_ack_delay.Write(&writer)) {
958           QUIC_BUG(Failed to write max_ack_delay)
959               << "Failed to write max_ack_delay for " << in;
960           return false;
961         }
962       } break;
963       // min_ack_delay_us
964       case TransportParameters::kMinAckDelay: {
965         if (!in.min_ack_delay_us.Write(&writer)) {
966           QUIC_BUG(Failed to write min_ack_delay_us)
967               << "Failed to write min_ack_delay_us for " << in;
968           return false;
969         }
970       } break;
971       // active_connection_id_limit
972       case TransportParameters::kActiveConnectionIdLimit: {
973         if (!in.active_connection_id_limit.Write(&writer)) {
974           QUIC_BUG(Failed to write active_connection_id_limit)
975               << "Failed to write active_connection_id_limit for " << in;
976           return false;
977         }
978       } break;
979       // max_datagram_frame_size
980       case TransportParameters::kMaxDatagramFrameSize: {
981         if (!in.max_datagram_frame_size.Write(&writer)) {
982           QUIC_BUG(Failed to write max_datagram_frame_size)
983               << "Failed to write max_datagram_frame_size for " << in;
984           return false;
985         }
986       } break;
987       // google_handshake_message
988       case TransportParameters::kGoogleHandshakeMessage: {
989         if (in.google_handshake_message.has_value()) {
990           if (!writer.WriteVarInt62(
991                   TransportParameters::kGoogleHandshakeMessage) ||
992               !writer.WriteStringPieceVarInt62(
993                   in.google_handshake_message.value())) {
994             QUIC_BUG(Failed to write google_handshake_message)
995                 << "Failed to write google_handshake_message: "
996                 << in.google_handshake_message.value() << " for " << in;
997             return false;
998           }
999         }
1000       } break;
1001       // initial_round_trip_time_us
1002       case TransportParameters::kInitialRoundTripTime: {
1003         if (!in.initial_round_trip_time_us.Write(&writer)) {
1004           QUIC_BUG(Failed to write initial_round_trip_time_us)
1005               << "Failed to write initial_round_trip_time_us for " << in;
1006           return false;
1007         }
1008       } break;
1009       // disable_active_migration
1010       case TransportParameters::kDisableActiveMigration: {
1011         if (in.disable_active_migration) {
1012           if (!writer.WriteVarInt62(
1013                   TransportParameters::kDisableActiveMigration) ||
1014               !writer.WriteVarInt62(/* transport parameter length */ 0)) {
1015             QUIC_BUG(Failed to write disable_active_migration)
1016                 << "Failed to write disable_active_migration for " << in;
1017             return false;
1018           }
1019         }
1020       } break;
1021       // preferred_address
1022       case TransportParameters::kPreferredAddress: {
1023         if (in.preferred_address) {
1024           std::string v4_address_bytes =
1025               in.preferred_address->ipv4_socket_address.host().ToPackedString();
1026           std::string v6_address_bytes =
1027               in.preferred_address->ipv6_socket_address.host().ToPackedString();
1028           if (v4_address_bytes.length() != 4 ||
1029               v6_address_bytes.length() != 16 ||
1030               in.preferred_address->stateless_reset_token.size() !=
1031                   kStatelessResetTokenLength) {
1032             QUIC_BUG(quic_bug_10743_12)
1033                 << "Bad lengths " << *in.preferred_address;
1034             return false;
1035           }
1036           const uint64_t preferred_address_length =
1037               v4_address_bytes.length() + /* IPv4 port */ sizeof(uint16_t) +
1038               v6_address_bytes.length() + /* IPv6 port */ sizeof(uint16_t) +
1039               /* connection ID length byte */ sizeof(uint8_t) +
1040               in.preferred_address->connection_id.length() +
1041               in.preferred_address->stateless_reset_token.size();
1042           if (!writer.WriteVarInt62(TransportParameters::kPreferredAddress) ||
1043               !writer.WriteVarInt62(
1044                   /* transport parameter length */ preferred_address_length) ||
1045               !writer.WriteStringPiece(v4_address_bytes) ||
1046               !writer.WriteUInt16(
1047                   in.preferred_address->ipv4_socket_address.port()) ||
1048               !writer.WriteStringPiece(v6_address_bytes) ||
1049               !writer.WriteUInt16(
1050                   in.preferred_address->ipv6_socket_address.port()) ||
1051               !writer.WriteUInt8(
1052                   in.preferred_address->connection_id.length()) ||
1053               !writer.WriteBytes(
1054                   in.preferred_address->connection_id.data(),
1055                   in.preferred_address->connection_id.length()) ||
1056               !writer.WriteBytes(
1057                   in.preferred_address->stateless_reset_token.data(),
1058                   in.preferred_address->stateless_reset_token.size())) {
1059             QUIC_BUG(Failed to write preferred_address)
1060                 << "Failed to write preferred_address for " << in;
1061             return false;
1062           }
1063         }
1064       } break;
1065       // initial_source_connection_id
1066       case TransportParameters::kInitialSourceConnectionId: {
1067         if (in.initial_source_connection_id.has_value()) {
1068           QuicConnectionId initial_source_connection_id =
1069               in.initial_source_connection_id.value();
1070           if (!writer.WriteVarInt62(
1071                   TransportParameters::kInitialSourceConnectionId) ||
1072               !writer.WriteStringPieceVarInt62(
1073                   absl::string_view(initial_source_connection_id.data(),
1074                                     initial_source_connection_id.length()))) {
1075             QUIC_BUG(Failed to write initial_source_connection_id)
1076                 << "Failed to write initial_source_connection_id "
1077                 << initial_source_connection_id << " for " << in;
1078             return false;
1079           }
1080         }
1081       } break;
1082       // retry_source_connection_id
1083       case TransportParameters::kRetrySourceConnectionId: {
1084         if (in.retry_source_connection_id.has_value()) {
1085           QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
1086           QuicConnectionId retry_source_connection_id =
1087               in.retry_source_connection_id.value();
1088           if (!writer.WriteVarInt62(
1089                   TransportParameters::kRetrySourceConnectionId) ||
1090               !writer.WriteStringPieceVarInt62(
1091                   absl::string_view(retry_source_connection_id.data(),
1092                                     retry_source_connection_id.length()))) {
1093             QUIC_BUG(Failed to write retry_source_connection_id)
1094                 << "Failed to write retry_source_connection_id "
1095                 << retry_source_connection_id << " for " << in;
1096             return false;
1097           }
1098         }
1099       } break;
1100       // Google-specific connection options.
1101       case TransportParameters::kGoogleConnectionOptions: {
1102         if (in.google_connection_options.has_value()) {
1103           static_assert(
1104               sizeof(in.google_connection_options.value().front()) == 4,
1105               "bad size");
1106           uint64_t connection_options_length =
1107               in.google_connection_options.value().size() * 4;
1108           if (!writer.WriteVarInt62(
1109                   TransportParameters::kGoogleConnectionOptions) ||
1110               !writer.WriteVarInt62(
1111                   /* transport parameter length */ connection_options_length)) {
1112             QUIC_BUG(Failed to write google_connection_options)
1113                 << "Failed to write google_connection_options of length "
1114                 << connection_options_length << " for " << in;
1115             return false;
1116           }
1117           for (const QuicTag& connection_option :
1118                in.google_connection_options.value()) {
1119             if (!writer.WriteTag(connection_option)) {
1120               QUIC_BUG(Failed to write google_connection_option)
1121                   << "Failed to write google_connection_option "
1122                   << QuicTagToString(connection_option) << " for " << in;
1123               return false;
1124             }
1125           }
1126         }
1127       } break;
1128       // Google-specific version extension.
1129       case TransportParameters::kGoogleQuicVersion: {
1130         if (!in.legacy_version_information.has_value()) {
1131           break;
1132         }
1133         static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
1134                       "bad length");
1135         uint64_t google_version_length =
1136             sizeof(in.legacy_version_information.value().version);
1137         if (in.perspective == Perspective::IS_SERVER) {
1138           google_version_length +=
1139               /* versions length */ sizeof(uint8_t) +
1140               sizeof(QuicVersionLabel) * in.legacy_version_information.value()
1141                                              .supported_versions.size();
1142         }
1143         if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
1144             !writer.WriteVarInt62(
1145                 /* transport parameter length */ google_version_length) ||
1146             !writer.WriteUInt32(
1147                 in.legacy_version_information.value().version)) {
1148           QUIC_BUG(Failed to write Google version extension)
1149               << "Failed to write Google version extension for " << in;
1150           return false;
1151         }
1152         if (in.perspective == Perspective::IS_SERVER) {
1153           if (!writer.WriteUInt8(sizeof(QuicVersionLabel) *
1154                                  in.legacy_version_information.value()
1155                                      .supported_versions.size())) {
1156             QUIC_BUG(Failed to write versions length)
1157                 << "Failed to write versions length for " << in;
1158             return false;
1159           }
1160           for (QuicVersionLabel version_label :
1161                in.legacy_version_information.value().supported_versions) {
1162             if (!writer.WriteUInt32(version_label)) {
1163               QUIC_BUG(Failed to write supported version)
1164                   << "Failed to write supported version for " << in;
1165               return false;
1166             }
1167           }
1168         }
1169       } break;
1170       // version_information.
1171       case TransportParameters::kVersionInformation: {
1172         if (!in.version_information.has_value()) {
1173           break;
1174         }
1175         static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
1176                       "bad length");
1177         QuicVersionLabelVector other_versions =
1178             in.version_information.value().other_versions;
1179         // Insert one GREASE version at a random index.
1180         const size_t grease_index =
1181             random->InsecureRandUint64() % (other_versions.size() + 1);
1182         other_versions.insert(
1183             other_versions.begin() + grease_index,
1184             CreateQuicVersionLabel(QuicVersionReservedForNegotiation()));
1185         const uint64_t version_information_length =
1186             sizeof(in.version_information.value().chosen_version) +
1187             sizeof(QuicVersionLabel) * other_versions.size();
1188         if (!writer.WriteVarInt62(TransportParameters::kVersionInformation) ||
1189             !writer.WriteVarInt62(
1190                 /* transport parameter length */ version_information_length) ||
1191             !writer.WriteUInt32(
1192                 in.version_information.value().chosen_version)) {
1193           QUIC_BUG(Failed to write chosen version)
1194               << "Failed to write chosen version for " << in;
1195           return false;
1196         }
1197         for (QuicVersionLabel version_label : other_versions) {
1198           if (!writer.WriteUInt32(version_label)) {
1199             QUIC_BUG(Failed to write other version)
1200                 << "Failed to write other version for " << in;
1201             return false;
1202           }
1203         }
1204       } break;
1205       // Custom parameters and GREASE.
1206       default: {
1207         auto it = custom_parameters.find(parameter_id);
1208         if (it == custom_parameters.end()) {
1209           QUIC_BUG(Unknown parameter) << "Unknown parameter " << parameter_id;
1210           return false;
1211         }
1212         if (!writer.WriteVarInt62(parameter_id) ||
1213             !writer.WriteStringPieceVarInt62(it->second)) {
1214           QUIC_BUG(Failed to write custom parameter)
1215               << "Failed to write custom parameter " << parameter_id;
1216           return false;
1217         }
1218       } break;
1219     }
1220   }
1221 
1222   out->resize(writer.length());
1223 
1224   QUIC_DLOG(INFO) << "Serialized " << in << " as " << writer.length()
1225                   << " bytes";
1226 
1227   return true;
1228 }
1229 
ParseTransportParameters(ParsedQuicVersion version,Perspective perspective,const uint8_t * in,size_t in_len,TransportParameters * out,std::string * error_details)1230 bool ParseTransportParameters(ParsedQuicVersion version,
1231                               Perspective perspective, const uint8_t* in,
1232                               size_t in_len, TransportParameters* out,
1233                               std::string* error_details) {
1234   out->perspective = perspective;
1235   QuicDataReader reader(reinterpret_cast<const char*>(in), in_len);
1236 
1237   while (!reader.IsDoneReading()) {
1238     uint64_t param_id64;
1239     if (!reader.ReadVarInt62(&param_id64)) {
1240       *error_details = "Failed to parse transport parameter ID";
1241       return false;
1242     }
1243     TransportParameters::TransportParameterId param_id =
1244         static_cast<TransportParameters::TransportParameterId>(param_id64);
1245     absl::string_view value;
1246     if (!reader.ReadStringPieceVarInt62(&value)) {
1247       *error_details =
1248           "Failed to read length and value of transport parameter " +
1249           TransportParameterIdToString(param_id);
1250       return false;
1251     }
1252     QuicDataReader value_reader(value);
1253     bool parse_success = true;
1254     switch (param_id) {
1255       case TransportParameters::kOriginalDestinationConnectionId: {
1256         if (out->original_destination_connection_id.has_value()) {
1257           *error_details =
1258               "Received a second original_destination_connection_id";
1259           return false;
1260         }
1261         const size_t connection_id_length = value_reader.BytesRemaining();
1262         if (!QuicUtils::IsConnectionIdLengthValidForVersion(
1263                 connection_id_length, version.transport_version)) {
1264           *error_details = absl::StrCat(
1265               "Received original_destination_connection_id of invalid length ",
1266               connection_id_length);
1267           return false;
1268         }
1269         QuicConnectionId original_destination_connection_id;
1270         if (!value_reader.ReadConnectionId(&original_destination_connection_id,
1271                                            connection_id_length)) {
1272           *error_details = "Failed to read original_destination_connection_id";
1273           return false;
1274         }
1275         out->original_destination_connection_id =
1276             original_destination_connection_id;
1277       } break;
1278       case TransportParameters::kMaxIdleTimeout:
1279         parse_success =
1280             out->max_idle_timeout_ms.Read(&value_reader, error_details);
1281         break;
1282       case TransportParameters::kStatelessResetToken: {
1283         if (!out->stateless_reset_token.empty()) {
1284           *error_details = "Received a second stateless_reset_token";
1285           return false;
1286         }
1287         absl::string_view stateless_reset_token =
1288             value_reader.ReadRemainingPayload();
1289         if (stateless_reset_token.length() != kStatelessResetTokenLength) {
1290           *error_details =
1291               absl::StrCat("Received stateless_reset_token of invalid length ",
1292                            stateless_reset_token.length());
1293           return false;
1294         }
1295         out->stateless_reset_token.assign(
1296             stateless_reset_token.data(),
1297             stateless_reset_token.data() + stateless_reset_token.length());
1298       } break;
1299       case TransportParameters::kMaxPacketSize:
1300         parse_success =
1301             out->max_udp_payload_size.Read(&value_reader, error_details);
1302         break;
1303       case TransportParameters::kInitialMaxData:
1304         parse_success =
1305             out->initial_max_data.Read(&value_reader, error_details);
1306         break;
1307       case TransportParameters::kInitialMaxStreamDataBidiLocal:
1308         parse_success = out->initial_max_stream_data_bidi_local.Read(
1309             &value_reader, error_details);
1310         break;
1311       case TransportParameters::kInitialMaxStreamDataBidiRemote:
1312         parse_success = out->initial_max_stream_data_bidi_remote.Read(
1313             &value_reader, error_details);
1314         break;
1315       case TransportParameters::kInitialMaxStreamDataUni:
1316         parse_success =
1317             out->initial_max_stream_data_uni.Read(&value_reader, error_details);
1318         break;
1319       case TransportParameters::kInitialMaxStreamsBidi:
1320         parse_success =
1321             out->initial_max_streams_bidi.Read(&value_reader, error_details);
1322         break;
1323       case TransportParameters::kInitialMaxStreamsUni:
1324         parse_success =
1325             out->initial_max_streams_uni.Read(&value_reader, error_details);
1326         break;
1327       case TransportParameters::kAckDelayExponent:
1328         parse_success =
1329             out->ack_delay_exponent.Read(&value_reader, error_details);
1330         break;
1331       case TransportParameters::kMaxAckDelay:
1332         parse_success = out->max_ack_delay.Read(&value_reader, error_details);
1333         break;
1334       case TransportParameters::kDisableActiveMigration:
1335         if (out->disable_active_migration) {
1336           *error_details = "Received a second disable_active_migration";
1337           return false;
1338         }
1339         out->disable_active_migration = true;
1340         break;
1341       case TransportParameters::kPreferredAddress: {
1342         TransportParameters::PreferredAddress preferred_address;
1343         uint16_t ipv4_port, ipv6_port;
1344         in_addr ipv4_address;
1345         in6_addr ipv6_address;
1346         preferred_address.stateless_reset_token.resize(
1347             kStatelessResetTokenLength);
1348         if (!value_reader.ReadBytes(&ipv4_address, sizeof(ipv4_address)) ||
1349             !value_reader.ReadUInt16(&ipv4_port) ||
1350             !value_reader.ReadBytes(&ipv6_address, sizeof(ipv6_address)) ||
1351             !value_reader.ReadUInt16(&ipv6_port) ||
1352             !value_reader.ReadLengthPrefixedConnectionId(
1353                 &preferred_address.connection_id) ||
1354             !value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
1355                                     kStatelessResetTokenLength)) {
1356           *error_details = "Failed to read preferred_address";
1357           return false;
1358         }
1359         preferred_address.ipv4_socket_address =
1360             QuicSocketAddress(QuicIpAddress(ipv4_address), ipv4_port);
1361         preferred_address.ipv6_socket_address =
1362             QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
1363         if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
1364             !preferred_address.ipv6_socket_address.host().IsIPv6()) {
1365           *error_details = "Received preferred_address of bad families " +
1366                            preferred_address.ToString();
1367           return false;
1368         }
1369         if (!QuicUtils::IsConnectionIdValidForVersion(
1370                 preferred_address.connection_id, version.transport_version)) {
1371           *error_details = "Received invalid preferred_address connection ID " +
1372                            preferred_address.ToString();
1373           return false;
1374         }
1375         out->preferred_address =
1376             std::make_unique<TransportParameters::PreferredAddress>(
1377                 preferred_address);
1378       } break;
1379       case TransportParameters::kActiveConnectionIdLimit:
1380         parse_success =
1381             out->active_connection_id_limit.Read(&value_reader, error_details);
1382         break;
1383       case TransportParameters::kInitialSourceConnectionId: {
1384         if (out->initial_source_connection_id.has_value()) {
1385           *error_details = "Received a second initial_source_connection_id";
1386           return false;
1387         }
1388         const size_t connection_id_length = value_reader.BytesRemaining();
1389         if (!QuicUtils::IsConnectionIdLengthValidForVersion(
1390                 connection_id_length, version.transport_version)) {
1391           *error_details = absl::StrCat(
1392               "Received initial_source_connection_id of invalid length ",
1393               connection_id_length);
1394           return false;
1395         }
1396         QuicConnectionId initial_source_connection_id;
1397         if (!value_reader.ReadConnectionId(&initial_source_connection_id,
1398                                            connection_id_length)) {
1399           *error_details = "Failed to read initial_source_connection_id";
1400           return false;
1401         }
1402         out->initial_source_connection_id = initial_source_connection_id;
1403       } break;
1404       case TransportParameters::kRetrySourceConnectionId: {
1405         if (out->retry_source_connection_id.has_value()) {
1406           *error_details = "Received a second retry_source_connection_id";
1407           return false;
1408         }
1409         const size_t connection_id_length = value_reader.BytesRemaining();
1410         if (!QuicUtils::IsConnectionIdLengthValidForVersion(
1411                 connection_id_length, version.transport_version)) {
1412           *error_details = absl::StrCat(
1413               "Received retry_source_connection_id of invalid length ",
1414               connection_id_length);
1415           return false;
1416         }
1417         QuicConnectionId retry_source_connection_id;
1418         if (!value_reader.ReadConnectionId(&retry_source_connection_id,
1419                                            connection_id_length)) {
1420           *error_details = "Failed to read retry_source_connection_id";
1421           return false;
1422         }
1423         out->retry_source_connection_id = retry_source_connection_id;
1424       } break;
1425       case TransportParameters::kMaxDatagramFrameSize:
1426         parse_success =
1427             out->max_datagram_frame_size.Read(&value_reader, error_details);
1428         break;
1429       case TransportParameters::kGoogleHandshakeMessage:
1430         if (out->google_handshake_message.has_value()) {
1431           *error_details = "Received a second google_handshake_message";
1432           return false;
1433         }
1434         out->google_handshake_message =
1435             std::string(value_reader.ReadRemainingPayload());
1436         break;
1437       case TransportParameters::kInitialRoundTripTime:
1438         parse_success =
1439             out->initial_round_trip_time_us.Read(&value_reader, error_details);
1440         break;
1441       case TransportParameters::kGoogleConnectionOptions: {
1442         if (out->google_connection_options.has_value()) {
1443           *error_details = "Received a second google_connection_options";
1444           return false;
1445         }
1446         out->google_connection_options = QuicTagVector{};
1447         while (!value_reader.IsDoneReading()) {
1448           QuicTag connection_option;
1449           if (!value_reader.ReadTag(&connection_option)) {
1450             *error_details = "Failed to read a google_connection_options";
1451             return false;
1452           }
1453           out->google_connection_options.value().push_back(connection_option);
1454         }
1455       } break;
1456       case TransportParameters::kGoogleQuicVersion: {
1457         if (!out->legacy_version_information.has_value()) {
1458           out->legacy_version_information =
1459               TransportParameters::LegacyVersionInformation();
1460         }
1461         if (!value_reader.ReadUInt32(
1462                 &out->legacy_version_information.value().version)) {
1463           *error_details = "Failed to read Google version extension version";
1464           return false;
1465         }
1466         if (perspective == Perspective::IS_SERVER) {
1467           uint8_t versions_length;
1468           if (!value_reader.ReadUInt8(&versions_length)) {
1469             *error_details = "Failed to parse Google supported versions length";
1470             return false;
1471           }
1472           const uint8_t num_versions = versions_length / sizeof(uint32_t);
1473           for (uint8_t i = 0; i < num_versions; ++i) {
1474             QuicVersionLabel version;
1475             if (!value_reader.ReadUInt32(&version)) {
1476               *error_details = "Failed to parse Google supported version";
1477               return false;
1478             }
1479             out->legacy_version_information.value()
1480                 .supported_versions.push_back(version);
1481           }
1482         }
1483       } break;
1484       case TransportParameters::kVersionInformation: {
1485         if (out->version_information.has_value()) {
1486           *error_details = "Received a second version_information";
1487           return false;
1488         }
1489         out->version_information = TransportParameters::VersionInformation();
1490         if (!value_reader.ReadUInt32(
1491                 &out->version_information.value().chosen_version)) {
1492           *error_details = "Failed to read chosen version";
1493           return false;
1494         }
1495         while (!value_reader.IsDoneReading()) {
1496           QuicVersionLabel other_version;
1497           if (!value_reader.ReadUInt32(&other_version)) {
1498             *error_details = "Failed to parse other version";
1499             return false;
1500           }
1501           out->version_information.value().other_versions.push_back(
1502               other_version);
1503         }
1504       } break;
1505       case TransportParameters::kMinAckDelay:
1506         parse_success =
1507             out->min_ack_delay_us.Read(&value_reader, error_details);
1508         break;
1509       default:
1510         if (out->custom_parameters.find(param_id) !=
1511             out->custom_parameters.end()) {
1512           *error_details = "Received a second unknown parameter" +
1513                            TransportParameterIdToString(param_id);
1514           return false;
1515         }
1516         out->custom_parameters[param_id] =
1517             std::string(value_reader.ReadRemainingPayload());
1518         break;
1519     }
1520     if (!parse_success) {
1521       QUICHE_DCHECK(!error_details->empty());
1522       return false;
1523     }
1524     if (!value_reader.IsDoneReading()) {
1525       *error_details = absl::StrCat(
1526           "Received unexpected ", value_reader.BytesRemaining(),
1527           " bytes after parsing ", TransportParameterIdToString(param_id));
1528       return false;
1529     }
1530   }
1531 
1532   if (!out->AreValid(error_details)) {
1533     QUICHE_DCHECK(!error_details->empty());
1534     return false;
1535   }
1536 
1537   QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
1538                   << in_len << " bytes";
1539 
1540   return true;
1541 }
1542 
1543 namespace {
1544 
DigestUpdateIntegerParam(EVP_MD_CTX * hash_ctx,const TransportParameters::IntegerParameter & param)1545 bool DigestUpdateIntegerParam(
1546     EVP_MD_CTX* hash_ctx, const TransportParameters::IntegerParameter& param) {
1547   uint64_t value = param.value();
1548   return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
1549 }
1550 
1551 }  // namespace
1552 
SerializeTransportParametersForTicket(const TransportParameters & in,const std::vector<uint8_t> & application_data,std::vector<uint8_t> * out)1553 bool SerializeTransportParametersForTicket(
1554     const TransportParameters& in, const std::vector<uint8_t>& application_data,
1555     std::vector<uint8_t>* out) {
1556   std::string error_details;
1557   if (!in.AreValid(&error_details)) {
1558     QUIC_BUG(quic_bug_10743_26)
1559         << "Not serializing invalid transport parameters: " << error_details;
1560     return false;
1561   }
1562 
1563   out->resize(SHA256_DIGEST_LENGTH + 1);
1564   const uint8_t serialization_version = 0;
1565   (*out)[0] = serialization_version;
1566 
1567   bssl::ScopedEVP_MD_CTX hash_ctx;
1568   // Write application data:
1569   uint64_t app_data_len = application_data.size();
1570   const uint64_t parameter_version = 0;
1571   // The format of the input to the hash function is as follows:
1572   // - The application data, prefixed with a 64-bit length field.
1573   // - Transport parameters:
1574   //   - A 64-bit version field indicating which version of encoding is used
1575   //     for transport parameters.
1576   //   - A list of 64-bit integers representing the relevant parameters.
1577   //
1578   //   When changing which parameters are included, additional parameters can be
1579   //   added to the end of the list without changing the version field. New
1580   //   parameters that are variable length must be length prefixed. If
1581   //   parameters are removed from the list, the version field must be
1582   //   incremented.
1583   //
1584   // Integers happen to be written in host byte order, not network byte order.
1585   if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
1586       !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
1587       !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
1588                         application_data.size()) ||
1589       !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
1590                         sizeof(parameter_version))) {
1591     QUIC_BUG(quic_bug_10743_27)
1592         << "Unexpected failure of EVP_Digest functions when hashing "
1593            "Transport Parameters for ticket";
1594     return false;
1595   }
1596 
1597   // Write transport parameters specified by draft-ietf-quic-transport-28,
1598   // section 7.4.1, that are remembered for 0-RTT.
1599   if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
1600       !DigestUpdateIntegerParam(hash_ctx.get(),
1601                                 in.initial_max_stream_data_bidi_local) ||
1602       !DigestUpdateIntegerParam(hash_ctx.get(),
1603                                 in.initial_max_stream_data_bidi_remote) ||
1604       !DigestUpdateIntegerParam(hash_ctx.get(),
1605                                 in.initial_max_stream_data_uni) ||
1606       !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
1607       !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
1608       !DigestUpdateIntegerParam(hash_ctx.get(),
1609                                 in.active_connection_id_limit)) {
1610     QUIC_BUG(quic_bug_10743_28)
1611         << "Unexpected failure of EVP_Digest functions when hashing "
1612            "Transport Parameters for ticket";
1613     return false;
1614   }
1615   uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
1616   if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
1617                         sizeof(disable_active_migration)) ||
1618       !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
1619     QUIC_BUG(quic_bug_10743_29)
1620         << "Unexpected failure of EVP_Digest functions when hashing "
1621            "Transport Parameters for ticket";
1622     return false;
1623   }
1624   return true;
1625 }
1626 
DegreaseTransportParameters(TransportParameters & parameters)1627 void DegreaseTransportParameters(TransportParameters& parameters) {
1628   // Strip GREASE from custom parameters.
1629   for (auto it = parameters.custom_parameters.begin();
1630        it != parameters.custom_parameters.end();
1631        /**/) {
1632     // See the "Reserved Transport Parameters" section of RFC 9000.
1633     if (it->first % 31 == 27) {
1634       parameters.custom_parameters.erase(it++);
1635     } else {
1636       ++it;
1637     }
1638   }
1639 
1640   // Strip GREASE from versions.
1641   if (parameters.version_information.has_value()) {
1642     QuicVersionLabelVector clean_versions;
1643     for (QuicVersionLabel version :
1644          parameters.version_information->other_versions) {
1645       // See the "Versions" section of RFC 9000.
1646       if ((version & kReservedVersionMask) != kReservedVersionBits) {
1647         clean_versions.push_back(version);
1648       }
1649     }
1650 
1651     parameters.version_information->other_versions = std::move(clean_versions);
1652   }
1653 }
1654 
1655 }  // namespace quic
1656