blob: b23ae086731d8084fbe9d0c6a7f11c155cc6e25c [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Definitions and utility functions related to handling of QUIC versions.
6//
7// QUIC version is a four-byte tag that can be represented in memory as a
8// QuicVersionLabel type (which is an alias to uint32_t). In actuality, all
9// versions supported by this implementation have the following format:
10// [QT]0\d\d
11// e.g. Q046. Q or T distinguishes the type of handshake used (Q for QUIC
12// Crypto handshake, T for TLS-based handshake), and the two digits at the end
13// is the actual numeric value of transport version used by the code.
14
15#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
16#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
17
vasilvv872e7a32019-03-12 16:42:44 -070018#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050019#include <vector>
20
21#include "net/third_party/quiche/src/quic/core/quic_tag.h"
22#include "net/third_party/quiche/src/quic/core/quic_types.h"
23#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050024
25namespace quic {
26
27// The available versions of QUIC. The numeric value of the enum is guaranteed
28// to match the number in the name. The versions not currently supported are
29// documented in comments.
30//
31// See go/new-quic-version for more details on how to roll out new versions.
32enum QuicTransportVersion {
33 // Special case to indicate unknown/unsupported QUIC version.
34 QUIC_VERSION_UNSUPPORTED = 0,
35
36 // Version 1 was the first version of QUIC that supported versioning.
37 // Version 2 decoupled versioning of non-cryptographic parameters from the
38 // SCFG.
39 // Version 3 moved public flags into the beginning of the packet.
40 // Version 4 added support for variable-length connection IDs.
41 // Version 5 made specifying FEC groups optional.
42 // Version 6 introduced variable-length packet numbers.
43 // Version 7 introduced a lower-overhead encoding for stream frames.
44 // Version 8 made salt length equal to digest length for the RSA-PSS
45 // signatures.
46 // Version 9 added stream priority.
47 // Version 10 redid the frame type numbering.
48 // Version 11 reduced the length of null encryption authentication tag
49 // from 16 to 12 bytes.
50 // Version 12 made the sequence numbers in the ACK frames variable-sized.
51 // Version 13 added the dedicated header stream.
52 // Version 14 added byte_offset to RST_STREAM frame.
53 // Version 15 added a list of packets recovered using FEC to the ACK frame.
54 // Version 16 added STOP_WAITING frame.
55 // Version 17 added per-stream flow control.
56 // Version 18 added PING frame.
57 // Version 19 added connection-level flow control
58 // Version 20 allowed to set stream- and connection-level flow control windows
59 // to different values.
60 // Version 21 made header and crypto streams flow-controlled.
61 // Version 22 added support for SCUP (server config update) messages.
62 // Version 23 added timestamps into the ACK frame.
63 // Version 24 added SPDY/4 header compression.
64 // Version 25 added support for SPDY/4 header keys and removed error_details
65 // from RST_STREAM frame.
66 // Version 26 added XLCT (expected leaf certificate) tag into CHLO.
67 // Version 27 added a nonce into SHLO.
68 // Version 28 allowed receiver to refuse creating a requested stream.
69 // Version 29 added support for QUIC_STREAM_NO_ERROR.
70 // Version 30 added server-side support for certificate transparency.
71 // Version 31 incorporated the hash of CHLO into the crypto proof supplied by
72 // the server.
73 // Version 32 removed FEC-related fields from wire format.
74 // Version 33 added diversification nonces.
75 // Version 34 removed entropy bits from packets and ACK frames, removed
76 // private flag from packet header and changed the ACK format to
77 // specify ranges of packets acknowledged rather than missing
78 // ranges.
79 // Version 35 allows endpoints to independently set stream limit.
80 // Version 36 added support for forced head-of-line blocking experiments.
81 // Version 37 added perspective into null encryption.
82 // Version 38 switched to IETF padding frame format and support for NSTP (no
83 // stop waiting frame) connection option.
84
85 QUIC_VERSION_39 = 39, // Integers and floating numbers are written in big
86 // endian. Dot not ack acks. Send a connection level
87 // WINDOW_UPDATE every 20 sent packets which do not
88 // contain retransmittable frames.
89
90 // Version 40 was an attempt to convert QUIC to IETF frame format; it was
91 // never shipped due to a bug.
92 // Version 41 was a bugfix for version 40. The working group changed the wire
93 // format before it shipped, which caused it to be never shipped
94 // and all the changes from it to be reverted. No changes from v40
95 // or v41 are present in subsequent versions.
96 // Version 42 allowed receiving overlapping stream data.
97
98 QUIC_VERSION_43 = 43, // PRIORITY frames are sent by client and accepted by
99 // server.
100 QUIC_VERSION_44 = 44, // Use IETF header format.
101
102 // Version 45 added MESSAGE frame.
103
104 QUIC_VERSION_46 = 46, // Use IETF draft-17 header format with demultiplexing
105 // bit.
QUICHE team9b41c972019-03-21 11:22:48 -0700106 QUIC_VERSION_47 = 47, // Allow variable-length QUIC connection IDs.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500107 QUIC_VERSION_99 = 99, // Dumping ground for IETF QUIC changes which are not
108 // yet ready for production.
109};
110
111// The crypto handshake protocols that can be used with QUIC.
112enum HandshakeProtocol {
113 PROTOCOL_UNSUPPORTED,
114 PROTOCOL_QUIC_CRYPTO,
115 PROTOCOL_TLS1_3,
116};
117
118// A parsed QUIC version label which determines that handshake protocol
119// and the transport version.
120struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
121 HandshakeProtocol handshake_protocol;
122 QuicTransportVersion transport_version;
123
124 ParsedQuicVersion(HandshakeProtocol handshake_protocol,
125 QuicTransportVersion transport_version);
126
127 ParsedQuicVersion(const ParsedQuicVersion& other)
128 : handshake_protocol(other.handshake_protocol),
129 transport_version(other.transport_version) {}
130
131 ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
132 if (this != &other) {
133 handshake_protocol = other.handshake_protocol;
134 transport_version = other.transport_version;
135 }
136 return *this;
137 }
138
139 bool operator==(const ParsedQuicVersion& other) const {
140 return handshake_protocol == other.handshake_protocol &&
141 transport_version == other.transport_version;
142 }
143
144 bool operator!=(const ParsedQuicVersion& other) const {
145 return handshake_protocol != other.handshake_protocol ||
146 transport_version != other.transport_version;
147 }
148};
149
150QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
151
152QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
153 const ParsedQuicVersion& version);
154
155using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
156
157// Representation of the on-the-wire QUIC version number. Will be written/read
158// to the wire in network-byte-order.
159using QuicVersionLabel = uint32_t;
160using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
161
162// This vector contains QUIC versions which we currently support.
163// This should be ordered such that the highest supported version is the first
164// element, with subsequent elements in descending order (versions can be
165// skipped as necessary).
166//
167// See go/new-quic-version for more details on how to roll out new versions.
168static const QuicTransportVersion kSupportedTransportVersions[] = {
169 QUIC_VERSION_99, QUIC_VERSION_47, QUIC_VERSION_46,
170 QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_39,
171};
172
173// This vector contains all crypto handshake protocols that are supported.
174static const HandshakeProtocol kSupportedHandshakeProtocols[] = {
175 PROTOCOL_QUIC_CRYPTO, PROTOCOL_TLS1_3};
176
177typedef std::vector<QuicTransportVersion> QuicTransportVersionVector;
178
179// Returns a vector of QUIC versions in kSupportedTransportVersions.
180QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
181
182// Returns a vector of QUIC versions that is the cartesian product of
183// kSupportedTransportVersions and kSupportedHandshakeProtocols.
184QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
185
186// Returns a vector of QUIC versions from kSupportedTransportVersions which
187// exclude any versions which are disabled by flags.
188QUIC_EXPORT_PRIVATE QuicTransportVersionVector
189CurrentSupportedTransportVersions();
190
191// Returns a vector of QUIC versions that is the cartesian product of
192// kSupportedTransportVersions and kSupportedHandshakeProtocols, with any
193// versions disabled by flags excluded.
194QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();
195
196// Returns a vector of QUIC versions from |versions| which exclude any versions
197// which are disabled by flags.
198QUIC_EXPORT_PRIVATE QuicTransportVersionVector
199FilterSupportedTransportVersions(QuicTransportVersionVector versions);
200
201// Returns a vector of QUIC versions from |versions| which exclude any versions
202// which are disabled by flags.
203QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
204FilterSupportedVersions(ParsedQuicVersionVector versions);
205
206// Returns QUIC version of |index| in result of |versions|. Returns
207// QUIC_VERSION_UNSUPPORTED if |index| is out of bounds.
208QUIC_EXPORT_PRIVATE QuicTransportVersionVector
209VersionOfIndex(const QuicTransportVersionVector& versions, int index);
210
211// Returns QUIC version of |index| in result of |versions|. Returns
212// UnsupportedQuicVersion() if |index| is out of bounds.
213QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
214ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
215
216// Returns a vector of QuicTransportVersions corresponding to just the transport
217// versions in |versions|. If the input vector contains multiple parsed versions
218// with different handshake protocols (but the same transport version), that
219// transport version will appear in the resulting vector multiple times.
220QUIC_EXPORT_PRIVATE QuicTransportVersionVector
221ParsedVersionsToTransportVersions(const ParsedQuicVersionVector& versions);
222
223// QuicVersionLabel is written to and read from the wire, but we prefer to use
224// the more readable ParsedQuicVersion at other levels.
225// Helper function which translates from a QuicVersionLabel to a
226// ParsedQuicVersion.
227QUIC_EXPORT_PRIVATE ParsedQuicVersion
228ParseQuicVersionLabel(QuicVersionLabel version_label);
229
230// Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
231QUIC_EXPORT_PRIVATE QuicVersionLabel
232CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
233
234// Constructs a QuicVersionLabelVector from the provided
235// ParsedQuicVersionVector.
236QUIC_EXPORT_PRIVATE QuicVersionLabelVector
237CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
238
239// QuicVersionLabel is written to and read from the wire, but we prefer to use
240// the more readable QuicTransportVersion at other levels.
241// Helper function which translates from a QuicTransportVersion to a
242// QuicVersionLabel. Returns 0 if |version| is unsupported.
243QUIC_EXPORT_PRIVATE QuicVersionLabel
244QuicVersionToQuicVersionLabel(QuicTransportVersion transport_version);
245
246// Helper function which translates from a QuicVersionLabel to a string.
vasilvvc48c8712019-03-11 13:38:16 -0700247QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
248 QuicVersionLabel version_label);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500249
250// Returns |separator|-separated list of string representations of
251// QuicVersionLabel values in the supplied |version_labels| vector. The values
252// after the (0-based) |skip_after_nth_version|'th are skipped.
vasilvvc48c8712019-03-11 13:38:16 -0700253QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
254 const QuicVersionLabelVector& version_labels,
255 const std::string& separator,
256 size_t skip_after_nth_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500257
258// Returns comma separated list of string representations of QuicVersionLabel
259// values in the supplied |version_labels| vector.
vasilvvc48c8712019-03-11 13:38:16 -0700260QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500261 const QuicVersionLabelVector& version_labels) {
262 return QuicVersionLabelVectorToString(version_labels, ",",
263 std::numeric_limits<size_t>::max());
264}
265
266// Returns appropriate QuicTransportVersion from a QuicVersionLabel.
267// Returns QUIC_VERSION_UNSUPPORTED if |version_label| cannot be understood.
268QUIC_EXPORT_PRIVATE QuicTransportVersion
269QuicVersionLabelToQuicVersion(QuicVersionLabel version_label);
270
271// Returns the HandshakeProtocol used with the given |version_label|, returning
272// PROTOCOL_UNSUPPORTED if it is unknown.
273QUIC_EXPORT_PRIVATE HandshakeProtocol
274QuicVersionLabelToHandshakeProtocol(QuicVersionLabel version_label);
275
276// Helper function which translates from a QuicTransportVersion to a string.
277// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
vasilvvc48c8712019-03-11 13:38:16 -0700278QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
279 QuicTransportVersion transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500280
281// Helper function which translates from a ParsedQuicVersion to a string.
282// Returns strings corresponding to the on-the-wire tag.
vasilvvc48c8712019-03-11 13:38:16 -0700283QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
284 ParsedQuicVersion version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500285
286// Returns comma separated list of string representations of
287// QuicTransportVersion enum values in the supplied |versions| vector.
vasilvvc48c8712019-03-11 13:38:16 -0700288QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
289 const QuicTransportVersionVector& versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500290
291// Returns comma separated list of string representations of ParsedQuicVersion
292// values in the supplied |versions| vector.
vasilvvc48c8712019-03-11 13:38:16 -0700293QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
294 const ParsedQuicVersionVector& versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500295
296// Returns |separator|-separated list of string representations of
297// ParsedQuicVersion values in the supplied |versions| vector. The values after
298// the (0-based) |skip_after_nth_version|'th are skipped.
vasilvvc48c8712019-03-11 13:38:16 -0700299QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
300 const ParsedQuicVersionVector& versions,
301 const std::string& separator,
302 size_t skip_after_nth_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500303
304// Returns comma separated list of string representations of ParsedQuicVersion
305// values in the supplied |versions| vector.
vasilvvc48c8712019-03-11 13:38:16 -0700306QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500307 const ParsedQuicVersionVector& versions) {
308 return ParsedQuicVersionVectorToString(versions, ",",
309 std::numeric_limits<size_t>::max());
310}
311
312// Returns true if QuicSpdyStream encodes body using HTTP/3 specification and
313// sends data frame header along with body.
314QUIC_EXPORT_PRIVATE inline bool VersionHasDataFrameHeader(
315 QuicTransportVersion transport_version) {
316 return transport_version == QUIC_VERSION_99;
317}
318
319// Returns true if QuicSpdySession instantiates a QPACK encoder and decoder.
320// TODO(123528590): Implement the following features and gate them on this
321// function as well, optionally renaming this function as appropriate.
322// Send HEADERS on the request/response stream instead of the headers stream.
323// Send PUSH_PROMISE on the request/response stream instead of headers stream.
324// Send PRIORITY on the request/response stream instead of the headers stream.
325// Do not instantiate the headers stream object.
326QUIC_EXPORT_PRIVATE inline bool VersionUsesQpack(
327 QuicTransportVersion transport_version) {
328 const bool uses_qpack = (transport_version == QUIC_VERSION_99);
329 if (uses_qpack) {
330 DCHECK(VersionHasDataFrameHeader(transport_version));
331 }
332 return uses_qpack;
333}
334
335// Returns whether the transport_version supports the variable length integer
336// length field as defined by IETF QUIC draft-13 and later.
337QUIC_EXPORT_PRIVATE inline bool QuicVersionHasLongHeaderLengths(
338 QuicTransportVersion transport_version) {
339 // TODO(dschinazi) if we enable long header lengths before v99, we need to
340 // add support for fixing up lengths in QuicFramer::BuildDataPacket.
341 return transport_version == QUIC_VERSION_99;
342}
343
QUICHE teamea740082019-03-11 17:58:43 -0700344// Returns whether |transport_version| uses CRYPTO frames for the handshake
345// instead of stream 1.
346QUIC_EXPORT_PRIVATE inline bool QuicVersionUsesCryptoFrames(
347 QuicTransportVersion transport_version) {
QUICHE team9b41c972019-03-21 11:22:48 -0700348 return transport_version == QUIC_VERSION_99;
QUICHE teamea740082019-03-11 17:58:43 -0700349}
350
QUICHE teama6ef0a62019-03-07 20:34:33 -0500351} // namespace quic
352
353#endif // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_