QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 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 | // |
dschinazi | a98acdf | 2020-05-21 15:34:16 -0700 | [diff] [blame] | 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 |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 22 | |
| 23 | #ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_ |
| 24 | #define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_ |
| 25 | |
vasilvv | 872e7a3 | 2019-03-12 16:42:44 -0700 | [diff] [blame] | 26 | #include <string> |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 27 | #include <vector> |
| 28 | |
| 29 | #include "net/third_party/quiche/src/quic/core/quic_tag.h" |
| 30 | #include "net/third_party/quiche/src/quic/core/quic_types.h" |
| 31 | #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" |
dschinazi | cee73cd | 2020-03-05 18:20:50 -0800 | [diff] [blame] | 32 | #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 33 | |
| 34 | namespace quic { |
| 35 | |
dschinazi | a98acdf | 2020-05-21 15:34:16 -0700 | [diff] [blame] | 36 | // The list of existing QUIC transport versions. Note that QUIC versions are |
| 37 | // sent over the wire as an encoding of ParsedQuicVersion, which requires a |
| 38 | // QUIC transport version and handshake protocol. For transport versions of the |
| 39 | // form QUIC_VERSION_XX where XX is decimal, the enum numeric value is |
| 40 | // guaranteed to match the name. Older deprecated transport versions are |
| 41 | // documented in comments below. |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 42 | enum QuicTransportVersion { |
| 43 | // Special case to indicate unknown/unsupported QUIC version. |
| 44 | QUIC_VERSION_UNSUPPORTED = 0, |
| 45 | |
| 46 | // Version 1 was the first version of QUIC that supported versioning. |
| 47 | // Version 2 decoupled versioning of non-cryptographic parameters from the |
| 48 | // SCFG. |
| 49 | // Version 3 moved public flags into the beginning of the packet. |
| 50 | // Version 4 added support for variable-length connection IDs. |
| 51 | // Version 5 made specifying FEC groups optional. |
| 52 | // Version 6 introduced variable-length packet numbers. |
| 53 | // Version 7 introduced a lower-overhead encoding for stream frames. |
| 54 | // Version 8 made salt length equal to digest length for the RSA-PSS |
| 55 | // signatures. |
| 56 | // Version 9 added stream priority. |
| 57 | // Version 10 redid the frame type numbering. |
| 58 | // Version 11 reduced the length of null encryption authentication tag |
| 59 | // from 16 to 12 bytes. |
| 60 | // Version 12 made the sequence numbers in the ACK frames variable-sized. |
| 61 | // Version 13 added the dedicated header stream. |
| 62 | // Version 14 added byte_offset to RST_STREAM frame. |
| 63 | // Version 15 added a list of packets recovered using FEC to the ACK frame. |
| 64 | // Version 16 added STOP_WAITING frame. |
| 65 | // Version 17 added per-stream flow control. |
| 66 | // Version 18 added PING frame. |
| 67 | // Version 19 added connection-level flow control |
| 68 | // Version 20 allowed to set stream- and connection-level flow control windows |
| 69 | // to different values. |
| 70 | // Version 21 made header and crypto streams flow-controlled. |
| 71 | // Version 22 added support for SCUP (server config update) messages. |
| 72 | // Version 23 added timestamps into the ACK frame. |
| 73 | // Version 24 added SPDY/4 header compression. |
| 74 | // Version 25 added support for SPDY/4 header keys and removed error_details |
| 75 | // from RST_STREAM frame. |
| 76 | // Version 26 added XLCT (expected leaf certificate) tag into CHLO. |
| 77 | // Version 27 added a nonce into SHLO. |
| 78 | // Version 28 allowed receiver to refuse creating a requested stream. |
| 79 | // Version 29 added support for QUIC_STREAM_NO_ERROR. |
| 80 | // Version 30 added server-side support for certificate transparency. |
| 81 | // Version 31 incorporated the hash of CHLO into the crypto proof supplied by |
| 82 | // the server. |
| 83 | // Version 32 removed FEC-related fields from wire format. |
| 84 | // Version 33 added diversification nonces. |
| 85 | // Version 34 removed entropy bits from packets and ACK frames, removed |
| 86 | // private flag from packet header and changed the ACK format to |
| 87 | // specify ranges of packets acknowledged rather than missing |
| 88 | // ranges. |
| 89 | // Version 35 allows endpoints to independently set stream limit. |
| 90 | // Version 36 added support for forced head-of-line blocking experiments. |
| 91 | // Version 37 added perspective into null encryption. |
| 92 | // Version 38 switched to IETF padding frame format and support for NSTP (no |
| 93 | // stop waiting frame) connection option. |
| 94 | |
fayang | 8265a2a | 2019-10-16 11:23:51 -0700 | [diff] [blame] | 95 | // Version 39 writes integers and floating numbers in big endian, stops acking |
| 96 | // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do |
| 97 | // not contain retransmittable frames. |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 98 | |
| 99 | // Version 40 was an attempt to convert QUIC to IETF frame format; it was |
| 100 | // never shipped due to a bug. |
| 101 | // Version 41 was a bugfix for version 40. The working group changed the wire |
| 102 | // format before it shipped, which caused it to be never shipped |
| 103 | // and all the changes from it to be reverted. No changes from v40 |
| 104 | // or v41 are present in subsequent versions. |
| 105 | // Version 42 allowed receiving overlapping stream data. |
| 106 | |
| 107 | QUIC_VERSION_43 = 43, // PRIORITY frames are sent by client and accepted by |
| 108 | // server. |
fayang | 36825da | 2019-08-21 14:01:27 -0700 | [diff] [blame] | 109 | // Version 44 used IETF header format from draft-ietf-quic-invariants-05. |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 110 | |
| 111 | // Version 45 added MESSAGE frame. |
| 112 | |
| 113 | QUIC_VERSION_46 = 46, // Use IETF draft-17 header format with demultiplexing |
| 114 | // bit. |
dschinazi | 8b1c45a | 2019-10-17 08:48:13 -0700 | [diff] [blame] | 115 | // Version 47 added variable-length QUIC server connection IDs. |
dschinazi | ceed866 | 2020-07-14 09:37:05 -0700 | [diff] [blame] | 116 | // Version 48 added CRYPTO frames for the handshake. |
| 117 | // Version 49 added client connection IDs, long header lengths, and the IETF |
| 118 | // header format from draft-ietf-quic-invariants-06 |
nharper | c32d8ab | 2019-10-09 11:09:06 -0700 | [diff] [blame] | 119 | QUIC_VERSION_50 = 50, // Header protection and initial obfuscators. |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 120 | QUIC_VERSION_51 = 51, // draft-29 features but with GoogleQUIC frames. |
dschinazi | 40f0b3d | 2020-02-19 17:54:05 -0800 | [diff] [blame] | 121 | QUIC_VERSION_IETF_DRAFT_25 = 70, // draft-ietf-quic-transport-25. |
dschinazi | c3316f3 | 2020-03-05 14:34:36 -0800 | [diff] [blame] | 122 | QUIC_VERSION_IETF_DRAFT_27 = 71, // draft-ietf-quic-transport-27. |
dschinazi | 6ab4524 | 2020-06-23 00:20:37 -0700 | [diff] [blame] | 123 | // Number 72 used to represent draft-ietf-quic-transport-28. |
dschinazi | b3fed9e | 2020-06-11 11:59:33 -0700 | [diff] [blame] | 124 | QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29. |
dschinazi | c3316f3 | 2020-03-05 14:34:36 -0800 | [diff] [blame] | 125 | // Version 99 was a dumping ground for IETF QUIC changes which were not yet |
| 126 | // yet ready for production between 2018-02 and 2020-02. |
| 127 | |
dschinazi | 1ac22cc | 2019-06-25 11:47:50 -0700 | [diff] [blame] | 128 | // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a |
dschinazi | 5a354c9 | 2019-05-09 12:18:53 -0700 | [diff] [blame] | 129 | // which is part of a range reserved by the IETF for version negotiation |
dschinazi | 1ac22cc | 2019-06-25 11:47:50 -0700 | [diff] [blame] | 130 | // testing (see the "Versions" section of draft-ietf-quic-transport). |
| 131 | // This version is intentionally meant to never be supported to trigger |
| 132 | // version negotiation when proposed by clients and to prevent client |
| 133 | // ossification when sent by servers. |
dschinazi | 5a354c9 | 2019-05-09 12:18:53 -0700 | [diff] [blame] | 134 | QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 135 | }; |
| 136 | |
dschinazi | a0b4d2e | 2020-03-16 16:22:08 -0700 | [diff] [blame] | 137 | // This array contains QUIC transport versions which we currently support. |
dschinazi | a98acdf | 2020-05-21 15:34:16 -0700 | [diff] [blame] | 138 | // DEPRECATED. Use SupportedVersions() instead. |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 139 | constexpr std::array<QuicTransportVersion, 7> SupportedTransportVersions() { |
dschinazi | b3fed9e | 2020-06-11 11:59:33 -0700 | [diff] [blame] | 140 | return {QUIC_VERSION_IETF_DRAFT_29, |
dschinazi | 2c78aac | 2020-05-21 17:21:58 -0700 | [diff] [blame] | 141 | QUIC_VERSION_IETF_DRAFT_27, |
dschinazi | a0b4d2e | 2020-03-16 16:22:08 -0700 | [diff] [blame] | 142 | QUIC_VERSION_IETF_DRAFT_25, |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 143 | QUIC_VERSION_51, |
dschinazi | a0b4d2e | 2020-03-16 16:22:08 -0700 | [diff] [blame] | 144 | QUIC_VERSION_50, |
dschinazi | a0b4d2e | 2020-03-16 16:22:08 -0700 | [diff] [blame] | 145 | QUIC_VERSION_46, |
| 146 | QUIC_VERSION_43}; |
| 147 | } |
| 148 | |
dschinazi | dc770fc | 2020-01-13 15:42:41 -0800 | [diff] [blame] | 149 | // Helper function which translates from a QuicTransportVersion to a string. |
| 150 | // Returns strings corresponding to enum names (e.g. QUIC_VERSION_6). |
| 151 | QUIC_EXPORT_PRIVATE std::string QuicVersionToString( |
| 152 | QuicTransportVersion transport_version); |
| 153 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 154 | // The crypto handshake protocols that can be used with QUIC. |
| 155 | enum HandshakeProtocol { |
| 156 | PROTOCOL_UNSUPPORTED, |
| 157 | PROTOCOL_QUIC_CRYPTO, |
| 158 | PROTOCOL_TLS1_3, |
| 159 | }; |
| 160 | |
dschinazi | dc770fc | 2020-01-13 15:42:41 -0800 | [diff] [blame] | 161 | // Helper function which translates from a HandshakeProtocol to a string. |
| 162 | QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString( |
| 163 | HandshakeProtocol handshake_protocol); |
| 164 | |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 165 | // Returns whether |transport_version| uses CRYPTO frames for the handshake |
| 166 | // instead of stream 1. |
| 167 | QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames( |
| 168 | QuicTransportVersion transport_version) { |
dschinazi | ceed866 | 2020-07-14 09:37:05 -0700 | [diff] [blame] | 169 | // CRYPTO frames were added in version 48. |
| 170 | return transport_version > QUIC_VERSION_46; |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 171 | } |
| 172 | |
dschinazi | dc770fc | 2020-01-13 15:42:41 -0800 | [diff] [blame] | 173 | // Returns whether this combination of handshake protocol and transport |
| 174 | // version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT |
| 175 | // allowed as TLS requires crypto frames which v43 does not support. Note that |
| 176 | // UnsupportedQuicVersion is a valid version. |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 177 | QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid( |
dschinazi | dc770fc | 2020-01-13 15:42:41 -0800 | [diff] [blame] | 178 | HandshakeProtocol handshake_protocol, |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 179 | QuicTransportVersion transport_version) { |
dschinazi | a0b4d2e | 2020-03-16 16:22:08 -0700 | [diff] [blame] | 180 | bool transport_version_is_valid = |
| 181 | transport_version == QUIC_VERSION_UNSUPPORTED || |
| 182 | transport_version == QUIC_VERSION_RESERVED_FOR_NEGOTIATION; |
| 183 | if (!transport_version_is_valid) { |
dschinazi | 5efb965 | 2020-03-17 10:16:45 -0700 | [diff] [blame] | 184 | // Iterators are not constexpr in C++14 which Chrome uses. |
| 185 | constexpr auto supported_transport_versions = SupportedTransportVersions(); |
| 186 | for (size_t i = 0; i < supported_transport_versions.size(); ++i) { |
| 187 | const QuicTransportVersion& trans_vers = supported_transport_versions[i]; |
dschinazi | a0b4d2e | 2020-03-16 16:22:08 -0700 | [diff] [blame] | 188 | if (trans_vers == transport_version) { |
| 189 | transport_version_is_valid = true; |
| 190 | break; |
| 191 | } |
| 192 | } |
| 193 | } |
| 194 | if (!transport_version_is_valid) { |
| 195 | return false; |
| 196 | } |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 197 | switch (handshake_protocol) { |
| 198 | case PROTOCOL_UNSUPPORTED: |
| 199 | return transport_version == QUIC_VERSION_UNSUPPORTED; |
| 200 | case PROTOCOL_QUIC_CRYPTO: |
dschinazi | 4161684 | 2020-01-21 15:46:11 -0800 | [diff] [blame] | 201 | return transport_version != QUIC_VERSION_UNSUPPORTED && |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 202 | transport_version != QUIC_VERSION_51 && |
dschinazi | 40f0b3d | 2020-02-19 17:54:05 -0800 | [diff] [blame] | 203 | transport_version != QUIC_VERSION_IETF_DRAFT_25 && |
dschinazi | 2c78aac | 2020-05-21 17:21:58 -0700 | [diff] [blame] | 204 | transport_version != QUIC_VERSION_IETF_DRAFT_27 && |
dschinazi | b3fed9e | 2020-06-11 11:59:33 -0700 | [diff] [blame] | 205 | transport_version != QUIC_VERSION_IETF_DRAFT_29; |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 206 | case PROTOCOL_TLS1_3: |
dschinazi | a0b4d2e | 2020-03-16 16:22:08 -0700 | [diff] [blame] | 207 | return transport_version != QUIC_VERSION_UNSUPPORTED && |
dschinazi | ceed866 | 2020-07-14 09:37:05 -0700 | [diff] [blame] | 208 | QuicVersionUsesCryptoFrames(transport_version); |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 209 | } |
| 210 | return false; |
| 211 | } |
dschinazi | dc770fc | 2020-01-13 15:42:41 -0800 | [diff] [blame] | 212 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 213 | // A parsed QUIC version label which determines that handshake protocol |
| 214 | // and the transport version. |
| 215 | struct QUIC_EXPORT_PRIVATE ParsedQuicVersion { |
| 216 | HandshakeProtocol handshake_protocol; |
| 217 | QuicTransportVersion transport_version; |
| 218 | |
dschinazi | 3f6ccf4 | 2019-10-25 16:58:37 -0700 | [diff] [blame] | 219 | constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol, |
| 220 | QuicTransportVersion transport_version) |
| 221 | : handshake_protocol(handshake_protocol), |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 222 | transport_version(transport_version) { |
| 223 | DCHECK(ParsedQuicVersionIsValid(handshake_protocol, transport_version)) |
| 224 | << QuicVersionToString(transport_version) << " " |
| 225 | << HandshakeProtocolToString(handshake_protocol); |
| 226 | } |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 227 | |
dschinazi | 3f6ccf4 | 2019-10-25 16:58:37 -0700 | [diff] [blame] | 228 | constexpr ParsedQuicVersion(const ParsedQuicVersion& other) |
dschinazi | 97da52b | 2020-01-13 15:44:43 -0800 | [diff] [blame] | 229 | : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {} |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 230 | |
| 231 | ParsedQuicVersion& operator=(const ParsedQuicVersion& other) { |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 232 | DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol, |
| 233 | other.transport_version)) |
| 234 | << QuicVersionToString(other.transport_version) << " " |
| 235 | << HandshakeProtocolToString(other.handshake_protocol); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 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 | } |
zhongyi | 546cc45 | 2019-04-12 15:27:49 -0700 | [diff] [blame] | 252 | |
dschinazi | b3fed9e | 2020-06-11 11:59:33 -0700 | [diff] [blame] | 253 | static constexpr ParsedQuicVersion Draft29() { |
| 254 | return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29); |
| 255 | } |
| 256 | |
dschinazi | 2be3a02 | 2020-05-29 13:52:19 -0700 | [diff] [blame] | 257 | static constexpr ParsedQuicVersion Draft27() { |
| 258 | return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27); |
| 259 | } |
| 260 | |
| 261 | static constexpr ParsedQuicVersion Draft25() { |
| 262 | return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25); |
| 263 | } |
| 264 | |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 265 | static constexpr ParsedQuicVersion T051() { |
| 266 | return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_51); |
| 267 | } |
| 268 | |
dschinazi | 2be3a02 | 2020-05-29 13:52:19 -0700 | [diff] [blame] | 269 | static constexpr ParsedQuicVersion T050() { |
| 270 | return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50); |
| 271 | } |
| 272 | |
| 273 | static constexpr ParsedQuicVersion Q050() { |
| 274 | return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50); |
| 275 | } |
| 276 | |
dschinazi | 2be3a02 | 2020-05-29 13:52:19 -0700 | [diff] [blame] | 277 | static constexpr ParsedQuicVersion Q046() { |
| 278 | return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46); |
| 279 | } |
| 280 | |
| 281 | static constexpr ParsedQuicVersion Q043() { |
| 282 | return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43); |
| 283 | } |
| 284 | |
| 285 | static constexpr ParsedQuicVersion Unsupported() { |
| 286 | return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED); |
| 287 | } |
| 288 | |
| 289 | static constexpr ParsedQuicVersion ReservedForNegotiation() { |
| 290 | return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, |
| 291 | QUIC_VERSION_RESERVED_FOR_NEGOTIATION); |
| 292 | } |
| 293 | |
dschinazi | dc770fc | 2020-01-13 15:42:41 -0800 | [diff] [blame] | 294 | // Returns whether our codebase understands this version. This should only be |
| 295 | // called on valid versions, see ParsedQuicVersionIsValid. Assuming the |
| 296 | // version is valid, IsKnown returns whether the version is not |
| 297 | // UnsupportedQuicVersion. |
| 298 | bool IsKnown() const; |
| 299 | |
zhongyi | 546cc45 | 2019-04-12 15:27:49 -0700 | [diff] [blame] | 300 | bool KnowsWhichDecrypterToUse() const; |
dschinazi | c703612 | 2019-04-30 12:46:34 -0700 | [diff] [blame] | 301 | |
nharper | c8d9e40 | 2019-09-12 18:30:14 -0700 | [diff] [blame] | 302 | // Returns whether this version uses keys derived from the Connection ID for |
| 303 | // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter). |
| 304 | bool UsesInitialObfuscators() const; |
| 305 | |
dschinazi | c703612 | 2019-04-30 12:46:34 -0700 | [diff] [blame] | 306 | // Indicates that this QUIC version does not have an enforced minimum value |
| 307 | // for flow control values negotiated during the handshake. |
| 308 | bool AllowsLowFlowControlLimits() const; |
nharper | cfafed7 | 2019-05-01 13:43:55 -0700 | [diff] [blame] | 309 | |
| 310 | // Returns whether header protection is used in this version of QUIC. |
| 311 | bool HasHeaderProtection() const; |
dschinazi | 244f6dc | 2019-05-06 15:45:16 -0700 | [diff] [blame] | 312 | |
| 313 | // Returns whether this version supports IETF RETRY packets. |
| 314 | bool SupportsRetry() const; |
dschinazi | b417d60 | 2019-05-29 13:08:45 -0700 | [diff] [blame] | 315 | |
dschinazi | 278efae | 2020-01-28 17:03:09 -0800 | [diff] [blame] | 316 | // Returns whether RETRY packets carry the Retry Integrity Tag field. |
| 317 | bool HasRetryIntegrityTag() const; |
| 318 | |
fayang | 3ac15c1 | 2019-06-14 14:04:51 -0700 | [diff] [blame] | 319 | // Returns true if this version sends variable length packet number in long |
| 320 | // header. |
| 321 | bool SendsVariableLengthPacketNumberInLongHeader() const; |
| 322 | |
dschinazi | 97da52b | 2020-01-13 15:44:43 -0800 | [diff] [blame] | 323 | // Returns whether this version allows server connection ID lengths |
| 324 | // that are not 64 bits. |
| 325 | bool AllowsVariableLengthConnectionIds() const; |
| 326 | |
dschinazi | b417d60 | 2019-05-29 13:08:45 -0700 | [diff] [blame] | 327 | // Returns whether this version supports client connection ID. |
| 328 | bool SupportsClientConnectionIds() const; |
dschinazi | 48ac919 | 2019-07-31 00:07:26 -0700 | [diff] [blame] | 329 | |
| 330 | // Returns whether this version supports long header 8-bit encoded |
| 331 | // connection ID lengths as described in draft-ietf-quic-invariants-06 and |
| 332 | // draft-ietf-quic-transport-22. |
| 333 | bool HasLengthPrefixedConnectionIds() const; |
fayang | 5f13505 | 2019-08-22 17:59:40 -0700 | [diff] [blame] | 334 | |
| 335 | // Returns whether this version supports IETF style anti-amplification limit, |
| 336 | // i.e., server will send no more than FLAGS_quic_anti_amplification_factor |
| 337 | // times received bytes until address can be validated. |
| 338 | bool SupportsAntiAmplificationLimit() const; |
fayang | 58f7107 | 2019-11-05 08:47:02 -0800 | [diff] [blame] | 339 | |
| 340 | // Returns true if this version can send coalesced packets. |
| 341 | bool CanSendCoalescedPackets() const; |
dschinazi | 97da52b | 2020-01-13 15:44:43 -0800 | [diff] [blame] | 342 | |
| 343 | // Returns true if this version supports the old Google-style Alt-Svc |
| 344 | // advertisement format. |
| 345 | bool SupportsGoogleAltSvcFormat() const; |
| 346 | |
| 347 | // Returns true if |transport_version| uses IETF invariant headers. |
| 348 | bool HasIetfInvariantHeader() const; |
| 349 | |
| 350 | // Returns true if |transport_version| supports MESSAGE frames. |
| 351 | bool SupportsMessageFrames() const; |
| 352 | |
| 353 | // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer. |
| 354 | // Notable changes are: |
| 355 | // * Headers stream no longer exists. |
| 356 | // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream. |
| 357 | // * PUSH_PROMISE is moved to request stream. |
| 358 | // * Unidirectional streams will have their first byte as a stream type. |
| 359 | // * HEADERS frames are compressed using QPACK. |
| 360 | // * DATA frame has frame headers. |
| 361 | // * GOAWAY is moved to HTTP layer. |
| 362 | bool UsesHttp3() const; |
| 363 | |
| 364 | // Returns whether the transport_version supports the variable length integer |
| 365 | // length field as defined by IETF QUIC draft-13 and later. |
| 366 | bool HasLongHeaderLengths() const; |
| 367 | |
| 368 | // Returns whether |transport_version| uses CRYPTO frames for the handshake |
| 369 | // instead of stream 1. |
| 370 | bool UsesCryptoFrames() const; |
| 371 | |
| 372 | // Returns whether |transport_version| makes use of IETF QUIC |
| 373 | // frames or not. |
| 374 | bool HasIetfQuicFrames() const; |
fayang | 0106294 | 2020-01-22 07:23:23 -0800 | [diff] [blame] | 375 | |
| 376 | // Returns true if this parsed version supports handshake done. |
| 377 | bool HasHandshakeDone() const; |
dschinazi | 7b8f0c7 | 2020-03-02 13:17:57 -0800 | [diff] [blame] | 378 | |
| 379 | // Returns true if this version uses variable-length integers when |
| 380 | // encoding transport parameter types and lengths. |
| 381 | bool HasVarIntTransportParams() const; |
dschinazi | 6750749 | 2020-04-24 12:10:39 -0700 | [diff] [blame] | 382 | |
dschinazi | 2c78aac | 2020-05-21 17:21:58 -0700 | [diff] [blame] | 383 | // Returns true if this version uses transport parameters to authenticate all |
| 384 | // the connection IDs used during the handshake. |
| 385 | bool AuthenticatesHandshakeConnectionIds() const; |
| 386 | |
dschinazi | 6750749 | 2020-04-24 12:10:39 -0700 | [diff] [blame] | 387 | // Returns whether this version uses PROTOCOL_TLS1_3. |
| 388 | bool UsesTls() const; |
| 389 | |
| 390 | // Returns whether this version uses PROTOCOL_QUIC_CRYPTO. |
| 391 | bool UsesQuicCrypto() const; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 392 | }; |
| 393 | |
| 394 | QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion(); |
| 395 | |
dschinazi | 5a354c9 | 2019-05-09 12:18:53 -0700 | [diff] [blame] | 396 | QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation(); |
| 397 | |
dschinazi | 6458eb3 | 2020-06-23 12:38:41 -0700 | [diff] [blame] | 398 | // Outer version used when encapsulating other packets using the Legacy Version |
| 399 | // Encapsulation feature. |
| 400 | QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation(); |
| 401 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 402 | QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| 403 | const ParsedQuicVersion& version); |
| 404 | |
| 405 | using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>; |
| 406 | |
dschinazi | 1ac7f01 | 2020-04-06 13:08:56 -0700 | [diff] [blame] | 407 | QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| 408 | std::ostream& os, |
| 409 | const ParsedQuicVersionVector& versions); |
| 410 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 411 | // Representation of the on-the-wire QUIC version number. Will be written/read |
| 412 | // to the wire in network-byte-order. |
| 413 | using QuicVersionLabel = uint32_t; |
| 414 | using QuicVersionLabelVector = std::vector<QuicVersionLabel>; |
| 415 | |
dschinazi | 1ac7f01 | 2020-04-06 13:08:56 -0700 | [diff] [blame] | 416 | QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| 417 | std::ostream& os, |
| 418 | const QuicVersionLabelVector& version_labels); |
| 419 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 420 | // This vector contains all crypto handshake protocols that are supported. |
vasilvv | 228602e | 2020-02-06 01:11:49 -0800 | [diff] [blame] | 421 | constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() { |
dschinazi | 0a9c20d | 2020-04-07 14:04:55 -0700 | [diff] [blame] | 422 | return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO}; |
vasilvv | 228602e | 2020-02-06 01:11:49 -0800 | [diff] [blame] | 423 | } |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 424 | |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 425 | constexpr std::array<ParsedQuicVersion, 8> SupportedVersions() { |
dschinazi | c4c0e39 | 2020-03-16 11:22:09 -0700 | [diff] [blame] | 426 | return { |
dschinazi | 6ab4524 | 2020-06-23 00:20:37 -0700 | [diff] [blame] | 427 | ParsedQuicVersion::Draft29(), ParsedQuicVersion::Draft27(), |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 428 | ParsedQuicVersion::Draft25(), ParsedQuicVersion::T051(), |
| 429 | ParsedQuicVersion::T050(), ParsedQuicVersion::Q050(), |
| 430 | ParsedQuicVersion::Q046(), ParsedQuicVersion::Q043(), |
dschinazi | c4c0e39 | 2020-03-16 11:22:09 -0700 | [diff] [blame] | 431 | }; |
vasilvv | 228602e | 2020-02-06 01:11:49 -0800 | [diff] [blame] | 432 | } |
nharper | 2891b2d | 2020-01-14 16:46:07 -0800 | [diff] [blame] | 433 | |
vasilvv | 228602e | 2020-02-06 01:11:49 -0800 | [diff] [blame] | 434 | using QuicTransportVersionVector = std::vector<QuicTransportVersion>; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 435 | |
dschinazi | 1ac7f01 | 2020-04-06 13:08:56 -0700 | [diff] [blame] | 436 | QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| 437 | std::ostream& os, |
| 438 | const QuicTransportVersionVector& transport_versions); |
| 439 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 440 | // Returns a vector of QUIC versions in kSupportedTransportVersions. |
| 441 | QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions(); |
| 442 | |
| 443 | // Returns a vector of QUIC versions that is the cartesian product of |
| 444 | // kSupportedTransportVersions and kSupportedHandshakeProtocols. |
| 445 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions(); |
| 446 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 447 | // Returns a vector of QUIC versions that is the cartesian product of |
| 448 | // kSupportedTransportVersions and kSupportedHandshakeProtocols, with any |
| 449 | // versions disabled by flags excluded. |
| 450 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions(); |
| 451 | |
| 452 | // Returns a vector of QUIC versions from |versions| which exclude any versions |
| 453 | // which are disabled by flags. |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 454 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| 455 | FilterSupportedVersions(ParsedQuicVersionVector versions); |
| 456 | |
bnc | 36b7a03 | 2020-03-04 10:27:23 -0800 | [diff] [blame] | 457 | // Returns a subset of AllSupportedVersions() with |
| 458 | // handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order. |
| 459 | // Deprecated; only to be used in components that do not yet support |
| 460 | // PROTOCOL_TLS1_3. |
dschinazi | 7544877 | 2020-03-05 05:09:55 -0800 | [diff] [blame] | 461 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| 462 | AllSupportedVersionsWithQuicCrypto(); |
bnc | 36b7a03 | 2020-03-04 10:27:23 -0800 | [diff] [blame] | 463 | |
| 464 | // Returns a subset of CurrentSupportedVersions() with |
| 465 | // handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order. |
dschinazi | 7544877 | 2020-03-05 05:09:55 -0800 | [diff] [blame] | 466 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| 467 | CurrentSupportedVersionsWithQuicCrypto(); |
bnc | 36b7a03 | 2020-03-04 10:27:23 -0800 | [diff] [blame] | 468 | |
dschinazi | 8c628f2 | 2020-04-09 16:40:11 -0700 | [diff] [blame] | 469 | // Returns a subset of AllSupportedVersions() with |
| 470 | // handshake_protocol == PROTOCOL_TLS1_3, in the same order. |
| 471 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls(); |
| 472 | |
fayang | 3b3e301 | 2020-03-26 10:31:13 -0700 | [diff] [blame] | 473 | // Returns a subset of CurrentSupportedVersions() with handshake_protocol == |
| 474 | // PROTOCOL_TLS1_3. |
| 475 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls(); |
| 476 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 477 | // Returns QUIC version of |index| in result of |versions|. Returns |
| 478 | // QUIC_VERSION_UNSUPPORTED if |index| is out of bounds. |
| 479 | QUIC_EXPORT_PRIVATE QuicTransportVersionVector |
| 480 | VersionOfIndex(const QuicTransportVersionVector& versions, int index); |
| 481 | |
| 482 | // Returns QUIC version of |index| in result of |versions|. Returns |
| 483 | // UnsupportedQuicVersion() if |index| is out of bounds. |
| 484 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| 485 | ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index); |
| 486 | |
| 487 | // Returns a vector of QuicTransportVersions corresponding to just the transport |
| 488 | // versions in |versions|. If the input vector contains multiple parsed versions |
| 489 | // with different handshake protocols (but the same transport version), that |
| 490 | // transport version will appear in the resulting vector multiple times. |
| 491 | QUIC_EXPORT_PRIVATE QuicTransportVersionVector |
| 492 | ParsedVersionsToTransportVersions(const ParsedQuicVersionVector& versions); |
| 493 | |
| 494 | // QuicVersionLabel is written to and read from the wire, but we prefer to use |
| 495 | // the more readable ParsedQuicVersion at other levels. |
| 496 | // Helper function which translates from a QuicVersionLabel to a |
| 497 | // ParsedQuicVersion. |
| 498 | QUIC_EXPORT_PRIVATE ParsedQuicVersion |
| 499 | ParseQuicVersionLabel(QuicVersionLabel version_label); |
| 500 | |
dschinazi | cee73cd | 2020-03-05 18:20:50 -0800 | [diff] [blame] | 501 | // Parses a QUIC version string such as "Q043" or "T050". Also supports parsing |
| 502 | // ALPN such as "h3-25" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also |
| 503 | // supports parsing numbers such as "46". |
dschinazi | 8ae6001 | 2019-04-04 18:07:27 -0700 | [diff] [blame] | 504 | QUIC_EXPORT_PRIVATE ParsedQuicVersion |
dschinazi | cee73cd | 2020-03-05 18:20:50 -0800 | [diff] [blame] | 505 | ParseQuicVersionString(quiche::QuicheStringPiece version_string); |
| 506 | |
| 507 | // Parses a comma-separated list of QUIC version strings. Supports parsing by |
| 508 | // label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions. |
| 509 | // For example: "h3-25,Q050,46". |
| 510 | QUIC_EXPORT_PRIVATE ParsedQuicVersionVector |
| 511 | ParseQuicVersionVectorString(quiche::QuicheStringPiece versions_string); |
dschinazi | 8ae6001 | 2019-04-04 18:07:27 -0700 | [diff] [blame] | 512 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 513 | // Constructs a QuicVersionLabel from the provided ParsedQuicVersion. |
| 514 | QUIC_EXPORT_PRIVATE QuicVersionLabel |
| 515 | CreateQuicVersionLabel(ParsedQuicVersion parsed_version); |
| 516 | |
| 517 | // Constructs a QuicVersionLabelVector from the provided |
| 518 | // ParsedQuicVersionVector. |
| 519 | QUIC_EXPORT_PRIVATE QuicVersionLabelVector |
| 520 | CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions); |
| 521 | |
| 522 | // QuicVersionLabel is written to and read from the wire, but we prefer to use |
| 523 | // the more readable QuicTransportVersion at other levels. |
| 524 | // Helper function which translates from a QuicTransportVersion to a |
| 525 | // QuicVersionLabel. Returns 0 if |version| is unsupported. |
| 526 | QUIC_EXPORT_PRIVATE QuicVersionLabel |
| 527 | QuicVersionToQuicVersionLabel(QuicTransportVersion transport_version); |
| 528 | |
| 529 | // Helper function which translates from a QuicVersionLabel to a string. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 530 | QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString( |
| 531 | QuicVersionLabel version_label); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 532 | |
| 533 | // Returns |separator|-separated list of string representations of |
| 534 | // QuicVersionLabel values in the supplied |version_labels| vector. The values |
| 535 | // after the (0-based) |skip_after_nth_version|'th are skipped. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 536 | QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString( |
| 537 | const QuicVersionLabelVector& version_labels, |
| 538 | const std::string& separator, |
| 539 | size_t skip_after_nth_version); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 540 | |
| 541 | // Returns comma separated list of string representations of QuicVersionLabel |
| 542 | // values in the supplied |version_labels| vector. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 543 | QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString( |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 544 | const QuicVersionLabelVector& version_labels) { |
| 545 | return QuicVersionLabelVectorToString(version_labels, ",", |
| 546 | std::numeric_limits<size_t>::max()); |
| 547 | } |
| 548 | |
| 549 | // Returns appropriate QuicTransportVersion from a QuicVersionLabel. |
| 550 | // Returns QUIC_VERSION_UNSUPPORTED if |version_label| cannot be understood. |
| 551 | QUIC_EXPORT_PRIVATE QuicTransportVersion |
| 552 | QuicVersionLabelToQuicVersion(QuicVersionLabel version_label); |
| 553 | |
| 554 | // Returns the HandshakeProtocol used with the given |version_label|, returning |
| 555 | // PROTOCOL_UNSUPPORTED if it is unknown. |
| 556 | QUIC_EXPORT_PRIVATE HandshakeProtocol |
| 557 | QuicVersionLabelToHandshakeProtocol(QuicVersionLabel version_label); |
| 558 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 559 | // Helper function which translates from a ParsedQuicVersion to a string. |
| 560 | // Returns strings corresponding to the on-the-wire tag. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 561 | QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString( |
| 562 | ParsedQuicVersion version); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 563 | |
| 564 | // Returns comma separated list of string representations of |
| 565 | // QuicTransportVersion enum values in the supplied |versions| vector. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 566 | QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString( |
| 567 | const QuicTransportVersionVector& versions); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 568 | |
| 569 | // Returns comma separated list of string representations of ParsedQuicVersion |
| 570 | // values in the supplied |versions| vector. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 571 | QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString( |
| 572 | const ParsedQuicVersionVector& versions); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 573 | |
| 574 | // Returns |separator|-separated list of string representations of |
| 575 | // ParsedQuicVersion values in the supplied |versions| vector. The values after |
| 576 | // the (0-based) |skip_after_nth_version|'th are skipped. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 577 | QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString( |
| 578 | const ParsedQuicVersionVector& versions, |
| 579 | const std::string& separator, |
| 580 | size_t skip_after_nth_version); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 581 | |
| 582 | // Returns comma separated list of string representations of ParsedQuicVersion |
| 583 | // values in the supplied |versions| vector. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 584 | QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString( |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 585 | const ParsedQuicVersionVector& versions) { |
| 586 | return ParsedQuicVersionVectorToString(versions, ",", |
| 587 | std::numeric_limits<size_t>::max()); |
| 588 | } |
| 589 | |
fayang | d4291e4 | 2019-05-30 10:31:21 -0700 | [diff] [blame] | 590 | // Returns true if |transport_version| uses IETF invariant headers. |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 591 | QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader( |
fayang | d4291e4 | 2019-05-30 10:31:21 -0700 | [diff] [blame] | 592 | QuicTransportVersion transport_version) { |
| 593 | return transport_version > QUIC_VERSION_43; |
| 594 | } |
| 595 | |
| 596 | // Returns true if |transport_version| supports MESSAGE frames. |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 597 | QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames( |
fayang | d4291e4 | 2019-05-30 10:31:21 -0700 | [diff] [blame] | 598 | QuicTransportVersion transport_version) { |
dschinazi | ceed866 | 2020-07-14 09:37:05 -0700 | [diff] [blame] | 599 | // MESSAGE frames were added in version 45. |
| 600 | return transport_version > QUIC_VERSION_43; |
fayang | d4291e4 | 2019-05-30 10:31:21 -0700 | [diff] [blame] | 601 | } |
| 602 | |
renjietang | a29a96a | 2019-10-10 12:47:50 -0700 | [diff] [blame] | 603 | // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer. |
| 604 | // Notable changes are: |
| 605 | // * Headers stream no longer exists. |
| 606 | // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream. |
| 607 | // * PUSH_PROMISE is moved to request stream. |
| 608 | // * Unidirectional streams will have their first byte as a stream type. |
| 609 | // * HEADERS frames are compressed using QPACK. |
| 610 | // * DATA frame has frame headers. |
| 611 | // * GOAWAY is moved to HTTP layer. |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 612 | QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3( |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 613 | QuicTransportVersion transport_version) { |
dschinazi | 4769220 | 2020-07-30 11:09:42 -0700 | [diff] [blame] | 614 | return transport_version > QUIC_VERSION_51; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 615 | } |
| 616 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 617 | // Returns whether the transport_version supports the variable length integer |
| 618 | // length field as defined by IETF QUIC draft-13 and later. |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 619 | QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths( |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 620 | QuicTransportVersion transport_version) { |
dschinazi | ceed866 | 2020-07-14 09:37:05 -0700 | [diff] [blame] | 621 | // Long header lengths were added in version 49. |
| 622 | return transport_version > QUIC_VERSION_46; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 623 | } |
| 624 | |
fkastenholz | 305e173 | 2019-06-18 05:01:22 -0700 | [diff] [blame] | 625 | // Returns whether |transport_version| makes use of IETF QUIC |
| 626 | // frames or not. |
dschinazi | 0da4390 | 2020-01-17 15:26:14 -0800 | [diff] [blame] | 627 | QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames( |
fkastenholz | 305e173 | 2019-06-18 05:01:22 -0700 | [diff] [blame] | 628 | QuicTransportVersion transport_version) { |
dschinazi | ceed866 | 2020-07-14 09:37:05 -0700 | [diff] [blame] | 629 | return VersionUsesHttp3(transport_version); |
fkastenholz | 305e173 | 2019-06-18 05:01:22 -0700 | [diff] [blame] | 630 | } |
| 631 | |
dschinazi | 48ac919 | 2019-07-31 00:07:26 -0700 | [diff] [blame] | 632 | // Returns whether this version supports long header 8-bit encoded |
| 633 | // connection ID lengths as described in draft-ietf-quic-invariants-06 and |
| 634 | // draft-ietf-quic-transport-22. |
| 635 | QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds( |
| 636 | QuicTransportVersion transport_version); |
| 637 | |
rch | eb78dbb | 2019-10-26 08:37:15 -0700 | [diff] [blame] | 638 | // Returns true if this version supports the old Google-style Alt-Svc |
| 639 | // advertisement format. |
| 640 | QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat( |
| 641 | QuicTransportVersion transport_version); |
| 642 | |
dschinazi | 97da52b | 2020-01-13 15:44:43 -0800 | [diff] [blame] | 643 | // Returns whether this version allows server connection ID lengths that are |
| 644 | // not 64 bits. |
| 645 | QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds( |
| 646 | QuicTransportVersion transport_version); |
| 647 | |
dschinazi | 48ac919 | 2019-07-31 00:07:26 -0700 | [diff] [blame] | 648 | // Returns whether this version label supports long header 4-bit encoded |
| 649 | // connection ID lengths as described in draft-ietf-quic-invariants-05 and |
| 650 | // draft-ietf-quic-transport-21. |
| 651 | QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength( |
| 652 | QuicVersionLabel version_label); |
| 653 | |
dschinazi | 35e749e | 2019-04-09 09:36:04 -0700 | [diff] [blame] | 654 | // Returns the ALPN string to use in TLS for this version of QUIC. |
| 655 | QUIC_EXPORT_PRIVATE std::string AlpnForVersion( |
| 656 | ParsedQuicVersion parsed_version); |
| 657 | |
rch | a702be2 | 2019-08-30 15:20:12 -0700 | [diff] [blame] | 658 | // Initializes support for the provided IETF draft version by setting the |
| 659 | // correct flags. |
| 660 | QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft(); |
dschinazi | 8ae6001 | 2019-04-04 18:07:27 -0700 | [diff] [blame] | 661 | |
dschinazi | 5a50d93 | 2020-06-17 12:43:36 -0700 | [diff] [blame] | 662 | // Configures the flags required to enable support for this version of QUIC. |
| 663 | QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version); |
| 664 | |
| 665 | // Configures the flags required to disable support for this version of QUIC. |
| 666 | QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version); |
| 667 | |
| 668 | // Returns whether support for this version of QUIC is currently enabled. |
| 669 | QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version); |
dschinazi | 8ae6001 | 2019-04-04 18:07:27 -0700 | [diff] [blame] | 670 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 671 | } // namespace quic |
| 672 | |
| 673 | #endif // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_ |