Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/doc/designs/quic-design/rx-depacketizer.md
34877 views

RX depacketizer

This component takes a QUIC packet and parses the frames contained therein, to be forwarded to appropriate other components for further processing.

In the overview, this is called the "RX Frame Handler". The name "RX depacketizer" was chosen to reflect the kinship with the TX packetizer.

Main structures

Connection

Represented by an QUIC_CONNECTION object, defined in include/internal/quic_ssl.h.

Stream

Represented by an QUIC_STREAM object (yet to be defined).

Packets

Represented by the OSSL_QRX_PKT structure, defined in include/internal/quic_record_rx.h in QUIC Demuxer and Record Layer (RX+TX).

Interactions

The RX depacketizer receives a packet from the QUIC Read Record Layer, and then processes frames in two phases:

  1. Collect information for the ACK Manager

  2. Pass frame data

Other components

There are a number of other components that the RX depacketizer wants to interact with:

  • ACK manager

  • Handshake manager, which is currently unspecified. It's assumed that this will wrap around what is called the "TLS Handshake Record Layer", in the overview

  • Session manager, which is currently unspecified for QUIC, but may very well be the existing SSL_SESSION functionality, extended to fit QUIC purposes.

  • Flow control, which is currently unspecified. In the overview, it's called the "Flow Controller And Statistics Collector"

  • Connection manager, which is currently unspecified. In the overview, there's a "Connection State Machine" that the "RX Frame Handler" isn't talking directly with, so it's possible that the Connection manager will turn out to be the Handshake manager.

  • Stream SSL objects, to pass the stream data to.

Read and process a packet

Following how things are designed elsewhere, the depacketizer is assumed to be called "from above" using the following function:

__owur int ossl_quic_depacketize(QUIC_CONNECTION *connection);

This function would create an OSSL_QRX_PKT and call the QUIC Read Record Layer with a pointer to it, leaving it to the QUIC Read Record Layer to fill in the data.

This uses the ossl_qrx_read_pkt() packet reading function from QUIC Demuxer and Record Layer (RX+TX). (the OSSL_QRX_PKT structure / sub-structure needs to be extended to take an OSSL_TIME, possibly by reference, which should be filled in with the packet reception time)

Collect information for the ACK manager

This collects appropriate data into a QUIC_ACKM_RX_PKT structure:

  • The packet number (packet->packet_number)

  • The packet receive time (received)

  • The packet space, which is always:

    • QUIC_PN_SPACE_INITIAL when packet->packet_type == pkt_initial

    • QUIC_PN_SPACE_HANDSHAKE when packet->packet_type == pkt_handshake

    • QUIC_PN_SPACE_APP for all other packet types

  • The ACK eliciting flag. This is calculated by looping through all frames and noting those that are ACK eliciting, as determined from Table 1 below)

Passing frame data

This loops through all the frames, extracts data where there is any and calls diverse other components as shown in the Passed to column in Table 1 below.

Table 1

Taken from RFC 9000 12.4 Frames and Frame Types

TypeNamePassed toACK elicitingIH01
0x00padding-
0x01ping-
0x02ack 0x02ACK manager [^1]
0x03ack 0x03ACK manager [^1]
0x04reset_stream- [^2]
0x05stop_sending- [^3]
0x06cryptoHandshake manager
0x07new_tokenSession manager
0x08stream 0x08Apprioriate stream [^4]
0x09stream 0x09Apprioriate stream [^4]
0x0Astream 0x0AApprioriate stream [^4]
0x0Bstream 0x0BApprioriate stream [^4]
0x0Cstream 0x0CApprioriate stream [^4]
0x0Dstream 0x0DApprioriate stream [^4]
0x0Estream 0x0EApprioriate stream [^4]
0x0Fstream 0x0FApprioriate stream [^4]
0x10max_dataFlow control [^5]
0x11max_stream_dataFlow control [^5]
0x12max_streams 0x12Connection manager? [^6]
0x13max_streams 0x13Connection manager? [^6]
0x14data_blockedFlow control [^5]
0x15stream_data_blockedFlow control [^5]
0x16streams_blocked 0x16Connection manager? [^6]
0x17streams_blocked 0x17Connection manager? [^6]
0x18new_connection_idConnection manager
0x19retire_connection_idConnection manager
0x1Apath_challengeConnection manager? [^7]
0x1Bpath_responseConnection manager? [^7]
0x1Cconnection_close 0x1CConnection manager
0x1Dconnection_close 0x1DConnection manager
0x1Ehandshake_doneHandshake manager
????Extension Frames- [^8]

The I, H, 0, and 1 columns are validity in different packet types, with this meaning:

PktsDescription
IValid in Initial packets
HValid in Handshake packets
0Valid in 0-RTT packets
1Valid in 1-RTT packets

Notes:

[^1]: This creates and populates an QUIC_ACKM_ACK structure, then calls QUIC_ACKM_on_rx_ack_frame(), with the appropriate context (QUIC_ACKM, the created QUIC_ACKM_ACK, pkt_space and rx_time) [^2]: Immediately terminates the appropriate receiving stream QUIC_STREAM object. This includes discarding any buffered application data. For a stream that's send-only, the error STREAM_STATE_ERROR is raised, and the QUIC_CONNECTION object is terminated. [^3]: Immediately terminates the appropriate sending stream QUIC_STREAM object. For a stream that's receive-only, the error STREAM_STATE_ERROR is raised, and the QUIC_CONNECTION object is terminated. [^4]: The frame payload (Stream Data) is passed as is to the QUIC_STREAM object, along with available metadata (offset and length, as determined to be available from the lower 3 bits of the frame type). [^5]: The details of what flow control will need are yet to be determined [^6]: I imagine that max_streams and streams_blocked concern a Connection manager before anything else. [^7]: I imagine that path challenge/response concerns a Connection manager before anything else. [^8]: We have no idea what extension frames there will be. However, we must at least acknowledge their presence, so much is clear from the RFC.