| // Copyright 2014 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. |
| |
| #ifndef QUICHE_QUIC_CORE_QUIC_TYPES_H_ |
| #define QUICHE_QUIC_CORE_QUIC_TYPES_H_ |
| |
| #include <array> |
| #include <cstddef> |
| #include <cstdint> |
| #include <map> |
| #include <ostream> |
| #include <vector> |
| |
| #include "absl/container/inlined_vector.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/types/optional.h" |
| #include "quic/core/quic_connection_id.h" |
| #include "quic/core/quic_error_codes.h" |
| #include "quic/core/quic_packet_number.h" |
| #include "quic/core/quic_time.h" |
| #include "quic/platform/api/quic_export.h" |
| #include "quic/platform/api/quic_flags.h" |
| |
| namespace quic { |
| |
| using QuicPacketLength = uint16_t; |
| using QuicControlFrameId = uint32_t; |
| using QuicMessageId = uint32_t; |
| |
| // TODO(b/181256914) replace QuicDatagramStreamId with QuicStreamId once we |
| // remove support for draft-ietf-masque-h3-datagram-00 in favor of later drafts. |
| using QuicDatagramStreamId = uint64_t; |
| using QuicDatagramContextId = uint64_t; |
| // Note that for draft-ietf-masque-h3-datagram-00, we represent the flow ID as a |
| // QuicDatagramStreamId. |
| |
| // IMPORTANT: IETF QUIC defines stream IDs and stream counts as being unsigned |
| // 62-bit numbers. However, we have decided to only support up to 2^32-1 streams |
| // in order to reduce the size of data structures such as QuicStreamFrame |
| // and QuicTransmissionInfo, as that allows them to fit in cache lines and has |
| // visible perfomance impact. |
| using QuicStreamId = uint32_t; |
| |
| // Count of stream IDs. Used in MAX_STREAMS and STREAMS_BLOCKED frames. |
| using QuicStreamCount = QuicStreamId; |
| |
| using QuicByteCount = uint64_t; |
| using QuicPacketCount = uint64_t; |
| using QuicPublicResetNonceProof = uint64_t; |
| using QuicStreamOffset = uint64_t; |
| using DiversificationNonce = std::array<char, 32>; |
| using PacketTimeVector = std::vector<std::pair<QuicPacketNumber, QuicTime>>; |
| |
| enum : size_t { kStatelessResetTokenLength = 16 }; |
| using StatelessResetToken = std::array<char, kStatelessResetTokenLength>; |
| |
| // WebTransport session IDs are stream IDs. |
| using WebTransportSessionId = uint64_t; |
| // WebTransport stream reset codes are 8-bit. |
| using WebTransportStreamError = uint8_t; |
| // WebTransport session error codes are 32-bit. |
| using WebTransportSessionError = uint32_t; |
| |
| enum : size_t { kQuicPathFrameBufferSize = 8 }; |
| using QuicPathFrameBuffer = std::array<uint8_t, kQuicPathFrameBufferSize>; |
| |
| // The connection id sequence number specifies the order that connection |
| // ids must be used in. This is also the sequence number carried in |
| // the IETF QUIC NEW_CONNECTION_ID and RETIRE_CONNECTION_ID frames. |
| using QuicConnectionIdSequenceNumber = uint64_t; |
| |
| // A custom data that represents application-specific settings. |
| // In HTTP/3 for example, it includes the encoded SETTINGS. |
| using ApplicationState = std::vector<uint8_t>; |
| |
| // A struct for functions which consume data payloads and fins. |
| struct QUIC_EXPORT_PRIVATE QuicConsumedData { |
| constexpr QuicConsumedData(size_t bytes_consumed, bool fin_consumed) |
| : bytes_consumed(bytes_consumed), fin_consumed(fin_consumed) {} |
| |
| // By default, gtest prints the raw bytes of an object. The bool data |
| // member causes this object to have padding bytes, which causes the |
| // default gtest object printer to read uninitialize memory. So we need |
| // to teach gtest how to print this object. |
| QUIC_EXPORT_PRIVATE friend std::ostream& operator<<( |
| std::ostream& os, const QuicConsumedData& s); |
| |
| // How many bytes were consumed. |
| size_t bytes_consumed; |
| |
| // True if an incoming fin was consumed. |
| bool fin_consumed; |
| }; |
| |
| // QuicAsyncStatus enumerates the possible results of an asynchronous |
| // operation. |
| enum QuicAsyncStatus { |
| QUIC_SUCCESS = 0, |
| QUIC_FAILURE = 1, |
| // QUIC_PENDING results from an operation that will occur asynchronously. When |
| // the operation is complete, a callback's |Run| method will be called. |
| QUIC_PENDING = 2, |
| }; |
| |
| // TODO(wtc): see if WriteStatus can be replaced by QuicAsyncStatus. |
| enum WriteStatus : int16_t { |
| WRITE_STATUS_OK, |
| // Write is blocked, caller needs to retry. |
| WRITE_STATUS_BLOCKED, |
| // Write is blocked but the packet data is buffered, caller should not retry. |
| WRITE_STATUS_BLOCKED_DATA_BUFFERED, |
| // To make the IsWriteError(WriteStatus) function work properly: |
| // - Non-errors MUST be added before WRITE_STATUS_ERROR. |
| // - Errors MUST be added after WRITE_STATUS_ERROR. |
| WRITE_STATUS_ERROR, |
| WRITE_STATUS_MSG_TOO_BIG, |
| WRITE_STATUS_FAILED_TO_COALESCE_PACKET, |
| WRITE_STATUS_NUM_VALUES, |
| }; |
| |
| std::string HistogramEnumString(WriteStatus enum_value); |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| const WriteStatus& status); |
| |
| inline std::string HistogramEnumDescription(WriteStatus /*dummy*/) { |
| return "status"; |
| } |
| |
| inline bool IsWriteBlockedStatus(WriteStatus status) { |
| return status == WRITE_STATUS_BLOCKED || |
| status == WRITE_STATUS_BLOCKED_DATA_BUFFERED; |
| } |
| |
| inline bool IsWriteError(WriteStatus status) { |
| return status >= WRITE_STATUS_ERROR; |
| } |
| |
| // A struct used to return the result of write calls including either the number |
| // of bytes written or the error code, depending upon the status. |
| struct QUIC_EXPORT_PRIVATE WriteResult { |
| constexpr WriteResult(WriteStatus status, int bytes_written_or_error_code) |
| : status(status), bytes_written(bytes_written_or_error_code) {} |
| |
| constexpr WriteResult() : WriteResult(WRITE_STATUS_ERROR, 0) {} |
| |
| bool operator==(const WriteResult& other) const { |
| if (status != other.status) { |
| return false; |
| } |
| switch (status) { |
| case WRITE_STATUS_OK: |
| return bytes_written == other.bytes_written; |
| case WRITE_STATUS_BLOCKED: |
| case WRITE_STATUS_BLOCKED_DATA_BUFFERED: |
| return true; |
| default: |
| return error_code == other.error_code; |
| } |
| } |
| |
| QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os, |
| const WriteResult& s); |
| |
| WriteStatus status; |
| // Number of packets dropped as a result of this write. |
| // Only used by batch writers. Otherwise always 0. |
| uint16_t dropped_packets = 0; |
| // The delta between a packet's ideal and actual send time: |
| // actual_send_time = ideal_send_time + send_time_offset |
| // = (now + release_time_delay) + send_time_offset |
| // Only valid if |status| is WRITE_STATUS_OK. |
| QuicTime::Delta send_time_offset = QuicTime::Delta::Zero(); |
| // TODO(wub): In some cases, WRITE_STATUS_ERROR may set an error_code and |
| // WRITE_STATUS_BLOCKED_DATA_BUFFERED may set bytes_written. This may need |
| // some cleaning up so that perhaps both values can be set and valid. |
| union { |
| int bytes_written; // only valid when status is WRITE_STATUS_OK |
| int error_code; // only valid when status is WRITE_STATUS_ERROR |
| }; |
| }; |
| |
| enum TransmissionType : int8_t { |
| NOT_RETRANSMISSION, |
| FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION, |
| HANDSHAKE_RETRANSMISSION, // Retransmits due to handshake timeouts. |
| ALL_ZERO_RTT_RETRANSMISSION, // Retransmits all packets encrypted with 0-RTT |
| // key. |
| LOSS_RETRANSMISSION, // Retransmits due to loss detection. |
| RTO_RETRANSMISSION, // Retransmits due to retransmit time out. |
| TLP_RETRANSMISSION, // Tail loss probes. |
| PTO_RETRANSMISSION, // Retransmission due to probe timeout. |
| PROBING_RETRANSMISSION, // Retransmission in order to probe bandwidth. |
| PATH_RETRANSMISSION, // Retransmission proactively due to underlying |
| // network change. |
| ALL_INITIAL_RETRANSMISSION, // Retransmit all packets encrypted with INITIAL |
| // key. |
| LAST_TRANSMISSION_TYPE = ALL_INITIAL_RETRANSMISSION, |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string TransmissionTypeToString( |
| TransmissionType transmission_type); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, TransmissionType transmission_type); |
| |
| enum HasRetransmittableData : uint8_t { |
| NO_RETRANSMITTABLE_DATA, |
| HAS_RETRANSMITTABLE_DATA, |
| }; |
| |
| enum IsHandshake : uint8_t { NOT_HANDSHAKE, IS_HANDSHAKE }; |
| |
| enum class Perspective : uint8_t { IS_SERVER, IS_CLIENT }; |
| |
| QUIC_EXPORT_PRIVATE std::string PerspectiveToString(Perspective perspective); |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| const Perspective& perspective); |
| |
| // Describes whether a ConnectionClose was originated by the peer. |
| enum class ConnectionCloseSource { FROM_PEER, FROM_SELF }; |
| |
| QUIC_EXPORT_PRIVATE std::string ConnectionCloseSourceToString( |
| ConnectionCloseSource connection_close_source); |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const ConnectionCloseSource& connection_close_source); |
| |
| // Should a connection be closed silently or not. |
| enum class ConnectionCloseBehavior { |
| SILENT_CLOSE, |
| SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED, |
| SEND_CONNECTION_CLOSE_PACKET |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string ConnectionCloseBehaviorToString( |
| ConnectionCloseBehavior connection_close_behavior); |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const ConnectionCloseBehavior& connection_close_behavior); |
| |
| enum QuicFrameType : uint8_t { |
| // Regular frame types. The values set here cannot change without the |
| // introduction of a new QUIC version. |
| PADDING_FRAME = 0, |
| RST_STREAM_FRAME = 1, |
| CONNECTION_CLOSE_FRAME = 2, |
| GOAWAY_FRAME = 3, |
| WINDOW_UPDATE_FRAME = 4, |
| BLOCKED_FRAME = 5, |
| STOP_WAITING_FRAME = 6, |
| PING_FRAME = 7, |
| CRYPTO_FRAME = 8, |
| // TODO(b/157935330): stop hard coding this when deprecate T050. |
| HANDSHAKE_DONE_FRAME = 9, |
| |
| // STREAM and ACK frames are special frames. They are encoded differently on |
| // the wire and their values do not need to be stable. |
| STREAM_FRAME, |
| ACK_FRAME, |
| // The path MTU discovery frame is encoded as a PING frame on the wire. |
| MTU_DISCOVERY_FRAME, |
| |
| // These are for IETF-specific frames for which there is no mapping |
| // from Google QUIC frames. These are valid/allowed if and only if IETF- |
| // QUIC has been negotiated. Values are not important, they are not |
| // the values that are in the packets (see QuicIetfFrameType, below). |
| NEW_CONNECTION_ID_FRAME, |
| MAX_STREAMS_FRAME, |
| STREAMS_BLOCKED_FRAME, |
| PATH_RESPONSE_FRAME, |
| PATH_CHALLENGE_FRAME, |
| STOP_SENDING_FRAME, |
| MESSAGE_FRAME, |
| NEW_TOKEN_FRAME, |
| RETIRE_CONNECTION_ID_FRAME, |
| ACK_FREQUENCY_FRAME, |
| |
| NUM_FRAME_TYPES |
| }; |
| |
| // Human-readable string suitable for logging. |
| QUIC_EXPORT_PRIVATE std::string QuicFrameTypeToString(QuicFrameType t); |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| const QuicFrameType& t); |
| |
| // Ietf frame types. These are defined in the IETF QUIC Specification. |
| // Explicit values are given in the enum so that we can be sure that |
| // the symbol will map to the correct stream type. |
| // All types are defined here, even if we have not yet implmented the |
| // quic/core/stream/.... stuff needed. |
| // Note: The protocol specifies that frame types are varint-62 encoded, |
| // further stating that the shortest encoding must be used. The current set of |
| // frame types all have values less than 0x40 (64) so can be encoded in a single |
| // byte, with the two most significant bits being 0. Thus, the following |
| // enumerations are valid as both the numeric values of frame types AND their |
| // encodings. |
| enum QuicIetfFrameType : uint64_t { |
| IETF_PADDING = 0x00, |
| IETF_PING = 0x01, |
| IETF_ACK = 0x02, |
| IETF_ACK_ECN = 0x03, |
| IETF_RST_STREAM = 0x04, |
| IETF_STOP_SENDING = 0x05, |
| IETF_CRYPTO = 0x06, |
| IETF_NEW_TOKEN = 0x07, |
| // the low-3 bits of the stream frame type value are actually flags |
| // declaring what parts of the frame are/are-not present, as well as |
| // some other control information. The code would then do something |
| // along the lines of "if ((frame_type & 0xf8) == 0x08)" to determine |
| // whether the frame is a stream frame or not, and then examine each |
| // bit specifically when/as needed. |
| IETF_STREAM = 0x08, |
| // 0x09 through 0x0f are various flag settings of the IETF_STREAM frame. |
| IETF_MAX_DATA = 0x10, |
| IETF_MAX_STREAM_DATA = 0x11, |
| IETF_MAX_STREAMS_BIDIRECTIONAL = 0x12, |
| IETF_MAX_STREAMS_UNIDIRECTIONAL = 0x13, |
| IETF_DATA_BLOCKED = 0x14, |
| IETF_STREAM_DATA_BLOCKED = 0x15, |
| IETF_STREAMS_BLOCKED_BIDIRECTIONAL = 0x16, |
| IETF_STREAMS_BLOCKED_UNIDIRECTIONAL = 0x17, |
| IETF_NEW_CONNECTION_ID = 0x18, |
| IETF_RETIRE_CONNECTION_ID = 0x19, |
| IETF_PATH_CHALLENGE = 0x1a, |
| IETF_PATH_RESPONSE = 0x1b, |
| // Both of the following are "Connection Close" frames, |
| // the first signals transport-layer errors, the second application-layer |
| // errors. |
| IETF_CONNECTION_CLOSE = 0x1c, |
| IETF_APPLICATION_CLOSE = 0x1d, |
| |
| IETF_HANDSHAKE_DONE = 0x1e, |
| |
| // The MESSAGE frame type has not yet been fully standardized. |
| // QUIC versions starting with 46 and before 99 use 0x20-0x21. |
| // IETF QUIC (v99) uses 0x30-0x31, see draft-pauly-quic-datagram. |
| IETF_EXTENSION_MESSAGE_NO_LENGTH = 0x20, |
| IETF_EXTENSION_MESSAGE = 0x21, |
| IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 = 0x30, |
| IETF_EXTENSION_MESSAGE_V99 = 0x31, |
| |
| // An QUIC extension frame for sender control of acknowledgement delays |
| IETF_ACK_FREQUENCY = 0xaf, |
| |
| // A QUIC extension frame which augments the IETF_ACK frame definition with |
| // packet receive timestamps. |
| // TODO(ianswett): Determine a proper value to replace this temporary value. |
| IETF_ACK_RECEIVE_TIMESTAMPS = 0x22, |
| }; |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| const QuicIetfFrameType& c); |
| QUIC_EXPORT_PRIVATE std::string QuicIetfFrameTypeString(QuicIetfFrameType t); |
| |
| // Masks for the bits that indicate the frame is a Stream frame vs the |
| // bits used as flags. |
| #define IETF_STREAM_FRAME_TYPE_MASK 0xfffffffffffffff8 |
| #define IETF_STREAM_FRAME_FLAG_MASK 0x07 |
| #define IS_IETF_STREAM_FRAME(_stype_) \ |
| (((_stype_)&IETF_STREAM_FRAME_TYPE_MASK) == IETF_STREAM) |
| |
| // These are the values encoded in the low-order 3 bits of the |
| // IETF_STREAMx frame type. |
| #define IETF_STREAM_FRAME_FIN_BIT 0x01 |
| #define IETF_STREAM_FRAME_LEN_BIT 0x02 |
| #define IETF_STREAM_FRAME_OFF_BIT 0x04 |
| |
| enum QuicVariableLengthIntegerLength : uint8_t { |
| // Length zero means the variable length integer is not present. |
| VARIABLE_LENGTH_INTEGER_LENGTH_0 = 0, |
| VARIABLE_LENGTH_INTEGER_LENGTH_1 = 1, |
| VARIABLE_LENGTH_INTEGER_LENGTH_2 = 2, |
| VARIABLE_LENGTH_INTEGER_LENGTH_4 = 4, |
| VARIABLE_LENGTH_INTEGER_LENGTH_8 = 8, |
| |
| // By default we write the IETF long header length using the 2-byte encoding |
| // of variable length integers, even when the length is below 64, which allows |
| // us to fill in the length before knowing what the length actually is. |
| kQuicDefaultLongHeaderLengthLength = VARIABLE_LENGTH_INTEGER_LENGTH_2, |
| }; |
| |
| enum QuicPacketNumberLength : uint8_t { |
| PACKET_1BYTE_PACKET_NUMBER = 1, |
| PACKET_2BYTE_PACKET_NUMBER = 2, |
| PACKET_3BYTE_PACKET_NUMBER = 3, // Used in versions 45+. |
| PACKET_4BYTE_PACKET_NUMBER = 4, |
| IETF_MAX_PACKET_NUMBER_LENGTH = 4, |
| // TODO(b/145819870): Remove 6 and 8 when we remove Q043 since these values |
| // are not representable with later versions. |
| PACKET_6BYTE_PACKET_NUMBER = 6, |
| PACKET_8BYTE_PACKET_NUMBER = 8 |
| }; |
| |
| // Used to indicate a QuicSequenceNumberLength using two flag bits. |
| enum QuicPacketNumberLengthFlags { |
| PACKET_FLAGS_1BYTE_PACKET = 0, // 00 |
| PACKET_FLAGS_2BYTE_PACKET = 1, // 01 |
| PACKET_FLAGS_4BYTE_PACKET = 1 << 1, // 10 |
| PACKET_FLAGS_8BYTE_PACKET = 1 << 1 | 1, // 11 |
| }; |
| |
| // The public flags are specified in one byte. |
| enum QuicPacketPublicFlags { |
| PACKET_PUBLIC_FLAGS_NONE = 0, |
| |
| // Bit 0: Does the packet header contains version info? |
| PACKET_PUBLIC_FLAGS_VERSION = 1 << 0, |
| |
| // Bit 1: Is this packet a public reset packet? |
| PACKET_PUBLIC_FLAGS_RST = 1 << 1, |
| |
| // Bit 2: indicates the header includes a nonce. |
| PACKET_PUBLIC_FLAGS_NONCE = 1 << 2, |
| |
| // Bit 3: indicates whether a ConnectionID is included. |
| PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID = 0, |
| PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID = 1 << 3, |
| |
| // Deprecated version 32 and earlier used two bits to indicate an 8-byte |
| // connection ID. We send this from the client because of some broken |
| // middleboxes that are still checking this bit. |
| PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD = 1 << 3 | 1 << 2, |
| |
| // Bits 4 and 5 describe the packet number length as follows: |
| // --00----: 1 byte |
| // --01----: 2 bytes |
| // --10----: 4 bytes |
| // --11----: 6 bytes |
| PACKET_PUBLIC_FLAGS_1BYTE_PACKET = PACKET_FLAGS_1BYTE_PACKET << 4, |
| PACKET_PUBLIC_FLAGS_2BYTE_PACKET = PACKET_FLAGS_2BYTE_PACKET << 4, |
| PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4, |
| PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_8BYTE_PACKET << 4, |
| |
| // Reserved, unimplemented flags: |
| |
| // Bit 7: indicates the presence of a second flags byte. |
| PACKET_PUBLIC_FLAGS_TWO_OR_MORE_BYTES = 1 << 7, |
| |
| // All bits set (bits 6 and 7 are not currently used): 00111111 |
| PACKET_PUBLIC_FLAGS_MAX = (1 << 6) - 1, |
| }; |
| |
| // The private flags are specified in one byte. |
| enum QuicPacketPrivateFlags { |
| PACKET_PRIVATE_FLAGS_NONE = 0, |
| |
| // Bit 0: Does this packet contain an entropy bit? |
| PACKET_PRIVATE_FLAGS_ENTROPY = 1 << 0, |
| |
| // (bits 1-7 are not used): 00000001 |
| PACKET_PRIVATE_FLAGS_MAX = (1 << 1) - 1 |
| }; |
| |
| // Defines for all types of congestion control algorithms that can be used in |
| // QUIC. Note that this is separate from the congestion feedback type - |
| // some congestion control algorithms may use the same feedback type |
| // (Reno and Cubic are the classic example for that). |
| enum CongestionControlType { |
| kCubicBytes, |
| kRenoBytes, |
| kBBR, |
| kPCC, |
| kGoogCC, |
| kBBRv2, |
| }; |
| |
| // EncryptionLevel enumerates the stages of encryption that a QUIC connection |
| // progresses through. When retransmitting a packet, the encryption level needs |
| // to be specified so that it is retransmitted at a level which the peer can |
| // understand. |
| enum EncryptionLevel : int8_t { |
| ENCRYPTION_INITIAL = 0, |
| ENCRYPTION_HANDSHAKE = 1, |
| ENCRYPTION_ZERO_RTT = 2, |
| ENCRYPTION_FORWARD_SECURE = 3, |
| |
| NUM_ENCRYPTION_LEVELS, |
| }; |
| |
| inline bool EncryptionLevelIsValid(EncryptionLevel level) { |
| return ENCRYPTION_INITIAL <= level && level < NUM_ENCRYPTION_LEVELS; |
| } |
| |
| QUIC_EXPORT_PRIVATE std::string EncryptionLevelToString(EncryptionLevel level); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| EncryptionLevel level); |
| |
| // Enumeration of whether a server endpoint will request a client certificate, |
| // and whether that endpoint requires a valid client certificate to establish a |
| // connection. |
| enum class ClientCertMode : uint8_t { |
| kNone, // Do not request a client certificate. Default server behavior. |
| kRequest, // Request a certificate, but allow unauthenticated connections. |
| kRequire, // Require clients to provide a valid certificate. |
| }; |
| |
| QUIC_EXPORT_PRIVATE absl::string_view ClientCertModeToString( |
| ClientCertMode mode); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| ClientCertMode mode); |
| |
| enum AddressChangeType : uint8_t { |
| // IP address and port remain unchanged. |
| NO_CHANGE, |
| // Port changed, but IP address remains unchanged. |
| PORT_CHANGE, |
| // IPv4 address changed, but within the /24 subnet (port may have changed.) |
| IPV4_SUBNET_CHANGE, |
| // IPv4 address changed, excluding /24 subnet change (port may have changed.) |
| IPV4_TO_IPV4_CHANGE, |
| // IP address change from an IPv4 to an IPv6 address (port may have changed.) |
| IPV4_TO_IPV6_CHANGE, |
| // IP address change from an IPv6 to an IPv4 address (port may have changed.) |
| IPV6_TO_IPV4_CHANGE, |
| // IP address change from an IPv6 to an IPv6 address (port may have changed.) |
| IPV6_TO_IPV6_CHANGE, |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string AddressChangeTypeToString( |
| AddressChangeType type); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| AddressChangeType type); |
| |
| enum StreamSendingState { |
| // Sender has more data to send on this stream. |
| NO_FIN, |
| // Sender is done sending on this stream. |
| FIN, |
| // Sender is done sending on this stream and random padding needs to be |
| // appended after all stream frames. |
| FIN_AND_PADDING, |
| }; |
| |
| enum SentPacketState : uint8_t { |
| // The packet is in flight and waiting to be acked. |
| OUTSTANDING, |
| FIRST_PACKET_STATE = OUTSTANDING, |
| // The packet was never sent. |
| NEVER_SENT, |
| // The packet has been acked. |
| ACKED, |
| // This packet is not expected to be acked. |
| UNACKABLE, |
| // This packet has been delivered or unneeded. |
| NEUTERED, |
| |
| // States below are corresponding to retransmission types in TransmissionType. |
| |
| // This packet has been retransmitted when retransmission timer fires in |
| // HANDSHAKE mode. |
| HANDSHAKE_RETRANSMITTED, |
| // This packet is considered as lost, this is used for LOST_RETRANSMISSION. |
| LOST, |
| // This packet has been retransmitted when TLP fires. |
| TLP_RETRANSMITTED, |
| // This packet has been retransmitted when RTO fires. |
| RTO_RETRANSMITTED, |
| // This packet has been retransmitted when PTO fires. |
| PTO_RETRANSMITTED, |
| // This packet has been retransmitted for probing purpose. |
| PROBE_RETRANSMITTED, |
| // This packet is sent on a different path or is a PING only packet. |
| // Do not update RTT stats and congestion control if the packet is the |
| // largest_acked of an incoming ACK. |
| NOT_CONTRIBUTING_RTT, |
| LAST_PACKET_STATE = NOT_CONTRIBUTING_RTT, |
| }; |
| |
| enum PacketHeaderFormat : uint8_t { |
| IETF_QUIC_LONG_HEADER_PACKET, |
| IETF_QUIC_SHORT_HEADER_PACKET, |
| GOOGLE_QUIC_PACKET, |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string PacketHeaderFormatToString( |
| PacketHeaderFormat format); |
| |
| // Information about a newly acknowledged packet. |
| struct QUIC_EXPORT_PRIVATE AckedPacket { |
| constexpr AckedPacket(QuicPacketNumber packet_number, |
| QuicPacketLength bytes_acked, |
| QuicTime receive_timestamp) |
| : packet_number(packet_number), |
| bytes_acked(bytes_acked), |
| receive_timestamp(receive_timestamp) {} |
| |
| friend QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const AckedPacket& acked_packet); |
| |
| QuicPacketNumber packet_number; |
| // Number of bytes sent in the packet that was acknowledged. |
| QuicPacketLength bytes_acked; |
| // The time |packet_number| was received by the peer, according to the |
| // optional timestamp the peer included in the ACK frame which acknowledged |
| // |packet_number|. Zero if no timestamp was available for this packet. |
| QuicTime receive_timestamp; |
| }; |
| |
| // A vector of acked packets. |
| using AckedPacketVector = absl::InlinedVector<AckedPacket, 2>; |
| |
| // Information about a newly lost packet. |
| struct QUIC_EXPORT_PRIVATE LostPacket { |
| LostPacket(QuicPacketNumber packet_number, QuicPacketLength bytes_lost) |
| : packet_number(packet_number), bytes_lost(bytes_lost) {} |
| |
| friend QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const LostPacket& lost_packet); |
| |
| QuicPacketNumber packet_number; |
| // Number of bytes sent in the packet that was lost. |
| QuicPacketLength bytes_lost; |
| }; |
| |
| // A vector of lost packets. |
| using LostPacketVector = absl::InlinedVector<LostPacket, 2>; |
| |
| // Please note, this value cannot used directly for packet serialization. |
| enum QuicLongHeaderType : uint8_t { |
| VERSION_NEGOTIATION, |
| INITIAL, |
| ZERO_RTT_PROTECTED, |
| HANDSHAKE, |
| RETRY, |
| |
| INVALID_PACKET_TYPE, |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string QuicLongHeaderTypeToString( |
| QuicLongHeaderType type); |
| |
| enum QuicPacketHeaderTypeFlags : uint8_t { |
| // Bit 2: Key phase bit for IETF QUIC short header packets. |
| FLAGS_KEY_PHASE_BIT = 1 << 2, |
| // Bit 3: Google QUIC Demultiplexing bit, the short header always sets this |
| // bit to 0, allowing to distinguish Google QUIC packets from short header |
| // packets. |
| FLAGS_DEMULTIPLEXING_BIT = 1 << 3, |
| // Bits 4 and 5: Reserved bits for short header. |
| FLAGS_SHORT_HEADER_RESERVED_1 = 1 << 4, |
| FLAGS_SHORT_HEADER_RESERVED_2 = 1 << 5, |
| // Bit 6: the 'QUIC' bit. |
| FLAGS_FIXED_BIT = 1 << 6, |
| // Bit 7: Indicates the header is long or short header. |
| FLAGS_LONG_HEADER = 1 << 7, |
| }; |
| |
| enum MessageStatus { |
| MESSAGE_STATUS_SUCCESS, |
| MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, // Failed to send message because |
| // encryption is not established |
| // yet. |
| MESSAGE_STATUS_UNSUPPORTED, // Failed to send message because MESSAGE frame |
| // is not supported by the connection. |
| MESSAGE_STATUS_BLOCKED, // Failed to send message because connection is |
| // congestion control blocked or underlying socket is |
| // write blocked. |
| MESSAGE_STATUS_TOO_LARGE, // Failed to send message because the message is |
| // too large to fit into a single packet. |
| MESSAGE_STATUS_INTERNAL_ERROR, // Failed to send message because connection |
| // reaches an invalid state. |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string MessageStatusToString( |
| MessageStatus message_status); |
| |
| // Used to return the result of SendMessage calls |
| struct QUIC_EXPORT_PRIVATE MessageResult { |
| MessageResult(MessageStatus status, QuicMessageId message_id); |
| |
| bool operator==(const MessageResult& other) const { |
| return status == other.status && message_id == other.message_id; |
| } |
| |
| QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os, |
| const MessageResult& mr); |
| |
| MessageStatus status; |
| // Only valid when status is MESSAGE_STATUS_SUCCESS. |
| QuicMessageId message_id; |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string MessageResultToString( |
| MessageResult message_result); |
| |
| enum WriteStreamDataResult { |
| WRITE_SUCCESS, |
| STREAM_MISSING, // Trying to write data of a nonexistent stream (e.g. |
| // closed). |
| WRITE_FAILED, // Trying to write nonexistent data of a stream |
| }; |
| |
| enum StreamType : uint8_t { |
| // Bidirectional streams allow for data to be sent in both directions. |
| BIDIRECTIONAL, |
| |
| // Unidirectional streams carry data in one direction only. |
| WRITE_UNIDIRECTIONAL, |
| READ_UNIDIRECTIONAL, |
| // Not actually a stream type. Used only by QuicCryptoStream when it uses |
| // CRYPTO frames and isn't actually a QuicStream. |
| CRYPTO, |
| }; |
| |
| // A packet number space is the context in which a packet can be processed and |
| // acknowledged. |
| enum PacketNumberSpace : uint8_t { |
| INITIAL_DATA = 0, // Only used in IETF QUIC. |
| HANDSHAKE_DATA = 1, |
| APPLICATION_DATA = 2, |
| |
| NUM_PACKET_NUMBER_SPACES, |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string PacketNumberSpaceToString( |
| PacketNumberSpace packet_number_space); |
| |
| // Used to return the result of processing a received ACK frame. |
| enum AckResult { |
| PACKETS_NEWLY_ACKED, |
| NO_PACKETS_NEWLY_ACKED, |
| UNSENT_PACKETS_ACKED, // Peer acks unsent packets. |
| UNACKABLE_PACKETS_ACKED, // Peer acks packets that are not expected to be |
| // acked. For example, encryption is reestablished, |
| // and all sent encrypted packets cannot be |
| // decrypted by the peer. Version gets negotiated, |
| // and all sent packets in the different version |
| // cannot be processed by the peer. |
| PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE, |
| }; |
| |
| // Indicates the fate of a serialized packet in WritePacket(). |
| enum SerializedPacketFate : uint8_t { |
| DISCARD, // Discard the packet. |
| COALESCE, // Try to coalesce packet. |
| BUFFER, // Buffer packet in buffered_packets_. |
| SEND_TO_WRITER, // Send packet to writer. |
| LEGACY_VERSION_ENCAPSULATE, // Perform Legacy Version Encapsulation on this |
| // packet. |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::string SerializedPacketFateToString( |
| SerializedPacketFate fate); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| const SerializedPacketFate fate); |
| |
| // There are three different forms of CONNECTION_CLOSE. |
| enum QuicConnectionCloseType { |
| GOOGLE_QUIC_CONNECTION_CLOSE = 0, |
| IETF_QUIC_TRANSPORT_CONNECTION_CLOSE = 1, |
| IETF_QUIC_APPLICATION_CONNECTION_CLOSE = 2 |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const QuicConnectionCloseType type); |
| |
| QUIC_EXPORT_PRIVATE std::string QuicConnectionCloseTypeString( |
| QuicConnectionCloseType type); |
| |
| // Indicate handshake state of a connection. |
| enum HandshakeState { |
| // Initial state. |
| HANDSHAKE_START, |
| // Only used in IETF QUIC with TLS handshake. State proceeds to |
| // HANDSHAKE_PROCESSED after a packet of HANDSHAKE packet number space |
| // gets successfully processed, and the initial key can be dropped. |
| HANDSHAKE_PROCESSED, |
| // In QUIC crypto, state proceeds to HANDSHAKE_COMPLETE if client receives |
| // SHLO or server successfully processes an ENCRYPTION_FORWARD_SECURE |
| // packet, such that the handshake packets can be neutered. In IETF QUIC |
| // with TLS handshake, state proceeds to HANDSHAKE_COMPLETE once the client |
| // has both 1-RTT send and receive keys. |
| HANDSHAKE_COMPLETE, |
| // Only used in IETF QUIC with TLS handshake. State proceeds to |
| // HANDSHAKE_CONFIRMED if 1) a client receives HANDSHAKE_DONE frame or |
| // acknowledgment for 1-RTT packet or 2) server has |
| // 1-RTT send and receive keys. |
| HANDSHAKE_CONFIRMED, |
| }; |
| |
| struct QUIC_NO_EXPORT NextReleaseTimeResult { |
| // The ideal release time of the packet being sent. |
| QuicTime release_time; |
| // Whether it is allowed to send the packet before release_time. |
| bool allow_burst; |
| }; |
| |
| // QuicPacketBuffer bundles a buffer and a function that releases it. Note |
| // it does not assume ownership of buffer, i.e. it doesn't release the buffer on |
| // destruction. |
| struct QUIC_NO_EXPORT QuicPacketBuffer { |
| QuicPacketBuffer() = default; |
| |
| QuicPacketBuffer(char* buffer, |
| std::function<void(const char*)> release_buffer) |
| : buffer(buffer), release_buffer(std::move(release_buffer)) {} |
| |
| char* buffer = nullptr; |
| std::function<void(const char*)> release_buffer; |
| }; |
| |
| // QuicOwnedPacketBuffer is a QuicPacketBuffer that assumes buffer ownership. |
| struct QUIC_NO_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer { |
| QuicOwnedPacketBuffer(const QuicOwnedPacketBuffer&) = delete; |
| QuicOwnedPacketBuffer& operator=(const QuicOwnedPacketBuffer&) = delete; |
| |
| QuicOwnedPacketBuffer(char* buffer, |
| std::function<void(const char*)> release_buffer) |
| : QuicPacketBuffer(buffer, std::move(release_buffer)) {} |
| |
| QuicOwnedPacketBuffer(QuicOwnedPacketBuffer&& owned_buffer) |
| : QuicPacketBuffer(std::move(owned_buffer)) { |
| // |owned_buffer| does not own a buffer any more. |
| owned_buffer.buffer = nullptr; |
| } |
| |
| explicit QuicOwnedPacketBuffer(QuicPacketBuffer&& packet_buffer) |
| : QuicPacketBuffer(std::move(packet_buffer)) {} |
| |
| ~QuicOwnedPacketBuffer() { |
| if (release_buffer != nullptr && buffer != nullptr) { |
| release_buffer(buffer); |
| } |
| } |
| }; |
| |
| // These values must remain stable as they are uploaded to UMA histograms. |
| enum class KeyUpdateReason { |
| kInvalid = 0, |
| kRemote = 1, |
| kLocalForTests = 2, |
| kLocalForInteropRunner = 3, |
| kLocalAeadConfidentialityLimit = 4, |
| kLocalKeyUpdateLimitOverride = 5, |
| kMaxValue = kLocalKeyUpdateLimitOverride, |
| }; |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| const KeyUpdateReason reason); |
| |
| QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason); |
| |
| // QuicSSLConfig contains configurations to be applied on a SSL object, which |
| // overrides the configurations in SSL_CTX. |
| struct QUIC_NO_EXPORT QuicSSLConfig { |
| // Whether TLS early data should be enabled. If not set, default to enabled. |
| absl::optional<bool> early_data_enabled; |
| // Whether TLS session tickets are supported. If not set, default to |
| // supported. |
| absl::optional<bool> disable_ticket_support; |
| // If set, used to configure the SSL object with |
| // SSL_set_signing_algorithm_prefs. |
| absl::optional<absl::InlinedVector<uint16_t, 8>> signing_algorithm_prefs; |
| // Client certificate mode for mTLS support. Only used at server side. |
| ClientCertMode client_cert_mode = ClientCertMode::kNone; |
| }; |
| |
| // QuicDelayedSSLConfig contains a subset of SSL config that can be applied |
| // after BoringSSL's early select certificate callback. This overwrites all SSL |
| // configs applied before cert selection. |
| struct QUIC_NO_EXPORT QuicDelayedSSLConfig { |
| // Client certificate mode for mTLS support. Only used at server side. |
| // absl::nullopt means do not change client certificate mode. |
| absl::optional<ClientCertMode> client_cert_mode; |
| }; |
| |
| // ParsedClientHello contains client hello information extracted from a fully |
| // received client hello. |
| struct QUIC_NO_EXPORT ParsedClientHello { |
| std::string sni; // QUIC crypto and TLS. |
| std::string uaid; // QUIC crypto only. |
| std::vector<std::string> alpns; // QUIC crypto and TLS. |
| std::string legacy_version_encapsulation_inner_packet; // QUIC crypto only. |
| // The unvalidated retry token from the last received packet of a potentially |
| // multi-packet client hello. TLS only. |
| std::string retry_token; |
| bool resumption_attempted = false; // TLS only. |
| bool early_data_attempted = false; // TLS only. |
| }; |
| |
| QUIC_EXPORT_PRIVATE bool operator==(const ParsedClientHello& a, |
| const ParsedClientHello& b); |
| |
| QUIC_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream& os, const ParsedClientHello& parsed_chlo); |
| |
| } // namespace quic |
| |
| #endif // QUICHE_QUIC_CORE_QUIC_TYPES_H_ |