xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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->ToString();
388   }
389   if (version_information.has_value()) {
390     rv += " " + version_information->ToString();
391   }
392   if (original_destination_connection_id.has_value()) {
393     rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
394           " " + original_destination_connection_id->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->ToString();
424   }
425   if (retry_source_connection_id.has_value()) {
426     rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
427           retry_source_connection_id->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->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) {
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->chosen_version;
646     const QuicVersionLabelVector& other_versions =
647         version_information->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->version == 0 ||
694       (in.perspective == Perspective::IS_SERVER &&
695        in.legacy_version_information->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->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->version) +
790         1 /* versions length */ +
791         in.legacy_version_information->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->chosen_version) +
798         // Add one for the added GREASE version.
799         (in.version_information->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->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;
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(*in.google_handshake_message)) {
993             QUIC_BUG(Failed to write google_handshake_message)
994                 << "Failed to write google_handshake_message: "
995                 << *in.google_handshake_message << " for " << in;
996             return false;
997           }
998         }
999       } break;
1000       // initial_round_trip_time_us
1001       case TransportParameters::kInitialRoundTripTime: {
1002         if (!in.initial_round_trip_time_us.Write(&writer)) {
1003           QUIC_BUG(Failed to write initial_round_trip_time_us)
1004               << "Failed to write initial_round_trip_time_us for " << in;
1005           return false;
1006         }
1007       } break;
1008       // disable_active_migration
1009       case TransportParameters::kDisableActiveMigration: {
1010         if (in.disable_active_migration) {
1011           if (!writer.WriteVarInt62(
1012                   TransportParameters::kDisableActiveMigration) ||
1013               !writer.WriteVarInt62(/* transport parameter length */ 0)) {
1014             QUIC_BUG(Failed to write disable_active_migration)
1015                 << "Failed to write disable_active_migration for " << in;
1016             return false;
1017           }
1018         }
1019       } break;
1020       // preferred_address
1021       case TransportParameters::kPreferredAddress: {
1022         if (in.preferred_address) {
1023           std::string v4_address_bytes =
1024               in.preferred_address->ipv4_socket_address.host().ToPackedString();
1025           std::string v6_address_bytes =
1026               in.preferred_address->ipv6_socket_address.host().ToPackedString();
1027           if (v4_address_bytes.length() != 4 ||
1028               v6_address_bytes.length() != 16 ||
1029               in.preferred_address->stateless_reset_token.size() !=
1030                   kStatelessResetTokenLength) {
1031             QUIC_BUG(quic_bug_10743_12)
1032                 << "Bad lengths " << *in.preferred_address;
1033             return false;
1034           }
1035           const uint64_t preferred_address_length =
1036               v4_address_bytes.length() + /* IPv4 port */ sizeof(uint16_t) +
1037               v6_address_bytes.length() + /* IPv6 port */ sizeof(uint16_t) +
1038               /* connection ID length byte */ sizeof(uint8_t) +
1039               in.preferred_address->connection_id.length() +
1040               in.preferred_address->stateless_reset_token.size();
1041           if (!writer.WriteVarInt62(TransportParameters::kPreferredAddress) ||
1042               !writer.WriteVarInt62(
1043                   /* transport parameter length */ preferred_address_length) ||
1044               !writer.WriteStringPiece(v4_address_bytes) ||
1045               !writer.WriteUInt16(
1046                   in.preferred_address->ipv4_socket_address.port()) ||
1047               !writer.WriteStringPiece(v6_address_bytes) ||
1048               !writer.WriteUInt16(
1049                   in.preferred_address->ipv6_socket_address.port()) ||
1050               !writer.WriteUInt8(
1051                   in.preferred_address->connection_id.length()) ||
1052               !writer.WriteBytes(
1053                   in.preferred_address->connection_id.data(),
1054                   in.preferred_address->connection_id.length()) ||
1055               !writer.WriteBytes(
1056                   in.preferred_address->stateless_reset_token.data(),
1057                   in.preferred_address->stateless_reset_token.size())) {
1058             QUIC_BUG(Failed to write preferred_address)
1059                 << "Failed to write preferred_address for " << in;
1060             return false;
1061           }
1062         }
1063       } break;
1064       // initial_source_connection_id
1065       case TransportParameters::kInitialSourceConnectionId: {
1066         if (in.initial_source_connection_id.has_value()) {
1067           QuicConnectionId initial_source_connection_id =
1068               *in.initial_source_connection_id;
1069           if (!writer.WriteVarInt62(
1070                   TransportParameters::kInitialSourceConnectionId) ||
1071               !writer.WriteStringPieceVarInt62(
1072                   absl::string_view(initial_source_connection_id.data(),
1073                                     initial_source_connection_id.length()))) {
1074             QUIC_BUG(Failed to write initial_source_connection_id)
1075                 << "Failed to write initial_source_connection_id "
1076                 << initial_source_connection_id << " for " << in;
1077             return false;
1078           }
1079         }
1080       } break;
1081       // retry_source_connection_id
1082       case TransportParameters::kRetrySourceConnectionId: {
1083         if (in.retry_source_connection_id.has_value()) {
1084           QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
1085           QuicConnectionId retry_source_connection_id =
1086               *in.retry_source_connection_id;
1087           if (!writer.WriteVarInt62(
1088                   TransportParameters::kRetrySourceConnectionId) ||
1089               !writer.WriteStringPieceVarInt62(
1090                   absl::string_view(retry_source_connection_id.data(),
1091                                     retry_source_connection_id.length()))) {
1092             QUIC_BUG(Failed to write retry_source_connection_id)
1093                 << "Failed to write retry_source_connection_id "
1094                 << retry_source_connection_id << " for " << in;
1095             return false;
1096           }
1097         }
1098       } break;
1099       // Google-specific connection options.
1100       case TransportParameters::kGoogleConnectionOptions: {
1101         if (in.google_connection_options.has_value()) {
1102           static_assert(sizeof(in.google_connection_options->front()) == 4,
1103                         "bad size");
1104           uint64_t connection_options_length =
1105               in.google_connection_options->size() * 4;
1106           if (!writer.WriteVarInt62(
1107                   TransportParameters::kGoogleConnectionOptions) ||
1108               !writer.WriteVarInt62(
1109                   /* transport parameter length */ connection_options_length)) {
1110             QUIC_BUG(Failed to write google_connection_options)
1111                 << "Failed to write google_connection_options of length "
1112                 << connection_options_length << " for " << in;
1113             return false;
1114           }
1115           for (const QuicTag& connection_option :
1116                *in.google_connection_options) {
1117             if (!writer.WriteTag(connection_option)) {
1118               QUIC_BUG(Failed to write google_connection_option)
1119                   << "Failed to write google_connection_option "
1120                   << QuicTagToString(connection_option) << " for " << in;
1121               return false;
1122             }
1123           }
1124         }
1125       } break;
1126       // Google-specific version extension.
1127       case TransportParameters::kGoogleQuicVersion: {
1128         if (!in.legacy_version_information.has_value()) {
1129           break;
1130         }
1131         static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
1132                       "bad length");
1133         uint64_t google_version_length =
1134             sizeof(in.legacy_version_information->version);
1135         if (in.perspective == Perspective::IS_SERVER) {
1136           google_version_length +=
1137               /* versions length */ sizeof(uint8_t) +
1138               sizeof(QuicVersionLabel) *
1139                   in.legacy_version_information->supported_versions.size();
1140         }
1141         if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
1142             !writer.WriteVarInt62(
1143                 /* transport parameter length */ google_version_length) ||
1144             !writer.WriteUInt32(in.legacy_version_information->version)) {
1145           QUIC_BUG(Failed to write Google version extension)
1146               << "Failed to write Google version extension for " << in;
1147           return false;
1148         }
1149         if (in.perspective == Perspective::IS_SERVER) {
1150           if (!writer.WriteUInt8(
1151                   sizeof(QuicVersionLabel) *
1152                   in.legacy_version_information->supported_versions.size())) {
1153             QUIC_BUG(Failed to write versions length)
1154                 << "Failed to write versions length for " << in;
1155             return false;
1156           }
1157           for (QuicVersionLabel version_label :
1158                in.legacy_version_information->supported_versions) {
1159             if (!writer.WriteUInt32(version_label)) {
1160               QUIC_BUG(Failed to write supported version)
1161                   << "Failed to write supported version for " << in;
1162               return false;
1163             }
1164           }
1165         }
1166       } break;
1167       // version_information.
1168       case TransportParameters::kVersionInformation: {
1169         if (!in.version_information.has_value()) {
1170           break;
1171         }
1172         static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
1173                       "bad length");
1174         QuicVersionLabelVector other_versions =
1175             in.version_information->other_versions;
1176         // Insert one GREASE version at a random index.
1177         const size_t grease_index =
1178             random->InsecureRandUint64() % (other_versions.size() + 1);
1179         other_versions.insert(
1180             other_versions.begin() + grease_index,
1181             CreateQuicVersionLabel(QuicVersionReservedForNegotiation()));
1182         const uint64_t version_information_length =
1183             sizeof(in.version_information->chosen_version) +
1184             sizeof(QuicVersionLabel) * other_versions.size();
1185         if (!writer.WriteVarInt62(TransportParameters::kVersionInformation) ||
1186             !writer.WriteVarInt62(
1187                 /* transport parameter length */ version_information_length) ||
1188             !writer.WriteUInt32(in.version_information->chosen_version)) {
1189           QUIC_BUG(Failed to write chosen version)
1190               << "Failed to write chosen version for " << in;
1191           return false;
1192         }
1193         for (QuicVersionLabel version_label : other_versions) {
1194           if (!writer.WriteUInt32(version_label)) {
1195             QUIC_BUG(Failed to write other version)
1196                 << "Failed to write other version for " << in;
1197             return false;
1198           }
1199         }
1200       } break;
1201       // Custom parameters and GREASE.
1202       default: {
1203         auto it = custom_parameters.find(parameter_id);
1204         if (it == custom_parameters.end()) {
1205           QUIC_BUG(Unknown parameter) << "Unknown parameter " << parameter_id;
1206           return false;
1207         }
1208         if (!writer.WriteVarInt62(parameter_id) ||
1209             !writer.WriteStringPieceVarInt62(it->second)) {
1210           QUIC_BUG(Failed to write custom parameter)
1211               << "Failed to write custom parameter " << parameter_id;
1212           return false;
1213         }
1214       } break;
1215     }
1216   }
1217 
1218   out->resize(writer.length());
1219 
1220   QUIC_DLOG(INFO) << "Serialized " << in << " as " << writer.length()
1221                   << " bytes";
1222 
1223   return true;
1224 }
1225 
ParseTransportParameters(ParsedQuicVersion version,Perspective perspective,const uint8_t * in,size_t in_len,TransportParameters * out,std::string * error_details)1226 bool ParseTransportParameters(ParsedQuicVersion version,
1227                               Perspective perspective, const uint8_t* in,
1228                               size_t in_len, TransportParameters* out,
1229                               std::string* error_details) {
1230   out->perspective = perspective;
1231   QuicDataReader reader(reinterpret_cast<const char*>(in), in_len);
1232 
1233   while (!reader.IsDoneReading()) {
1234     uint64_t param_id64;
1235     if (!reader.ReadVarInt62(&param_id64)) {
1236       *error_details = "Failed to parse transport parameter ID";
1237       return false;
1238     }
1239     TransportParameters::TransportParameterId param_id =
1240         static_cast<TransportParameters::TransportParameterId>(param_id64);
1241     absl::string_view value;
1242     if (!reader.ReadStringPieceVarInt62(&value)) {
1243       *error_details =
1244           "Failed to read length and value of transport parameter " +
1245           TransportParameterIdToString(param_id);
1246       return false;
1247     }
1248     QuicDataReader value_reader(value);
1249     bool parse_success = true;
1250     switch (param_id) {
1251       case TransportParameters::kOriginalDestinationConnectionId: {
1252         if (out->original_destination_connection_id.has_value()) {
1253           *error_details =
1254               "Received a second original_destination_connection_id";
1255           return false;
1256         }
1257         const size_t connection_id_length = value_reader.BytesRemaining();
1258         if (!QuicUtils::IsConnectionIdLengthValidForVersion(
1259                 connection_id_length, version.transport_version)) {
1260           *error_details = absl::StrCat(
1261               "Received original_destination_connection_id of invalid length ",
1262               connection_id_length);
1263           return false;
1264         }
1265         QuicConnectionId original_destination_connection_id;
1266         if (!value_reader.ReadConnectionId(&original_destination_connection_id,
1267                                            connection_id_length)) {
1268           *error_details = "Failed to read original_destination_connection_id";
1269           return false;
1270         }
1271         out->original_destination_connection_id =
1272             original_destination_connection_id;
1273       } break;
1274       case TransportParameters::kMaxIdleTimeout:
1275         parse_success =
1276             out->max_idle_timeout_ms.Read(&value_reader, error_details);
1277         break;
1278       case TransportParameters::kStatelessResetToken: {
1279         if (!out->stateless_reset_token.empty()) {
1280           *error_details = "Received a second stateless_reset_token";
1281           return false;
1282         }
1283         absl::string_view stateless_reset_token =
1284             value_reader.ReadRemainingPayload();
1285         if (stateless_reset_token.length() != kStatelessResetTokenLength) {
1286           *error_details =
1287               absl::StrCat("Received stateless_reset_token of invalid length ",
1288                            stateless_reset_token.length());
1289           return false;
1290         }
1291         out->stateless_reset_token.assign(
1292             stateless_reset_token.data(),
1293             stateless_reset_token.data() + stateless_reset_token.length());
1294       } break;
1295       case TransportParameters::kMaxPacketSize:
1296         parse_success =
1297             out->max_udp_payload_size.Read(&value_reader, error_details);
1298         break;
1299       case TransportParameters::kInitialMaxData:
1300         parse_success =
1301             out->initial_max_data.Read(&value_reader, error_details);
1302         break;
1303       case TransportParameters::kInitialMaxStreamDataBidiLocal:
1304         parse_success = out->initial_max_stream_data_bidi_local.Read(
1305             &value_reader, error_details);
1306         break;
1307       case TransportParameters::kInitialMaxStreamDataBidiRemote:
1308         parse_success = out->initial_max_stream_data_bidi_remote.Read(
1309             &value_reader, error_details);
1310         break;
1311       case TransportParameters::kInitialMaxStreamDataUni:
1312         parse_success =
1313             out->initial_max_stream_data_uni.Read(&value_reader, error_details);
1314         break;
1315       case TransportParameters::kInitialMaxStreamsBidi:
1316         parse_success =
1317             out->initial_max_streams_bidi.Read(&value_reader, error_details);
1318         break;
1319       case TransportParameters::kInitialMaxStreamsUni:
1320         parse_success =
1321             out->initial_max_streams_uni.Read(&value_reader, error_details);
1322         break;
1323       case TransportParameters::kAckDelayExponent:
1324         parse_success =
1325             out->ack_delay_exponent.Read(&value_reader, error_details);
1326         break;
1327       case TransportParameters::kMaxAckDelay:
1328         parse_success = out->max_ack_delay.Read(&value_reader, error_details);
1329         break;
1330       case TransportParameters::kDisableActiveMigration:
1331         if (out->disable_active_migration) {
1332           *error_details = "Received a second disable_active_migration";
1333           return false;
1334         }
1335         out->disable_active_migration = true;
1336         break;
1337       case TransportParameters::kPreferredAddress: {
1338         TransportParameters::PreferredAddress preferred_address;
1339         uint16_t ipv4_port, ipv6_port;
1340         in_addr ipv4_address;
1341         in6_addr ipv6_address;
1342         preferred_address.stateless_reset_token.resize(
1343             kStatelessResetTokenLength);
1344         if (!value_reader.ReadBytes(&ipv4_address, sizeof(ipv4_address)) ||
1345             !value_reader.ReadUInt16(&ipv4_port) ||
1346             !value_reader.ReadBytes(&ipv6_address, sizeof(ipv6_address)) ||
1347             !value_reader.ReadUInt16(&ipv6_port) ||
1348             !value_reader.ReadLengthPrefixedConnectionId(
1349                 &preferred_address.connection_id) ||
1350             !value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
1351                                     kStatelessResetTokenLength)) {
1352           *error_details = "Failed to read preferred_address";
1353           return false;
1354         }
1355         preferred_address.ipv4_socket_address =
1356             QuicSocketAddress(QuicIpAddress(ipv4_address), ipv4_port);
1357         preferred_address.ipv6_socket_address =
1358             QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
1359         if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
1360             !preferred_address.ipv6_socket_address.host().IsIPv6()) {
1361           *error_details = "Received preferred_address of bad families " +
1362                            preferred_address.ToString();
1363           return false;
1364         }
1365         if (!QuicUtils::IsConnectionIdValidForVersion(
1366                 preferred_address.connection_id, version.transport_version)) {
1367           *error_details = "Received invalid preferred_address connection ID " +
1368                            preferred_address.ToString();
1369           return false;
1370         }
1371         out->preferred_address =
1372             std::make_unique<TransportParameters::PreferredAddress>(
1373                 preferred_address);
1374       } break;
1375       case TransportParameters::kActiveConnectionIdLimit:
1376         parse_success =
1377             out->active_connection_id_limit.Read(&value_reader, error_details);
1378         break;
1379       case TransportParameters::kInitialSourceConnectionId: {
1380         if (out->initial_source_connection_id.has_value()) {
1381           *error_details = "Received a second initial_source_connection_id";
1382           return false;
1383         }
1384         const size_t connection_id_length = value_reader.BytesRemaining();
1385         if (!QuicUtils::IsConnectionIdLengthValidForVersion(
1386                 connection_id_length, version.transport_version)) {
1387           *error_details = absl::StrCat(
1388               "Received initial_source_connection_id of invalid length ",
1389               connection_id_length);
1390           return false;
1391         }
1392         QuicConnectionId initial_source_connection_id;
1393         if (!value_reader.ReadConnectionId(&initial_source_connection_id,
1394                                            connection_id_length)) {
1395           *error_details = "Failed to read initial_source_connection_id";
1396           return false;
1397         }
1398         out->initial_source_connection_id = initial_source_connection_id;
1399       } break;
1400       case TransportParameters::kRetrySourceConnectionId: {
1401         if (out->retry_source_connection_id.has_value()) {
1402           *error_details = "Received a second retry_source_connection_id";
1403           return false;
1404         }
1405         const size_t connection_id_length = value_reader.BytesRemaining();
1406         if (!QuicUtils::IsConnectionIdLengthValidForVersion(
1407                 connection_id_length, version.transport_version)) {
1408           *error_details = absl::StrCat(
1409               "Received retry_source_connection_id of invalid length ",
1410               connection_id_length);
1411           return false;
1412         }
1413         QuicConnectionId retry_source_connection_id;
1414         if (!value_reader.ReadConnectionId(&retry_source_connection_id,
1415                                            connection_id_length)) {
1416           *error_details = "Failed to read retry_source_connection_id";
1417           return false;
1418         }
1419         out->retry_source_connection_id = retry_source_connection_id;
1420       } break;
1421       case TransportParameters::kMaxDatagramFrameSize:
1422         parse_success =
1423             out->max_datagram_frame_size.Read(&value_reader, error_details);
1424         break;
1425       case TransportParameters::kGoogleHandshakeMessage:
1426         if (out->google_handshake_message.has_value()) {
1427           *error_details = "Received a second google_handshake_message";
1428           return false;
1429         }
1430         out->google_handshake_message =
1431             std::string(value_reader.ReadRemainingPayload());
1432         break;
1433       case TransportParameters::kInitialRoundTripTime:
1434         parse_success =
1435             out->initial_round_trip_time_us.Read(&value_reader, error_details);
1436         break;
1437       case TransportParameters::kGoogleConnectionOptions: {
1438         if (out->google_connection_options.has_value()) {
1439           *error_details = "Received a second google_connection_options";
1440           return false;
1441         }
1442         out->google_connection_options = QuicTagVector{};
1443         while (!value_reader.IsDoneReading()) {
1444           QuicTag connection_option;
1445           if (!value_reader.ReadTag(&connection_option)) {
1446             *error_details = "Failed to read a google_connection_options";
1447             return false;
1448           }
1449           out->google_connection_options->push_back(connection_option);
1450         }
1451       } break;
1452       case TransportParameters::kGoogleQuicVersion: {
1453         if (!out->legacy_version_information.has_value()) {
1454           out->legacy_version_information =
1455               TransportParameters::LegacyVersionInformation();
1456         }
1457         if (!value_reader.ReadUInt32(
1458                 &out->legacy_version_information->version)) {
1459           *error_details = "Failed to read Google version extension version";
1460           return false;
1461         }
1462         if (perspective == Perspective::IS_SERVER) {
1463           uint8_t versions_length;
1464           if (!value_reader.ReadUInt8(&versions_length)) {
1465             *error_details = "Failed to parse Google supported versions length";
1466             return false;
1467           }
1468           const uint8_t num_versions = versions_length / sizeof(uint32_t);
1469           for (uint8_t i = 0; i < num_versions; ++i) {
1470             QuicVersionLabel parsed_version;
1471             if (!value_reader.ReadUInt32(&parsed_version)) {
1472               *error_details = "Failed to parse Google supported version";
1473               return false;
1474             }
1475             out->legacy_version_information->supported_versions.push_back(
1476                 parsed_version);
1477           }
1478         }
1479       } break;
1480       case TransportParameters::kVersionInformation: {
1481         if (out->version_information.has_value()) {
1482           *error_details = "Received a second version_information";
1483           return false;
1484         }
1485         out->version_information = TransportParameters::VersionInformation();
1486         if (!value_reader.ReadUInt32(
1487                 &out->version_information->chosen_version)) {
1488           *error_details = "Failed to read chosen version";
1489           return false;
1490         }
1491         while (!value_reader.IsDoneReading()) {
1492           QuicVersionLabel other_version;
1493           if (!value_reader.ReadUInt32(&other_version)) {
1494             *error_details = "Failed to parse other version";
1495             return false;
1496           }
1497           out->version_information->other_versions.push_back(other_version);
1498         }
1499       } break;
1500       case TransportParameters::kMinAckDelay:
1501         parse_success =
1502             out->min_ack_delay_us.Read(&value_reader, error_details);
1503         break;
1504       default:
1505         if (out->custom_parameters.find(param_id) !=
1506             out->custom_parameters.end()) {
1507           *error_details = "Received a second unknown parameter" +
1508                            TransportParameterIdToString(param_id);
1509           return false;
1510         }
1511         out->custom_parameters[param_id] =
1512             std::string(value_reader.ReadRemainingPayload());
1513         break;
1514     }
1515     if (!parse_success) {
1516       QUICHE_DCHECK(!error_details->empty());
1517       return false;
1518     }
1519     if (!value_reader.IsDoneReading()) {
1520       *error_details = absl::StrCat(
1521           "Received unexpected ", value_reader.BytesRemaining(),
1522           " bytes after parsing ", TransportParameterIdToString(param_id));
1523       return false;
1524     }
1525   }
1526 
1527   if (!out->AreValid(error_details)) {
1528     QUICHE_DCHECK(!error_details->empty());
1529     return false;
1530   }
1531 
1532   QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
1533                   << in_len << " bytes";
1534 
1535   return true;
1536 }
1537 
1538 namespace {
1539 
DigestUpdateIntegerParam(EVP_MD_CTX * hash_ctx,const TransportParameters::IntegerParameter & param)1540 bool DigestUpdateIntegerParam(
1541     EVP_MD_CTX* hash_ctx, const TransportParameters::IntegerParameter& param) {
1542   uint64_t value = param.value();
1543   return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
1544 }
1545 
1546 }  // namespace
1547 
SerializeTransportParametersForTicket(const TransportParameters & in,const std::vector<uint8_t> & application_data,std::vector<uint8_t> * out)1548 bool SerializeTransportParametersForTicket(
1549     const TransportParameters& in, const std::vector<uint8_t>& application_data,
1550     std::vector<uint8_t>* out) {
1551   std::string error_details;
1552   if (!in.AreValid(&error_details)) {
1553     QUIC_BUG(quic_bug_10743_26)
1554         << "Not serializing invalid transport parameters: " << error_details;
1555     return false;
1556   }
1557 
1558   out->resize(SHA256_DIGEST_LENGTH + 1);
1559   const uint8_t serialization_version = 0;
1560   (*out)[0] = serialization_version;
1561 
1562   bssl::ScopedEVP_MD_CTX hash_ctx;
1563   // Write application data:
1564   uint64_t app_data_len = application_data.size();
1565   const uint64_t parameter_version = 0;
1566   // The format of the input to the hash function is as follows:
1567   // - The application data, prefixed with a 64-bit length field.
1568   // - Transport parameters:
1569   //   - A 64-bit version field indicating which version of encoding is used
1570   //     for transport parameters.
1571   //   - A list of 64-bit integers representing the relevant parameters.
1572   //
1573   //   When changing which parameters are included, additional parameters can be
1574   //   added to the end of the list without changing the version field. New
1575   //   parameters that are variable length must be length prefixed. If
1576   //   parameters are removed from the list, the version field must be
1577   //   incremented.
1578   //
1579   // Integers happen to be written in host byte order, not network byte order.
1580   if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
1581       !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
1582       !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
1583                         application_data.size()) ||
1584       !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
1585                         sizeof(parameter_version))) {
1586     QUIC_BUG(quic_bug_10743_27)
1587         << "Unexpected failure of EVP_Digest functions when hashing "
1588            "Transport Parameters for ticket";
1589     return false;
1590   }
1591 
1592   // Write transport parameters specified by draft-ietf-quic-transport-28,
1593   // section 7.4.1, that are remembered for 0-RTT.
1594   if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
1595       !DigestUpdateIntegerParam(hash_ctx.get(),
1596                                 in.initial_max_stream_data_bidi_local) ||
1597       !DigestUpdateIntegerParam(hash_ctx.get(),
1598                                 in.initial_max_stream_data_bidi_remote) ||
1599       !DigestUpdateIntegerParam(hash_ctx.get(),
1600                                 in.initial_max_stream_data_uni) ||
1601       !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
1602       !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
1603       !DigestUpdateIntegerParam(hash_ctx.get(),
1604                                 in.active_connection_id_limit)) {
1605     QUIC_BUG(quic_bug_10743_28)
1606         << "Unexpected failure of EVP_Digest functions when hashing "
1607            "Transport Parameters for ticket";
1608     return false;
1609   }
1610   uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
1611   if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
1612                         sizeof(disable_active_migration)) ||
1613       !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
1614     QUIC_BUG(quic_bug_10743_29)
1615         << "Unexpected failure of EVP_Digest functions when hashing "
1616            "Transport Parameters for ticket";
1617     return false;
1618   }
1619   return true;
1620 }
1621 
DegreaseTransportParameters(TransportParameters & parameters)1622 void DegreaseTransportParameters(TransportParameters& parameters) {
1623   // Strip GREASE from custom parameters.
1624   for (auto it = parameters.custom_parameters.begin();
1625        it != parameters.custom_parameters.end();
1626        /**/) {
1627     // See the "Reserved Transport Parameters" section of RFC 9000.
1628     if (it->first % 31 == 27) {
1629       parameters.custom_parameters.erase(it++);
1630     } else {
1631       ++it;
1632     }
1633   }
1634 
1635   // Strip GREASE from versions.
1636   if (parameters.version_information.has_value()) {
1637     QuicVersionLabelVector clean_versions;
1638     for (QuicVersionLabel version :
1639          parameters.version_information->other_versions) {
1640       // See the "Versions" section of RFC 9000.
1641       if ((version & kReservedVersionMask) != kReservedVersionBits) {
1642         clean_versions.push_back(version);
1643       }
1644     }
1645 
1646     parameters.version_information->other_versions = std::move(clean_versions);
1647   }
1648 }
1649 
1650 }  // namespace quic
1651