blob: c387f3add3e4c28727d763c07d8a62a258a4e407 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 "net/third_party/quiche/src/quic/core/quic_versions.h"
6
vasilvv872e7a32019-03-12 16:42:44 -07007#include <string>
8
dschinazi1ac22cc2019-06-25 11:47:50 -07009#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/quic_tag.h"
11#include "net/third_party/quiche/src/quic/core/quic_types.h"
dschinazi8ae60012019-04-04 18:07:27 -070012#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
QUICHE team173c48f2019-11-19 16:34:44 -080017#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080018#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019
20namespace quic {
21namespace {
22
23// Constructs a version label from the 4 bytes such that the on-the-wire
24// order will be: d, c, b, a.
25QuicVersionLabel MakeVersionLabel(char a, char b, char c, char d) {
26 return MakeQuicTag(d, c, b, a);
27}
28
dschinazi1ac22cc2019-06-25 11:47:50 -070029QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
dschinazi1ac22cc2019-06-25 11:47:50 -070030 QuicVersionLabel result;
31 if (!GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness)) {
32 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
QUICHE teama6ef0a62019-03-07 20:34:33 -050041} // namespace
42
zhongyi546cc452019-04-12 15:27:49 -070043bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
dschinazi8b1c45a2019-10-17 08:48:13 -070044 return transport_version > QUIC_VERSION_46 ||
zhongyi546cc452019-04-12 15:27:49 -070045 handshake_protocol == PROTOCOL_TLS1_3;
46}
47
nharperc8d9e402019-09-12 18:30:14 -070048bool ParsedQuicVersion::UsesInitialObfuscators() const {
nharperc32d8ab2019-10-09 11:09:06 -070049 return transport_version > QUIC_VERSION_49 ||
nharper965e5922019-09-23 22:33:54 -070050 handshake_protocol == PROTOCOL_TLS1_3;
nharperc8d9e402019-09-12 18:30:14 -070051}
52
dschinazic7036122019-04-30 12:46:34 -070053bool ParsedQuicVersion::AllowsLowFlowControlLimits() const {
54 return transport_version == QUIC_VERSION_99 &&
55 handshake_protocol == PROTOCOL_TLS1_3;
56}
57
nharpercfafed72019-05-01 13:43:55 -070058bool ParsedQuicVersion::HasHeaderProtection() const {
nharperc32d8ab2019-10-09 11:09:06 -070059 return transport_version > QUIC_VERSION_49;
nharpercfafed72019-05-01 13:43:55 -070060}
61
dschinazi244f6dc2019-05-06 15:45:16 -070062bool ParsedQuicVersion::SupportsRetry() const {
dschinazi2431fa22019-05-09 13:05:19 -070063 return transport_version > QUIC_VERSION_46;
dschinazi244f6dc2019-05-06 15:45:16 -070064}
65
fayang3ac15c12019-06-14 14:04:51 -070066bool ParsedQuicVersion::SendsVariableLengthPacketNumberInLongHeader() const {
67 return transport_version > QUIC_VERSION_46;
68}
69
dschinazib417d602019-05-29 13:08:45 -070070bool ParsedQuicVersion::SupportsClientConnectionIds() const {
dschinazic73506e2019-09-20 13:26:46 -070071 return transport_version > QUIC_VERSION_48;
dschinazib417d602019-05-29 13:08:45 -070072}
73
dschinazi48ac9192019-07-31 00:07:26 -070074bool ParsedQuicVersion::HasLengthPrefixedConnectionIds() const {
75 return VersionHasLengthPrefixedConnectionIds(transport_version);
76}
77
fayang5f135052019-08-22 17:59:40 -070078bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
fayangd6db04a2019-10-02 14:21:42 -070079 return transport_version == QUIC_VERSION_99 &&
80 handshake_protocol == PROTOCOL_TLS1_3;
fayang5f135052019-08-22 17:59:40 -070081}
82
fayang58f71072019-11-05 08:47:02 -080083bool ParsedQuicVersion::CanSendCoalescedPackets() const {
84 return QuicVersionHasLongHeaderLengths(transport_version) &&
85 handshake_protocol == PROTOCOL_TLS1_3;
86}
87
dschinazi48ac9192019-07-31 00:07:26 -070088bool VersionHasLengthPrefixedConnectionIds(
89 QuicTransportVersion transport_version) {
dschinazic73506e2019-09-20 13:26:46 -070090 return transport_version > QUIC_VERSION_48;
dschinazi48ac9192019-07-31 00:07:26 -070091}
92
QUICHE teama6ef0a62019-03-07 20:34:33 -050093std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
94 os << ParsedQuicVersionToString(version);
95 return os;
96}
97
98QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
99 char proto = 0;
100 switch (parsed_version.handshake_protocol) {
101 case PROTOCOL_QUIC_CRYPTO:
102 proto = 'Q';
103 break;
104 case PROTOCOL_TLS1_3:
105 proto = 'T';
106 break;
107 default:
nharper4fd11052019-06-04 14:23:22 -0700108 QUIC_BUG << "Invalid HandshakeProtocol: "
109 << parsed_version.handshake_protocol;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110 return 0;
111 }
dschinazi8b1c45a2019-10-17 08:48:13 -0700112 static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
dschinazic73506e2019-09-20 13:26:46 -0700113 "Supported versions out of sync");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500114 switch (parsed_version.transport_version) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115 case QUIC_VERSION_43:
116 return MakeVersionLabel(proto, '0', '4', '3');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117 case QUIC_VERSION_46:
118 return MakeVersionLabel(proto, '0', '4', '6');
nharper107ba5f2019-07-02 21:33:39 -0700119 case QUIC_VERSION_48:
120 return MakeVersionLabel(proto, '0', '4', '8');
dschinazic73506e2019-09-20 13:26:46 -0700121 case QUIC_VERSION_49:
122 return MakeVersionLabel(proto, '0', '4', '9');
nharperc32d8ab2019-10-09 11:09:06 -0700123 case QUIC_VERSION_50:
124 return MakeVersionLabel(proto, '0', '5', '0');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 case QUIC_VERSION_99:
rcha702be22019-08-30 15:20:12 -0700126 if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
127 return MakeVersionLabel(0xff, 0x00, 0x00, kQuicIetfDraftVersion);
dschinazi8ae60012019-04-04 18:07:27 -0700128 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129 return MakeVersionLabel(proto, '0', '9', '9');
dschinazi5a354c92019-05-09 12:18:53 -0700130 case QUIC_VERSION_RESERVED_FOR_NEGOTIATION:
dschinazi1ac22cc2019-06-25 11:47:50 -0700131 return CreateRandomVersionLabelForNegotiation();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132 default:
nharper4fd11052019-06-04 14:23:22 -0700133 // This is a bug because we should never attempt to convert an invalid
134 // QuicTransportVersion to be written to the wire.
135 QUIC_BUG << "Unsupported QuicTransportVersion: "
136 << parsed_version.transport_version;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137 return 0;
138 }
139}
140
141QuicVersionLabelVector CreateQuicVersionLabelVector(
142 const ParsedQuicVersionVector& versions) {
143 QuicVersionLabelVector out;
144 out.reserve(versions.size());
145 for (const auto& version : versions) {
146 out.push_back(CreateQuicVersionLabel(version));
147 }
148 return out;
149}
150
151ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) {
nharperf5e68452019-05-29 17:24:18 -0700152 std::vector<HandshakeProtocol> protocols = {PROTOCOL_QUIC_CRYPTO,
153 PROTOCOL_TLS1_3};
QUICHE teama6ef0a62019-03-07 20:34:33 -0500154 for (QuicTransportVersion version : kSupportedTransportVersions) {
155 for (HandshakeProtocol handshake : protocols) {
156 if (version_label ==
157 CreateQuicVersionLabel(ParsedQuicVersion(handshake, version))) {
158 return ParsedQuicVersion(handshake, version);
159 }
160 }
161 }
162 // Reading from the client so this should not be considered an ERROR.
163 QUIC_DLOG(INFO) << "Unsupported QuicVersionLabel version: "
164 << QuicVersionLabelToString(version_label);
165 return UnsupportedQuicVersion();
166}
167
dschinazi8ae60012019-04-04 18:07:27 -0700168ParsedQuicVersion ParseQuicVersionString(std::string version_string) {
dschinazi35e749e2019-04-09 09:36:04 -0700169 if (version_string.empty()) {
dschinazi8ae60012019-04-04 18:07:27 -0700170 return UnsupportedQuicVersion();
171 }
172 int quic_version_number = 0;
dmcardlecf0bfcf2019-12-13 08:08:21 -0800173 if (quiche::QuicheTextUtils::StringToInt(version_string,
174 &quic_version_number) &&
dschinazi8ae60012019-04-04 18:07:27 -0700175 quic_version_number > 0) {
176 return ParsedQuicVersion(
177 PROTOCOL_QUIC_CRYPTO,
178 static_cast<QuicTransportVersion>(quic_version_number));
179 }
dschinazi8ae60012019-04-04 18:07:27 -0700180 for (QuicTransportVersion version : kSupportedTransportVersions) {
dschinazi76881f02019-12-09 14:56:14 -0800181 for (HandshakeProtocol handshake : kSupportedHandshakeProtocols) {
dschinazi8ae60012019-04-04 18:07:27 -0700182 const ParsedQuicVersion parsed_version =
183 ParsedQuicVersion(handshake, version);
184 if (version_string == ParsedQuicVersionToString(parsed_version)) {
185 return parsed_version;
186 }
187 }
188 }
dschinazi52627472019-04-09 16:20:20 -0700189 // Still recognize T099 even if flag quic_ietf_draft_version has been changed.
dschinazi76881f02019-12-09 14:56:14 -0800190 if (GetQuicReloadableFlag(quic_enable_version_t099) &&
wubeddb74b2019-05-01 10:26:55 -0700191 version_string == "T099") {
dschinazi8ae60012019-04-04 18:07:27 -0700192 return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99);
193 }
194 // Reading from the client so this should not be considered an ERROR.
195 QUIC_DLOG(INFO) << "Unsupported QUIC version string: \"" << version_string
196 << "\".";
197 return UnsupportedQuicVersion();
198}
199
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200QuicTransportVersionVector AllSupportedTransportVersions() {
201 QuicTransportVersionVector supported_versions;
202 for (QuicTransportVersion version : kSupportedTransportVersions) {
203 supported_versions.push_back(version);
204 }
205 return supported_versions;
206}
207
208ParsedQuicVersionVector AllSupportedVersions() {
209 ParsedQuicVersionVector supported_versions;
210 for (HandshakeProtocol protocol : kSupportedHandshakeProtocols) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500211 for (QuicTransportVersion version : kSupportedTransportVersions) {
QUICHE teamea740082019-03-11 17:58:43 -0700212 if (protocol == PROTOCOL_TLS1_3 &&
dschinazi0ce303d2019-12-05 14:53:15 -0800213 (!QuicVersionUsesCryptoFrames(version) ||
214 version <= QUIC_VERSION_49)) {
nharper107ba5f2019-07-02 21:33:39 -0700215 // The TLS handshake is only deployable if CRYPTO frames are also used.
dschinazi0ce303d2019-12-05 14:53:15 -0800216 // We explicitly removed support for T048 and T049 to reduce test load.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500217 continue;
218 }
219 supported_versions.push_back(ParsedQuicVersion(protocol, version));
220 }
221 }
222 return supported_versions;
223}
224
QUICHE teama6ef0a62019-03-07 20:34:33 -0500225ParsedQuicVersionVector CurrentSupportedVersions() {
226 return FilterSupportedVersions(AllSupportedVersions());
227}
228
QUICHE teama6ef0a62019-03-07 20:34:33 -0500229ParsedQuicVersionVector FilterSupportedVersions(
230 ParsedQuicVersionVector versions) {
231 ParsedQuicVersionVector filtered_versions;
232 filtered_versions.reserve(versions.size());
233 for (ParsedQuicVersion version : versions) {
234 if (version.transport_version == QUIC_VERSION_99) {
dschinazi76881f02019-12-09 14:56:14 -0800235 if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
236 if (GetQuicReloadableFlag(quic_enable_version_q099)) {
237 filtered_versions.push_back(version);
238 }
239 } else {
240 if (GetQuicReloadableFlag(quic_enable_version_t099)) {
241 filtered_versions.push_back(version);
242 }
243 }
244 } else if (version.transport_version == QUIC_VERSION_50) {
245 if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
246 if (!GetQuicReloadableFlag(quic_disable_version_q050)) {
247 filtered_versions.push_back(version);
248 }
249 } else {
250 if (GetQuicReloadableFlag(quic_enable_version_t050)) {
251 filtered_versions.push_back(version);
252 }
253 }
254 } else if (version.transport_version == QUIC_VERSION_49) {
255 if (!GetQuicReloadableFlag(quic_disable_version_q049)) {
256 filtered_versions.push_back(version);
257 }
258 } else if (version.transport_version == QUIC_VERSION_48) {
259 if (!GetQuicReloadableFlag(quic_disable_version_q048)) {
260 filtered_versions.push_back(version);
261 }
262 } else if (version.transport_version == QUIC_VERSION_46) {
263 if (!GetQuicReloadableFlag(quic_disable_version_q046)) {
264 filtered_versions.push_back(version);
265 }
266 } else if (version.transport_version == QUIC_VERSION_43) {
267 if (!GetQuicReloadableFlag(quic_disable_version_q043)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500268 filtered_versions.push_back(version);
269 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500270 } else {
271 filtered_versions.push_back(version);
272 }
273 }
274 return filtered_versions;
275}
276
277QuicTransportVersionVector VersionOfIndex(
278 const QuicTransportVersionVector& versions,
279 int index) {
280 QuicTransportVersionVector version;
281 int version_count = versions.size();
282 if (index >= 0 && index < version_count) {
283 version.push_back(versions[index]);
284 } else {
285 version.push_back(QUIC_VERSION_UNSUPPORTED);
286 }
287 return version;
288}
289
290ParsedQuicVersionVector ParsedVersionOfIndex(
291 const ParsedQuicVersionVector& versions,
292 int index) {
293 ParsedQuicVersionVector version;
294 int version_count = versions.size();
295 if (index >= 0 && index < version_count) {
296 version.push_back(versions[index]);
297 } else {
298 version.push_back(UnsupportedQuicVersion());
299 }
300 return version;
301}
302
303QuicTransportVersionVector ParsedVersionsToTransportVersions(
304 const ParsedQuicVersionVector& versions) {
305 QuicTransportVersionVector transport_versions;
306 transport_versions.resize(versions.size());
307 for (size_t i = 0; i < versions.size(); ++i) {
308 transport_versions[i] = versions[i].transport_version;
309 }
310 return transport_versions;
311}
312
313QuicVersionLabel QuicVersionToQuicVersionLabel(
314 QuicTransportVersion transport_version) {
315 return CreateQuicVersionLabel(
316 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version));
317}
318
vasilvvc48c8712019-03-11 13:38:16 -0700319std::string QuicVersionLabelToString(QuicVersionLabel version_label) {
QUICHE team173c48f2019-11-19 16:34:44 -0800320 return QuicTagToString(quiche::QuicheEndian::HostToNet32(version_label));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500321}
322
vasilvvc48c8712019-03-11 13:38:16 -0700323std::string QuicVersionLabelVectorToString(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500324 const QuicVersionLabelVector& version_labels,
vasilvvc48c8712019-03-11 13:38:16 -0700325 const std::string& separator,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500326 size_t skip_after_nth_version) {
vasilvvc48c8712019-03-11 13:38:16 -0700327 std::string result;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500328 for (size_t i = 0; i < version_labels.size(); ++i) {
329 if (i != 0) {
330 result.append(separator);
331 }
332
333 if (i > skip_after_nth_version) {
334 result.append("...");
335 break;
336 }
337 result.append(QuicVersionLabelToString(version_labels[i]));
338 }
339 return result;
340}
341
342QuicTransportVersion QuicVersionLabelToQuicVersion(
343 QuicVersionLabel version_label) {
344 return ParseQuicVersionLabel(version_label).transport_version;
345}
346
347HandshakeProtocol QuicVersionLabelToHandshakeProtocol(
348 QuicVersionLabel version_label) {
349 return ParseQuicVersionLabel(version_label).handshake_protocol;
350}
351
352#define RETURN_STRING_LITERAL(x) \
353 case x: \
354 return #x
355
vasilvvc48c8712019-03-11 13:38:16 -0700356std::string QuicVersionToString(QuicTransportVersion transport_version) {
dschinazi8b1c45a2019-10-17 08:48:13 -0700357 static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
dschinazic73506e2019-09-20 13:26:46 -0700358 "Supported versions out of sync");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500359 switch (transport_version) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500360 RETURN_STRING_LITERAL(QUIC_VERSION_43);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500361 RETURN_STRING_LITERAL(QUIC_VERSION_46);
nharper107ba5f2019-07-02 21:33:39 -0700362 RETURN_STRING_LITERAL(QUIC_VERSION_48);
dschinazic73506e2019-09-20 13:26:46 -0700363 RETURN_STRING_LITERAL(QUIC_VERSION_49);
nharperc32d8ab2019-10-09 11:09:06 -0700364 RETURN_STRING_LITERAL(QUIC_VERSION_50);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500365 RETURN_STRING_LITERAL(QUIC_VERSION_99);
366 default:
367 return "QUIC_VERSION_UNSUPPORTED";
368 }
369}
370
vasilvvc48c8712019-03-11 13:38:16 -0700371std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
nharper4fd11052019-06-04 14:23:22 -0700372 if (version == UnsupportedQuicVersion()) {
373 return "0";
374 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500375 return QuicVersionLabelToString(CreateQuicVersionLabel(version));
376}
377
vasilvvc48c8712019-03-11 13:38:16 -0700378std::string QuicTransportVersionVectorToString(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500379 const QuicTransportVersionVector& versions) {
vasilvvc48c8712019-03-11 13:38:16 -0700380 std::string result = "";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500381 for (size_t i = 0; i < versions.size(); ++i) {
382 if (i != 0) {
383 result.append(",");
384 }
385 result.append(QuicVersionToString(versions[i]));
386 }
387 return result;
388}
389
vasilvvc48c8712019-03-11 13:38:16 -0700390std::string ParsedQuicVersionVectorToString(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500391 const ParsedQuicVersionVector& versions,
vasilvvc48c8712019-03-11 13:38:16 -0700392 const std::string& separator,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500393 size_t skip_after_nth_version) {
vasilvvc48c8712019-03-11 13:38:16 -0700394 std::string result;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500395 for (size_t i = 0; i < versions.size(); ++i) {
396 if (i != 0) {
397 result.append(separator);
398 }
399 if (i > skip_after_nth_version) {
400 result.append("...");
401 break;
402 }
403 result.append(ParsedQuicVersionToString(versions[i]));
404 }
405 return result;
406}
407
rcheb78dbb2019-10-26 08:37:15 -0700408bool VersionSupportsGoogleAltSvcFormat(QuicTransportVersion transport_version) {
409 return transport_version <= QUIC_VERSION_46;
410}
411
dschinazi48ac9192019-07-31 00:07:26 -0700412bool QuicVersionLabelUses4BitConnectionIdLength(
413 QuicVersionLabel version_label) {
414 // As we deprecate old versions, we still need the ability to send valid
415 // version negotiation packets for those versions. This function keeps track
416 // of the versions that ever supported the 4bit connection ID length encoding
417 // that we know about. Google QUIC 43 and earlier used a different encoding,
dschinazic73506e2019-09-20 13:26:46 -0700418 // and Google QUIC 49 and later use the new length prefixed encoding.
dschinazi48ac9192019-07-31 00:07:26 -0700419 // Similarly, only IETF drafts 11 to 21 used this encoding.
420
421 // Check Q044, Q045, Q046, Q047 and Q048.
422 for (uint8_t c = '4'; c <= '8'; ++c) {
423 if (version_label == MakeVersionLabel('Q', '0', '4', c)) {
424 return true;
425 }
426 }
427 // Check T048.
428 if (version_label == MakeVersionLabel('T', '0', '4', '8')) {
429 return true;
430 }
431 // Check IETF draft versions in [11,21].
432 for (uint8_t draft_number = 11; draft_number <= 21; ++draft_number) {
433 if (version_label == MakeVersionLabel(0xff, 0x00, 0x00, draft_number)) {
434 return true;
435 }
436 }
437 return false;
438}
439
QUICHE teama6ef0a62019-03-07 20:34:33 -0500440ParsedQuicVersion UnsupportedQuicVersion() {
441 return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
442}
443
dschinazi5a354c92019-05-09 12:18:53 -0700444ParsedQuicVersion QuicVersionReservedForNegotiation() {
445 return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
446 QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
447}
448
dschinazi35e749e2019-04-09 09:36:04 -0700449std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
450 if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3 &&
rcha702be22019-08-30 15:20:12 -0700451 parsed_version.transport_version == QUIC_VERSION_99) {
dmcardlecf0bfcf2019-12-13 08:08:21 -0800452 return "h3-" +
453 quiche::QuicheTextUtils::Uint64ToString(kQuicIetfDraftVersion);
dschinazi35e749e2019-04-09 09:36:04 -0700454 }
rch5a2b3eb2019-08-23 11:49:33 -0700455 return "h3-" + ParsedQuicVersionToString(parsed_version);
dschinazi35e749e2019-04-09 09:36:04 -0700456}
457
rcha702be22019-08-30 15:20:12 -0700458void QuicVersionInitializeSupportForIetfDraft() {
dschinazi8ae60012019-04-04 18:07:27 -0700459 // Enable necessary flags.
dschinazi8ae60012019-04-04 18:07:27 -0700460}
461
462void QuicEnableVersion(ParsedQuicVersion parsed_version) {
dschinazi8b1c45a2019-10-17 08:48:13 -0700463 static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
dschinazi8ae60012019-04-04 18:07:27 -0700464 "Supported versions out of sync");
dschinazi6d2aea02019-06-26 02:59:06 -0700465 if (parsed_version.transport_version == QUIC_VERSION_99) {
dschinazi76881f02019-12-09 14:56:14 -0800466 if (parsed_version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
467 SetQuicReloadableFlag(quic_enable_version_q099, true);
468 } else {
469 SetQuicReloadableFlag(quic_enable_version_t099, true);
470 }
471 } else if (parsed_version.transport_version == QUIC_VERSION_50) {
472 if (parsed_version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
473 SetQuicReloadableFlag(quic_disable_version_q050, false);
474 } else {
475 SetQuicReloadableFlag(quic_enable_version_t050, true);
476 }
477 } else if (parsed_version.transport_version == QUIC_VERSION_49) {
478 SetQuicReloadableFlag(quic_disable_version_q049, false);
479 } else if (parsed_version.transport_version == QUIC_VERSION_48) {
480 SetQuicReloadableFlag(quic_disable_version_q048, false);
481 } else if (parsed_version.transport_version == QUIC_VERSION_46) {
482 SetQuicReloadableFlag(quic_disable_version_q046, false);
483 } else if (parsed_version.transport_version == QUIC_VERSION_43) {
484 SetQuicReloadableFlag(quic_disable_version_q043, false);
dschinazi8ae60012019-04-04 18:07:27 -0700485 }
dschinazi8ae60012019-04-04 18:07:27 -0700486}
487
QUICHE teama6ef0a62019-03-07 20:34:33 -0500488#undef RETURN_STRING_LITERAL // undef for jumbo builds
489} // namespace quic