Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
new file mode 100644
index 0000000..c0fa34a
--- /dev/null
+++ b/quic/core/quic_versions.h
@@ -0,0 +1,346 @@
+// 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 version is a four-byte tag that can be represented in memory as a
+// QuicVersionLabel type (which is an alias to uint32_t).  In actuality, all
+// versions supported by this implementation have the following format:
+//   [QT]0\d\d
+// e.g. Q046.  Q or T distinguishes the type of handshake used (Q for QUIC
+// Crypto handshake, T for TLS-based handshake), and the two digits at the end
+// is the actual numeric value of transport version used by the code.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
+#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
+
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/quic_tag.h"
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+// The available versions of QUIC.  The numeric value of the enum is guaranteed
+// to match the number in the name.  The versions not currently supported are
+// documented in comments.
+//
+// See go/new-quic-version for more details on how to roll out new versions.
+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.
+
+  QUIC_VERSION_39 = 39,  // Integers and floating numbers are written in big
+                         // endian. Dot not ack acks. Send 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.
+  QUIC_VERSION_44 = 44,  // Use IETF header format.
+
+  // Version 45 added MESSAGE frame.
+
+  QUIC_VERSION_46 = 46,  // Use IETF draft-17 header format with demultiplexing
+                         // bit.
+  QUIC_VERSION_47 = 47,  // Use CRYPTO frames for QuicCryptoStreams.
+  QUIC_VERSION_99 = 99,  // Dumping ground for IETF QUIC changes which are not
+                         // yet ready for production.
+};
+
+// The crypto handshake protocols that can be used with QUIC.
+enum HandshakeProtocol {
+  PROTOCOL_UNSUPPORTED,
+  PROTOCOL_QUIC_CRYPTO,
+  PROTOCOL_TLS1_3,
+};
+
+// 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;
+
+  ParsedQuicVersion(HandshakeProtocol handshake_protocol,
+                    QuicTransportVersion transport_version);
+
+  ParsedQuicVersion(const ParsedQuicVersion& other)
+      : handshake_protocol(other.handshake_protocol),
+        transport_version(other.transport_version) {}
+
+  ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
+    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;
+  }
+};
+
+QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const ParsedQuicVersion& version);
+
+using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
+
+// 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>;
+
+// This vector contains QUIC versions which we currently support.
+// This should be ordered such that the highest supported version is the first
+// element, with subsequent elements in descending order (versions can be
+// skipped as necessary).
+//
+// See go/new-quic-version for more details on how to roll out new versions.
+static const QuicTransportVersion kSupportedTransportVersions[] = {
+    QUIC_VERSION_99, QUIC_VERSION_47, QUIC_VERSION_46,
+    QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_39,
+};
+
+// This vector contains all crypto handshake protocols that are supported.
+static const HandshakeProtocol kSupportedHandshakeProtocols[] = {
+    PROTOCOL_QUIC_CRYPTO, PROTOCOL_TLS1_3};
+
+typedef std::vector<QuicTransportVersion> QuicTransportVersionVector;
+
+// Returns a vector of QUIC versions in kSupportedTransportVersions.
+QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
+
+// Returns a vector of QUIC versions that is the cartesian product of
+// kSupportedTransportVersions and kSupportedHandshakeProtocols.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
+
+// Returns a vector of QUIC versions from kSupportedTransportVersions which
+// exclude any versions which are disabled by flags.
+QUIC_EXPORT_PRIVATE QuicTransportVersionVector
+CurrentSupportedTransportVersions();
+
+// Returns a vector of QUIC versions that is the cartesian product of
+// kSupportedTransportVersions and kSupportedHandshakeProtocols, 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 QuicTransportVersionVector
+FilterSupportedTransportVersions(QuicTransportVersionVector versions);
+
+// 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 QUIC version of |index| in result of |versions|. Returns
+// QUIC_VERSION_UNSUPPORTED if |index| is out of bounds.
+QUIC_EXPORT_PRIVATE QuicTransportVersionVector
+VersionOfIndex(const QuicTransportVersionVector& versions, int index);
+
+// 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);
+
+// Returns a vector of QuicTransportVersions corresponding to just the transport
+// versions in |versions|. If the input vector contains multiple parsed versions
+// with different handshake protocols (but the same transport version), that
+// transport version will appear in the resulting vector multiple times.
+QUIC_EXPORT_PRIVATE QuicTransportVersionVector
+ParsedVersionsToTransportVersions(const ParsedQuicVersionVector& versions);
+
+// 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);
+
+// Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
+QUIC_EXPORT_PRIVATE QuicVersionLabel
+CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
+
+// Constructs a QuicVersionLabelVector from the provided
+// ParsedQuicVersionVector.
+QUIC_EXPORT_PRIVATE QuicVersionLabelVector
+CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
+
+// QuicVersionLabel is written to and read from the wire, but we prefer to use
+// the more readable QuicTransportVersion at other levels.
+// Helper function which translates from a QuicTransportVersion to a
+// QuicVersionLabel. Returns 0 if |version| is unsupported.
+QUIC_EXPORT_PRIVATE QuicVersionLabel
+QuicVersionToQuicVersionLabel(QuicTransportVersion transport_version);
+
+// Helper function which translates from a QuicVersionLabel to a string.
+QUIC_EXPORT_PRIVATE QuicString
+QuicVersionLabelToString(QuicVersionLabel version_label);
+
+// 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 QuicString
+QuicVersionLabelVectorToString(const QuicVersionLabelVector& version_labels,
+                               const QuicString& 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 QuicString QuicVersionLabelVectorToString(
+    const QuicVersionLabelVector& version_labels) {
+  return QuicVersionLabelVectorToString(version_labels, ",",
+                                        std::numeric_limits<size_t>::max());
+}
+
+// Returns appropriate QuicTransportVersion from a QuicVersionLabel.
+// Returns QUIC_VERSION_UNSUPPORTED if |version_label| cannot be understood.
+QUIC_EXPORT_PRIVATE QuicTransportVersion
+QuicVersionLabelToQuicVersion(QuicVersionLabel version_label);
+
+// Returns the HandshakeProtocol used with the given |version_label|, returning
+// PROTOCOL_UNSUPPORTED if it is unknown.
+QUIC_EXPORT_PRIVATE HandshakeProtocol
+QuicVersionLabelToHandshakeProtocol(QuicVersionLabel version_label);
+
+// Helper function which translates from a QuicTransportVersion to a string.
+// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
+QUIC_EXPORT_PRIVATE QuicString
+QuicVersionToString(QuicTransportVersion transport_version);
+
+// Helper function which translates from a ParsedQuicVersion to a string.
+// Returns strings corresponding to the on-the-wire tag.
+QUIC_EXPORT_PRIVATE QuicString
+ParsedQuicVersionToString(ParsedQuicVersion version);
+
+// Returns comma separated list of string representations of
+// QuicTransportVersion enum values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE QuicString
+QuicTransportVersionVectorToString(const QuicTransportVersionVector& versions);
+
+// Returns comma separated list of string representations of ParsedQuicVersion
+// values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE QuicString
+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 QuicString
+ParsedQuicVersionVectorToString(const ParsedQuicVersionVector& versions,
+                                const QuicString& 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 QuicString ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions) {
+  return ParsedQuicVersionVectorToString(versions, ",",
+                                         std::numeric_limits<size_t>::max());
+}
+
+// Returns true if QuicSpdyStream encodes body using HTTP/3 specification and
+// sends data frame header along with body.
+QUIC_EXPORT_PRIVATE inline bool VersionHasDataFrameHeader(
+    QuicTransportVersion transport_version) {
+  return transport_version == QUIC_VERSION_99;
+}
+
+// Returns true if QuicSpdySession instantiates a QPACK encoder and decoder.
+// TODO(123528590): Implement the following features and gate them on this
+// function as well, optionally renaming this function as appropriate.
+// Send HEADERS on the request/response stream instead of the headers stream.
+// Send PUSH_PROMISE on the request/response stream instead of headers stream.
+// Send PRIORITY on the request/response stream instead of the headers stream.
+// Do not instantiate the headers stream object.
+QUIC_EXPORT_PRIVATE inline bool VersionUsesQpack(
+    QuicTransportVersion transport_version) {
+  const bool uses_qpack = (transport_version == QUIC_VERSION_99);
+  if (uses_qpack) {
+    DCHECK(VersionHasDataFrameHeader(transport_version));
+  }
+  return uses_qpack;
+}
+
+// Returns whether the transport_version supports the variable length integer
+// length field as defined by IETF QUIC draft-13 and later.
+QUIC_EXPORT_PRIVATE inline bool QuicVersionHasLongHeaderLengths(
+    QuicTransportVersion transport_version) {
+  // TODO(dschinazi) if we enable long header lengths before v99, we need to
+  // add support for fixing up lengths in QuicFramer::BuildDataPacket.
+  return transport_version == QUIC_VERSION_99;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_