blob: f40cc334a208f1fe9993d3d18dd413215ee24d3d [file] [log] [blame]
Bence Békybac04052022-04-07 15:44:29 -04001// Copyright (c) 2012 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/quic_versions.h"
6
QUICHE team7baee702024-05-21 11:18:15 -07007#include <algorithm>
8#include <ostream>
Bence Békybac04052022-04-07 15:44:29 -04009#include <string>
QUICHE team7baee702024-05-21 11:18:15 -070010#include <vector>
Bence Békybac04052022-04-07 15:44:29 -040011
12#include "absl/base/macros.h"
13#include "absl/strings/numbers.h"
14#include "absl/strings/str_cat.h"
15#include "absl/strings/str_split.h"
16#include "quiche/quic/core/crypto/quic_random.h"
17#include "quiche/quic/core/quic_tag.h"
18#include "quiche/quic/core/quic_types.h"
19#include "quiche/quic/platform/api/quic_bug_tracker.h"
20#include "quiche/quic/platform/api/quic_flag_utils.h"
21#include "quiche/quic/platform/api/quic_flags.h"
22#include "quiche/quic/platform/api/quic_logging.h"
23#include "quiche/common/quiche_endian.h"
24#include "quiche/common/quiche_text_utils.h"
25
26namespace quic {
27namespace {
28
29QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
30 QuicVersionLabel result;
birenroyef686222022-09-12 11:34:34 -070031 if (!GetQuicFlag(quic_disable_version_negotiation_grease_randomness)) {
Bence Békybac04052022-04-07 15:44:29 -040032 QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
33 } else {
34 result = MakeVersionLabel(0xd1, 0x57, 0x38, 0x3f);
35 }
36 result &= 0xf0f0f0f0;
37 result |= 0x0a0a0a0a;
38 return result;
39}
40
41void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
rch6767ab52024-03-20 22:20:34 -070042 static_assert(SupportedVersions().size() == 4u,
Bence Békybac04052022-04-07 15:44:29 -040043 "Supported versions out of sync");
44 const bool enable = should_enable;
45 const bool disable = !should_enable;
martinduke88918ac2023-06-02 10:44:08 -070046 if (version == ParsedQuicVersion::RFCv2()) {
47 SetQuicReloadableFlag(quic_enable_version_rfcv2, enable);
Bence Békybac04052022-04-07 15:44:29 -040048 } else if (version == ParsedQuicVersion::RFCv1()) {
49 SetQuicReloadableFlag(quic_disable_version_rfcv1, disable);
50 } else if (version == ParsedQuicVersion::Draft29()) {
51 SetQuicReloadableFlag(quic_disable_version_draft_29, disable);
Bence Békybac04052022-04-07 15:44:29 -040052 } else if (version == ParsedQuicVersion::Q046()) {
53 SetQuicReloadableFlag(quic_disable_version_q046, disable);
Bence Békybac04052022-04-07 15:44:29 -040054 } else {
55 QUIC_BUG(quic_bug_10589_1)
56 << "Cannot " << (enable ? "en" : "dis") << "able version " << version;
57 }
58}
59
60} // namespace
61
62bool ParsedQuicVersion::IsKnown() const {
63 QUICHE_DCHECK(ParsedQuicVersionIsValid(handshake_protocol, transport_version))
64 << QuicVersionToString(transport_version) << " "
65 << HandshakeProtocolToString(handshake_protocol);
66 return transport_version != QUIC_VERSION_UNSUPPORTED;
67}
68
69bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
70 QUICHE_DCHECK(IsKnown());
71 return transport_version > QUIC_VERSION_46;
72}
73
74bool ParsedQuicVersion::UsesInitialObfuscators() const {
75 QUICHE_DCHECK(IsKnown());
76 // Initial obfuscators were added in version 50.
77 return transport_version > QUIC_VERSION_46;
78}
79
80bool ParsedQuicVersion::AllowsLowFlowControlLimits() const {
81 QUICHE_DCHECK(IsKnown());
82 // Low flow-control limits are used for all IETF versions.
83 return UsesHttp3();
84}
85
86bool ParsedQuicVersion::HasHeaderProtection() const {
87 QUICHE_DCHECK(IsKnown());
88 // Header protection was added in version 50.
89 return transport_version > QUIC_VERSION_46;
90}
91
92bool ParsedQuicVersion::SupportsRetry() const {
93 QUICHE_DCHECK(IsKnown());
94 // Retry was added in version 47.
95 return transport_version > QUIC_VERSION_46;
96}
97
98bool ParsedQuicVersion::SendsVariableLengthPacketNumberInLongHeader() const {
99 QUICHE_DCHECK(IsKnown());
100 return transport_version > QUIC_VERSION_46;
101}
102
103bool ParsedQuicVersion::AllowsVariableLengthConnectionIds() const {
104 QUICHE_DCHECK(IsKnown());
105 return VersionAllowsVariableLengthConnectionIds(transport_version);
106}
107
108bool ParsedQuicVersion::SupportsClientConnectionIds() const {
109 QUICHE_DCHECK(IsKnown());
110 // Client connection IDs were added in version 49.
111 return transport_version > QUIC_VERSION_46;
112}
113
114bool ParsedQuicVersion::HasLengthPrefixedConnectionIds() const {
115 QUICHE_DCHECK(IsKnown());
116 return VersionHasLengthPrefixedConnectionIds(transport_version);
117}
118
119bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
120 QUICHE_DCHECK(IsKnown());
121 // The anti-amplification limit is used for all IETF versions.
122 return UsesHttp3();
123}
124
125bool ParsedQuicVersion::CanSendCoalescedPackets() const {
126 QUICHE_DCHECK(IsKnown());
127 return HasLongHeaderLengths() && UsesTls();
128}
129
130bool ParsedQuicVersion::SupportsGoogleAltSvcFormat() const {
131 QUICHE_DCHECK(IsKnown());
132 return VersionSupportsGoogleAltSvcFormat(transport_version);
133}
134
Bence Békybac04052022-04-07 15:44:29 -0400135bool ParsedQuicVersion::UsesHttp3() const {
136 QUICHE_DCHECK(IsKnown());
137 return VersionUsesHttp3(transport_version);
138}
139
140bool ParsedQuicVersion::HasLongHeaderLengths() const {
141 QUICHE_DCHECK(IsKnown());
142 return QuicVersionHasLongHeaderLengths(transport_version);
143}
144
145bool ParsedQuicVersion::UsesCryptoFrames() const {
146 QUICHE_DCHECK(IsKnown());
147 return QuicVersionUsesCryptoFrames(transport_version);
148}
149
150bool ParsedQuicVersion::HasIetfQuicFrames() const {
151 QUICHE_DCHECK(IsKnown());
152 return VersionHasIetfQuicFrames(transport_version);
153}
154
155bool ParsedQuicVersion::UsesLegacyTlsExtension() const {
156 QUICHE_DCHECK(IsKnown());
157 return UsesTls() && transport_version <= QUIC_VERSION_IETF_DRAFT_29;
158}
159
160bool ParsedQuicVersion::UsesTls() const {
161 QUICHE_DCHECK(IsKnown());
162 return handshake_protocol == PROTOCOL_TLS1_3;
163}
164
165bool ParsedQuicVersion::UsesQuicCrypto() const {
166 QUICHE_DCHECK(IsKnown());
167 return handshake_protocol == PROTOCOL_QUIC_CRYPTO;
168}
169
170bool ParsedQuicVersion::UsesV2PacketTypes() const {
171 QUICHE_DCHECK(IsKnown());
martinduke88918ac2023-06-02 10:44:08 -0700172 return transport_version == QUIC_VERSION_IETF_RFC_V2;
Bence Békybac04052022-04-07 15:44:29 -0400173}
174
175bool ParsedQuicVersion::AlpnDeferToRFCv1() const {
176 QUICHE_DCHECK(IsKnown());
martinduke88918ac2023-06-02 10:44:08 -0700177 return transport_version == QUIC_VERSION_IETF_RFC_V2;
Bence Békybac04052022-04-07 15:44:29 -0400178}
179
180bool VersionHasLengthPrefixedConnectionIds(
181 QuicTransportVersion transport_version) {
182 QUICHE_DCHECK(transport_version != QUIC_VERSION_UNSUPPORTED);
183 // Length-prefixed connection IDs were added in version 49.
184 return transport_version > QUIC_VERSION_46;
185}
186
187std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
188 os << ParsedQuicVersionToString(version);
189 return os;
190}
191
192std::ostream& operator<<(std::ostream& os,
193 const ParsedQuicVersionVector& versions) {
194 os << ParsedQuicVersionVectorToString(versions);
195 return os;
196}
197
198QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
199 return MakeQuicTag(d, c, b, a);
200}
201
202std::ostream& operator<<(std::ostream& os,
203 const QuicVersionLabelVector& version_labels) {
204 os << QuicVersionLabelVectorToString(version_labels);
205 return os;
206}
207
208std::ostream& operator<<(std::ostream& os,
209 const QuicTransportVersionVector& transport_versions) {
210 os << QuicTransportVersionVectorToString(transport_versions);
211 return os;
212}
213
214QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
rch6767ab52024-03-20 22:20:34 -0700215 static_assert(SupportedVersions().size() == 4u,
Bence Békybac04052022-04-07 15:44:29 -0400216 "Supported versions out of sync");
martinduke88918ac2023-06-02 10:44:08 -0700217 if (parsed_version == ParsedQuicVersion::RFCv2()) {
martindukea2cb68a2022-12-12 17:24:39 -0800218 return MakeVersionLabel(0x6b, 0x33, 0x43, 0xcf);
Bence Békybac04052022-04-07 15:44:29 -0400219 } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
220 return MakeVersionLabel(0x00, 0x00, 0x00, 0x01);
221 } else if (parsed_version == ParsedQuicVersion::Draft29()) {
222 return MakeVersionLabel(0xff, 0x00, 0x00, 29);
Bence Békybac04052022-04-07 15:44:29 -0400223 } else if (parsed_version == ParsedQuicVersion::Q046()) {
224 return MakeVersionLabel('Q', '0', '4', '6');
Bence Békybac04052022-04-07 15:44:29 -0400225 } else if (parsed_version == ParsedQuicVersion::ReservedForNegotiation()) {
226 return CreateRandomVersionLabelForNegotiation();
227 }
228 QUIC_BUG(quic_bug_10589_2)
229 << "Unsupported version "
230 << QuicVersionToString(parsed_version.transport_version) << " "
231 << HandshakeProtocolToString(parsed_version.handshake_protocol);
232 return 0;
233}
234
235QuicVersionLabelVector CreateQuicVersionLabelVector(
236 const ParsedQuicVersionVector& versions) {
237 QuicVersionLabelVector out;
238 out.reserve(versions.size());
239 for (const auto& version : versions) {
240 out.push_back(CreateQuicVersionLabel(version));
241 }
242 return out;
243}
244
245ParsedQuicVersionVector AllSupportedVersionsWithQuicCrypto() {
246 ParsedQuicVersionVector versions;
247 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
248 if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
249 versions.push_back(version);
250 }
251 }
252 QUIC_BUG_IF(quic_bug_10589_3, versions.empty())
253 << "No version with QUIC crypto found.";
254 return versions;
255}
256
257ParsedQuicVersionVector CurrentSupportedVersionsWithQuicCrypto() {
258 ParsedQuicVersionVector versions;
259 for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
260 if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
261 versions.push_back(version);
262 }
263 }
264 QUIC_BUG_IF(quic_bug_10589_4, versions.empty())
265 << "No version with QUIC crypto found.";
266 return versions;
267}
268
269ParsedQuicVersionVector AllSupportedVersionsWithTls() {
270 ParsedQuicVersionVector versions;
271 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
272 if (version.UsesTls()) {
273 versions.push_back(version);
274 }
275 }
276 QUIC_BUG_IF(quic_bug_10589_5, versions.empty())
277 << "No version with TLS handshake found.";
278 return versions;
279}
280
281ParsedQuicVersionVector CurrentSupportedVersionsWithTls() {
282 ParsedQuicVersionVector versions;
283 for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
284 if (version.UsesTls()) {
285 versions.push_back(version);
286 }
287 }
288 QUIC_BUG_IF(quic_bug_10589_6, versions.empty())
289 << "No version with TLS handshake found.";
290 return versions;
291}
292
rch29577022023-09-14 13:45:51 -0700293ParsedQuicVersionVector ObsoleteSupportedVersions() {
294 return ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046(),
rch29577022023-09-14 13:45:51 -0700295 quic::ParsedQuicVersion::Draft29()};
296}
297
298bool IsObsoleteSupportedVersion(ParsedQuicVersion version) {
299 static const ParsedQuicVersionVector obsolete_versions =
300 ObsoleteSupportedVersions();
301 for (const ParsedQuicVersion& obsolete_version : obsolete_versions) {
302 if (version == obsolete_version) {
303 return true;
304 }
305 }
306 return false;
307}
308
309ParsedQuicVersionVector CurrentSupportedVersionsForClients() {
310 ParsedQuicVersionVector versions;
311 for (const ParsedQuicVersion& version : CurrentSupportedVersionsWithTls()) {
312 QUICHE_DCHECK_EQ(version.handshake_protocol, PROTOCOL_TLS1_3);
313 if (version.transport_version >= QUIC_VERSION_IETF_RFC_V1) {
314 versions.push_back(version);
315 }
316 }
317 QUIC_BUG_IF(quic_bug_10589_8, versions.empty())
318 << "No supported client versions found.";
319 return versions;
320}
321
Bence Békybac04052022-04-07 15:44:29 -0400322ParsedQuicVersionVector CurrentSupportedHttp3Versions() {
323 ParsedQuicVersionVector versions;
324 for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
325 if (version.UsesHttp3()) {
326 versions.push_back(version);
327 }
328 }
329 QUIC_BUG_IF(no_version_uses_http3, versions.empty())
330 << "No version speaking Http3 found.";
331 return versions;
332}
333
334ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) {
335 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
336 if (version_label == CreateQuicVersionLabel(version)) {
337 return version;
338 }
339 }
340 // Reading from the client so this should not be considered an ERROR.
341 QUIC_DLOG(INFO) << "Unsupported QuicVersionLabel version: "
342 << QuicVersionLabelToString(version_label);
343 return UnsupportedQuicVersion();
344}
345
346ParsedQuicVersionVector ParseQuicVersionLabelVector(
347 const QuicVersionLabelVector& version_labels) {
348 ParsedQuicVersionVector parsed_versions;
349 for (const QuicVersionLabel& version_label : version_labels) {
350 ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
351 if (parsed_version.IsKnown()) {
352 parsed_versions.push_back(parsed_version);
353 }
354 }
355 return parsed_versions;
356}
357
358ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) {
359 if (version_string.empty()) {
360 return UnsupportedQuicVersion();
361 }
362 const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
363 for (const ParsedQuicVersion& version : supported_versions) {
364 if (version_string == ParsedQuicVersionToString(version) ||
365 (version_string == AlpnForVersion(version) &&
366 !version.AlpnDeferToRFCv1()) ||
367 (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
368 version_string == QuicVersionToString(version.transport_version))) {
369 return version;
370 }
371 }
372 for (const ParsedQuicVersion& version : supported_versions) {
373 if (version.UsesHttp3() &&
374 version_string ==
375 QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
376 return version;
377 }
378 }
379 int quic_version_number = 0;
380 if (absl::SimpleAtoi(version_string, &quic_version_number) &&
381 quic_version_number > 0) {
382 QuicTransportVersion transport_version =
383 static_cast<QuicTransportVersion>(quic_version_number);
384 if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
385 return UnsupportedQuicVersion();
386 }
387 ParsedQuicVersion version(PROTOCOL_QUIC_CRYPTO, transport_version);
388 if (std::find(supported_versions.begin(), supported_versions.end(),
389 version) != supported_versions.end()) {
390 return version;
391 }
392 return UnsupportedQuicVersion();
393 }
394 // Reading from the client so this should not be considered an ERROR.
395 QUIC_DLOG(INFO) << "Unsupported QUIC version string: \"" << version_string
396 << "\".";
397 return UnsupportedQuicVersion();
398}
399
400ParsedQuicVersionVector ParseQuicVersionVectorString(
401 absl::string_view versions_string) {
402 ParsedQuicVersionVector versions;
403 std::vector<absl::string_view> version_strings =
404 absl::StrSplit(versions_string, ',');
405 for (absl::string_view version_string : version_strings) {
406 quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
407 &version_string);
408 ParsedQuicVersion version = ParseQuicVersionString(version_string);
409 if (!version.IsKnown() || std::find(versions.begin(), versions.end(),
410 version) != versions.end()) {
411 continue;
412 }
413 versions.push_back(version);
414 }
415 return versions;
416}
417
418QuicTransportVersionVector AllSupportedTransportVersions() {
419 QuicTransportVersionVector transport_versions;
420 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
421 if (std::find(transport_versions.begin(), transport_versions.end(),
422 version.transport_version) == transport_versions.end()) {
423 transport_versions.push_back(version.transport_version);
424 }
425 }
426 return transport_versions;
427}
428
429ParsedQuicVersionVector AllSupportedVersions() {
430 constexpr auto supported_versions = SupportedVersions();
431 return ParsedQuicVersionVector(supported_versions.begin(),
432 supported_versions.end());
433}
434
435ParsedQuicVersionVector CurrentSupportedVersions() {
436 return FilterSupportedVersions(AllSupportedVersions());
437}
438
439ParsedQuicVersionVector FilterSupportedVersions(
440 ParsedQuicVersionVector versions) {
rch6767ab52024-03-20 22:20:34 -0700441 static_assert(SupportedVersions().size() == 4u,
Bence Békybac04052022-04-07 15:44:29 -0400442 "Supported versions out of sync");
443 ParsedQuicVersionVector filtered_versions;
444 filtered_versions.reserve(versions.size());
445 for (const ParsedQuicVersion& version : versions) {
martinduke88918ac2023-06-02 10:44:08 -0700446 if (version == ParsedQuicVersion::RFCv2()) {
447 if (GetQuicReloadableFlag(quic_enable_version_rfcv2)) {
Bence Békybac04052022-04-07 15:44:29 -0400448 filtered_versions.push_back(version);
449 }
450 } else if (version == ParsedQuicVersion::RFCv1()) {
451 if (!GetQuicReloadableFlag(quic_disable_version_rfcv1)) {
452 filtered_versions.push_back(version);
453 }
454 } else if (version == ParsedQuicVersion::Draft29()) {
455 if (!GetQuicReloadableFlag(quic_disable_version_draft_29)) {
456 filtered_versions.push_back(version);
457 }
Bence Békybac04052022-04-07 15:44:29 -0400458 } else if (version == ParsedQuicVersion::Q046()) {
459 if (!GetQuicReloadableFlag(quic_disable_version_q046)) {
460 filtered_versions.push_back(version);
461 }
Bence Békybac04052022-04-07 15:44:29 -0400462 } else {
463 QUIC_BUG(quic_bug_10589_7)
464 << "QUIC version " << version << " has no flag protection";
465 filtered_versions.push_back(version);
466 }
467 }
468 return filtered_versions;
469}
470
471ParsedQuicVersionVector ParsedVersionOfIndex(
472 const ParsedQuicVersionVector& versions, int index) {
473 ParsedQuicVersionVector version;
474 int version_count = versions.size();
475 if (index >= 0 && index < version_count) {
476 version.push_back(versions[index]);
477 } else {
478 version.push_back(UnsupportedQuicVersion());
479 }
480 return version;
481}
482
483std::string QuicVersionLabelToString(QuicVersionLabel version_label) {
484 return QuicTagToString(quiche::QuicheEndian::HostToNet32(version_label));
485}
486
487ParsedQuicVersion ParseQuicVersionLabelString(
488 absl::string_view version_label_string) {
489 const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
490 for (const ParsedQuicVersion& version : supported_versions) {
491 if (version_label_string ==
492 QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
493 return version;
494 }
495 }
496 return UnsupportedQuicVersion();
497}
498
499std::string QuicVersionLabelVectorToString(
500 const QuicVersionLabelVector& version_labels, const std::string& separator,
501 size_t skip_after_nth_version) {
502 std::string result;
503 for (size_t i = 0; i < version_labels.size(); ++i) {
504 if (i != 0) {
505 result.append(separator);
506 }
507
508 if (i > skip_after_nth_version) {
509 result.append("...");
510 break;
511 }
512 result.append(QuicVersionLabelToString(version_labels[i]));
513 }
514 return result;
515}
516
517#define RETURN_STRING_LITERAL(x) \
518 case x: \
519 return #x
520
521std::string QuicVersionToString(QuicTransportVersion transport_version) {
522 switch (transport_version) {
Bence Békybac04052022-04-07 15:44:29 -0400523 RETURN_STRING_LITERAL(QUIC_VERSION_46);
Bence Békybac04052022-04-07 15:44:29 -0400524 RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
525 RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V1);
martinduke88918ac2023-06-02 10:44:08 -0700526 RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V2);
Bence Békybac04052022-04-07 15:44:29 -0400527 RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
528 RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
529 }
530 return absl::StrCat("QUIC_VERSION_UNKNOWN(",
531 static_cast<int>(transport_version), ")");
532}
533
534std::string HandshakeProtocolToString(HandshakeProtocol handshake_protocol) {
535 switch (handshake_protocol) {
536 RETURN_STRING_LITERAL(PROTOCOL_UNSUPPORTED);
537 RETURN_STRING_LITERAL(PROTOCOL_QUIC_CRYPTO);
538 RETURN_STRING_LITERAL(PROTOCOL_TLS1_3);
539 }
540 return absl::StrCat("PROTOCOL_UNKNOWN(", static_cast<int>(handshake_protocol),
541 ")");
542}
543
544std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
rch6767ab52024-03-20 22:20:34 -0700545 static_assert(SupportedVersions().size() == 4u,
Bence Békybac04052022-04-07 15:44:29 -0400546 "Supported versions out of sync");
547 if (version == UnsupportedQuicVersion()) {
548 return "0";
martinduke88918ac2023-06-02 10:44:08 -0700549 } else if (version == ParsedQuicVersion::RFCv2()) {
Bence Békybac04052022-04-07 15:44:29 -0400550 QUICHE_DCHECK(version.UsesHttp3());
martinduke88918ac2023-06-02 10:44:08 -0700551 return "RFCv2";
Bence Békybac04052022-04-07 15:44:29 -0400552 } else if (version == ParsedQuicVersion::RFCv1()) {
553 QUICHE_DCHECK(version.UsesHttp3());
554 return "RFCv1";
555 } else if (version == ParsedQuicVersion::Draft29()) {
556 QUICHE_DCHECK(version.UsesHttp3());
557 return "draft29";
558 }
559
560 return QuicVersionLabelToString(CreateQuicVersionLabel(version));
561}
562
563std::string QuicTransportVersionVectorToString(
564 const QuicTransportVersionVector& versions) {
565 std::string result = "";
566 for (size_t i = 0; i < versions.size(); ++i) {
567 if (i != 0) {
568 result.append(",");
569 }
570 result.append(QuicVersionToString(versions[i]));
571 }
572 return result;
573}
574
575std::string ParsedQuicVersionVectorToString(
576 const ParsedQuicVersionVector& versions, const std::string& separator,
577 size_t skip_after_nth_version) {
578 std::string result;
579 for (size_t i = 0; i < versions.size(); ++i) {
580 if (i != 0) {
581 result.append(separator);
582 }
583 if (i > skip_after_nth_version) {
584 result.append("...");
585 break;
586 }
587 result.append(ParsedQuicVersionToString(versions[i]));
588 }
589 return result;
590}
591
592bool VersionSupportsGoogleAltSvcFormat(QuicTransportVersion transport_version) {
593 return transport_version <= QUIC_VERSION_46;
594}
595
596bool VersionAllowsVariableLengthConnectionIds(
597 QuicTransportVersion transport_version) {
598 QUICHE_DCHECK_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
599 return transport_version > QUIC_VERSION_46;
600}
601
602bool QuicVersionLabelUses4BitConnectionIdLength(
603 QuicVersionLabel version_label) {
604 // As we deprecate old versions, we still need the ability to send valid
605 // version negotiation packets for those versions. This function keeps track
606 // of the versions that ever supported the 4bit connection ID length encoding
607 // that we know about. Google QUIC 43 and earlier used a different encoding,
608 // and Google QUIC 49 and later use the new length prefixed encoding.
609 // Similarly, only IETF drafts 11 to 21 used this encoding.
610
fayangfc04b8a2023-05-18 09:26:25 -0700611 // Check Q043, Q044, Q045, Q046, Q047 and Q048.
612 for (uint8_t c = '3'; c <= '8'; ++c) {
Bence Békybac04052022-04-07 15:44:29 -0400613 if (version_label == MakeVersionLabel('Q', '0', '4', c)) {
614 return true;
615 }
616 }
617 // Check T048.
618 if (version_label == MakeVersionLabel('T', '0', '4', '8')) {
619 return true;
620 }
621 // Check IETF draft versions in [11,21].
622 for (uint8_t draft_number = 11; draft_number <= 21; ++draft_number) {
623 if (version_label == MakeVersionLabel(0xff, 0x00, 0x00, draft_number)) {
624 return true;
625 }
626 }
627 return false;
628}
629
630ParsedQuicVersion UnsupportedQuicVersion() {
631 return ParsedQuicVersion::Unsupported();
632}
633
634ParsedQuicVersion QuicVersionReservedForNegotiation() {
635 return ParsedQuicVersion::ReservedForNegotiation();
636}
637
Bence Békybac04052022-04-07 15:44:29 -0400638std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
martinduke88918ac2023-06-02 10:44:08 -0700639 if (parsed_version == ParsedQuicVersion::RFCv2()) {
Bence Békybac04052022-04-07 15:44:29 -0400640 return "h3";
641 } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
642 return "h3";
643 } else if (parsed_version == ParsedQuicVersion::Draft29()) {
644 return "h3-29";
645 }
646 return "h3-" + ParsedQuicVersionToString(parsed_version);
647}
648
Bence Békybac04052022-04-07 15:44:29 -0400649void QuicEnableVersion(const ParsedQuicVersion& version) {
650 SetVersionFlag(version, /*should_enable=*/true);
651}
652
653void QuicDisableVersion(const ParsedQuicVersion& version) {
654 SetVersionFlag(version, /*should_enable=*/false);
655}
656
657bool QuicVersionIsEnabled(const ParsedQuicVersion& version) {
658 ParsedQuicVersionVector current = CurrentSupportedVersions();
659 return std::find(current.begin(), current.end(), version) != current.end();
660}
661
662#undef RETURN_STRING_LITERAL // undef for jumbo builds
663} // namespace quic