pluginop_common/
quic.rs

1//! All QUIC-related common structures.
2
3use std::net::SocketAddr;
4
5use serde::{Deserialize, Serialize};
6use unix_time::Instant as UnixInstant;
7
8use crate::{Bytes, ConversionError, PluginVal};
9
10/// Define how many times a frame should be considered sending in a single packet.
11#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
12#[repr(C)]
13pub enum FrameSendKind {
14    OncePerPacket,
15    ManyPerPacket,
16}
17
18/// Determine in which order frames should be sent. The order may have some importance
19/// regarding the sending priority (an early scheduled frame would usually have more
20/// available bytes to write than a late one).
21#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
22#[repr(C)]
23pub enum FrameSendOrder {
24    /// Before the host implementation has scheduled any frame.
25    First,
26    /// After the host implementation has scheduled ACK frame(s).
27    AfterACK,
28    /// Before the host implementation has scheduled data frame(s) (STREAM).
29    BeforeStream,
30    /// After the host implementation has scheduled all possible frames.
31    End,
32}
33
34/// A registration, made by a plugin bytecode, to advertise to the host implementation
35/// its support of a specific frame type.
36#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
37#[repr(C)]
38pub struct FrameRegistration {
39    ty: u64,
40    send_order: FrameSendOrder,
41    send_kind: FrameSendKind,
42    ack_eliciting: bool,
43    count_in_flight: bool,
44}
45
46impl FrameRegistration {
47    /// Create a new frame registration with the provided parameters.
48    pub fn new(
49        ty: u64,
50        send_order: FrameSendOrder,
51        send_kind: FrameSendKind,
52        ack_eliciting: bool,
53        count_in_flight: bool,
54    ) -> Self {
55        Self {
56            ty,
57            send_order,
58            send_kind,
59            ack_eliciting,
60            count_in_flight,
61        }
62    }
63
64    /// Return the type of the frame that the registration supports.
65    pub fn get_type(&self) -> u64 {
66        self.ty
67    }
68
69    /// Return the `FrameSendOrder` indicating when the frame should be scheduled.
70    pub fn send_order(&self) -> FrameSendOrder {
71        self.send_order
72    }
73
74    /// Whether the related frame is ACK-eliciting.
75    pub fn ack_eliciting(&self) -> bool {
76        self.ack_eliciting
77    }
78
79    /// Whether the related frame is considered for the congestion window.
80    pub fn count_for_in_flight(&self) -> bool {
81        self.count_in_flight
82    }
83}
84
85/// A request from the plugin at initialization time.
86#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
87#[repr(C)]
88pub enum Registration {
89    /// A transport parameter.
90    TransportParameter(u64),
91    /// A frame.
92    Frame(FrameRegistration),
93}
94
95/// QUIC packet type.
96#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
97pub enum PacketType {
98    /// Initial packet.
99    Initial,
100
101    /// Retry packet.
102    Retry,
103
104    /// Handshake packet.
105    Handshake,
106
107    /// 0-RTT packet.
108    ZeroRTT,
109
110    /// Version negotiation packet.
111    VersionNegotiation,
112
113    /// 1-RTT short header packet.
114    Short,
115}
116
117/// An enum to enumerate the three packet number spaces, as defined by Section
118/// A.2 of quic-recovery.
119#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
120#[repr(usize)]
121pub enum KPacketNumberSpace {
122    Initial = 0,
123    Handshake = 1,
124    ApplicationData = 2,
125}
126
127/// A QUIC packet number.
128pub type PacketNumber = u64;
129
130/// Fields for the Recovery as defined by quic-recovery, Section A.3. These
131/// fields also include the congestion control ones, as defined by
132/// quic-recovery, Section B.2.
133#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
134#[repr(C)]
135pub enum RecoveryField {
136    /// The most recent RTT measurement made when receiving an ack for a
137    /// previously unacked packet.
138    LatestRtt,
139    /// The smoothed RTT of the connection, computed as described in Section
140    /// 5.3 of quic-recovery.
141    SmoothedRtt,
142    /// The RTT variation, computed as described in Section 5.3 of
143    /// quic-recovery.
144    Rttvar,
145    /// The minimum RTT seen in the connection, ignoring acknowledgment delay,
146    /// as described in Section 5.2 of quic-recovery.
147    MinRtt,
148    /// The time that the first RTT sample was obtained.
149    FirstRttSample,
150    /// The maximum amount of time by which the receiver intends to delay
151    /// acknowledgments for packets in the Application Data packet number
152    /// space, as defined by the eponymous transport parameter (Section
153    /// 18.2 of [QUIC-TRANSPORT]).  Note that the actual ack_delay in a
154    /// received ACK frame may be larger due to late timers, reordering,
155    /// or loss.
156    MaxAckDelay,
157    /// Multi-modal timer used for loss detection.
158    LossDetectionTimer,
159    /// The number of times a PTO has been sent without receiving an ack.
160    /// Unlike specified in the recovery draft, this value is returned on a
161    /// per-epoch basis. Returns a `usize`.
162    PtoCount(KPacketNumberSpace),
163    /// The time the most recent ack-eliciting packet was sent.
164    TimeOfLastAckElicitingPacket(KPacketNumberSpace),
165    /// The largest packet number acknowledged in the packet number space so
166    /// far.
167    LargestAckedPacket(KPacketNumberSpace),
168    /// The time at which the next packet inthat packet number space will be
169    /// considered lost based on exceeding the reordering window in time.
170    LossTime(KPacketNumberSpace),
171    /// An association of packet numbers in a packet number space to
172    /// information about them. Described in detail above in Appendix A.1 of
173    /// quic-recovery.
174    SentPackets(KPacketNumberSpace, PacketNumber),
175    /// The sender's current maximum payload size. Does not include UDP or IP
176    /// overhead. The max datagram size is used for congestion window
177    /// computations. An endpoint sets the value of this variable based on its
178    /// Path Maximum Transmission Unit (PMTU; see Section 14.2 of
179    /// [QUIC-TRANSPORT]), with a minimum value of 1200 bytes.
180    MaxDatagramSize,
181    /// The highest value reported for the ECN-CE counter in the packet number
182    /// space by the peer in an ACK frame. This value is used to detect
183    /// increases in the reported ECN-CE counter.
184    EcnCeCounters(KPacketNumberSpace),
185    /// The sum of the size in bytes of all sent packets that contain at least
186    /// one ack-eliciting or PADDING frame, and have not been acknowledged or
187    /// declared lost. The size does not include IP or UDP overhead, but does
188    /// include the QUIC header and AEAD overhead. Packets only containing ACK
189    /// frames do not count towards bytes_in_flight to ensure congestion control
190    /// does not impede congestion feedback.
191    BytesInFlight,
192    /// Maximum number of bytes-in-flight that may be sent.
193    CongestionWindow,
194    /// The time when QUIC first detects congestion due to loss or ECN, causing
195    /// it to enter congestion recovery. When a packet sent after this time is
196    /// acknowledged, QUIC exits congestion recovery.
197    CongestionRecoveryStartTime,
198    /// Slow start threshold in bytes. When the congestion window is below
199    /// ssthresh, the mode is slow start and the window grows by the number of
200    /// bytes acknowledged.
201    Ssthresh,
202}
203
204/// Field of a range set.
205///
206/// WARNING: unstable API.
207#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
208#[repr(C)]
209pub enum RangeSetField {
210    /// The length of the range set as a `usize`.
211    Length,
212}
213
214/// Field of a packet number space.
215///
216/// WARNING: unstable API.
217#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
218#[repr(C)]
219pub enum PacketNumberSpaceField {
220    /// Whether there is unacknowledged received packets, as a `bool`.
221    ReceivedPacketNeedAck,
222    /// Boolean indicating if a ACK frame must be sent.
223    AckEllicited,
224    /// The next packet number to be sent, as a `u64`.
225    NextPacketNumber,
226    /// Indicates if this packet number space has the keys to send packets over it, as a `bool`.
227    HasSendKeys,
228    /// Indicates if this packet number space must send some data, as a `bool`.
229    ShouldSend,
230    /// The largest packet number being received, as a `u64`.
231    LargestRxPacketNumber,
232}
233
234/// Indicates if the info is local or remote.
235#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
236#[repr(C)]
237pub enum Host {
238    Local,
239    Remote,
240}
241
242/// Indicates if the info is about source or destination.
243#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
244#[repr(C)]
245pub enum Direction {
246    Source,
247    Destination,
248}
249
250/// Classical transport parameters.
251#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
252#[repr(C)]
253pub enum TransportParameterField {
254    AckDelayExponent,
255}
256
257/// A subfield used when a collection of elements using a monotonically increasing ID.
258#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
259#[repr(C)]
260pub enum IDList {
261    /// The length of the `IDList`. This is a `u64`.
262    Length,
263    /// The minimum ID used in the `IDList´. This is a `u64`.
264    MinID,
265    /// The maximum ID used in the `IDList`. This is a `u64`.
266    MaxID,
267    /// The element with index `ID`. When getting this, returns a `Option<Elem>`.
268    Elem(u64),
269    /// Get all elements, regardless of their ID. Returns a `Vec<Elem>`.
270    All,
271}
272
273/// A QUIC address available over the connection.
274#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
275#[repr(C)]
276pub struct Address {
277    /// The value of the address.
278    pub addr: SocketAddr,
279    /// Is this address local?
280    pub local: bool,
281    /// If it is local, is this address verified by the peer? If it is remote, was
282    /// this address verified?
283    pub verified: bool,
284}
285
286/// Field of a connection.
287///
288/// WARNING: changing API.
289#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
290#[repr(C)]
291pub enum ConnectionField {
292    /// Boolean indicating if this is a server-side connection.
293    IsServer,
294    /// An `Option<u64>` being an internal identifier of this connection. Might be `None`.
295    InternalID,
296    /// The version used by this connection, as a `u32`.
297    Version,
298    /// Peer's flow control limit for the connection.
299    MaxTxData,
300    /// Connection IDs associated to this connection. The ID corresponds to the sequence number.
301    ConnectionID(Direction, IDList),
302    /// Packet number space.
303    PacketNumberSpace(KPacketNumberSpace, PacketNumberSpaceField),
304    /// Exchanged transport parameters.
305    TransportParameter(Host, TransportParameterField),
306    /// The token used over this connection, as an `Option<Vec<u8>>`.
307    Token,
308    /// The connection error code, if any, as an `Option<u64>`.
309    ConnectionError,
310    /// The handshake write level, as a `i32`.
311    /// TODO FIXME: this should probably move in a crypto field.
312    HandshakeWriteLevel,
313    /// Indicates if the handshake completed, as a `bool`.
314    IsEstablished,
315    /// Indicates if the connection is in the early data, as a `bool`.
316    IsInEarlyData,
317    /// Indicates if the connection is blocked by the connection-level flow limit, as a `bool`.
318    IsBlocked,
319    /// Indicates if the connection has flushable streams, as a `bool`.
320    HasFlushableStreams,
321    /// Indicates if the connection has blocked streams, as a `bool`.
322    HasBlockedStreams,
323    /// Returns the maximum length of a packet to be sent as a `u64`.
324    MaxSendUdpPayloadLength,
325    /// Returns the maximum number of bytes the server can send without creating amplification
326    /// attacks, as a `u64`.
327    MaxSendBytes,
328    /// The addresses associated to the connection, as `Address`.
329    Address(Host, IDList),
330    /// Total number of bytes received from the peer, as a `u64`.
331    RxData,
332}
333
334/// Fields of the SentPacket as defined by quic-recovery, Section A.1.1. Compared to the
335/// specification, additional fields are present.
336#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
337#[repr(C)]
338pub enum SentPacketField {
339    /// The packet number of the sent packet.
340    PacketNumber,
341    /// A boolean that indicates whether a packet is ack-eliciting.  If true,
342    /// it is expected that an acknowledgement will be received, though the
343    /// peer could delay sending the ACK frame containing it by up to the
344    /// max_ack_delay.
345    AckEliciting,
346    /// A boolean that indicates whether the packet counts towards bytes in
347    /// flight.
348    InFlight,
349    /// The number of bytes sent in the packet, not including UDP or IP
350    /// overhead, but including QUIC framing overhead.
351    SentBytes,
352    /// The time the packet was sent, as a `Instant`.
353    TimeSent,
354    /// The source address used by this packet, as a `SocketAddr`.
355    SourceAddress,
356    /// The destination address used by this packet, as a `SocketAddr´.
357    DestinationAddress,
358}
359
360/// Fields of the RcvPacket, only available in receiving workflow.
361#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
362#[repr(C)]
363pub enum RcvPacketField {
364    /// The source address contained in this packet, as a `SocketAddr`.
365    SourceAddress,
366    /// The destination address contained in this packet, as a `SocketAddr`.
367    DestinationAddress,
368}
369
370/// Some additional fields that may be present in QUICv1, but are not ensure to be always
371/// present.
372#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
373#[repr(C)]
374pub struct HeaderExt {
375    /// The packet number.
376    pub packet_number: Option<u64>,
377    /// The packet number length.
378    pub packet_number_len: Option<u8>,
379    /// The address verification token of the packet. Only present in `Initial` and
380    /// `Retry` packets.
381    pub token: Option<Bytes>,
382    /// The key phase of the packet.
383    pub key_phase: Option<bool>,
384}
385
386/// A QUIC packet header structure, as close as it is encoded on the wire.
387#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
388#[repr(C)]
389pub struct Header {
390    /// The first byte of the header, defining its type + version-specific bits.
391    pub first: u8,
392    /// The version contained in the header, if any. Is 0 for version negotiation packets.
393    pub version: Option<u32>,
394    /// The destination connection ID. A 0-length connection ID is Some of an empty Vec.
395    pub destination_cid: Bytes,
396    /// The source connection ID. A 0-length connection ID is Some of an empty Vec, absence of
397    /// source connection ID is None.
398    pub source_cid: Option<Bytes>,
399    /// Supported version, only present in a Version Negotiation packet. Should represents a
400    /// `Vec<u32>`.
401    pub supported_versions: Option<Bytes>,
402    /// Additional fields that are not guaranteed to stay in the invariants. The host implementation
403    /// may provide some information here for received packets, but it is not mandatory. All fields
404    /// being part of the header but requiring decryption are put there. Hence, prior to decryption
405    /// process, this field may contain meaningless information. The main use of this field is for
406    /// the sending of packets.
407    pub ext: Option<HeaderExt>,
408}
409
410/// A SentPacket as defined by quic-recovery, Section A.1.1. This has the difference that this
411/// structure is not only used for recovery purpose, but also during the whole process of packet
412/// sending.
413#[derive(Clone, Debug, Deserialize, Serialize)]
414#[repr(C)]
415pub struct SentPacket {
416    /// The header of the packet being sent.
417    pub header: Header,
418    /// The source address used by this packet.
419    pub source_address: SocketAddr,
420    /// The destination address used by this packet.
421    pub destination_address: SocketAddr,
422    /// The packet number of the sent packet.
423    pub packet_number: u64,
424    /// The length of the packet number endoded in the header.
425    pub packet_number_len: u8,
426    /// Is this packet ack-elliciting? If true, it is expected that an acknowledgment with be
427    /// received, though the peer could delay sending the ACK frame containing it up to the
428    /// max_ack_delay.
429    pub ack_elliciting: bool,
430    /// Does this packet counts towards bytes in flight?
431    pub in_flight: bool,
432    /// The number of bytes sent in this packet, not including UDP or IP overhead, but including
433    /// QUIC framing overhead.
434    pub sent_bytes: usize,
435    /// The time the packet was sent, relative to the beginning of the session.
436    pub time_sent: UnixInstant,
437}
438
439/// Each ACK Range consists of alternating Gap and ACK Range values in descending packet number
440/// order. ACK Ranges can be repeated. The number of Gap and ACK Range values is determined by the
441/// ACK Range Count field; one of each value is present for each value in the ACK Range Count field.
442#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
443#[repr(C)]
444pub struct AckRange {
445    /// A variable-length integer indicating the number of contiguous unacknowledged packets
446    /// preceding the packet number one lower than the smallest in the preceding ACK Range.
447    pub gap: u64,
448    /// A variable-length integer indicating the number of contiguous acknowledged packets
449    /// preceding the largest packet number, as determined by the preceding Gap.
450    pub ack_range_length: u64,
451}
452
453/// The ACK frame uses the least significant bit (that is, type 0x03) to indicate ECN feedback and
454/// report receipt of QUIC packets with associated ECN codepoints of ECT(0), ECT(1), or CE in the
455/// packet's IP header. ECN Counts are only present when the ACK frame type is 0x03.
456#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
457#[repr(C)]
458pub struct EcnCount {
459    /// A variable-length integer representing the total number of packets received with the ECT(0)
460    /// codepoint in the packet number space of the ACK frame.
461    pub ect0_count: u64,
462    /// A variable-length integer representing the total number of packets received with the ECT(1)
463    /// codepoint in the packet number space of the ACK frame.
464    pub ect1_count: u64,
465    /// A variable-length integer representing the total number of packets received with the CE
466    /// codepoint in the packet number space of the ACK frame.
467    pub ectce_count: u64,
468}
469
470/// A Connection ID structure, exposed to the plugin.
471#[derive(Clone, Debug, Deserialize, Serialize)]
472#[repr(C)]
473pub struct ConnectionId {
474    /// The sequence number assigned to the connection ID by the sender, encoded as a
475    /// variable-length integer.
476    pub sequence_number: u64,
477    /// The raw value of the connection ID. Its length can be obtained using the `len()` method.
478    pub connection_id: Vec<u8>,
479    /// An associated stateless reset token.
480    pub stateless_reset_token: Option<Vec<u8>>,
481}
482
483/// A QUIC frame structure, as close as it is encoded on the wire.
484#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
485#[non_exhaustive]
486#[repr(C)]
487pub enum Frame {
488    Padding(PaddingFrame),
489    Ping(PingFrame),
490    ACK(ACKFrame),
491    ResetStream(ResetStreamFrame),
492    StopSending(StopSendingFrame),
493    Crypto(CryptoFrame),
494    NewToken(NewTokenFrame),
495    Stream(StreamFrame),
496    MaxData(MaxDataFrame),
497    MaxStreamData(MaxStreamDataFrame),
498    MaxStreams(MaxStreamsFrame),
499    DataBlocked(DataBlockedFrame),
500    StreamDataBlocked(StreamDataBlockedFrame),
501    StreamsBlocked(StreamsBlockedFrame),
502    NewConnectionId(NewConnectionIdFrame),
503    RetireConnectionId(RetireConnectionIdFrame),
504    PathChallenge(PathChallengeFrame),
505    PathResponse(PathResponseFrame),
506    ConnectionClose(ConnectionCloseFrame),
507    HandshakeDone(HandshakeDoneFrame),
508    Extension(ExtensionFrame),
509}
510
511/// A PADDING frame (type=0x00) has no semantic value. PADDING frames can be used to increase
512/// the size of a packet. Padding can be used to increase an initial client packet to the
513/// minimum required size, or to provide protection against traffic analysis for protected
514/// packets.
515#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
516#[repr(C)]
517pub struct PaddingFrame {
518    /// The number of consecutive padding frames put together.
519    pub length: u64,
520}
521
522/// Endpoints can use PING frames (type=0x01) to verify that their peers are still alive or to
523/// check reachability to the peer.
524#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
525#[repr(C)]
526pub struct PingFrame;
527
528/// Receivers send ACK frames (types 0x02 and 0x03) to inform senders of packets they have
529/// received and processed. The ACK frame contains one or more ACK Ranges. ACK Ranges identify
530/// acknowledged packets. If the frame type is 0x03, ACK frames also contain the sum of QUIC
531/// packets with associated ECN marks received on the connection up until this point. QUIC
532/// implementations MUST properly handle both types and, if they have enabled ECN for packets
533/// they send, they SHOULD use the information in the ECN section to manage their congestion
534/// state.
535///
536/// QUIC acknowledgements are irrevocable. Once acknowledged, a packet remains acknowledged,
537/// even if it does not appear in a future ACK frame. This is unlike reneging for TCP SACKs
538/// (see \[RFC2018\]).
539///
540/// Packets from different packet number spaces can be identified using the same numeric value.
541/// An acknowledgment for a packet needs to indicate both a packet number and a packet number
542/// space. This is accomplished by having each ACK frame only acknowledge packet numbers in the
543/// same space as the packet in which the ACK frame is contained.
544///
545/// Version Negotiation and Retry packets cannot be acknowledged because they do not contain a
546/// packet number. Rather than relying on ACK frames, these packets are implicitly acknowledged
547/// by the next Initial packet sent by the client.
548#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
549#[repr(C)]
550pub struct ACKFrame {
551    /// A variable-length integer representing the largest packet number the peer is
552    /// acknowledging; this is usually the largest packet number that the peer has received
553    /// prior to generating the ACK frame. Unlike the packet number in the QUIC long or short
554    /// header, the value in an ACK frame is not truncated.
555    pub largest_acknowledged: u64,
556    /// A variable-length integer encoding the acknowledgement delay in microseconds; see
557    /// Section 13.2.5. It is decoded by multiplying the value in the field by 2 to the power
558    /// of the ack_delay_exponent transport parameter sent by the sender of the ACK frame; see
559    /// Section 18.2. Compared to simply expressing the delay as an integer, this encoding
560    /// allows for a larger range of values within the same number of bytes, at the cost of
561    /// lower resolution.
562    pub ack_delay: u64,
563    /// A variable-length integer specifying the number of Gap and ACK Range fields in the
564    /// frame.
565    pub ack_range_count: u64,
566    /// A variable-length integer indicating the number of contiguous packets preceding the
567    /// Largest Acknowledged that are being acknowledged. The First ACK Range is encoded as an
568    /// ACK Range; see Section 19.3.1 starting from the Largest Acknowledged. That is, the
569    /// smallest packet acknowledged in the range is determined by subtracting the First ACK
570    /// Range value from the Largest Acknowledged.
571    pub first_ack_range: u64,
572    /// Contains additional ranges of packets that are alternately not acknowledged (Gap) and
573    /// acknowledged (ACK Range).
574    pub ack_ranges: Bytes,
575    /// The three ECN Counts.
576    pub ecn_counts: Option<EcnCount>,
577}
578
579/// An endpoint uses a RESET_STREAM frame (type=0x04) to abruptly terminate the sending part of
580/// a stream.
581///
582/// After sending a RESET_STREAM, an endpoint ceases transmission and retransmission of STREAM
583/// frames on the identified stream. A receiver of RESET_STREAM can discard any data that it
584/// already received on that stream.An endpoint that receives a RESET_STREAM frame for a
585/// send-only stream MUST terminate the connection with error STREAM_STATE_ERROR.
586#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
587#[repr(C)]
588pub struct ResetStreamFrame {
589    /// A variable-length integer encoding of the Stream ID of the stream being terminated.
590    pub stream_id: u64,
591    /// A variable-length integer containing the application protocol error code that indicates
592    /// why the stream is being closed.
593    pub application_protocol_error_code: u64,
594    /// A variable-length integer indicating the final size of the stream by the RESET_STREAM
595    /// sender, in unit of bytes.
596    pub final_size: u64,
597}
598
599/// An endpoint uses a STOP_SENDING frame (type=0x05) to communicate that incoming data is
600/// being discarded on receipt at application request. STOP_SENDING requests that a peer cease
601/// transmission on a stream.
602///
603/// A STOP_SENDING frame can be sent for streams in the Recv or Size Known states; see Section
604/// 3.1. Receiving a STOP_SENDING frame for a locally-initiated stream that has not yet been
605/// created MUST be treated as a connection error of type STREAM_STATE_ERROR. An endpoint that
606/// receives a STOP_SENDING frame for a receive-only stream MUST terminate the connection with
607/// error STREAM_STATE_ERROR.
608#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
609#[repr(C)]
610pub struct StopSendingFrame {
611    /// A variable-length integer carrying the Stream ID of the stream being ignored.
612    pub stream_id: u64,
613    /// A variable-length integer containing the application-specified reason the sender is
614    /// ignoring the stream.
615    pub application_protocol_error_code: u64,
616}
617
618/// A CRYPTO frame (type=0x06) is used to transmit cryptographic handshake messages. It can be
619/// sent in all packet types except 0-RTT. The CRYPTO frame offers the cryptographic protocol
620/// an in-order stream of bytes. CRYPTO frames are functionally identical to STREAM frames,
621/// except that they do not bear a stream identifier; they are not flow controlled; and they do
622/// not carry markers for optional offset, optional length, and the end of the stream.
623#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
624#[repr(C)]
625pub struct CryptoFrame {
626    /// A variable-length integer specifying the byte offset in the stream for the data in this
627    /// CRYPTO frame.
628    pub offset: u64,
629    /// A variable-length integer specifying the length of the Crypto Data field in this CRYPTO
630    /// frame.
631    pub length: u64,
632    /// The cryptographic message data.
633    pub crypto_data: Bytes,
634}
635
636/// A server sends a NEW_TOKEN frame (type=0x07) to provide the client with a token to send in
637/// the header of an Initial packet for a future connection.
638#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
639#[repr(C)]
640pub struct NewTokenFrame {
641    /// A variable-length integer specifying the length of the token in bytes.
642    pub token_length: u64,
643    /// An opaque blob that the client can use with a future Initial packet. The token MUST NOT
644    /// be empty. A client MUST treat receipt of a NEW_TOKEN frame with an empty Token field as
645    /// a connection error of type FRAME_ENCODING_ERROR.
646    pub token: Bytes,
647}
648
649/// STREAM frames implicitly create a stream and carry stream data. The STREAM frame Type field
650/// takes the form 0b00001XXX (or the set of values from 0x08 to 0x0f). The three low-order
651/// bits of the frame type determine the fields that are present in the frame:
652/// - The OFF bit (0x04) in the frame type is set to indicate that there is an Offset field
653///   present. When set to 1, the Offset field is present. When set to 0, the Offset field is
654///   absent and the Stream Data starts at an offset of 0 (that is, the frame contains the
655///   first bytes of the stream, or the end of a stream that includes no data).
656/// - The LEN bit (0x02) in the frame type is set to indicate that there is a Length field
657///   present. If this bit is set to 0, the Length field is absent and the Stream Data field
658///   extends to the end of the packet. If this bit is set to 1, the Length field is present.
659/// - The FIN bit (0x01) indicates that the frame marks the end of the stream. The final size
660///   of the stream is the sum of the offset and the length of this frame.
661///
662/// An endpoint MUST terminate the connection with error STREAM_STATE_ERROR if it receives a
663/// STREAM frame for a locally-initiated stream that has not yet been created, or for a
664/// send-only stream.
665#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
666#[repr(C)]
667pub struct StreamFrame {
668    /// A variable-length integer indicating the stream ID of the stream.
669    pub stream_id: u64,
670    /// A variable-length integer specifying the byte offset in the stream for the data in this
671    /// STREAM frame. This field is present when the OFF bit is set to 1. When the Offset field
672    /// is absent, the offset is 0.
673    pub offset: Option<u64>,
674    /// A variable-length integer specifying the length of the Stream Data field in this STREAM
675    /// frame. This field is present when the LEN bit is set to 1. When the LEN bit is set to
676    /// 0, the Stream Data field consumes all the remaining bytes in the packet.
677    pub length: Option<u64>,
678    /// Indicates that the frame marks the end of the stream. The final size of the stream is
679    /// the sum of the offset and the length of this frame.
680    pub fin: bool,
681    /// The bytes from the designated stream to be delivered.
682    pub stream_data: Bytes,
683}
684
685/// A MAX_DATA frame (type=0x10) is used in flow control to inform the peer of the maximum
686/// amount of data that can be sent on the connection as a whole.
687#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
688#[repr(C)]
689pub struct MaxDataFrame {
690    /// A variable-length integer indicating the maximum amount of data that can be sent on the
691    /// entire connection, in units of bytes.
692    pub maximum_data: u64,
693}
694
695/// A MAX_STREAM_DATA frame (type=0x11) is used in flow control to inform a peer of the maximum
696/// amount of data that can be sent on a stream.
697///
698/// A MAX_STREAM_DATA frame can be sent for streams in the Recv state. Receiving a
699/// MAX_STREAM_DATA frame for a locally-initiated stream that has not yet been created MUST be
700/// treated as a connection error of type STREAM_STATE_ERROR. An endpoint that receives a
701/// MAX_STREAM_DATA frame for a receive-only stream MUST terminate the connection with error
702/// STREAM_STATE_ERROR.
703#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
704#[repr(C)]
705pub struct MaxStreamDataFrame {
706    /// The stream ID of the stream that is affected encoded as a variable-length integer.
707    pub stream_id: u64,
708    /// A variable-length integer indicating the maximum amount of data that can be sent on the
709    /// identified stream, in units of bytes.
710    pub maximum_stream_data: u64,
711}
712
713/// A MAX_STREAMS frame (type=0x12 or 0x13) inform the peer of the cumulative number of streams
714/// of a given type it is permitted to open. A MAX_STREAMS frame with a type of 0x12 applies to
715/// bidirectional streams, and a MAX_STREAMS frame with a type of 0x13 applies to
716/// unidirectional streams.
717#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
718#[repr(C)]
719pub struct MaxStreamsFrame {
720    /// Indicates if this frame concerns unidirectional streams (type=0x13) or bidirectional
721    /// streams (type=0x12).
722    pub unidirectional: bool,
723    /// A count of the cumulative number of streams of the corresponding type that can be
724    /// opened over the lifetime of the connection. This value cannot exceed 2^60, as it is not
725    /// possible to encode stream IDs larger than 2^62-1. Receipt of a frame that permits
726    /// opening of a stream larger than this limit MUST be treated as a FRAME_ENCODING_ERROR.
727    pub maximum_streams: u64,
728}
729
730/// A sender SHOULD send a DATA_BLOCKED frame (type=0x14) when it wishes to send data, but is
731/// unable to do so due to connection-level flow control. DATA_BLOCKED frames can be used as
732/// input to tuning of flow control algorithms.
733#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
734#[repr(C)]
735pub struct DataBlockedFrame {
736    /// A variable-length integer indicating the connection-level limit at which blocking
737    /// occurred.
738    pub maximum_data: u64,
739}
740
741/// A sender SHOULD send a STREAM_DATA_BLOCKED frame (type=0x15) when it wishes to send data,
742/// but is unable to do so due to stream-level flow control. This frame is analogous to
743/// DATA_BLOCKED.
744///
745/// An endpoint that receives a STREAM_DATA_BLOCKED frame for a send-only stream MUST terminate
746/// the connection with error STREAM_STATE_ERROR.
747#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
748#[repr(C)]
749pub struct StreamDataBlockedFrame {
750    /// A variable-length integer indicating the stream that is blocked due to flow control.
751    pub stream_id: u64,
752    /// A variable-length integer indicating the offset of the stream at which the blocking
753    /// occurred.
754    pub maximum_stream_data: u64,
755}
756
757/// A sender SHOULD send a STREAMS_BLOCKED frame (type=0x16 or 0x17) when it wishes to open a
758/// stream, but is unable to due to the maximum stream limit set by its peer. A STREAMS_BLOCKED
759/// frame of type 0x16 is used to indicate reaching the bidirectional stream limit, and a
760/// STREAMS_BLOCKED frame of type 0x17 is used to indicate reaching the unidirectional stream
761/// limit.
762///
763/// A STREAMS_BLOCKED frame does not open the stream, but informs the peer that a new stream
764/// was needed and the stream limit prevented the creation of the stream.
765#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
766#[repr(C)]
767pub struct StreamsBlockedFrame {
768    /// Indicates if this frame concerns unidirectional streams (type=0x17) or bidirectional
769    /// streams (type=0x16).
770    pub unidirectional: bool,
771    /// A variable-length integer indicating the maximum number of streams allowed at the time
772    /// the frame was sent. This value cannot exceed 2^60, as it is not possible to encode
773    /// stream IDs larger than 2^62-1. Receipt of a frame that encodes a larger stream ID MUST
774    /// be treated as a STREAM_LIMIT_ERROR or a FRAME_ENCODING_ERROR.
775    pub maximum_streams: u64,
776}
777
778/// An endpoint sends a NEW_CONNECTION_ID frame (type=0x18) to provide its peer with
779/// alternative connection IDs that can be used to break linkability when migrating
780/// connections.
781#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
782#[repr(C)]
783pub struct NewConnectionIdFrame {
784    /// The sequence number assigned to the connection ID by the sender, encoded as a
785    /// variable-length integer.
786    pub sequence_number: u64,
787    /// A variable-length integer indicating which connection IDs should be retired.
788    pub retire_prior_to: u64,
789    /// An 8-bit unsigned integer containing the length of the connection ID. Values less than
790    /// 1 and greater than 20 are invalid and MUST be treated as a connection error of type
791    /// FRAME_ENCODING_ERROR.
792    pub length: u8,
793    /// A connection ID of the specified length.
794    pub connection_id: Bytes,
795    /// A 128-bit value that will be used for a stateless reset when the associated connection
796    /// ID is used. Probably easier to manipulate as a `Vec<u8>`.
797    pub stateless_reset_token: Bytes,
798}
799
800/// An endpoint sends a RETIRE_CONNECTION_ID frame (type=0x19) to indicate that it will no
801/// longer use a connection ID that was issued by its peer. This includes the connection ID
802/// provided during the handshake. Sending a RETIRE_CONNECTION_ID frame also serves as a
803/// request to the peer to send additional connection IDs for future use. New connection IDs
804/// can be delivered to a peer using the NEW_CONNECTION_ID frame.
805///
806/// Retiring a connection ID invalidates the stateless reset token associated with that
807/// connection ID.
808#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
809#[repr(C)]
810pub struct RetireConnectionIdFrame {
811    /// The sequence number of the connection ID being retired.
812    pub sequence_number: u64,
813}
814
815/// Endpoints can use PATH_CHALLENGE frames (type=0x1a) to check reachability to the peer and
816/// for path validation during connection migration.
817#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
818#[repr(C)]
819pub struct PathChallengeFrame {
820    /// This 8-byte field contains arbitrary data.
821    pub data: u64,
822}
823
824/// A PATH_RESPONSE frame (type=0x1b) is sent in response to a PATH_CHALLENGE frame.
825#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
826#[repr(C)]
827pub struct PathResponseFrame {
828    /// This 8-byte field contains arbitrary data.
829    pub data: u64,
830}
831
832/// An endpoint sends a CONNECTION_CLOSE frame (type=0x1c or 0x1d) to notify its peer that the
833/// connection is being closed. The CONNECTION_CLOSE with a frame type of 0x1c is used to
834/// signal errors at only the QUIC layer, or the absence of errors (with the NO_ERROR code).
835/// The CONNECTION_CLOSE frame with a type of 0x1d is used to signal an error with the
836/// application that uses QUIC.
837///
838/// If there are open streams that have not been explicitly closed, they are implicitly closed
839/// when the connection is closed.
840#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
841#[repr(C)]
842pub struct ConnectionCloseFrame {
843    /// A variable-length integer error code that indicates the reason for closing this
844    /// connection. A CONNECTION_CLOSE frame of type 0x1c uses codes from the space. A
845    /// CONNECTION_CLOSE frame of type 0x1d uses codes from the application protocol error code
846    /// space.
847    pub error_code: u64,
848    /// A variable-length integer encoding the type of frame that triggered the error. A value
849    /// of 0 (equivalent to the mention of the PADDING frame) is used when the frame type is
850    /// unknown. The application-specific variant of CONNECTION_CLOSE (type 0x1d) does not
851    /// include this field.
852    pub frame_type: Option<u64>,
853    /// A variable-length integer specifying the length of the reason phrase in bytes. Because
854    /// a CONNECTION_CLOSE frame cannot be split between packets, any limits on packet size
855    /// will also limit the space available for a reason phrase.
856    pub reason_phrase_length: u64,
857    /// A human-readable explanation for why the connection was closed. This can be zero length
858    /// if the sender chooses not to give details beyond the Error Code. This SHOULD be a UTF-8
859    /// encoded string \[RFC3629\].
860    pub reason_phrase: Bytes,
861}
862
863/// The server uses a HANDSHAKE_DONE frame (type=0x1e) to signal confirmation of the handshake
864/// to the client.
865#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
866#[repr(C)]
867pub struct HandshakeDoneFrame;
868
869/// QUIC frames do not use a self-describing encoding. An endpoint therefore needs to
870/// understand the syntax of all frames before it can successfully process a packet. This
871/// allows for efficient encoding of frames, but it means that an endpoint cannot send a frame
872/// of a type that is unknown to its peer.
873///
874/// An extension to QUIC that wishes to use a new type of frame MUST first ensure that a peer
875/// is able to understand the frame. An endpoint can use a transport parameter to signal its
876/// willingness to receive extension frame types. One transport parameter can indicate support
877/// for one or more extension frame types.
878///
879/// Extensions that modify or replace core protocol functionality (including frame types) will
880/// be difficult to combine with other extensions that modify or replace the same functionality
881/// unless the behavior of the combination is explicitly defined. Such extensions SHOULD define
882/// their interaction with previously-defined extensions modifying the same protocol
883/// components.
884///
885/// Extension frames MUST be congestion controlled and MUST cause an ACK frame to be sent. The
886/// exception is extension frames that replace or supplement the ACK frame. Extension frames
887/// are not included in flow control unless specified in the extension.
888///
889/// An IANA registry is used to manage the assignment of frame types
890#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
891#[repr(C)]
892pub struct ExtensionFrame {
893    /// The corresponding frame type of the extension frame.
894    pub frame_type: u64,
895    /// The content of the frame is opaque to the host implementation. All the frame-specific
896    /// fields are maintained by the plugin itself. The tag enables the plugin to retrieve such
897    /// information.
898    pub tag: u64,
899}
900
901#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
902#[repr(C)]
903/// Network-layer information about the packet being received.
904pub struct RcvInfo {
905    /// The source address of the received packet.
906    pub from: SocketAddr,
907    /// The destination address of the received packet.
908    pub to: SocketAddr,
909}
910
911/// Inputs that can be passed to protocol operations for the QUIC protocol.
912#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)]
913#[repr(C)]
914pub enum QVal {
915    /// The QUIC Header.
916    Header(Header),
917    /// The QUIC Frame.
918    Frame(Frame),
919    /// Reception information.
920    RcvInfo(RcvInfo),
921    /// Packet number space.
922    PacketNumberSpace(KPacketNumberSpace),
923    // Packet type.
924    PacketType(PacketType),
925    // /// The next packet to be sent.
926    // SentPacket(SentPacket),
927}
928
929macro_rules! impl_from_try_from_qval {
930    ($e:ident, $v:ident, $t:ty, $err:ident, $verr:ident) => {
931        impl From<$t> for $e {
932            fn from(v: $t) -> Self {
933                $e::QUIC(QVal::$v(v))
934            }
935        }
936
937        impl TryFrom<$e> for $t {
938            type Error = $err;
939
940            fn try_from(v: $e) -> Result<Self, Self::Error> {
941                match v {
942                    $e::QUIC(QVal::$v(v)) => Ok(v),
943                    _ => Err($err::$verr),
944                }
945            }
946        }
947    };
948}
949
950impl_from_try_from_qval!(PluginVal, Header, Header, ConversionError, InvalidQVal);
951impl_from_try_from_qval!(PluginVal, Frame, Frame, ConversionError, InvalidQVal);
952impl_from_try_from_qval!(PluginVal, RcvInfo, RcvInfo, ConversionError, InvalidQVal);
953impl_from_try_from_qval!(
954    PluginVal,
955    PacketNumberSpace,
956    KPacketNumberSpace,
957    ConversionError,
958    InvalidQVal
959);
960impl_from_try_from_qval!(
961    PluginVal,
962    PacketType,
963    PacketType,
964    ConversionError,
965    InvalidQVal
966);
967
968// impl From<Header> for Input {
969//     fn from(h: Header) -> Self {
970//         Self::QUIC(QVal::Header(h))
971//     }
972// }
973
974// impl TryFrom<Input> for Header {
975//     type Error = ConversionError;
976
977//     fn try_from(value: Input) -> Result<Self, Self::Error> {
978//         match value {
979//             Input::QUIC(QVal::Header(h)) => Ok(h),
980//             _ => Err(ConversionError::InvalidHeader),
981//         }
982//     }
983// }
984
985// impl From<Frame> for Input {
986//     fn from(f: Frame) -> Self {
987//         Self::QUIC(QVal::Frame(f))
988//     }
989// }
990
991// impl TryFrom<Input> for Frame {
992//     type Error = ConversionError;
993
994//     fn try_from(value: Input) -> Result<Self, Self::Error> {
995//         match value {
996//             Input::QUIC(QVal::Frame(f)) => Ok(f),
997//             _ => Err(ConversionError::InvalidFrame),
998//         }
999//     }
1000// }
1001
1002// impl From<SentPacket> for Input {
1003//     fn from(sp: SentPacket) -> Self {
1004//         Input::QUIC(QVal::SentPacket(sp))
1005//     }
1006// }
1007
1008// impl TryFrom<Input> for SentPacket {
1009//     type Error = ConversionError;
1010
1011//     fn try_from(value: Input) -> Result<Self, Self::Error> {
1012//         match value {
1013//             Input::QUIC(QVal::SentPacket(sp)) => Ok(sp),
1014//             _ => Err(ConversionError::InvalidSentPacket),
1015//         }
1016//     }
1017// }