1 // 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 // Definitions and utility functions related to handling of QUIC versions.
6 //
7 // QUIC versions are encoded over the wire as an opaque 32bit field. The wire
8 // encoding is represented in memory as a QuicVersionLabel type (which is an
9 // alias to uint32_t). Conceptual versions are represented in memory as
10 // ParsedQuicVersion.
11 //
12 // We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
13 //
14 // All GoogleQUIC versions use a wire encoding that matches the following regex
15 // when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the
16 // type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS
17 // handshake), and the two digits at the end contain the numeric value of
18 // the transport version used.
19 //
20 // All IETF QUIC versions use the wire encoding described in:
21 // https://tools.ietf.org/html/draft-ietf-quic-transport
22
23 #ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
24 #define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
25
26 #include <cstdint>
27 #include <string>
28 #include <vector>
29
30 #include "absl/base/macros.h"
31 #include "absl/strings/string_view.h"
32 #include "quiche/quic/core/quic_tag.h"
33 #include "quiche/quic/core/quic_types.h"
34 #include "quiche/quic/platform/api/quic_export.h"
35
36 namespace quic {
37
38 // The list of existing QUIC transport versions. Note that QUIC versions are
39 // sent over the wire as an encoding of ParsedQuicVersion, which requires a
40 // QUIC transport version and handshake protocol. For transport versions of the
41 // form QUIC_VERSION_XX where XX is decimal, the enum numeric value is
42 // guaranteed to match the name. Older deprecated transport versions are
43 // documented in comments below.
44 enum QuicTransportVersion {
45 // Special case to indicate unknown/unsupported QUIC version.
46 QUIC_VERSION_UNSUPPORTED = 0,
47
48 // Version 1 was the first version of QUIC that supported versioning.
49 // Version 2 decoupled versioning of non-cryptographic parameters from the
50 // SCFG.
51 // Version 3 moved public flags into the beginning of the packet.
52 // Version 4 added support for variable-length connection IDs.
53 // Version 5 made specifying FEC groups optional.
54 // Version 6 introduced variable-length packet numbers.
55 // Version 7 introduced a lower-overhead encoding for stream frames.
56 // Version 8 made salt length equal to digest length for the RSA-PSS
57 // signatures.
58 // Version 9 added stream priority.
59 // Version 10 redid the frame type numbering.
60 // Version 11 reduced the length of null encryption authentication tag
61 // from 16 to 12 bytes.
62 // Version 12 made the sequence numbers in the ACK frames variable-sized.
63 // Version 13 added the dedicated header stream.
64 // Version 14 added byte_offset to RST_STREAM frame.
65 // Version 15 added a list of packets recovered using FEC to the ACK frame.
66 // Version 16 added STOP_WAITING frame.
67 // Version 17 added per-stream flow control.
68 // Version 18 added PING frame.
69 // Version 19 added connection-level flow control
70 // Version 20 allowed to set stream- and connection-level flow control windows
71 // to different values.
72 // Version 21 made header and crypto streams flow-controlled.
73 // Version 22 added support for SCUP (server config update) messages.
74 // Version 23 added timestamps into the ACK frame.
75 // Version 24 added SPDY/4 header compression.
76 // Version 25 added support for SPDY/4 header keys and removed error_details
77 // from RST_STREAM frame.
78 // Version 26 added XLCT (expected leaf certificate) tag into CHLO.
79 // Version 27 added a nonce into SHLO.
80 // Version 28 allowed receiver to refuse creating a requested stream.
81 // Version 29 added support for QUIC_STREAM_NO_ERROR.
82 // Version 30 added server-side support for certificate transparency.
83 // Version 31 incorporated the hash of CHLO into the crypto proof supplied by
84 // the server.
85 // Version 32 removed FEC-related fields from wire format.
86 // Version 33 added diversification nonces.
87 // Version 34 removed entropy bits from packets and ACK frames, removed
88 // private flag from packet header and changed the ACK format to
89 // specify ranges of packets acknowledged rather than missing
90 // ranges.
91 // Version 35 allows endpoints to independently set stream limit.
92 // Version 36 added support for forced head-of-line blocking experiments.
93 // Version 37 added perspective into null encryption.
94 // Version 38 switched to IETF padding frame format and support for NSTP (no
95 // stop waiting frame) connection option.
96
97 // Version 39 writes integers and floating numbers in big endian, stops acking
98 // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do
99 // not contain retransmittable frames.
100
101 // Version 40 was an attempt to convert QUIC to IETF frame format; it was
102 // never shipped due to a bug.
103 // Version 41 was a bugfix for version 40. The working group changed the wire
104 // format before it shipped, which caused it to be never shipped
105 // and all the changes from it to be reverted. No changes from v40
106 // or v41 are present in subsequent versions.
107 // Version 42 allowed receiving overlapping stream data.
108
109 // Version 43 PRIORITY frames are sent by client and accepted by server.
110 // Version 44 used IETF header format from draft-ietf-quic-invariants-05.
111
112 // Version 45 added MESSAGE frame.
113
114 QUIC_VERSION_46 = 46, // Use IETF draft-17 header format with demultiplexing
115 // bit.
116 // Version 47 added variable-length QUIC server connection IDs.
117 // Version 48 added CRYPTO frames for the handshake.
118 // Version 49 added client connection IDs, long header lengths, and the IETF
119 // header format from draft-ietf-quic-invariants-06
120 QUIC_VERSION_50 = 50, // Header protection and initial obfuscators.
121 // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames.
122 // Number 70 used to represent draft-ietf-quic-transport-25.
123 // Number 71 used to represent draft-ietf-quic-transport-27.
124 // Number 72 used to represent draft-ietf-quic-transport-28.
125 QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29.
126 QUIC_VERSION_IETF_RFC_V1 = 80, // RFC 9000.
127 // Number 81 used to represent draft-ietf-quic-v2-01.
128 QUIC_VERSION_IETF_RFC_V2 = 82, // RFC 9369.
129 // Version 99 was a dumping ground for IETF QUIC changes which were not yet
130 // ready for production between 2018-02 and 2020-02.
131
132 // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
133 // which is part of a range reserved by the IETF for version negotiation
134 // testing (see the "Versions" section of draft-ietf-quic-transport).
135 // This version is intentionally meant to never be supported to trigger
136 // version negotiation when proposed by clients and to prevent client
137 // ossification when sent by servers.
138 QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
139 };
140
141 // Helper function which translates from a QuicTransportVersion to a string.
142 // Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
143 QUICHE_EXPORT std::string QuicVersionToString(
144 QuicTransportVersion transport_version);
145
146 // The crypto handshake protocols that can be used with QUIC.
147 // We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of
148 // PROTOCOL_TLS1_3.
149 enum HandshakeProtocol {
150 PROTOCOL_UNSUPPORTED,
151 PROTOCOL_QUIC_CRYPTO,
152 PROTOCOL_TLS1_3,
153 };
154
155 // Helper function which translates from a HandshakeProtocol to a string.
156 QUICHE_EXPORT std::string HandshakeProtocolToString(
157 HandshakeProtocol handshake_protocol);
158
159 // Returns whether |transport_version| uses CRYPTO frames for the handshake
160 // instead of stream 1.
QuicVersionUsesCryptoFrames(QuicTransportVersion transport_version)161 QUICHE_EXPORT constexpr bool QuicVersionUsesCryptoFrames(
162 QuicTransportVersion transport_version) {
163 // CRYPTO frames were added in version 48.
164 return transport_version > QUIC_VERSION_46;
165 }
166
167 // Returns whether this combination of handshake protocol and transport
168 // version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_46} is NOT
169 // allowed as TLS requires crypto frames which v46 does not support. Note that
170 // UnsupportedQuicVersion is a valid version.
ParsedQuicVersionIsValid(HandshakeProtocol handshake_protocol,QuicTransportVersion transport_version)171 QUICHE_EXPORT constexpr bool ParsedQuicVersionIsValid(
172 HandshakeProtocol handshake_protocol,
173 QuicTransportVersion transport_version) {
174 bool transport_version_is_valid = false;
175 constexpr QuicTransportVersion valid_transport_versions[] = {
176 QUIC_VERSION_IETF_RFC_V2,
177 QUIC_VERSION_IETF_RFC_V1,
178 QUIC_VERSION_IETF_DRAFT_29,
179 QUIC_VERSION_50,
180 QUIC_VERSION_46,
181 QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
182 QUIC_VERSION_UNSUPPORTED,
183 };
184 for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) {
185 if (transport_version == valid_transport_versions[i]) {
186 transport_version_is_valid = true;
187 break;
188 }
189 }
190 if (!transport_version_is_valid) {
191 return false;
192 }
193 switch (handshake_protocol) {
194 case PROTOCOL_UNSUPPORTED:
195 return transport_version == QUIC_VERSION_UNSUPPORTED;
196 case PROTOCOL_QUIC_CRYPTO:
197 return transport_version != QUIC_VERSION_UNSUPPORTED &&
198 transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
199 transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
200 transport_version != QUIC_VERSION_IETF_RFC_V1 &&
201 transport_version != QUIC_VERSION_IETF_RFC_V2;
202 case PROTOCOL_TLS1_3:
203 return transport_version != QUIC_VERSION_UNSUPPORTED &&
204 transport_version != QUIC_VERSION_50 &&
205 QuicVersionUsesCryptoFrames(transport_version);
206 }
207 return false;
208 }
209
210 // A parsed QUIC version label which determines that handshake protocol
211 // and the transport version.
212 struct QUICHE_EXPORT ParsedQuicVersion {
213 HandshakeProtocol handshake_protocol;
214 QuicTransportVersion transport_version;
215
ParsedQuicVersionParsedQuicVersion216 constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol,
217 QuicTransportVersion transport_version)
218 : handshake_protocol(handshake_protocol),
219 transport_version(transport_version) {
220 QUICHE_DCHECK(
221 ParsedQuicVersionIsValid(handshake_protocol, transport_version))
222 << QuicVersionToString(transport_version) << " "
223 << HandshakeProtocolToString(handshake_protocol);
224 }
225
ParsedQuicVersionParsedQuicVersion226 constexpr ParsedQuicVersion(const ParsedQuicVersion& other)
227 : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {}
228
229 ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
230 QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol,
231 other.transport_version))
232 << QuicVersionToString(other.transport_version) << " "
233 << HandshakeProtocolToString(other.handshake_protocol);
234 if (this != &other) {
235 handshake_protocol = other.handshake_protocol;
236 transport_version = other.transport_version;
237 }
238 return *this;
239 }
240
241 bool operator==(const ParsedQuicVersion& other) const {
242 return handshake_protocol == other.handshake_protocol &&
243 transport_version == other.transport_version;
244 }
245
246 bool operator!=(const ParsedQuicVersion& other) const {
247 return handshake_protocol != other.handshake_protocol ||
248 transport_version != other.transport_version;
249 }
250
RFCv2ParsedQuicVersion251 static constexpr ParsedQuicVersion RFCv2() {
252 return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V2);
253 }
254
RFCv1ParsedQuicVersion255 static constexpr ParsedQuicVersion RFCv1() {
256 return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
257 }
258
Draft29ParsedQuicVersion259 static constexpr ParsedQuicVersion Draft29() {
260 return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
261 }
262
Q050ParsedQuicVersion263 static constexpr ParsedQuicVersion Q050() {
264 return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
265 }
266
Q046ParsedQuicVersion267 static constexpr ParsedQuicVersion Q046() {
268 return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
269 }
270
UnsupportedParsedQuicVersion271 static constexpr ParsedQuicVersion Unsupported() {
272 return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
273 }
274
ReservedForNegotiationParsedQuicVersion275 static constexpr ParsedQuicVersion ReservedForNegotiation() {
276 return ParsedQuicVersion(PROTOCOL_TLS1_3,
277 QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
278 }
279
280 // Returns whether our codebase understands this version. This should only be
281 // called on valid versions, see ParsedQuicVersionIsValid. Assuming the
282 // version is valid, IsKnown returns whether the version is not
283 // UnsupportedQuicVersion.
284 bool IsKnown() const;
285
286 bool KnowsWhichDecrypterToUse() const;
287
288 // Returns whether this version uses keys derived from the Connection ID for
289 // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter).
290 bool UsesInitialObfuscators() const;
291
292 // Indicates that this QUIC version does not have an enforced minimum value
293 // for flow control values negotiated during the handshake.
294 bool AllowsLowFlowControlLimits() const;
295
296 // Returns whether header protection is used in this version of QUIC.
297 bool HasHeaderProtection() const;
298
299 // Returns whether this version supports IETF RETRY packets.
300 bool SupportsRetry() const;
301
302 // Returns true if this version sends variable length packet number in long
303 // header.
304 bool SendsVariableLengthPacketNumberInLongHeader() const;
305
306 // Returns whether this version allows server connection ID lengths
307 // that are not 64 bits.
308 bool AllowsVariableLengthConnectionIds() const;
309
310 // Returns whether this version supports client connection ID.
311 bool SupportsClientConnectionIds() const;
312
313 // Returns whether this version supports long header 8-bit encoded
314 // connection ID lengths as described in draft-ietf-quic-invariants-06 and
315 // draft-ietf-quic-transport-22.
316 bool HasLengthPrefixedConnectionIds() const;
317
318 // Returns whether this version supports IETF style anti-amplification limit,
319 // i.e., server will send no more than FLAGS_quic_anti_amplification_factor
320 // times received bytes until address can be validated.
321 bool SupportsAntiAmplificationLimit() const;
322
323 // Returns true if this version can send coalesced packets.
324 bool CanSendCoalescedPackets() const;
325
326 // Returns true if this version supports the old Google-style Alt-Svc
327 // advertisement format.
328 bool SupportsGoogleAltSvcFormat() const;
329
330 // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
331 // Notable changes are:
332 // * Headers stream no longer exists.
333 // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
334 // * PUSH_PROMISE is moved to request stream.
335 // * Unidirectional streams will have their first byte as a stream type.
336 // * HEADERS frames are compressed using QPACK.
337 // * DATA frame has frame headers.
338 // * GOAWAY is moved to HTTP layer.
339 bool UsesHttp3() const;
340
341 // Returns whether the transport_version supports the variable length integer
342 // length field as defined by IETF QUIC draft-13 and later.
343 bool HasLongHeaderLengths() const;
344
345 // Returns whether |transport_version| uses CRYPTO frames for the handshake
346 // instead of stream 1.
347 bool UsesCryptoFrames() const;
348
349 // Returns whether |transport_version| makes use of IETF QUIC
350 // frames or not.
351 bool HasIetfQuicFrames() const;
352
353 // Returns whether this version uses the legacy TLS extension codepoint.
354 bool UsesLegacyTlsExtension() const;
355
356 // Returns whether this version uses PROTOCOL_TLS1_3.
357 bool UsesTls() const;
358
359 // Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
360 bool UsesQuicCrypto() const;
361
362 // Returns whether this version uses the QUICv2 Long Header Packet Types.
363 bool UsesV2PacketTypes() const;
364
365 // Returns true if this shares ALPN codes with RFCv1, and endpoints should
366 // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
367 // RFCv1.
368 bool AlpnDeferToRFCv1() const;
369 };
370
371 QUICHE_EXPORT ParsedQuicVersion UnsupportedQuicVersion();
372
373 QUICHE_EXPORT ParsedQuicVersion QuicVersionReservedForNegotiation();
374
375 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
376 const ParsedQuicVersion& version);
377
378 using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
379
380 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
381 const ParsedQuicVersionVector& versions);
382
383 // Representation of the on-the-wire QUIC version number. Will be written/read
384 // to the wire in network-byte-order.
385 using QuicVersionLabel = uint32_t;
386 using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
387
388 // Constructs a version label from the 4 bytes such that the on-the-wire
389 // order will be: d, c, b, a.
390 QUICHE_EXPORT QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c,
391 uint8_t d);
392
393 QUICHE_EXPORT std::ostream& operator<<(
394 std::ostream& os, const QuicVersionLabelVector& version_labels);
395
396 // This vector contains all crypto handshake protocols that are supported.
SupportedHandshakeProtocols()397 constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
398 return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
399 }
400
SupportedVersions()401 constexpr std::array<ParsedQuicVersion, 5> SupportedVersions() {
402 return {
403 ParsedQuicVersion::RFCv2(), ParsedQuicVersion::RFCv1(),
404 ParsedQuicVersion::Draft29(), ParsedQuicVersion::Q050(),
405 ParsedQuicVersion::Q046(),
406 };
407 }
408
409 using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
410
411 QUICHE_EXPORT std::ostream& operator<<(
412 std::ostream& os, const QuicTransportVersionVector& transport_versions);
413
414 // Returns a vector of supported QUIC versions.
415 QUICHE_EXPORT ParsedQuicVersionVector AllSupportedVersions();
416
417 // Returns a vector of supported QUIC versions, with any versions disabled by
418 // flags excluded.
419 QUICHE_EXPORT ParsedQuicVersionVector CurrentSupportedVersions();
420
421 // Obsolete QUIC supported versions are versions that are supported in
422 // QUICHE but which should not be used by by modern clients.
423 QUICHE_EXPORT ParsedQuicVersionVector ObsoleteSupportedVersions();
424
425 // Returns true if `version` is in `ObsoleteSupportedVersions`.
426 QUICHE_EXPORT bool IsObsoleteSupportedVersion(ParsedQuicVersion version);
427
428 // Returns a vector of supported QUIC versions which should be used by clients.
429 // Server need to support old clients, but new client should only be using
430 // QUIC versions in this list.
431 QUICHE_EXPORT ParsedQuicVersionVector CurrentSupportedVersionsForClients();
432
433 // Returns a vector of QUIC versions from |versions| which exclude any versions
434 // which are disabled by flags.
435 QUICHE_EXPORT ParsedQuicVersionVector
436 FilterSupportedVersions(ParsedQuicVersionVector versions);
437
438 // Returns a subset of AllSupportedVersions() with
439 // handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
440 // Deprecated; only to be used in components that do not yet support
441 // PROTOCOL_TLS1_3.
442 QUICHE_EXPORT ParsedQuicVersionVector AllSupportedVersionsWithQuicCrypto();
443
444 // Returns a subset of CurrentSupportedVersions() with
445 // handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
446 QUICHE_EXPORT ParsedQuicVersionVector CurrentSupportedVersionsWithQuicCrypto();
447
448 // Returns a subset of AllSupportedVersions() with
449 // handshake_protocol == PROTOCOL_TLS1_3, in the same order.
450 QUICHE_EXPORT ParsedQuicVersionVector AllSupportedVersionsWithTls();
451
452 // Returns a subset of CurrentSupportedVersions() with handshake_protocol ==
453 // PROTOCOL_TLS1_3.
454 QUICHE_EXPORT ParsedQuicVersionVector CurrentSupportedVersionsWithTls();
455
456 // Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP
457 // layer.
458 QUICHE_EXPORT ParsedQuicVersionVector CurrentSupportedHttp3Versions();
459
460 // Returns QUIC version of |index| in result of |versions|. Returns
461 // UnsupportedQuicVersion() if |index| is out of bounds.
462 QUICHE_EXPORT ParsedQuicVersionVector
463 ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
464
465 // QuicVersionLabel is written to and read from the wire, but we prefer to use
466 // the more readable ParsedQuicVersion at other levels.
467 // Helper function which translates from a QuicVersionLabel to a
468 // ParsedQuicVersion.
469 QUICHE_EXPORT ParsedQuicVersion
470 ParseQuicVersionLabel(QuicVersionLabel version_label);
471
472 // Helper function that translates from a QuicVersionLabelVector to a
473 // ParsedQuicVersionVector.
474 QUICHE_EXPORT ParsedQuicVersionVector
475 ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels);
476
477 // Parses a QUIC version string such as "Q043" or "T051". Also supports parsing
478 // ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also
479 // supports parsing numbers such as "46".
480 QUICHE_EXPORT ParsedQuicVersion
481 ParseQuicVersionString(absl::string_view version_string);
482
483 // Parses a comma-separated list of QUIC version strings. Supports parsing by
484 // label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions.
485 // For example: "h3-29,Q050,46".
486 QUICHE_EXPORT ParsedQuicVersionVector
487 ParseQuicVersionVectorString(absl::string_view versions_string);
488
489 // Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
490 // QuicVersionLabel is written to and read from the wire, but we prefer to use
491 // the more readable ParsedQuicVersion at other levels.
492 // Helper function which translates from a ParsedQuicVersion to a
493 // QuicVersionLabel. Returns 0 if |parsed_version| is unsupported.
494 QUICHE_EXPORT QuicVersionLabel
495 CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
496
497 // Constructs a QuicVersionLabelVector from the provided
498 // ParsedQuicVersionVector.
499 QUICHE_EXPORT QuicVersionLabelVector
500 CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
501
502 // Helper function which translates from a QuicVersionLabel to a string.
503 QUICHE_EXPORT std::string QuicVersionLabelToString(
504 QuicVersionLabel version_label);
505
506 // Helper function which translates from a QuicVersionLabel string to a
507 // ParsedQuicVersion. The version label string must be of the form returned
508 // by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
509 // "51303433" (the hex encoding of the Q064 version label). Returns
510 // the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
511 // otherwise.
512 QUICHE_EXPORT ParsedQuicVersion
513 ParseQuicVersionLabelString(absl::string_view version_label_string);
514
515 // Returns |separator|-separated list of string representations of
516 // QuicVersionLabel values in the supplied |version_labels| vector. The values
517 // after the (0-based) |skip_after_nth_version|'th are skipped.
518 QUICHE_EXPORT std::string QuicVersionLabelVectorToString(
519 const QuicVersionLabelVector& version_labels, const std::string& separator,
520 size_t skip_after_nth_version);
521
522 // Returns comma separated list of string representations of QuicVersionLabel
523 // values in the supplied |version_labels| vector.
QuicVersionLabelVectorToString(const QuicVersionLabelVector & version_labels)524 QUICHE_EXPORT inline std::string QuicVersionLabelVectorToString(
525 const QuicVersionLabelVector& version_labels) {
526 return QuicVersionLabelVectorToString(version_labels, ",",
527 std::numeric_limits<size_t>::max());
528 }
529
530 // Helper function which translates from a ParsedQuicVersion to a string.
531 // Returns strings corresponding to the on-the-wire tag.
532 QUICHE_EXPORT std::string ParsedQuicVersionToString(ParsedQuicVersion version);
533
534 // Returns a vector of supported QUIC transport versions. DEPRECATED, use
535 // AllSupportedVersions instead.
536 QUICHE_EXPORT QuicTransportVersionVector AllSupportedTransportVersions();
537
538 // Returns comma separated list of string representations of
539 // QuicTransportVersion enum values in the supplied |versions| vector.
540 QUICHE_EXPORT std::string QuicTransportVersionVectorToString(
541 const QuicTransportVersionVector& versions);
542
543 // Returns comma separated list of string representations of ParsedQuicVersion
544 // values in the supplied |versions| vector.
545 QUICHE_EXPORT std::string ParsedQuicVersionVectorToString(
546 const ParsedQuicVersionVector& versions);
547
548 // Returns |separator|-separated list of string representations of
549 // ParsedQuicVersion values in the supplied |versions| vector. The values after
550 // the (0-based) |skip_after_nth_version|'th are skipped.
551 QUICHE_EXPORT std::string ParsedQuicVersionVectorToString(
552 const ParsedQuicVersionVector& versions, const std::string& separator,
553 size_t skip_after_nth_version);
554
555 // Returns comma separated list of string representations of ParsedQuicVersion
556 // values in the supplied |versions| vector.
ParsedQuicVersionVectorToString(const ParsedQuicVersionVector & versions)557 QUICHE_EXPORT inline std::string ParsedQuicVersionVectorToString(
558 const ParsedQuicVersionVector& versions) {
559 return ParsedQuicVersionVectorToString(versions, ",",
560 std::numeric_limits<size_t>::max());
561 }
562
563 // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
564 // Notable changes are:
565 // * Headers stream no longer exists.
566 // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
567 // * PUSH_PROMISE is moved to request stream.
568 // * Unidirectional streams will have their first byte as a stream type.
569 // * HEADERS frames are compressed using QPACK.
570 // * DATA frame has frame headers.
571 // * GOAWAY is moved to HTTP layer.
VersionUsesHttp3(QuicTransportVersion transport_version)572 QUICHE_EXPORT constexpr bool VersionUsesHttp3(
573 QuicTransportVersion transport_version) {
574 return transport_version >= QUIC_VERSION_IETF_DRAFT_29;
575 }
576
577 // Returns whether the transport_version supports the variable length integer
578 // length field as defined by IETF QUIC draft-13 and later.
QuicVersionHasLongHeaderLengths(QuicTransportVersion transport_version)579 QUICHE_EXPORT constexpr bool QuicVersionHasLongHeaderLengths(
580 QuicTransportVersion transport_version) {
581 // Long header lengths were added in version 49.
582 return transport_version > QUIC_VERSION_46;
583 }
584
585 // Returns whether |transport_version| makes use of IETF QUIC
586 // frames or not.
VersionHasIetfQuicFrames(QuicTransportVersion transport_version)587 QUICHE_EXPORT constexpr bool VersionHasIetfQuicFrames(
588 QuicTransportVersion transport_version) {
589 return VersionUsesHttp3(transport_version);
590 }
591
592 // Returns whether this version supports long header 8-bit encoded
593 // connection ID lengths as described in draft-ietf-quic-invariants-06 and
594 // draft-ietf-quic-transport-22.
595 QUICHE_EXPORT bool VersionHasLengthPrefixedConnectionIds(
596 QuicTransportVersion transport_version);
597
598 // Returns true if this version supports the old Google-style Alt-Svc
599 // advertisement format.
600 QUICHE_EXPORT bool VersionSupportsGoogleAltSvcFormat(
601 QuicTransportVersion transport_version);
602
603 // Returns whether this version allows server connection ID lengths that are
604 // not 64 bits.
605 QUICHE_EXPORT bool VersionAllowsVariableLengthConnectionIds(
606 QuicTransportVersion transport_version);
607
608 // Returns whether this version label supports long header 4-bit encoded
609 // connection ID lengths as described in draft-ietf-quic-invariants-05 and
610 // draft-ietf-quic-transport-21.
611 QUICHE_EXPORT bool QuicVersionLabelUses4BitConnectionIdLength(
612 QuicVersionLabel version_label);
613
614 // Returns the ALPN string to use in TLS for this version of QUIC.
615 QUICHE_EXPORT std::string AlpnForVersion(ParsedQuicVersion parsed_version);
616
617 // Configures the flags required to enable support for this version of QUIC.
618 QUICHE_EXPORT void QuicEnableVersion(const ParsedQuicVersion& version);
619
620 // Configures the flags required to disable support for this version of QUIC.
621 QUICHE_EXPORT void QuicDisableVersion(const ParsedQuicVersion& version);
622
623 // Returns whether support for this version of QUIC is currently enabled.
624 QUICHE_EXPORT bool QuicVersionIsEnabled(const ParsedQuicVersion& version);
625
626 } // namespace quic
627
628 #endif // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
629