• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   QUIC_VERSION_43 = 43,  // PRIORITY frames are sent by client and accepted by
110                          // server.
111   // Version 44 used IETF header format from draft-ietf-quic-invariants-05.
112 
113   // Version 45 added MESSAGE frame.
114 
115   QUIC_VERSION_46 = 46,  // Use IETF draft-17 header format with demultiplexing
116                          // bit.
117   // Version 47 added variable-length QUIC server connection IDs.
118   // Version 48 added CRYPTO frames for the handshake.
119   // Version 49 added client connection IDs, long header lengths, and the IETF
120   // header format from draft-ietf-quic-invariants-06
121   QUIC_VERSION_50 = 50,  // Header protection and initial obfuscators.
122   // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames.
123   // Number 70 used to represent draft-ietf-quic-transport-25.
124   // Number 71 used to represent draft-ietf-quic-transport-27.
125   // Number 72 used to represent draft-ietf-quic-transport-28.
126   QUIC_VERSION_IETF_DRAFT_29 = 73,  // draft-ietf-quic-transport-29.
127   QUIC_VERSION_IETF_RFC_V1 = 80,    // RFC 9000.
128   // Number 81 used to represent draft-ietf-quic-v2-01.
129   QUIC_VERSION_IETF_2_DRAFT_08 = 82,  // draft-ietf-quic-v2-08.
130   // Version 99 was a dumping ground for IETF QUIC changes which were not yet
131   // ready for production between 2018-02 and 2020-02.
132 
133   // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
134   // which is part of a range reserved by the IETF for version negotiation
135   // testing (see the "Versions" section of draft-ietf-quic-transport).
136   // This version is intentionally meant to never be supported to trigger
137   // version negotiation when proposed by clients and to prevent client
138   // ossification when sent by servers.
139   QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
140 };
141 
142 // Helper function which translates from a QuicTransportVersion to a string.
143 // Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
144 QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
145     QuicTransportVersion transport_version);
146 
147 // The crypto handshake protocols that can be used with QUIC.
148 // We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of
149 // PROTOCOL_TLS1_3.
150 enum HandshakeProtocol {
151   PROTOCOL_UNSUPPORTED,
152   PROTOCOL_QUIC_CRYPTO,
153   PROTOCOL_TLS1_3,
154 };
155 
156 // Helper function which translates from a HandshakeProtocol to a string.
157 QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString(
158     HandshakeProtocol handshake_protocol);
159 
160 // Returns whether |transport_version| uses CRYPTO frames for the handshake
161 // instead of stream 1.
QuicVersionUsesCryptoFrames(QuicTransportVersion transport_version)162 QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames(
163     QuicTransportVersion transport_version) {
164   // CRYPTO frames were added in version 48.
165   return transport_version > QUIC_VERSION_46;
166 }
167 
168 // Returns whether this combination of handshake protocol and transport
169 // version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT
170 // allowed as TLS requires crypto frames which v43 does not support. Note that
171 // UnsupportedQuicVersion is a valid version.
ParsedQuicVersionIsValid(HandshakeProtocol handshake_protocol,QuicTransportVersion transport_version)172 QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
173     HandshakeProtocol handshake_protocol,
174     QuicTransportVersion transport_version) {
175   bool transport_version_is_valid = false;
176   constexpr QuicTransportVersion valid_transport_versions[] = {
177       QUIC_VERSION_IETF_2_DRAFT_08,
178       QUIC_VERSION_IETF_RFC_V1,
179       QUIC_VERSION_IETF_DRAFT_29,
180       QUIC_VERSION_50,
181       QUIC_VERSION_46,
182       QUIC_VERSION_43,
183       QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
184       QUIC_VERSION_UNSUPPORTED,
185   };
186   for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) {
187     if (transport_version == valid_transport_versions[i]) {
188       transport_version_is_valid = true;
189       break;
190     }
191   }
192   if (!transport_version_is_valid) {
193     return false;
194   }
195   switch (handshake_protocol) {
196     case PROTOCOL_UNSUPPORTED:
197       return transport_version == QUIC_VERSION_UNSUPPORTED;
198     case PROTOCOL_QUIC_CRYPTO:
199       return transport_version != QUIC_VERSION_UNSUPPORTED &&
200              transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
201              transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
202              transport_version != QUIC_VERSION_IETF_RFC_V1 &&
203              transport_version != QUIC_VERSION_IETF_2_DRAFT_08;
204     case PROTOCOL_TLS1_3:
205       return transport_version != QUIC_VERSION_UNSUPPORTED &&
206              transport_version != QUIC_VERSION_50 &&
207              QuicVersionUsesCryptoFrames(transport_version);
208   }
209   return false;
210 }
211 
212 // A parsed QUIC version label which determines that handshake protocol
213 // and the transport version.
214 struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
215   HandshakeProtocol handshake_protocol;
216   QuicTransportVersion transport_version;
217 
ParsedQuicVersionParsedQuicVersion218   constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol,
219                               QuicTransportVersion transport_version)
220       : handshake_protocol(handshake_protocol),
221         transport_version(transport_version) {
222     QUICHE_DCHECK(
223         ParsedQuicVersionIsValid(handshake_protocol, transport_version))
224         << QuicVersionToString(transport_version) << " "
225         << HandshakeProtocolToString(handshake_protocol);
226   }
227 
ParsedQuicVersionParsedQuicVersion228   constexpr ParsedQuicVersion(const ParsedQuicVersion& other)
229       : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {}
230 
231   ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
232     QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol,
233                                            other.transport_version))
234         << QuicVersionToString(other.transport_version) << " "
235         << HandshakeProtocolToString(other.handshake_protocol);
236     if (this != &other) {
237       handshake_protocol = other.handshake_protocol;
238       transport_version = other.transport_version;
239     }
240     return *this;
241   }
242 
243   bool operator==(const ParsedQuicVersion& other) const {
244     return handshake_protocol == other.handshake_protocol &&
245            transport_version == other.transport_version;
246   }
247 
248   bool operator!=(const ParsedQuicVersion& other) const {
249     return handshake_protocol != other.handshake_protocol ||
250            transport_version != other.transport_version;
251   }
252 
V2Draft08ParsedQuicVersion253   static constexpr ParsedQuicVersion V2Draft08() {
254     return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_08);
255   }
256 
RFCv1ParsedQuicVersion257   static constexpr ParsedQuicVersion RFCv1() {
258     return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
259   }
260 
Draft29ParsedQuicVersion261   static constexpr ParsedQuicVersion Draft29() {
262     return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
263   }
264 
Q050ParsedQuicVersion265   static constexpr ParsedQuicVersion Q050() {
266     return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
267   }
268 
Q046ParsedQuicVersion269   static constexpr ParsedQuicVersion Q046() {
270     return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
271   }
272 
Q043ParsedQuicVersion273   static constexpr ParsedQuicVersion Q043() {
274     return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
275   }
276 
UnsupportedParsedQuicVersion277   static constexpr ParsedQuicVersion Unsupported() {
278     return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
279   }
280 
ReservedForNegotiationParsedQuicVersion281   static constexpr ParsedQuicVersion ReservedForNegotiation() {
282     return ParsedQuicVersion(PROTOCOL_TLS1_3,
283                              QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
284   }
285 
286   // Returns whether our codebase understands this version. This should only be
287   // called on valid versions, see ParsedQuicVersionIsValid. Assuming the
288   // version is valid, IsKnown returns whether the version is not
289   // UnsupportedQuicVersion.
290   bool IsKnown() const;
291 
292   bool KnowsWhichDecrypterToUse() const;
293 
294   // Returns whether this version uses keys derived from the Connection ID for
295   // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter).
296   bool UsesInitialObfuscators() const;
297 
298   // Indicates that this QUIC version does not have an enforced minimum value
299   // for flow control values negotiated during the handshake.
300   bool AllowsLowFlowControlLimits() const;
301 
302   // Returns whether header protection is used in this version of QUIC.
303   bool HasHeaderProtection() const;
304 
305   // Returns whether this version supports IETF RETRY packets.
306   bool SupportsRetry() const;
307 
308   // Returns true if this version sends variable length packet number in long
309   // header.
310   bool SendsVariableLengthPacketNumberInLongHeader() const;
311 
312   // Returns whether this version allows server connection ID lengths
313   // that are not 64 bits.
314   bool AllowsVariableLengthConnectionIds() const;
315 
316   // Returns whether this version supports client connection ID.
317   bool SupportsClientConnectionIds() const;
318 
319   // Returns whether this version supports long header 8-bit encoded
320   // connection ID lengths as described in draft-ietf-quic-invariants-06 and
321   // draft-ietf-quic-transport-22.
322   bool HasLengthPrefixedConnectionIds() const;
323 
324   // Returns whether this version supports IETF style anti-amplification limit,
325   // i.e., server will send no more than FLAGS_quic_anti_amplification_factor
326   // times received bytes until address can be validated.
327   bool SupportsAntiAmplificationLimit() const;
328 
329   // Returns true if this version can send coalesced packets.
330   bool CanSendCoalescedPackets() const;
331 
332   // Returns true if this version supports the old Google-style Alt-Svc
333   // advertisement format.
334   bool SupportsGoogleAltSvcFormat() const;
335 
336   // Returns true if |transport_version| uses IETF invariant headers.
337   bool HasIetfInvariantHeader() const;
338 
339   // Returns true if |transport_version| supports MESSAGE frames.
340   bool SupportsMessageFrames() const;
341 
342   // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
343   // Notable changes are:
344   // * Headers stream no longer exists.
345   // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
346   // * PUSH_PROMISE is moved to request stream.
347   // * Unidirectional streams will have their first byte as a stream type.
348   // * HEADERS frames are compressed using QPACK.
349   // * DATA frame has frame headers.
350   // * GOAWAY is moved to HTTP layer.
351   bool UsesHttp3() const;
352 
353   // Returns whether the transport_version supports the variable length integer
354   // length field as defined by IETF QUIC draft-13 and later.
355   bool HasLongHeaderLengths() const;
356 
357   // Returns whether |transport_version| uses CRYPTO frames for the handshake
358   // instead of stream 1.
359   bool UsesCryptoFrames() const;
360 
361   // Returns whether |transport_version| makes use of IETF QUIC
362   // frames or not.
363   bool HasIetfQuicFrames() const;
364 
365   // Returns whether this version uses the legacy TLS extension codepoint.
366   bool UsesLegacyTlsExtension() const;
367 
368   // Returns whether this version uses PROTOCOL_TLS1_3.
369   bool UsesTls() const;
370 
371   // Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
372   bool UsesQuicCrypto() const;
373 
374   // Returns whether this version uses the QUICv2 Long Header Packet Types.
375   bool UsesV2PacketTypes() const;
376 
377   // Returns true if this shares ALPN codes with RFCv1, and endpoints should
378   // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
379   // RFCv1.
380   bool AlpnDeferToRFCv1() const;
381 };
382 
383 QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
384 
385 QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();
386 
387 QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
388                                              const ParsedQuicVersion& version);
389 
390 using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
391 
392 QUIC_EXPORT_PRIVATE std::ostream& operator<<(
393     std::ostream& os, const ParsedQuicVersionVector& versions);
394 
395 // Representation of the on-the-wire QUIC version number. Will be written/read
396 // to the wire in network-byte-order.
397 using QuicVersionLabel = uint32_t;
398 using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
399 
400 // Constructs a version label from the 4 bytes such that the on-the-wire
401 // order will be: d, c, b, a.
402 QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b,
403                                                       uint8_t c, uint8_t d);
404 
405 QUIC_EXPORT_PRIVATE std::ostream& operator<<(
406     std::ostream& os, const QuicVersionLabelVector& version_labels);
407 
408 // This vector contains all crypto handshake protocols that are supported.
SupportedHandshakeProtocols()409 constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
410   return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
411 }
412 
SupportedVersions()413 constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
414   return {
415       ParsedQuicVersion::V2Draft08(), ParsedQuicVersion::RFCv1(),
416       ParsedQuicVersion::Draft29(),   ParsedQuicVersion::Q050(),
417       ParsedQuicVersion::Q046(),      ParsedQuicVersion::Q043(),
418   };
419 }
420 
421 using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
422 
423 QUIC_EXPORT_PRIVATE std::ostream& operator<<(
424     std::ostream& os, const QuicTransportVersionVector& transport_versions);
425 
426 // Returns a vector of supported QUIC versions.
427 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
428 
429 // Returns a vector of supported QUIC versions, with any versions disabled by
430 // flags excluded.
431 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();
432 
433 // Returns a vector of QUIC versions from |versions| which exclude any versions
434 // which are disabled by flags.
435 QUIC_EXPORT_PRIVATE 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 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
443 AllSupportedVersionsWithQuicCrypto();
444 
445 // Returns a subset of CurrentSupportedVersions() with
446 // handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
447 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
448 CurrentSupportedVersionsWithQuicCrypto();
449 
450 // Returns a subset of AllSupportedVersions() with
451 // handshake_protocol == PROTOCOL_TLS1_3, in the same order.
452 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls();
453 
454 // Returns a subset of CurrentSupportedVersions() with handshake_protocol ==
455 // PROTOCOL_TLS1_3.
456 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls();
457 
458 // Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP
459 // layer.
460 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedHttp3Versions();
461 
462 // Returns QUIC version of |index| in result of |versions|. Returns
463 // UnsupportedQuicVersion() if |index| is out of bounds.
464 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
465 ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
466 
467 // QuicVersionLabel is written to and read from the wire, but we prefer to use
468 // the more readable ParsedQuicVersion at other levels.
469 // Helper function which translates from a QuicVersionLabel to a
470 // ParsedQuicVersion.
471 QUIC_EXPORT_PRIVATE ParsedQuicVersion
472 ParseQuicVersionLabel(QuicVersionLabel version_label);
473 
474 // Helper function that translates from a QuicVersionLabelVector to a
475 // ParsedQuicVersionVector.
476 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
477 ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels);
478 
479 // Parses a QUIC version string such as "Q043" or "T051". Also supports parsing
480 // ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also
481 // supports parsing numbers such as "46".
482 QUIC_EXPORT_PRIVATE ParsedQuicVersion
483 ParseQuicVersionString(absl::string_view version_string);
484 
485 // Parses a comma-separated list of QUIC version strings. Supports parsing by
486 // label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions.
487 // For example: "h3-29,Q050,46".
488 QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
489 ParseQuicVersionVectorString(absl::string_view versions_string);
490 
491 // Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
492 // QuicVersionLabel is written to and read from the wire, but we prefer to use
493 // the more readable ParsedQuicVersion at other levels.
494 // Helper function which translates from a ParsedQuicVersion to a
495 // QuicVersionLabel. Returns 0 if |parsed_version| is unsupported.
496 QUIC_EXPORT_PRIVATE QuicVersionLabel
497 CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
498 
499 // Constructs a QuicVersionLabelVector from the provided
500 // ParsedQuicVersionVector.
501 QUIC_EXPORT_PRIVATE QuicVersionLabelVector
502 CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
503 
504 // Helper function which translates from a QuicVersionLabel to a string.
505 QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
506     QuicVersionLabel version_label);
507 
508 // Helper function which translates from a QuicVersionLabel string to a
509 // ParsedQuicVersion. The version label string must be of the form returned
510 // by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
511 // "51303433" (the hex encoding of the Q064 version label). Returns
512 // the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
513 // otherwise.
514 QUIC_EXPORT_PRIVATE ParsedQuicVersion
515 ParseQuicVersionLabelString(absl::string_view version_label_string);
516 
517 // Returns |separator|-separated list of string representations of
518 // QuicVersionLabel values in the supplied |version_labels| vector. The values
519 // after the (0-based) |skip_after_nth_version|'th are skipped.
520 QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
521     const QuicVersionLabelVector& version_labels, const std::string& separator,
522     size_t skip_after_nth_version);
523 
524 // Returns comma separated list of string representations of QuicVersionLabel
525 // values in the supplied |version_labels| vector.
QuicVersionLabelVectorToString(const QuicVersionLabelVector & version_labels)526 QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString(
527     const QuicVersionLabelVector& version_labels) {
528   return QuicVersionLabelVectorToString(version_labels, ",",
529                                         std::numeric_limits<size_t>::max());
530 }
531 
532 // Helper function which translates from a ParsedQuicVersion to a string.
533 // Returns strings corresponding to the on-the-wire tag.
534 QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
535     ParsedQuicVersion version);
536 
537 // Returns a vector of supported QUIC transport versions. DEPRECATED, use
538 // AllSupportedVersions instead.
539 QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
540 
541 // Returns comma separated list of string representations of
542 // QuicTransportVersion enum values in the supplied |versions| vector.
543 QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
544     const QuicTransportVersionVector& versions);
545 
546 // Returns comma separated list of string representations of ParsedQuicVersion
547 // values in the supplied |versions| vector.
548 QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
549     const ParsedQuicVersionVector& versions);
550 
551 // Returns |separator|-separated list of string representations of
552 // ParsedQuicVersion values in the supplied |versions| vector. The values after
553 // the (0-based) |skip_after_nth_version|'th are skipped.
554 QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
555     const ParsedQuicVersionVector& versions, const std::string& separator,
556     size_t skip_after_nth_version);
557 
558 // Returns comma separated list of string representations of ParsedQuicVersion
559 // values in the supplied |versions| vector.
ParsedQuicVersionVectorToString(const ParsedQuicVersionVector & versions)560 QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString(
561     const ParsedQuicVersionVector& versions) {
562   return ParsedQuicVersionVectorToString(versions, ",",
563                                          std::numeric_limits<size_t>::max());
564 }
565 
566 // Returns true if |transport_version| uses IETF invariant headers.
VersionHasIetfInvariantHeader(QuicTransportVersion transport_version)567 QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader(
568     QuicTransportVersion transport_version) {
569   return transport_version > QUIC_VERSION_43;
570 }
571 
572 // Returns true if |transport_version| supports MESSAGE frames.
VersionSupportsMessageFrames(QuicTransportVersion transport_version)573 QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames(
574     QuicTransportVersion transport_version) {
575   // MESSAGE frames were added in version 45.
576   return transport_version > QUIC_VERSION_43;
577 }
578 
579 // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
580 // Notable changes are:
581 // * Headers stream no longer exists.
582 // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
583 // * PUSH_PROMISE is moved to request stream.
584 // * Unidirectional streams will have their first byte as a stream type.
585 // * HEADERS frames are compressed using QPACK.
586 // * DATA frame has frame headers.
587 // * GOAWAY is moved to HTTP layer.
VersionUsesHttp3(QuicTransportVersion transport_version)588 QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
589     QuicTransportVersion transport_version) {
590   return transport_version >= QUIC_VERSION_IETF_DRAFT_29;
591 }
592 
593 // Returns whether the transport_version supports the variable length integer
594 // length field as defined by IETF QUIC draft-13 and later.
QuicVersionHasLongHeaderLengths(QuicTransportVersion transport_version)595 QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths(
596     QuicTransportVersion transport_version) {
597   // Long header lengths were added in version 49.
598   return transport_version > QUIC_VERSION_46;
599 }
600 
601 // Returns whether |transport_version| makes use of IETF QUIC
602 // frames or not.
VersionHasIetfQuicFrames(QuicTransportVersion transport_version)603 QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames(
604     QuicTransportVersion transport_version) {
605   return VersionUsesHttp3(transport_version);
606 }
607 
608 // Returns whether this version supports long header 8-bit encoded
609 // connection ID lengths as described in draft-ietf-quic-invariants-06 and
610 // draft-ietf-quic-transport-22.
611 QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds(
612     QuicTransportVersion transport_version);
613 
614 // Returns true if this version supports the old Google-style Alt-Svc
615 // advertisement format.
616 QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat(
617     QuicTransportVersion transport_version);
618 
619 // Returns whether this version allows server connection ID lengths that are
620 // not 64 bits.
621 QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds(
622     QuicTransportVersion transport_version);
623 
624 // Returns whether this version label supports long header 4-bit encoded
625 // connection ID lengths as described in draft-ietf-quic-invariants-05 and
626 // draft-ietf-quic-transport-21.
627 QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength(
628     QuicVersionLabel version_label);
629 
630 // Returns the ALPN string to use in TLS for this version of QUIC.
631 QUIC_EXPORT_PRIVATE std::string AlpnForVersion(
632     ParsedQuicVersion parsed_version);
633 
634 // Initializes support for the provided IETF draft version by setting the
635 // correct flags.
636 QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft();
637 
638 // Configures the flags required to enable support for this version of QUIC.
639 QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version);
640 
641 // Configures the flags required to disable support for this version of QUIC.
642 QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version);
643 
644 // Returns whether support for this version of QUIC is currently enabled.
645 QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version);
646 
647 }  // namespace quic
648 
649 #endif  // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
650