1 // Copyright 2014 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 #ifndef QUICHE_QUIC_CORE_QUIC_TYPES_H_
6 #define QUICHE_QUIC_CORE_QUIC_TYPES_H_
7
8 #include <array>
9 #include <cstddef>
10 #include <cstdint>
11 #include <map>
12 #include <optional>
13 #include <ostream>
14 #include <vector>
15
16 #include "absl/container/inlined_vector.h"
17 #include "absl/strings/str_format.h"
18 #include "absl/strings/string_view.h"
19 #include "quiche/quic/core/quic_connection_id.h"
20 #include "quiche/quic/core/quic_error_codes.h"
21 #include "quiche/quic/core/quic_packet_number.h"
22 #include "quiche/quic/core/quic_time.h"
23 #include "quiche/quic/platform/api/quic_export.h"
24 #include "quiche/quic/platform/api/quic_flags.h"
25 #include "quiche/common/quiche_endian.h"
26 #include "quiche/web_transport/web_transport.h"
27
28 namespace quic {
29
30 using QuicPacketLength = uint16_t;
31 using QuicControlFrameId = uint32_t;
32 using QuicMessageId = uint32_t;
33
34 // IMPORTANT: IETF QUIC defines stream IDs and stream counts as being unsigned
35 // 62-bit numbers. However, we have decided to only support up to 2^32-1 streams
36 // in order to reduce the size of data structures such as QuicStreamFrame
37 // and QuicTransmissionInfo, as that allows them to fit in cache lines and has
38 // visible perfomance impact.
39 using QuicStreamId = uint32_t;
40
41 // Count of stream IDs. Used in MAX_STREAMS and STREAMS_BLOCKED frames.
42 using QuicStreamCount = QuicStreamId;
43
44 using QuicByteCount = uint64_t;
45 using QuicPacketCount = uint64_t;
46 using QuicPublicResetNonceProof = uint64_t;
47 using QuicStreamOffset = uint64_t;
48 using DiversificationNonce = std::array<char, 32>;
49 using PacketTimeVector = std::vector<std::pair<QuicPacketNumber, QuicTime>>;
50
51 enum : size_t { kStatelessResetTokenLength = 16 };
52 using StatelessResetToken = std::array<char, kStatelessResetTokenLength>;
53
54 // WebTransport session IDs are stream IDs.
55 using WebTransportSessionId = uint64_t;
56 // WebTransport stream reset codes are 32-bit.
57 using WebTransportStreamError = ::webtransport::StreamErrorCode;
58 // WebTransport session error codes are 32-bit.
59 using WebTransportSessionError = ::webtransport::SessionErrorCode;
60
61 enum : size_t { kQuicPathFrameBufferSize = 8 };
62 using QuicPathFrameBuffer = std::array<uint8_t, kQuicPathFrameBufferSize>;
63
64 // The connection id sequence number specifies the order that connection
65 // ids must be used in. This is also the sequence number carried in
66 // the IETF QUIC NEW_CONNECTION_ID and RETIRE_CONNECTION_ID frames.
67 using QuicConnectionIdSequenceNumber = uint64_t;
68
69 // A custom data that represents application-specific settings.
70 // In HTTP/3 for example, it includes the encoded SETTINGS.
71 using ApplicationState = std::vector<uint8_t>;
72
73 // A struct for functions which consume data payloads and fins.
74 struct QUICHE_EXPORT QuicConsumedData {
QuicConsumedDataQuicConsumedData75 constexpr QuicConsumedData(size_t bytes_consumed, bool fin_consumed)
76 : bytes_consumed(bytes_consumed), fin_consumed(fin_consumed) {}
77
78 // By default, gtest prints the raw bytes of an object. The bool data
79 // member causes this object to have padding bytes, which causes the
80 // default gtest object printer to read uninitialize memory. So we need
81 // to teach gtest how to print this object.
82 QUICHE_EXPORT friend std::ostream& operator<<(std::ostream& os,
83 const QuicConsumedData& s);
84
85 // How many bytes were consumed.
86 size_t bytes_consumed;
87
88 // True if an incoming fin was consumed.
89 bool fin_consumed;
90 };
91
92 // QuicAsyncStatus enumerates the possible results of an asynchronous
93 // operation.
94 enum QuicAsyncStatus {
95 QUIC_SUCCESS = 0,
96 QUIC_FAILURE = 1,
97 // QUIC_PENDING results from an operation that will occur asynchronously. When
98 // the operation is complete, a callback's |Run| method will be called.
99 QUIC_PENDING = 2,
100 };
101
102 // TODO(wtc): see if WriteStatus can be replaced by QuicAsyncStatus.
103 enum WriteStatus : int16_t {
104 WRITE_STATUS_OK,
105 // Write is blocked, caller needs to retry.
106 WRITE_STATUS_BLOCKED,
107 // Write is blocked but the packet data is buffered, caller should not retry.
108 WRITE_STATUS_BLOCKED_DATA_BUFFERED,
109 // To make the IsWriteError(WriteStatus) function work properly:
110 // - Non-errors MUST be added before WRITE_STATUS_ERROR.
111 // - Errors MUST be added after WRITE_STATUS_ERROR.
112 WRITE_STATUS_ERROR,
113 WRITE_STATUS_MSG_TOO_BIG,
114 WRITE_STATUS_FAILED_TO_COALESCE_PACKET,
115 WRITE_STATUS_NUM_VALUES,
116 };
117
118 std::string HistogramEnumString(WriteStatus enum_value);
119 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
120 const WriteStatus& status);
121
HistogramEnumDescription(WriteStatus)122 inline std::string HistogramEnumDescription(WriteStatus /*dummy*/) {
123 return "status";
124 }
125
IsWriteBlockedStatus(WriteStatus status)126 inline bool IsWriteBlockedStatus(WriteStatus status) {
127 return status == WRITE_STATUS_BLOCKED ||
128 status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
129 }
130
IsWriteError(WriteStatus status)131 inline bool IsWriteError(WriteStatus status) {
132 return status >= WRITE_STATUS_ERROR;
133 }
134
135 // A struct used to return the result of write calls including either the number
136 // of bytes written or the error code, depending upon the status.
137 struct QUICHE_EXPORT WriteResult {
WriteResultWriteResult138 constexpr WriteResult(WriteStatus status, int bytes_written_or_error_code)
139 : status(status), bytes_written(bytes_written_or_error_code) {}
140
WriteResultWriteResult141 constexpr WriteResult() : WriteResult(WRITE_STATUS_ERROR, 0) {}
142
143 bool operator==(const WriteResult& other) const {
144 if (status != other.status) {
145 return false;
146 }
147 switch (status) {
148 case WRITE_STATUS_OK:
149 return bytes_written == other.bytes_written;
150 case WRITE_STATUS_BLOCKED:
151 case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
152 return true;
153 default:
154 return error_code == other.error_code;
155 }
156 }
157
158 QUICHE_EXPORT friend std::ostream& operator<<(std::ostream& os,
159 const WriteResult& s);
160
set_batch_idWriteResult161 WriteResult& set_batch_id(uint32_t new_batch_id) {
162 batch_id = new_batch_id;
163 return *this;
164 }
165
166 WriteStatus status;
167 // Number of packets dropped as a result of this write.
168 // Only used by batch writers. Otherwise always 0.
169 uint16_t dropped_packets = 0;
170 // The batch id the packet being written belongs to. For debugging only.
171 // Only used by batch writers. Only valid if the packet being written started
172 // a new batch, or added to an existing batch.
173 uint32_t batch_id = 0;
174 // The delta between a packet's ideal and actual send time:
175 // actual_send_time = ideal_send_time + send_time_offset
176 // = (now + release_time_delay) + send_time_offset
177 // Only valid if |status| is WRITE_STATUS_OK.
178 QuicTime::Delta send_time_offset = QuicTime::Delta::Zero();
179 // TODO(wub): In some cases, WRITE_STATUS_ERROR may set an error_code and
180 // WRITE_STATUS_BLOCKED_DATA_BUFFERED may set bytes_written. This may need
181 // some cleaning up so that perhaps both values can be set and valid.
182 union {
183 int bytes_written; // only valid when status is WRITE_STATUS_OK
184 int error_code; // only valid when status is WRITE_STATUS_ERROR
185 };
186 };
187
188 enum TransmissionType : int8_t {
189 NOT_RETRANSMISSION,
190 FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION,
191 HANDSHAKE_RETRANSMISSION, // Retransmits due to handshake timeouts.
192 ALL_ZERO_RTT_RETRANSMISSION, // Retransmits all packets encrypted with 0-RTT
193 // key.
194 LOSS_RETRANSMISSION, // Retransmits due to loss detection.
195 PTO_RETRANSMISSION, // Retransmission due to probe timeout.
196 PATH_RETRANSMISSION, // Retransmission proactively due to underlying
197 // network change.
198 ALL_INITIAL_RETRANSMISSION, // Retransmit all packets encrypted with INITIAL
199 // key.
200 LAST_TRANSMISSION_TYPE = ALL_INITIAL_RETRANSMISSION,
201 };
202
203 QUICHE_EXPORT std::string TransmissionTypeToString(
204 TransmissionType transmission_type);
205
206 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
207 TransmissionType transmission_type);
208
209 enum HasRetransmittableData : uint8_t {
210 NO_RETRANSMITTABLE_DATA,
211 HAS_RETRANSMITTABLE_DATA,
212 };
213
214 enum IsHandshake : uint8_t { NOT_HANDSHAKE, IS_HANDSHAKE };
215
216 enum class Perspective : uint8_t { IS_SERVER, IS_CLIENT };
217
218 QUICHE_EXPORT std::string PerspectiveToString(Perspective perspective);
219 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
220 const Perspective& perspective);
221
222 // Describes whether a ConnectionClose was originated by the peer.
223 enum class ConnectionCloseSource { FROM_PEER, FROM_SELF };
224
225 QUICHE_EXPORT std::string ConnectionCloseSourceToString(
226 ConnectionCloseSource connection_close_source);
227 QUICHE_EXPORT std::ostream& operator<<(
228 std::ostream& os, const ConnectionCloseSource& connection_close_source);
229
230 // Should a connection be closed silently or not.
231 enum class ConnectionCloseBehavior {
232 SILENT_CLOSE,
233 SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED,
234 SEND_CONNECTION_CLOSE_PACKET
235 };
236
237 QUICHE_EXPORT std::string ConnectionCloseBehaviorToString(
238 ConnectionCloseBehavior connection_close_behavior);
239 QUICHE_EXPORT std::ostream& operator<<(
240 std::ostream& os, const ConnectionCloseBehavior& connection_close_behavior);
241
242 enum QuicFrameType : uint8_t {
243 // Regular frame types. The values set here cannot change without the
244 // introduction of a new QUIC version.
245 PADDING_FRAME = 0,
246 RST_STREAM_FRAME = 1,
247 CONNECTION_CLOSE_FRAME = 2,
248 GOAWAY_FRAME = 3,
249 WINDOW_UPDATE_FRAME = 4,
250 BLOCKED_FRAME = 5,
251 STOP_WAITING_FRAME = 6,
252 PING_FRAME = 7,
253 CRYPTO_FRAME = 8,
254 // TODO(b/157935330): stop hard coding this when deprecate T050.
255 HANDSHAKE_DONE_FRAME = 9,
256
257 // STREAM and ACK frames are special frames. They are encoded differently on
258 // the wire and their values do not need to be stable.
259 STREAM_FRAME,
260 ACK_FRAME,
261 // The path MTU discovery frame is encoded as a PING frame on the wire.
262 MTU_DISCOVERY_FRAME,
263
264 // These are for IETF-specific frames for which there is no mapping
265 // from Google QUIC frames. These are valid/allowed if and only if IETF-
266 // QUIC has been negotiated. Values are not important, they are not
267 // the values that are in the packets (see QuicIetfFrameType, below).
268 NEW_CONNECTION_ID_FRAME,
269 MAX_STREAMS_FRAME,
270 STREAMS_BLOCKED_FRAME,
271 PATH_RESPONSE_FRAME,
272 PATH_CHALLENGE_FRAME,
273 STOP_SENDING_FRAME,
274 MESSAGE_FRAME,
275 NEW_TOKEN_FRAME,
276 RETIRE_CONNECTION_ID_FRAME,
277 ACK_FREQUENCY_FRAME,
278
279 NUM_FRAME_TYPES
280 };
281
282 // Human-readable string suitable for logging.
283 QUICHE_EXPORT std::string QuicFrameTypeToString(QuicFrameType t);
284 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
285 const QuicFrameType& t);
286
287 // Ietf frame types. These are defined in the IETF QUIC Specification.
288 // Explicit values are given in the enum so that we can be sure that
289 // the symbol will map to the correct stream type.
290 // All types are defined here, even if we have not yet implmented the
291 // quic/core/stream/.... stuff needed.
292 // Note: The protocol specifies that frame types are varint-62 encoded,
293 // further stating that the shortest encoding must be used. The current set of
294 // frame types all have values less than 0x40 (64) so can be encoded in a single
295 // byte, with the two most significant bits being 0. Thus, the following
296 // enumerations are valid as both the numeric values of frame types AND their
297 // encodings.
298 enum QuicIetfFrameType : uint64_t {
299 IETF_PADDING = 0x00,
300 IETF_PING = 0x01,
301 IETF_ACK = 0x02,
302 IETF_ACK_ECN = 0x03,
303 IETF_RST_STREAM = 0x04,
304 IETF_STOP_SENDING = 0x05,
305 IETF_CRYPTO = 0x06,
306 IETF_NEW_TOKEN = 0x07,
307 // the low-3 bits of the stream frame type value are actually flags
308 // declaring what parts of the frame are/are-not present, as well as
309 // some other control information. The code would then do something
310 // along the lines of "if ((frame_type & 0xf8) == 0x08)" to determine
311 // whether the frame is a stream frame or not, and then examine each
312 // bit specifically when/as needed.
313 IETF_STREAM = 0x08,
314 // 0x09 through 0x0f are various flag settings of the IETF_STREAM frame.
315 IETF_MAX_DATA = 0x10,
316 IETF_MAX_STREAM_DATA = 0x11,
317 IETF_MAX_STREAMS_BIDIRECTIONAL = 0x12,
318 IETF_MAX_STREAMS_UNIDIRECTIONAL = 0x13,
319 IETF_DATA_BLOCKED = 0x14,
320 IETF_STREAM_DATA_BLOCKED = 0x15,
321 IETF_STREAMS_BLOCKED_BIDIRECTIONAL = 0x16,
322 IETF_STREAMS_BLOCKED_UNIDIRECTIONAL = 0x17,
323 IETF_NEW_CONNECTION_ID = 0x18,
324 IETF_RETIRE_CONNECTION_ID = 0x19,
325 IETF_PATH_CHALLENGE = 0x1a,
326 IETF_PATH_RESPONSE = 0x1b,
327 // Both of the following are "Connection Close" frames,
328 // the first signals transport-layer errors, the second application-layer
329 // errors.
330 IETF_CONNECTION_CLOSE = 0x1c,
331 IETF_APPLICATION_CLOSE = 0x1d,
332
333 IETF_HANDSHAKE_DONE = 0x1e,
334
335 // The MESSAGE frame type has not yet been fully standardized.
336 // QUIC versions starting with 46 and before 99 use 0x20-0x21.
337 // IETF QUIC (v99) uses 0x30-0x31, see draft-pauly-quic-datagram.
338 IETF_EXTENSION_MESSAGE_NO_LENGTH = 0x20,
339 IETF_EXTENSION_MESSAGE = 0x21,
340 IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 = 0x30,
341 IETF_EXTENSION_MESSAGE_V99 = 0x31,
342
343 // An QUIC extension frame for sender control of acknowledgement delays
344 IETF_ACK_FREQUENCY = 0xaf,
345
346 // A QUIC extension frame which augments the IETF_ACK frame definition with
347 // packet receive timestamps.
348 // TODO(ianswett): Determine a proper value to replace this temporary value.
349 IETF_ACK_RECEIVE_TIMESTAMPS = 0x22,
350 };
351 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
352 const QuicIetfFrameType& c);
353 QUICHE_EXPORT std::string QuicIetfFrameTypeString(QuicIetfFrameType t);
354
355 // Masks for the bits that indicate the frame is a Stream frame vs the
356 // bits used as flags.
357 #define IETF_STREAM_FRAME_TYPE_MASK 0xfffffffffffffff8
358 #define IETF_STREAM_FRAME_FLAG_MASK 0x07
359 #define IS_IETF_STREAM_FRAME(_stype_) \
360 (((_stype_)&IETF_STREAM_FRAME_TYPE_MASK) == IETF_STREAM)
361
362 // These are the values encoded in the low-order 3 bits of the
363 // IETF_STREAMx frame type.
364 #define IETF_STREAM_FRAME_FIN_BIT 0x01
365 #define IETF_STREAM_FRAME_LEN_BIT 0x02
366 #define IETF_STREAM_FRAME_OFF_BIT 0x04
367
368 enum QuicPacketNumberLength : uint8_t {
369 PACKET_1BYTE_PACKET_NUMBER = 1,
370 PACKET_2BYTE_PACKET_NUMBER = 2,
371 PACKET_3BYTE_PACKET_NUMBER = 3, // Used in versions 45+.
372 PACKET_4BYTE_PACKET_NUMBER = 4,
373 IETF_MAX_PACKET_NUMBER_LENGTH = 4,
374 // TODO(b/145819870): Remove 6 and 8 when we remove Q043 since these values
375 // are not representable with later versions.
376 PACKET_6BYTE_PACKET_NUMBER = 6,
377 PACKET_8BYTE_PACKET_NUMBER = 8
378 };
379
380 // Used to indicate a QuicSequenceNumberLength using two flag bits.
381 enum QuicPacketNumberLengthFlags {
382 PACKET_FLAGS_1BYTE_PACKET = 0, // 00
383 PACKET_FLAGS_2BYTE_PACKET = 1, // 01
384 PACKET_FLAGS_4BYTE_PACKET = 1 << 1, // 10
385 PACKET_FLAGS_8BYTE_PACKET = 1 << 1 | 1, // 11
386 };
387
388 // The public flags are specified in one byte.
389 enum QuicPacketPublicFlags {
390 PACKET_PUBLIC_FLAGS_NONE = 0,
391
392 // Bit 0: Does the packet header contains version info?
393 PACKET_PUBLIC_FLAGS_VERSION = 1 << 0,
394
395 // Bit 1: Is this packet a public reset packet?
396 PACKET_PUBLIC_FLAGS_RST = 1 << 1,
397
398 // Bit 2: indicates the header includes a nonce.
399 PACKET_PUBLIC_FLAGS_NONCE = 1 << 2,
400
401 // Bit 3: indicates whether a ConnectionID is included.
402 PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID = 0,
403 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID = 1 << 3,
404
405 // Deprecated version 32 and earlier used two bits to indicate an 8-byte
406 // connection ID. We send this from the client because of some broken
407 // middleboxes that are still checking this bit.
408 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD = 1 << 3 | 1 << 2,
409
410 // Bits 4 and 5 describe the packet number length as follows:
411 // --00----: 1 byte
412 // --01----: 2 bytes
413 // --10----: 4 bytes
414 // --11----: 6 bytes
415 PACKET_PUBLIC_FLAGS_1BYTE_PACKET = PACKET_FLAGS_1BYTE_PACKET << 4,
416 PACKET_PUBLIC_FLAGS_2BYTE_PACKET = PACKET_FLAGS_2BYTE_PACKET << 4,
417 PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4,
418 PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_8BYTE_PACKET << 4,
419
420 // Reserved, unimplemented flags:
421
422 // Bit 7: indicates the presence of a second flags byte.
423 PACKET_PUBLIC_FLAGS_TWO_OR_MORE_BYTES = 1 << 7,
424
425 // All bits set (bits 6 and 7 are not currently used): 00111111
426 PACKET_PUBLIC_FLAGS_MAX = (1 << 6) - 1,
427 };
428
429 // The private flags are specified in one byte.
430 enum QuicPacketPrivateFlags {
431 PACKET_PRIVATE_FLAGS_NONE = 0,
432
433 // Bit 0: Does this packet contain an entropy bit?
434 PACKET_PRIVATE_FLAGS_ENTROPY = 1 << 0,
435
436 // (bits 1-7 are not used): 00000001
437 PACKET_PRIVATE_FLAGS_MAX = (1 << 1) - 1
438 };
439
440 // Defines for all types of congestion control algorithms that can be used in
441 // QUIC. Note that this is separate from the congestion feedback type -
442 // some congestion control algorithms may use the same feedback type
443 // (Reno and Cubic are the classic example for that).
444 enum CongestionControlType {
445 kCubicBytes,
446 kRenoBytes,
447 kBBR,
448 kPCC,
449 kGoogCC,
450 kBBRv2,
451 };
452
453 QUICHE_EXPORT std::string CongestionControlTypeToString(
454 CongestionControlType cc_type);
455
456 // EncryptionLevel enumerates the stages of encryption that a QUIC connection
457 // progresses through. When retransmitting a packet, the encryption level needs
458 // to be specified so that it is retransmitted at a level which the peer can
459 // understand.
460 enum EncryptionLevel : int8_t {
461 ENCRYPTION_INITIAL = 0,
462 ENCRYPTION_HANDSHAKE = 1,
463 ENCRYPTION_ZERO_RTT = 2,
464 ENCRYPTION_FORWARD_SECURE = 3,
465
466 NUM_ENCRYPTION_LEVELS,
467 };
468
EncryptionLevelIsValid(EncryptionLevel level)469 inline bool EncryptionLevelIsValid(EncryptionLevel level) {
470 return ENCRYPTION_INITIAL <= level && level < NUM_ENCRYPTION_LEVELS;
471 }
472
473 QUICHE_EXPORT std::string EncryptionLevelToString(EncryptionLevel level);
474
475 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os, EncryptionLevel level);
476
477 // Enumeration of whether a server endpoint will request a client certificate,
478 // and whether that endpoint requires a valid client certificate to establish a
479 // connection.
480 enum class ClientCertMode : uint8_t {
481 kNone, // Do not request a client certificate. Default server behavior.
482 kRequest, // Request a certificate, but allow unauthenticated connections.
483 kRequire, // Require clients to provide a valid certificate.
484 };
485
486 QUICHE_EXPORT absl::string_view ClientCertModeToString(ClientCertMode mode);
487
488 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os, ClientCertMode mode);
489
490 enum AddressChangeType : uint8_t {
491 // IP address and port remain unchanged.
492 NO_CHANGE,
493 // Port changed, but IP address remains unchanged.
494 PORT_CHANGE,
495 // IPv4 address changed, but within the /24 subnet (port may have changed.)
496 IPV4_SUBNET_CHANGE,
497 // IPv4 address changed, excluding /24 subnet change (port may have changed.)
498 IPV4_TO_IPV4_CHANGE,
499 // IP address change from an IPv4 to an IPv6 address (port may have changed.)
500 IPV4_TO_IPV6_CHANGE,
501 // IP address change from an IPv6 to an IPv4 address (port may have changed.)
502 IPV6_TO_IPV4_CHANGE,
503 // IP address change from an IPv6 to an IPv6 address (port may have changed.)
504 IPV6_TO_IPV6_CHANGE,
505 };
506
507 QUICHE_EXPORT std::string AddressChangeTypeToString(AddressChangeType type);
508
509 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
510 AddressChangeType type);
511
512 enum StreamSendingState {
513 // Sender has more data to send on this stream.
514 NO_FIN,
515 // Sender is done sending on this stream.
516 FIN,
517 // Sender is done sending on this stream and random padding needs to be
518 // appended after all stream frames.
519 FIN_AND_PADDING,
520 };
521
522 enum SentPacketState : uint8_t {
523 // The packet is in flight and waiting to be acked.
524 OUTSTANDING,
525 FIRST_PACKET_STATE = OUTSTANDING,
526 // The packet was never sent.
527 NEVER_SENT,
528 // The packet has been acked.
529 ACKED,
530 // This packet is not expected to be acked.
531 UNACKABLE,
532 // This packet has been delivered or unneeded.
533 NEUTERED,
534
535 // States below are corresponding to retransmission types in TransmissionType.
536
537 // This packet has been retransmitted when retransmission timer fires in
538 // HANDSHAKE mode.
539 HANDSHAKE_RETRANSMITTED,
540 // This packet is considered as lost, this is used for LOST_RETRANSMISSION.
541 LOST,
542 // This packet has been retransmitted when PTO fires.
543 PTO_RETRANSMITTED,
544 // This packet is sent on a different path or is a PING only packet.
545 // Do not update RTT stats and congestion control if the packet is the
546 // largest_acked of an incoming ACK.
547 NOT_CONTRIBUTING_RTT,
548 LAST_PACKET_STATE = NOT_CONTRIBUTING_RTT,
549 };
550
551 enum PacketHeaderFormat : uint8_t {
552 IETF_QUIC_LONG_HEADER_PACKET,
553 IETF_QUIC_SHORT_HEADER_PACKET,
554 GOOGLE_QUIC_PACKET,
555 };
556
557 QUICHE_EXPORT std::string PacketHeaderFormatToString(PacketHeaderFormat format);
558
559 // Information about a newly acknowledged packet.
560 struct QUICHE_EXPORT AckedPacket {
AckedPacketAckedPacket561 constexpr AckedPacket(QuicPacketNumber packet_number,
562 QuicPacketLength bytes_acked,
563 QuicTime receive_timestamp)
564 : packet_number(packet_number),
565 bytes_acked(bytes_acked),
566 receive_timestamp(receive_timestamp) {}
567
568 friend QUICHE_EXPORT std::ostream& operator<<(
569 std::ostream& os, const AckedPacket& acked_packet);
570
571 QuicPacketNumber packet_number;
572 // Number of bytes sent in the packet that was acknowledged.
573 QuicPacketLength bytes_acked;
574 // The time |packet_number| was received by the peer, according to the
575 // optional timestamp the peer included in the ACK frame which acknowledged
576 // |packet_number|. Zero if no timestamp was available for this packet.
577 QuicTime receive_timestamp;
578 };
579
580 // A vector of acked packets.
581 using AckedPacketVector = absl::InlinedVector<AckedPacket, 2>;
582
583 // Information about a newly lost packet.
584 struct QUICHE_EXPORT LostPacket {
LostPacketLostPacket585 LostPacket(QuicPacketNumber packet_number, QuicPacketLength bytes_lost)
586 : packet_number(packet_number), bytes_lost(bytes_lost) {}
587
588 friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
589 const LostPacket& lost_packet);
590
591 QuicPacketNumber packet_number;
592 // Number of bytes sent in the packet that was lost.
593 QuicPacketLength bytes_lost;
594 };
595
596 // A vector of lost packets.
597 using LostPacketVector = absl::InlinedVector<LostPacket, 2>;
598
599 // Please note, this value cannot used directly for packet serialization.
600 enum QuicLongHeaderType : uint8_t {
601 VERSION_NEGOTIATION,
602 INITIAL,
603 ZERO_RTT_PROTECTED,
604 HANDSHAKE,
605 RETRY,
606
607 INVALID_PACKET_TYPE,
608 };
609
610 QUICHE_EXPORT std::string QuicLongHeaderTypeToString(QuicLongHeaderType type);
611
612 enum QuicPacketHeaderTypeFlags : uint8_t {
613 // Bit 2: Key phase bit for IETF QUIC short header packets.
614 FLAGS_KEY_PHASE_BIT = 1 << 2,
615 // Bit 3: Google QUIC Demultiplexing bit, the short header always sets this
616 // bit to 0, allowing to distinguish Google QUIC packets from short header
617 // packets.
618 FLAGS_DEMULTIPLEXING_BIT = 1 << 3,
619 // Bits 4 and 5: Reserved bits for short header.
620 FLAGS_SHORT_HEADER_RESERVED_1 = 1 << 4,
621 FLAGS_SHORT_HEADER_RESERVED_2 = 1 << 5,
622 // Bit 6: the 'QUIC' bit.
623 FLAGS_FIXED_BIT = 1 << 6,
624 // Bit 7: Indicates the header is long or short header.
625 FLAGS_LONG_HEADER = 1 << 7,
626 };
627
628 enum MessageStatus {
629 MESSAGE_STATUS_SUCCESS,
630 MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, // Failed to send message because
631 // encryption is not established
632 // yet.
633 MESSAGE_STATUS_UNSUPPORTED, // Failed to send message because MESSAGE frame
634 // is not supported by the connection.
635 MESSAGE_STATUS_BLOCKED, // Failed to send message because connection is
636 // congestion control blocked or underlying socket is
637 // write blocked.
638 MESSAGE_STATUS_TOO_LARGE, // Failed to send message because the message is
639 // too large to fit into a single packet.
640 MESSAGE_STATUS_INTERNAL_ERROR, // Failed to send message because connection
641 // reaches an invalid state.
642 };
643
644 QUICHE_EXPORT std::string MessageStatusToString(MessageStatus message_status);
645
646 // Used to return the result of SendMessage calls
647 struct QUICHE_EXPORT MessageResult {
648 MessageResult(MessageStatus status, QuicMessageId message_id);
649
650 bool operator==(const MessageResult& other) const {
651 return status == other.status && message_id == other.message_id;
652 }
653
654 QUICHE_EXPORT friend std::ostream& operator<<(std::ostream& os,
655 const MessageResult& mr);
656
657 MessageStatus status;
658 // Only valid when status is MESSAGE_STATUS_SUCCESS.
659 QuicMessageId message_id;
660 };
661
662 QUICHE_EXPORT std::string MessageResultToString(MessageResult message_result);
663
664 enum WriteStreamDataResult {
665 WRITE_SUCCESS,
666 STREAM_MISSING, // Trying to write data of a nonexistent stream (e.g.
667 // closed).
668 WRITE_FAILED, // Trying to write nonexistent data of a stream
669 };
670
671 enum StreamType : uint8_t {
672 // Bidirectional streams allow for data to be sent in both directions.
673 BIDIRECTIONAL,
674
675 // Unidirectional streams carry data in one direction only.
676 WRITE_UNIDIRECTIONAL,
677 READ_UNIDIRECTIONAL,
678 // Not actually a stream type. Used only by QuicCryptoStream when it uses
679 // CRYPTO frames and isn't actually a QuicStream.
680 CRYPTO,
681 };
682
683 // A packet number space is the context in which a packet can be processed and
684 // acknowledged.
685 enum PacketNumberSpace : uint8_t {
686 INITIAL_DATA = 0, // Only used in IETF QUIC.
687 HANDSHAKE_DATA = 1,
688 APPLICATION_DATA = 2,
689
690 NUM_PACKET_NUMBER_SPACES,
691 };
692
693 QUICHE_EXPORT std::string PacketNumberSpaceToString(
694 PacketNumberSpace packet_number_space);
695
696 // Used to return the result of processing a received ACK frame.
697 enum AckResult {
698 PACKETS_NEWLY_ACKED,
699 NO_PACKETS_NEWLY_ACKED,
700 UNSENT_PACKETS_ACKED, // Peer acks unsent packets.
701 UNACKABLE_PACKETS_ACKED, // Peer acks packets that are not expected to be
702 // acked. For example, encryption is reestablished,
703 // and all sent encrypted packets cannot be
704 // decrypted by the peer. Version gets negotiated,
705 // and all sent packets in the different version
706 // cannot be processed by the peer.
707 PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
708 };
709
710 // Used to return the result of processing a received NEW_CID frame.
711 enum class NewConnectionIdResult : uint8_t {
712 kOk,
713 kDuplicateFrame, // Not an error.
714 kProtocolViolation,
715 };
716
717 // Indicates the fate of a serialized packet in WritePacket().
718 enum SerializedPacketFate : uint8_t {
719 DISCARD, // Discard the packet.
720 COALESCE, // Try to coalesce packet.
721 BUFFER, // Buffer packet in buffered_packets_.
722 SEND_TO_WRITER, // Send packet to writer.
723 };
724
725 QUICHE_EXPORT std::string SerializedPacketFateToString(
726 SerializedPacketFate fate);
727
728 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
729 const SerializedPacketFate fate);
730
731 // There are three different forms of CONNECTION_CLOSE.
732 enum QuicConnectionCloseType {
733 GOOGLE_QUIC_CONNECTION_CLOSE = 0,
734 IETF_QUIC_TRANSPORT_CONNECTION_CLOSE = 1,
735 IETF_QUIC_APPLICATION_CONNECTION_CLOSE = 2
736 };
737
738 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
739 const QuicConnectionCloseType type);
740
741 QUICHE_EXPORT std::string QuicConnectionCloseTypeString(
742 QuicConnectionCloseType type);
743
744 // Indicate handshake state of a connection.
745 enum HandshakeState {
746 // Initial state.
747 HANDSHAKE_START,
748 // Only used in IETF QUIC with TLS handshake. State proceeds to
749 // HANDSHAKE_PROCESSED after a packet of HANDSHAKE packet number space
750 // gets successfully processed, and the initial key can be dropped.
751 HANDSHAKE_PROCESSED,
752 // In QUIC crypto, state proceeds to HANDSHAKE_COMPLETE if client receives
753 // SHLO or server successfully processes an ENCRYPTION_FORWARD_SECURE
754 // packet, such that the handshake packets can be neutered. In IETF QUIC
755 // with TLS handshake, state proceeds to HANDSHAKE_COMPLETE once the client
756 // has both 1-RTT send and receive keys.
757 HANDSHAKE_COMPLETE,
758 // Only used in IETF QUIC with TLS handshake. State proceeds to
759 // HANDSHAKE_CONFIRMED if 1) a client receives HANDSHAKE_DONE frame or
760 // acknowledgment for 1-RTT packet or 2) server has
761 // 1-RTT send and receive keys.
762 HANDSHAKE_CONFIRMED,
763 };
764
765 struct QUICHE_EXPORT NextReleaseTimeResult {
766 // The ideal release time of the packet being sent.
767 QuicTime release_time;
768 // Whether it is allowed to send the packet before release_time.
769 bool allow_burst;
770 };
771
772 // QuicPacketBuffer bundles a buffer and a function that releases it. Note
773 // it does not assume ownership of buffer, i.e. it doesn't release the buffer on
774 // destruction.
775 struct QUICHE_EXPORT QuicPacketBuffer {
776 QuicPacketBuffer() = default;
777
QuicPacketBufferQuicPacketBuffer778 QuicPacketBuffer(char* buffer,
779 std::function<void(const char*)> release_buffer)
780 : buffer(buffer), release_buffer(std::move(release_buffer)) {}
781
782 char* buffer = nullptr;
783 std::function<void(const char*)> release_buffer;
784 };
785
786 // QuicOwnedPacketBuffer is a QuicPacketBuffer that assumes buffer ownership.
787 struct QUICHE_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer {
788 QuicOwnedPacketBuffer(const QuicOwnedPacketBuffer&) = delete;
789 QuicOwnedPacketBuffer& operator=(const QuicOwnedPacketBuffer&) = delete;
790
QuicOwnedPacketBufferQuicOwnedPacketBuffer791 QuicOwnedPacketBuffer(char* buffer,
792 std::function<void(const char*)> release_buffer)
793 : QuicPacketBuffer(buffer, std::move(release_buffer)) {}
794
QuicOwnedPacketBufferQuicOwnedPacketBuffer795 QuicOwnedPacketBuffer(QuicOwnedPacketBuffer&& owned_buffer)
796 : QuicPacketBuffer(std::move(owned_buffer)) {
797 // |owned_buffer| does not own a buffer any more.
798 owned_buffer.buffer = nullptr;
799 }
800
QuicOwnedPacketBufferQuicOwnedPacketBuffer801 explicit QuicOwnedPacketBuffer(QuicPacketBuffer&& packet_buffer)
802 : QuicPacketBuffer(std::move(packet_buffer)) {}
803
~QuicOwnedPacketBufferQuicOwnedPacketBuffer804 ~QuicOwnedPacketBuffer() {
805 if (release_buffer != nullptr && buffer != nullptr) {
806 release_buffer(buffer);
807 }
808 }
809 };
810
811 // These values must remain stable as they are uploaded to UMA histograms.
812 enum class KeyUpdateReason {
813 kInvalid = 0,
814 kRemote = 1,
815 kLocalForTests = 2,
816 kLocalForInteropRunner = 3,
817 kLocalAeadConfidentialityLimit = 4,
818 kLocalKeyUpdateLimitOverride = 5,
819 kMaxValue = kLocalKeyUpdateLimitOverride,
820 };
821
822 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
823 const KeyUpdateReason reason);
824
825 QUICHE_EXPORT std::string KeyUpdateReasonString(KeyUpdateReason reason);
826
827 using QuicSignatureAlgorithmVector = absl::InlinedVector<uint16_t, 8>;
828
829 // QuicSSLConfig contains configurations to be applied on a SSL object, which
830 // overrides the configurations in SSL_CTX.
831 struct QUICHE_EXPORT QuicSSLConfig {
832 // Whether TLS early data should be enabled. If not set, default to enabled.
833 std::optional<bool> early_data_enabled;
834 // Whether TLS session tickets are supported. If not set, default to
835 // supported.
836 std::optional<bool> disable_ticket_support;
837 // If set, used to configure the SSL object with
838 // SSL_set_signing_algorithm_prefs.
839 std::optional<QuicSignatureAlgorithmVector> signing_algorithm_prefs;
840 // Client certificate mode for mTLS support. Only used at server side.
841 ClientCertMode client_cert_mode = ClientCertMode::kNone;
842 // As a client, the ECHConfigList to use with ECH. If empty, ECH is not
843 // offered.
844 std::string ech_config_list;
845 // As a client, whether ECH GREASE is enabled. If `ech_config_list` is
846 // not empty, this value does nothing.
847 bool ech_grease_enabled = false;
848 };
849
850 // QuicDelayedSSLConfig contains a subset of SSL config that can be applied
851 // after BoringSSL's early select certificate callback. This overwrites all SSL
852 // configs applied before cert selection.
853 struct QUICHE_EXPORT QuicDelayedSSLConfig {
854 // Client certificate mode for mTLS support. Only used at server side.
855 // std::nullopt means do not change client certificate mode.
856 std::optional<ClientCertMode> client_cert_mode;
857 // QUIC transport parameters as serialized by ProofSourceHandle.
858 std::optional<std::vector<uint8_t>> quic_transport_parameters;
859 };
860
861 // ParsedClientHello contains client hello information extracted from a fully
862 // received client hello.
863 struct QUICHE_EXPORT ParsedClientHello {
864 std::string sni; // QUIC crypto and TLS.
865 std::string uaid; // QUIC crypto only.
866 std::vector<uint16_t> supported_groups; // TLS only.
867 std::vector<std::string> alpns; // QUIC crypto and TLS.
868 // The unvalidated retry token from the last received packet of a potentially
869 // multi-packet client hello. TLS only.
870 std::string retry_token;
871 bool resumption_attempted = false; // TLS only.
872 bool early_data_attempted = false; // TLS only.
873 };
874
875 QUICHE_EXPORT bool operator==(const ParsedClientHello& a,
876 const ParsedClientHello& b);
877
878 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
879 const ParsedClientHello& parsed_chlo);
880
881 // The two bits in the IP header for Explicit Congestion Notification can take
882 // one of four values.
883 enum QuicEcnCodepoint {
884 // The NOT-ECT codepoint, indicating the packet sender is not using (or the
885 // network has disabled) ECN.
886 ECN_NOT_ECT = 0,
887 // The ECT(1) codepoint, indicating the packet sender is using Low Latency,
888 // Low Loss, Scalable Throughput (L4S) ECN (RFC9330).
889 ECN_ECT1 = 1,
890 // The ECT(0) codepoint, indicating the packet sender is using classic ECN
891 // (RFC3168).
892 ECN_ECT0 = 2,
893 // The CE ("Congestion Experienced") codepoint, indicating the packet sender
894 // is using ECN, and a router is experiencing congestion.
895 ECN_CE = 3,
896 };
897
898 QUICHE_EXPORT std::string EcnCodepointToString(QuicEcnCodepoint ecn);
899
900 // This struct reports the Explicit Congestion Notification (ECN) contents of
901 // the ACK_ECN frame. They are the cumulative number of QUIC packets received
902 // for that codepoint in a given Packet Number Space.
903 struct QUICHE_EXPORT QuicEcnCounts {
904 QuicEcnCounts() = default;
QuicEcnCountsQuicEcnCounts905 QuicEcnCounts(QuicPacketCount ect0, QuicPacketCount ect1, QuicPacketCount ce)
906 : ect0(ect0), ect1(ect1), ce(ce) {}
907
ToStringQuicEcnCounts908 std::string ToString() const {
909 return absl::StrFormat("ECT(0): %s, ECT(1): %s, CE: %s",
910 std::to_string(ect0), std::to_string(ect1),
911 std::to_string(ce));
912 }
913
914 bool operator==(const QuicEcnCounts& other) const {
915 return (this->ect0 == other.ect0 && this->ect1 == other.ect1 &&
916 this->ce == other.ce);
917 }
918
919 QuicPacketCount ect0 = 0;
920 QuicPacketCount ect1 = 0;
921 QuicPacketCount ce = 0;
922 };
923
924 // Type of the priorities used by a QUIC session.
925 enum class QuicPriorityType : uint8_t {
926 // HTTP priorities as defined by RFC 9218
927 kHttp,
928 // WebTransport priorities as defined by <https://w3c.github.io/webtransport/>
929 kWebTransport,
930 };
931
932 QUICHE_EXPORT std::string QuicPriorityTypeToString(QuicPriorityType type);
933 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os, QuicPriorityType type);
934
935 } // namespace quic
936
937 #endif // QUICHE_QUIC_CORE_QUIC_TYPES_H_
938