| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Definitions and utility functions related to handling of QUIC versions. |
| // |
| // QUIC versions are encoded over the wire as an opaque 32bit field. The wire |
| // encoding is represented in memory as a QuicVersionLabel type (which is an |
| // alias to uint32_t). Conceptual versions are represented in memory as |
| // ParsedQuicVersion. |
| // |
| // We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC. |
| // |
| // All GoogleQUIC versions use a wire encoding that matches the following regex |
| // when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the |
| // type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS |
| // handshake), and the two digits at the end contain the numeric value of |
| // the transport version used. |
| // |
| // All IETF QUIC versions use the wire encoding described in: |
| // https://tools.ietf.org/html/draft-ietf-quic-transport |
| |
| #ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_ |
| #define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_ |
| |
| #include <cstdint> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/base/macros.h" |
| #include "absl/strings/string_view.h" |
| #include "quic/core/quic_tag.h" |
| #include "quic/core/quic_types.h" |
| #include "quic/platform/api/quic_export.h" |
| |
| namespace quic { |
| |
| // The list of existing QUIC transport versions. Note that QUIC versions are |
| // sent over the wire as an encoding of ParsedQuicVersion, which requires a |
| // QUIC transport version and handshake protocol. For transport versions of the |
| // form QUIC_VERSION_XX where XX is decimal, the enum numeric value is |
| // guaranteed to match the name. Older deprecated transport versions are |
| // documented in comments below. |
| enum QuicTransportVersion { |
| // Special case to indicate unknown/unsupported QUIC version. |
| QUIC_VERSION_UNSUPPORTED = 0, |
| |
| // Version 1 was the first version of QUIC that supported versioning. |
| // Version 2 decoupled versioning of non-cryptographic parameters from the |
| // SCFG. |
| // Version 3 moved public flags into the beginning of the packet. |
| // Version 4 added support for variable-length connection IDs. |
| // Version 5 made specifying FEC groups optional. |
| // Version 6 introduced variable-length packet numbers. |
| // Version 7 introduced a lower-overhead encoding for stream frames. |
| // Version 8 made salt length equal to digest length for the RSA-PSS |
| // signatures. |
| // Version 9 added stream priority. |
| // Version 10 redid the frame type numbering. |
| // Version 11 reduced the length of null encryption authentication tag |
| // from 16 to 12 bytes. |
| // Version 12 made the sequence numbers in the ACK frames variable-sized. |
| // Version 13 added the dedicated header stream. |
| // Version 14 added byte_offset to RST_STREAM frame. |
| // Version 15 added a list of packets recovered using FEC to the ACK frame. |
| // Version 16 added STOP_WAITING frame. |
| // Version 17 added per-stream flow control. |
| // Version 18 added PING frame. |
| // Version 19 added connection-level flow control |
| // Version 20 allowed to set stream- and connection-level flow control windows |
| // to different values. |
| // Version 21 made header and crypto streams flow-controlled. |
| // Version 22 added support for SCUP (server config update) messages. |
| // Version 23 added timestamps into the ACK frame. |
| // Version 24 added SPDY/4 header compression. |
| // Version 25 added support for SPDY/4 header keys and removed error_details |
| // from RST_STREAM frame. |
| // Version 26 added XLCT (expected leaf certificate) tag into CHLO. |
| // Version 27 added a nonce into SHLO. |
| // Version 28 allowed receiver to refuse creating a requested stream. |
| // Version 29 added support for QUIC_STREAM_NO_ERROR. |
| // Version 30 added server-side support for certificate transparency. |
| // Version 31 incorporated the hash of CHLO into the crypto proof supplied by |
| // the server. |
| // Version 32 removed FEC-related fields from wire format. |
| // Version 33 added diversification nonces. |
| // Version 34 removed entropy bits from packets and ACK frames, removed |
| // private flag from packet header and changed the ACK format to |
| // specify ranges of packets acknowledged rather than missing |
| // ranges. |
| // Version 35 allows endpoints to independently set stream limit. |
| // Version 36 added support for forced head-of-line blocking experiments. |
| // Version 37 added perspective into null encryption. |
| // Version 38 switched to IETF padding frame format and support for NSTP (no |
| // stop waiting frame) connection option. |
| |
| // Version 39 writes integers and floating numbers in big endian, stops acking |
| // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do |
| // not contain retransmittable frames. |
| |
| // Version 40 was an attempt to convert QUIC to IETF frame format; it was |
| // never shipped due to a bug. |
| // Version 41 was a bugfix for version 40. The working group changed the wire |
| // format before it shipped, which caused it to be never shipped |
| // and all the changes from it to be reverted. No changes from v40 |
| // or v41 are present in subsequent versions. |
| // Version 42 allowed receiving overlapping stream data. |
| |
| QUIC_VERSION_43 = 43, // PRIORITY frames are sent by client and accepted by |
| // server. |
| // Version 44 used IETF header format from draft-ietf-quic-invariants-05. |
| |
| // Version 45 added MESSAGE frame. |
| |
| QUIC_VERSION_46 = 46, // Use IETF draft-17 header format with demultiplexing |
| // bit. |
| // Version 47 added variable-length QUIC server connection IDs. |
| // Version 48 added CRYPTO frames for the handshake. |
| // Version 49 added client connection IDs, long header lengths, and the IETF |
| // header format from draft-ietf-quic-invariants-06 |
| QUIC_VERSION_50 = 50, // Header protection and initial obfuscators. |
| // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames. |
| // Number 70 used to represent draft-ietf-quic-transport-25. |
| // Number 71 used to represent draft-ietf-quic-transport-27. |
| // Number 72 used to represent draft-ietf-quic-transport-28. |
| QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29. |
| QUIC_VERSION_IETF_RFC_V1 = 80, // RFC 9000. |
| QUIC_VERSION_IETF_2_DRAFT_01 = 81, // draft-ietf-quic-v2-01. |
| // Version 99 was a dumping ground for IETF QUIC changes which were not yet |
| // ready for production between 2018-02 and 2020-02. |
| |
| // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a |
| // which is part of a range reserved by the IETF for version negotiation |
| // testing (see the "Versions" section of draft-ietf-quic-transport). |
| // This version is intentionally meant to never be supported to trigger |
| // version negotiation when proposed by clients and to prevent client |
| // ossification when sent by servers. |
| QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999, |
| }; |
| |
| // Helper function which translates from a QuicTransportVersion to a string. |
| // Returns strings corresponding to enum names (e.g. QUIC_VERSION_6). |
| QUIC_EXPORT_PRIVATE std::string QuicVersionToString( |
| QuicTransportVersion transport_version); |
| |
| // The crypto handshake protocols that can be used with QUIC. |
| // We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of |
| // PROTOCOL_TLS1_3. |
| enum HandshakeProtocol { |
| PROTOCOL_UNSUPPORTED, |
| PROTOCOL_QUIC_CRYPTO, |
| PROTOCOL_TLS1_3, |
| }; |
| |
| // Helper function which translates from a HandshakeProtocol to a string. |
| QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString( |
| HandshakeProtocol handshake_protocol); |
| |
| // Returns whether |transport_version| uses CRYPTO frames for the handshake |
| // instead of stream 1. |
| QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames( |
| QuicTransportVersion transport_version) { |
| // CRYPTO frames were added in version 48. |
| return transport_version > QUIC_VERSION_46; |
| } |
| |
| // Returns whether this combination of handshake protocol and transport |
| // version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT |
| // allowed as TLS requires crypto frames which v43 does not support. Note that |
| // UnsupportedQuicVersion is a valid version. |
| QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid( |
| HandshakeProtocol handshake_protocol, |
| QuicTransportVersion transport_version) { |
| bool transport_version_is_valid = false; |
| constexpr QuicTransportVersion valid_transport_versions[] = { |
| QUIC_VERSION_IETF_2_DRAFT_01, |
| QUIC_VERSION_IETF_RFC_V1, |
| QUIC_VERSION_IETF_DRAFT_29, |
| QUIC_VERSION_50, |
| QUIC_VERSION_46, |
| QUIC_VERSION_43, |
| QUIC_VERSION_RESERVED_FOR_NEGOTIATION, |
| QUIC_VERSION_UNSUPPORTED, |
| }; |
| for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) { |
| if (transport_version == valid_transport_versions[i]) { |
| transport_version_is_valid = true; |
| break; |
| } |
| } |
| if (!transport_version_is_valid) { |
| return false; |
| } |
| switch (handshake_protocol) { |
| case PROTOCOL_UNSUPPORTED: |
| return transport_version == QUIC_VERSION_UNSUPPORTED; |
| case PROTOCOL_QUIC_CRYPTO: |
| return transport_version != QUIC_VERSION_UNSUPPORTED && |
| transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION && |
| transport_version != QUIC_VERSION_IETF_DRAFT_29 && |
| transport_version != QUIC_VERSION_IETF_RFC_V1 && |
| transport_version != QUIC_VERSION_IETF_2_DRAFT_01; |
| case PROTOCOL_TLS1_3: |
| return transport_version != QUIC_VERSION_UNSUPPORTED && |
| transport_version != QUIC_VERSION_50 && |
| QuicVersionUsesCryptoFrames(transport_version); |
| } |
| return false; |
| } |
| |
| // A parsed QUIC version label which determines that handshake protocol |
| // and the transport version. |
| struct QUIC_EXPORT_PRIVATE ParsedQuicVersion { |
| HandshakeProtocol handshake_protocol; |
| QuicTransportVersion transport_version; |
| |
| constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol, |
| QuicTransportVersion transport_version) |
| : handshake_protocol(handshake_protocol), |
| transport_version(transport_version) { |
| QUICHE_DCHECK( |
| ParsedQuicVersionIsValid(handshake_protocol, transport_version)) |
| << QuicVersionToString(transport_version) << " " |
| << HandshakeProtocolToString(handshake_protocol); |
| } |
| |
| constexpr ParsedQuicVersion(const ParsedQuicVersion& other) |
| : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {} |
| |
| ParsedQuicVersion& operator=(const ParsedQuicVersion& other) { |
| QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol, |
| other.transport_version)) |
| << QuicVersionToString(other.transport_version) << " " |
| << HandshakeProtocolToString(other.handshake_protocol); |
| if (this != &other) { |
| handshake_protocol = other.handshake_protocol; |
| transport_version = other.transport_version; |
| } |
| return *this; |
| } |
| |
| bool operator==(const ParsedQuicVersion& other) const { |
| return handshake_protocol == other.handshake_protocol && |
| transport_version == other.transport_version; |
| } |
| |
| bool operator!=(const ParsedQuicVersion& other) const { |
| return handshake_protocol != other.handshake_protocol || |
| transport_version != other.transport_version; |
| } |
| |
| static constexpr ParsedQuicVersion V2Draft01() { |
| return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01); |
| } |
| |
| static constexpr ParsedQuicVersion RFCv1() { |
| return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1); |
| } |
| |
| static constexpr ParsedQuicVersion Draft29() { |
| return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29); |
| } |
| |
| static constexpr ParsedQuicVersion Q050() { |
| return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50); |
| } |
| |
| static constexpr ParsedQuicVersion Q046() { |
| return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46); |
| } |
| |
| static constexpr ParsedQuicVersion Q043() { |
| return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43); |
| } |
| |
| static constexpr ParsedQuicVersion Unsupported() { |
| return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED); |
| } |
| |
| static constexpr ParsedQuicVersion ReservedForNegotiation() { |
| return ParsedQuicVersion(PROTOCOL_TLS1_3, |
| QUIC_VERSION_RESERVED_FOR_NEGOTIATION); |
| } |
| |
| // Returns whether our codebase understands this version. This should only be |
| // called on valid versions, see ParsedQuicVersionIsValid. Assuming the |
| // version is valid, IsKnown returns whether the version is not |
| // UnsupportedQuicVersion. |
| bool IsKnown() const; |
| |
| bool KnowsWhichDecrypterToUse() const; |
| |
| // Returns whether this version uses keys derived from the Connection ID for |
| // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter). |
| bool UsesInitialObfuscators() const; |
| |
| // Indicates that this QUIC version does not have an enforced minimum value |
| // for flow control values negotiated during the handshake. |
| bool AllowsLowFlowControlLimits() const; |
| |
| // Returns whether header protection is used in this version of QUIC. |
| bool HasHeaderProtection() const; |
| |
| // Returns whether this version supports IETF RETRY packets. |
| bool SupportsRetry() const; |
| |
| // Returns true if this version sends variable length packet number in long |
| // header. |
| bool SendsVariableLengthPacketNumberInLongHeader() const; |
| |
| // Returns whether this version allows server connection ID lengths |
| // that are not 64 bits. |
| bool AllowsVariableLengthConnectionIds() const; |
| |
| // Returns whether this version supports client connection ID. |
| bool SupportsClientConnectionIds() const; |
| |
| // Returns whether this version supports long header 8-bit encoded |
| // connection ID lengths as described in draft-ietf-quic-invariants-06 and |
| // draft-ietf-quic-transport-22. |
| bool HasLengthPrefixedConnectionIds() const; |
| |
| // Returns whether this version supports IETF style anti-amplification limit, |
| // i.e., server will send no more than FLAGS_quic_anti_amplification_factor |
| // times received bytes until address can be validated. |
| bool SupportsAntiAmplificationLimit() const; |
| |
| // Returns true if this version can send coalesced packets. |
| bool CanSendCoalescedPackets() const; |
| |
| // Returns true if this version supports the old Google-style Alt-Svc |
| // advertisement format. |
| bool SupportsGoogleAltSvcFormat() const; |
| |
| // Returns true if |transport_version| uses IETF invariant headers. |
| bool HasIetfInvariantHeader() const; |
| |
| // Returns true if |transport_version| supports MESSAGE frames. |
| bool SupportsMessageFrames() const; |
| |
| // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer. |
| // Notable changes are: |
| // * Headers stream no longer exists. |
| // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream. |
| // * PUSH_PROMISE is moved to request stream. |
| // * Unidirectional streams will have their first byte as a stream type. |
| // * HEADERS frames are compressed using QPACK. |
| // * DATA frame has frame headers. |
| // * GOAWAY is moved to HTTP layer. |
| bool UsesHttp3() const; |
| |
| // Returns whether the transport_version supports the variable length integer |
| // length field as defined by IETF QUIC draft-13 and later. |
| bool HasLongHeaderLengths() const; |
| |
| // Returns whether |transport_version| uses CRYPTO frames for the handshake |
| // instead of stream 1. |
| bool UsesCryptoFrames() const; |
| |
| // Returns whether |transport_version| makes use of IETF QUIC |
| // frames or not. |
| bool HasIetfQuicFrames() const; |
| |
| // Returns whether this version uses the legacy TLS extension codepoint. |
| bool UsesLegacyTlsExtension() const; |
| |
| // Returns whether this version uses PROTOCOL_TLS1_3. |
| bool UsesTls() const; |
| |
| // Returns whether this version uses PROTOCOL_QUIC_CRYPTO. |
| bool UsesQuicCrypto() const; |
| |
| // Returns whether this version uses the QUICv2 Long Header Packet Types. |
| bool UsesV2PacketTypes() const; |
| |
| // Returns true if this shares ALPN codes with RFCv1, and endpoints should |
| // choose RFCv1 when presented with a v1 ALPN. Note that this is false for |
| // RFCv1. |
| bool AlpnDeferToRFCv1() const; |
| }; |
| |
| QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion(); |
| |
| QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation(); |
| |
| // Outer version used when encapsulating other packets using the Legacy Version |
| // Encapsulation feature. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation(); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| const ParsedQuicVersion& version); |
| |
| using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>; |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const ParsedQuicVersionVector& versions); |
| |
| // Representation of the on-the-wire QUIC version number. Will be written/read |
| // to the wire in network-byte-order. |
| using QuicVersionLabel = uint32_t; |
| using QuicVersionLabelVector = std::vector<QuicVersionLabel>; |
| |
| // Constructs a version label from the 4 bytes such that the on-the-wire |
| // order will be: d, c, b, a. |
| QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, |
| uint8_t c, uint8_t d); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const QuicVersionLabelVector& version_labels); |
| |
| // This vector contains all crypto handshake protocols that are supported. |
| constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() { |
| return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO}; |
| } |
| |
| constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() { |
| return { |
| ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(), |
| ParsedQuicVersion::Draft29(), ParsedQuicVersion::Q050(), |
| ParsedQuicVersion::Q046(), ParsedQuicVersion::Q043(), |
| }; |
| } |
| |
| using QuicTransportVersionVector = std::vector<QuicTransportVersion>; |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const QuicTransportVersionVector& transport_versions); |
| |
| // Returns a vector of supported QUIC versions. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions(); |
| |
| // Returns a vector of supported QUIC versions, with any versions disabled by |
| // flags excluded. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions(); |
| |
| // Returns a vector of QUIC versions from |versions| which exclude any versions |
| // which are disabled by flags. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| FilterSupportedVersions(ParsedQuicVersionVector versions); |
| |
| // Returns a subset of AllSupportedVersions() with |
| // handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order. |
| // Deprecated; only to be used in components that do not yet support |
| // PROTOCOL_TLS1_3. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| AllSupportedVersionsWithQuicCrypto(); |
| |
| // Returns a subset of CurrentSupportedVersions() with |
| // handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| CurrentSupportedVersionsWithQuicCrypto(); |
| |
| // Returns a subset of AllSupportedVersions() with |
| // handshake_protocol == PROTOCOL_TLS1_3, in the same order. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls(); |
| |
| // Returns a subset of CurrentSupportedVersions() with handshake_protocol == |
| // PROTOCOL_TLS1_3. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls(); |
| |
| // Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP |
| // layer. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedHttp3Versions(); |
| |
| // Returns QUIC version of |index| in result of |versions|. Returns |
| // UnsupportedQuicVersion() if |index| is out of bounds. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index); |
| |
| // QuicVersionLabel is written to and read from the wire, but we prefer to use |
| // the more readable ParsedQuicVersion at other levels. |
| // Helper function which translates from a QuicVersionLabel to a |
| // ParsedQuicVersion. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersion |
| ParseQuicVersionLabel(QuicVersionLabel version_label); |
| |
| // Helper function that translates from a QuicVersionLabelVector to a |
| // ParsedQuicVersionVector. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels); |
| |
| // Parses a QUIC version string such as "Q043" or "T051". Also supports parsing |
| // ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also |
| // supports parsing numbers such as "46". |
| QUIC_EXPORT_PRIVATE ParsedQuicVersion |
| ParseQuicVersionString(absl::string_view version_string); |
| |
| // Parses a comma-separated list of QUIC version strings. Supports parsing by |
| // label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions. |
| // For example: "h3-29,Q050,46". |
| QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| ParseQuicVersionVectorString(absl::string_view versions_string); |
| |
| // Constructs a QuicVersionLabel from the provided ParsedQuicVersion. |
| // QuicVersionLabel is written to and read from the wire, but we prefer to use |
| // the more readable ParsedQuicVersion at other levels. |
| // Helper function which translates from a ParsedQuicVersion to a |
| // QuicVersionLabel. Returns 0 if |parsed_version| is unsupported. |
| QUIC_EXPORT_PRIVATE QuicVersionLabel |
| CreateQuicVersionLabel(ParsedQuicVersion parsed_version); |
| |
| // Constructs a QuicVersionLabelVector from the provided |
| // ParsedQuicVersionVector. |
| QUIC_EXPORT_PRIVATE QuicVersionLabelVector |
| CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions); |
| |
| // Helper function which translates from a QuicVersionLabel to a string. |
| QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString( |
| QuicVersionLabel version_label); |
| |
| // Helper function which translates from a QuicVersionLabel string to a |
| // ParsedQuicVersion. The version label string must be of the form returned |
| // by QuicVersionLabelToString, for example, "00000001" or "Q046", but not |
| // "51303433" (the hex encoding of the Q064 version label). Returns |
| // the ParsedQuicVersion which matches the label or UnsupportedQuicVersion() |
| // otherwise. |
| QUIC_EXPORT_PRIVATE ParsedQuicVersion |
| ParseQuicVersionLabelString(absl::string_view version_label_string); |
| |
| // Returns |separator|-separated list of string representations of |
| // QuicVersionLabel values in the supplied |version_labels| vector. The values |
| // after the (0-based) |skip_after_nth_version|'th are skipped. |
| QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString( |
| const QuicVersionLabelVector& version_labels, const std::string& separator, |
| size_t skip_after_nth_version); |
| |
| // Returns comma separated list of string representations of QuicVersionLabel |
| // values in the supplied |version_labels| vector. |
| QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString( |
| const QuicVersionLabelVector& version_labels) { |
| return QuicVersionLabelVectorToString(version_labels, ",", |
| std::numeric_limits<size_t>::max()); |
| } |
| |
| // Helper function which translates from a ParsedQuicVersion to a string. |
| // Returns strings corresponding to the on-the-wire tag. |
| QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString( |
| ParsedQuicVersion version); |
| |
| // Returns a vector of supported QUIC transport versions. DEPRECATED, use |
| // AllSupportedVersions instead. |
| QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions(); |
| |
| // Returns comma separated list of string representations of |
| // QuicTransportVersion enum values in the supplied |versions| vector. |
| QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString( |
| const QuicTransportVersionVector& versions); |
| |
| // Returns comma separated list of string representations of ParsedQuicVersion |
| // values in the supplied |versions| vector. |
| QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString( |
| const ParsedQuicVersionVector& versions); |
| |
| // Returns |separator|-separated list of string representations of |
| // ParsedQuicVersion values in the supplied |versions| vector. The values after |
| // the (0-based) |skip_after_nth_version|'th are skipped. |
| QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString( |
| const ParsedQuicVersionVector& versions, const std::string& separator, |
| size_t skip_after_nth_version); |
| |
| // Returns comma separated list of string representations of ParsedQuicVersion |
| // values in the supplied |versions| vector. |
| QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString( |
| const ParsedQuicVersionVector& versions) { |
| return ParsedQuicVersionVectorToString(versions, ",", |
| std::numeric_limits<size_t>::max()); |
| } |
| |
| // Returns true if |transport_version| uses IETF invariant headers. |
| QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader( |
| QuicTransportVersion transport_version) { |
| return transport_version > QUIC_VERSION_43; |
| } |
| |
| // Returns true if |transport_version| supports MESSAGE frames. |
| QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames( |
| QuicTransportVersion transport_version) { |
| // MESSAGE frames were added in version 45. |
| return transport_version > QUIC_VERSION_43; |
| } |
| |
| // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer. |
| // Notable changes are: |
| // * Headers stream no longer exists. |
| // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream. |
| // * PUSH_PROMISE is moved to request stream. |
| // * Unidirectional streams will have their first byte as a stream type. |
| // * HEADERS frames are compressed using QPACK. |
| // * DATA frame has frame headers. |
| // * GOAWAY is moved to HTTP layer. |
| QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3( |
| QuicTransportVersion transport_version) { |
| return transport_version >= QUIC_VERSION_IETF_DRAFT_29; |
| } |
| |
| // Returns whether the transport_version supports the variable length integer |
| // length field as defined by IETF QUIC draft-13 and later. |
| QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths( |
| QuicTransportVersion transport_version) { |
| // Long header lengths were added in version 49. |
| return transport_version > QUIC_VERSION_46; |
| } |
| |
| // Returns whether |transport_version| makes use of IETF QUIC |
| // frames or not. |
| QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames( |
| QuicTransportVersion transport_version) { |
| return VersionUsesHttp3(transport_version); |
| } |
| |
| // Returns whether this version supports long header 8-bit encoded |
| // connection ID lengths as described in draft-ietf-quic-invariants-06 and |
| // draft-ietf-quic-transport-22. |
| QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds( |
| QuicTransportVersion transport_version); |
| |
| // Returns true if this version supports the old Google-style Alt-Svc |
| // advertisement format. |
| QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat( |
| QuicTransportVersion transport_version); |
| |
| // Returns whether this version allows server connection ID lengths that are |
| // not 64 bits. |
| QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds( |
| QuicTransportVersion transport_version); |
| |
| // Returns whether this version label supports long header 4-bit encoded |
| // connection ID lengths as described in draft-ietf-quic-invariants-05 and |
| // draft-ietf-quic-transport-21. |
| QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength( |
| QuicVersionLabel version_label); |
| |
| // Returns the ALPN string to use in TLS for this version of QUIC. |
| QUIC_EXPORT_PRIVATE std::string AlpnForVersion( |
| ParsedQuicVersion parsed_version); |
| |
| // Initializes support for the provided IETF draft version by setting the |
| // correct flags. |
| QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft(); |
| |
| // Configures the flags required to enable support for this version of QUIC. |
| QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version); |
| |
| // Configures the flags required to disable support for this version of QUIC. |
| QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version); |
| |
| // Returns whether support for this version of QUIC is currently enabled. |
| QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version); |
| |
| } // namespace quic |
| |
| #endif // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_ |