xref: /freebsd/crypto/openssl/doc/designs/quic-design/rx-depacketizer.md (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre ProncheryRX depacketizer
2*e7be843bSPierre Pronchery===============
3*e7be843bSPierre Pronchery
4*e7be843bSPierre ProncheryThis component takes a QUIC packet and parses the frames contained therein,
5*e7be843bSPierre Proncheryto be forwarded to appropriate other components for further processing.
6*e7be843bSPierre Pronchery
7*e7be843bSPierre ProncheryIn the [overview], this is called the "RX Frame Handler".  The name "RX
8*e7be843bSPierre Proncherydepacketizer" was chosen to reflect the kinship with the [TX packetizer].
9*e7be843bSPierre Pronchery
10*e7be843bSPierre ProncheryMain structures
11*e7be843bSPierre Pronchery---------------
12*e7be843bSPierre Pronchery
13*e7be843bSPierre Pronchery### Connection
14*e7be843bSPierre Pronchery
15*e7be843bSPierre ProncheryRepresented by an `QUIC_CONNECTION` object, defined in
16*e7be843bSPierre Pronchery[`include/internal/quic_ssl.h`](../../../include/internal/quic_ssl.h).
17*e7be843bSPierre Pronchery
18*e7be843bSPierre Pronchery### Stream
19*e7be843bSPierre Pronchery
20*e7be843bSPierre ProncheryRepresented by an `QUIC_STREAM` object (yet to be defined).
21*e7be843bSPierre Pronchery
22*e7be843bSPierre Pronchery### Packets
23*e7be843bSPierre Pronchery
24*e7be843bSPierre ProncheryRepresented by the `OSSL_QRX_PKT` structure, defined in
25*e7be843bSPierre Pronchery`include/internal/quic_record_rx.h` in [QUIC Demuxer and Record Layer (RX+TX)].
26*e7be843bSPierre Pronchery
27*e7be843bSPierre ProncheryInteractions
28*e7be843bSPierre Pronchery------------
29*e7be843bSPierre Pronchery
30*e7be843bSPierre ProncheryThe RX depacketizer receives a packet from the QUIC Read Record Layer, and
31*e7be843bSPierre Proncherythen processes frames in two phases:
32*e7be843bSPierre Pronchery
33*e7be843bSPierre Pronchery1.  [Collect information for the ACK Manager](#collect-information-for-the-ack-manager)
34*e7be843bSPierre Pronchery2.  [Pass frame data](#pass-frame-data)
35*e7be843bSPierre Pronchery
36*e7be843bSPierre Pronchery### Other components
37*e7be843bSPierre Pronchery
38*e7be843bSPierre ProncheryThere are a number of other components that the RX depacketizer wants to
39*e7be843bSPierre Proncheryinteract with:
40*e7be843bSPierre Pronchery
41*e7be843bSPierre Pronchery-   [ACK manager]
42*e7be843bSPierre Pronchery-   Handshake manager, which is currently unspecified.  It's assumed that
43*e7be843bSPierre Pronchery    this will wrap around what is called the "TLS Handshake Record Layer",
44*e7be843bSPierre Pronchery    in the [overview]
45*e7be843bSPierre Pronchery-   Session manager, which is currently unspecified for QUIC, but may very
46*e7be843bSPierre Pronchery    well be the existing `SSL_SESSION` functionality, extended to fit QUIC
47*e7be843bSPierre Pronchery    purposes.
48*e7be843bSPierre Pronchery-   Flow control, which is currently unspecified.  In the [overview], it's
49*e7be843bSPierre Pronchery    called the "Flow Controller And Statistics Collector"
50*e7be843bSPierre Pronchery-   Connection manager, which is currently unspecified.  In the [overview],
51*e7be843bSPierre Pronchery    there's a "Connection State Machine" that the "RX Frame Handler" isn't
52*e7be843bSPierre Pronchery    talking directly with, so it's possible that the Connection manager will
53*e7be843bSPierre Pronchery    turn out to be the Handshake manager.
54*e7be843bSPierre Pronchery-   Stream SSL objects, to pass the stream data to.
55*e7be843bSPierre Pronchery
56*e7be843bSPierre Pronchery### Read and process a packet
57*e7be843bSPierre Pronchery
58*e7be843bSPierre ProncheryFollowing how things are designed elsewhere, the depacketizer is assumed to
59*e7be843bSPierre Proncherybe called "from above" using the following function:
60*e7be843bSPierre Pronchery
61*e7be843bSPierre Pronchery``` C
62*e7be843bSPierre Pronchery__owur int ossl_quic_depacketize(QUIC_CONNECTION *connection);
63*e7be843bSPierre Pronchery```
64*e7be843bSPierre Pronchery
65*e7be843bSPierre ProncheryThis function would create an `OSSL_QRX_PKT` and call the QUIC Read Record
66*e7be843bSPierre ProncheryLayer with a pointer to it, leaving it to the QUIC Read Record Layer to fill
67*e7be843bSPierre Proncheryin the data.
68*e7be843bSPierre Pronchery
69*e7be843bSPierre ProncheryThis uses the `ossl_qrx_read_pkt()` packet reading function from
70*e7be843bSPierre Pronchery[QUIC Demuxer and Record Layer (RX+TX)].
71*e7be843bSPierre Pronchery(the `OSSL_QRX_PKT` structure / sub-structure needs to be extended to take
72*e7be843bSPierre Proncheryan `OSSL_TIME`, possibly by reference, which should be filled in with the
73*e7be843bSPierre Proncherypacket reception time)
74*e7be843bSPierre Pronchery
75*e7be843bSPierre Pronchery### Collect information for the [ACK manager]
76*e7be843bSPierre Pronchery
77*e7be843bSPierre ProncheryThis collects appropriate data into a `QUIC_ACKM_RX_PKT` structure:
78*e7be843bSPierre Pronchery
79*e7be843bSPierre Pronchery-   The packet number (`packet->packet_number`)
80*e7be843bSPierre Pronchery-   The packet receive time (`received`)
81*e7be843bSPierre Pronchery-   The packet space, which is always:
82*e7be843bSPierre Pronchery    -   `QUIC_PN_SPACE_INITIAL` when `packet->packet_type == pkt_initial`
83*e7be843bSPierre Pronchery    -   `QUIC_PN_SPACE_HANDSHAKE` when `packet->packet_type == pkt_handshake`
84*e7be843bSPierre Pronchery    -   `QUIC_PN_SPACE_APP` for all other packet types
85*e7be843bSPierre Pronchery-   The ACK eliciting flag.  This is calculated by looping through all
86*e7be843bSPierre Pronchery    frames and noting those that are ACK eliciting, as determined from
87*e7be843bSPierre Pronchery    [Table 1](#table-1) below)
88*e7be843bSPierre Pronchery
89*e7be843bSPierre Pronchery### Passing frame data
90*e7be843bSPierre Pronchery
91*e7be843bSPierre ProncheryThis loops through all the frames, extracts data where there is any
92*e7be843bSPierre Proncheryand calls diverse other components as shown in the Passed to column in
93*e7be843bSPierre Pronchery[Table 1](#table-1) below.
94*e7be843bSPierre Pronchery
95*e7be843bSPierre Pronchery#### Table 1
96*e7be843bSPierre Pronchery
97*e7be843bSPierre ProncheryTaken from [RFC 9000 12.4 Frames and Frame Types]
98*e7be843bSPierre Pronchery
99*e7be843bSPierre Pronchery| Type | Name                    | Passed to                | ACK eliciting | I        | H        | 0        | 1        |
100*e7be843bSPierre Pronchery|------|-------------------------|--------------------------|---------------|----------|----------|----------|----------|
101*e7be843bSPierre Pronchery| 0x00 | [padding]               | -                        |               | ✔ | ✔ | ✔ | ✔ |
102*e7be843bSPierre Pronchery| 0x01 | [ping]                  | -                        | ✔      | ✔ | ✔ | ✔ | ✔ |
103*e7be843bSPierre Pronchery| 0x02 | [ack 0x02]              | [ACK manager] [^1]       |               | ✔ | ✔ |          | ✔ |
104*e7be843bSPierre Pronchery| 0x03 | [ack 0x03]              | [ACK manager] [^1]       |               | ✔ | ✔ |          | ✔ |
105*e7be843bSPierre Pronchery| 0x04 | [reset_stream]          | - [^2]                   | ✔      |          |          | ✔ | ✔ |
106*e7be843bSPierre Pronchery| 0x05 | [stop_sending]          | - [^3]                   | ✔      |          |          | ✔ | ✔ |
107*e7be843bSPierre Pronchery| 0x06 | [crypto]                | Handshake manager        | ✔      | ✔ | ✔ |          | ✔ |
108*e7be843bSPierre Pronchery| 0x07 | [new_token]             | Session manager          | ✔      |          |          |          | ✔ |
109*e7be843bSPierre Pronchery| 0x08 | [stream 0x08]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
110*e7be843bSPierre Pronchery| 0x09 | [stream 0x09]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
111*e7be843bSPierre Pronchery| 0x0A | [stream 0x0A]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
112*e7be843bSPierre Pronchery| 0x0B | [stream 0x0B]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
113*e7be843bSPierre Pronchery| 0x0C | [stream 0x0C]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
114*e7be843bSPierre Pronchery| 0x0D | [stream 0x0D]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
115*e7be843bSPierre Pronchery| 0x0E | [stream 0x0E]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
116*e7be843bSPierre Pronchery| 0x0F | [stream 0x0F]           | Apprioriate stream [^4]  | ✔      |          |          | ✔ | ✔ |
117*e7be843bSPierre Pronchery| 0x10 | [max_data]              | Flow control [^5]        | ✔      |          |          | ✔ | ✔ |
118*e7be843bSPierre Pronchery| 0x11 | [max_stream_data]       | Flow control [^5]        | ✔      |          |          | ✔ | ✔ |
119*e7be843bSPierre Pronchery| 0x12 | [max_streams 0x12]      | Connection manager? [^6] | ✔      |          |          | ✔ | ✔ |
120*e7be843bSPierre Pronchery| 0x13 | [max_streams 0x13]      | Connection manager? [^6] | ✔      |          |          | ✔ | ✔ |
121*e7be843bSPierre Pronchery| 0x14 | [data_blocked]          | Flow control [^5]        | ✔      |          |          | ✔ | ✔ |
122*e7be843bSPierre Pronchery| 0x15 | [stream_data_blocked]   | Flow control [^5]        | ✔      |          |          | ✔ | ✔ |
123*e7be843bSPierre Pronchery| 0x16 | [streams_blocked 0x16]  | Connection manager? [^6] | ✔      |          |          | ✔ | ✔ |
124*e7be843bSPierre Pronchery| 0x17 | [streams_blocked 0x17]  | Connection manager? [^6] | ✔      |          |          | ✔ | ✔ |
125*e7be843bSPierre Pronchery| 0x18 | [new_connection_id]     | Connection manager       | ✔      |          |          | ✔ | ✔ |
126*e7be843bSPierre Pronchery| 0x19 | [retire_connection_id]  | Connection manager       | ✔      |          |          | ✔ | ✔ |
127*e7be843bSPierre Pronchery| 0x1A | [path_challenge]        | Connection manager? [^7] | ✔      |          |          | ✔ | ✔ |
128*e7be843bSPierre Pronchery| 0x1B | [path_response]         | Connection manager? [^7] | ✔      |          |          |          | ✔ |
129*e7be843bSPierre Pronchery| 0x1C | [connection_close 0x1C] | Connection manager       |               | ✔ | ✔ | ✔ | ✔ |
130*e7be843bSPierre Pronchery| 0x1D | [connection_close 0x1D] | Connection manager       |               |          |          | ✔ | ✔ |
131*e7be843bSPierre Pronchery| 0x1E | [handshake_done]        | Handshake manager        | ✔      |          |          |          | ✔ |
132*e7be843bSPierre Pronchery| ???? | *[Extension Frames]*    | - [^8]                   | ✔      |          |          |          |          |
133*e7be843bSPierre Pronchery
134*e7be843bSPierre ProncheryThe I, H, 0, and 1 columns are validity in different packet types, with this meaning:
135*e7be843bSPierre Pronchery
136*e7be843bSPierre Pronchery| Pkts | Description                |
137*e7be843bSPierre Pronchery|:----:|----------------------------|
138*e7be843bSPierre Pronchery| I    | Valid in Initial packets   |
139*e7be843bSPierre Pronchery| H    | Valid in Handshake packets |
140*e7be843bSPierre Pronchery| 0    | Valid in 0-RTT packets     |
141*e7be843bSPierre Pronchery| 1    | Valid in 1-RTT packets     |
142*e7be843bSPierre Pronchery
143*e7be843bSPierre ProncheryNotes:
144*e7be843bSPierre Pronchery
145*e7be843bSPierre Pronchery[^1]: This creates and populates an `QUIC_ACKM_ACK` structure, then calls
146*e7be843bSPierre Pronchery    `QUIC_ACKM_on_rx_ack_frame()`, with the appropriate context
147*e7be843bSPierre Pronchery    (`QUIC_ACKM`, the created `QUIC_ACKM_ACK`, `pkt_space` and `rx_time`)
148*e7be843bSPierre Pronchery[^2]: Immediately terminates the appropriate receiving stream `QUIC_STREAM`
149*e7be843bSPierre Pronchery    object.
150*e7be843bSPierre Pronchery    This includes discarding any buffered application data.
151*e7be843bSPierre Pronchery    For a stream that's send-only, the error `STREAM_STATE_ERROR` is raised,
152*e7be843bSPierre Pronchery    and the `QUIC_CONNECTION` object is terminated.
153*e7be843bSPierre Pronchery[^3]: Immediately terminates the appropriate sending stream `QUIC_STREAM`
154*e7be843bSPierre Pronchery    object.
155*e7be843bSPierre Pronchery    For a stream that's receive-only, the error `STREAM_STATE_ERROR` is
156*e7be843bSPierre Pronchery    raised, and the `QUIC_CONNECTION` object is terminated.
157*e7be843bSPierre Pronchery[^4]: The frame payload (Stream Data) is passed as is to the `QUIC_STREAM`
158*e7be843bSPierre Pronchery    object, along with available metadata (offset and length, as determined
159*e7be843bSPierre Pronchery    to be available from the lower 3 bits of the frame type).
160*e7be843bSPierre Pronchery[^5]: The details of what flow control will need are yet to be determined
161*e7be843bSPierre Pronchery[^6]: I imagine that `max_streams` and `streams_blocked` concern a Connection
162*e7be843bSPierre Pronchery    manager before anything else.
163*e7be843bSPierre Pronchery[^7]: I imagine that path challenge/response concerns a Connection manager
164*e7be843bSPierre Pronchery    before anything else.
165*e7be843bSPierre Pronchery[^8]: We have no idea what extension frames there will be.  However, we
166*e7be843bSPierre Pronchery    must at least acknowledge their presence, so much is clear from the RFC.
167*e7be843bSPierre Pronchery
168*e7be843bSPierre Pronchery[overview]: https://github.com/openssl/openssl/blob/master/doc/designs/quic-design/quic-overview.md
169*e7be843bSPierre Pronchery[TX packetizer]: https://github.com/openssl/openssl/pull/18570
170*e7be843bSPierre Pronchery[SSL object refactoring using SSL_CONNECTION object]: https://github.com/openssl/openssl/pull/18612
171*e7be843bSPierre Pronchery[QUIC Demuxer and Record Layer (RX+TX)]: https://github.com/openssl/openssl/pull/18949
172*e7be843bSPierre Pronchery[ACK manager]: https://github.com/openssl/openssl/pull/18564
173*e7be843bSPierre Pronchery[RFC 9000 12.4 Frames and Frame Types]: https://datatracker.ietf.org/doc/html/rfc9000#section-12.4
174*e7be843bSPierre Pronchery[padding]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.1
175*e7be843bSPierre Pronchery[ping]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.2
176*e7be843bSPierre Pronchery[ack 0x02]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.3
177*e7be843bSPierre Pronchery[ack 0x03]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.3
178*e7be843bSPierre Pronchery[reset_stream]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.4
179*e7be843bSPierre Pronchery[stop_sending]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.5
180*e7be843bSPierre Pronchery[crypto]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.6
181*e7be843bSPierre Pronchery[new_token]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.7
182*e7be843bSPierre Pronchery[stream 0x08]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
183*e7be843bSPierre Pronchery[stream 0x09]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
184*e7be843bSPierre Pronchery[stream 0x0A]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
185*e7be843bSPierre Pronchery[stream 0x0B]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
186*e7be843bSPierre Pronchery[stream 0x0C]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
187*e7be843bSPierre Pronchery[stream 0x0D]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
188*e7be843bSPierre Pronchery[stream 0x0E]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
189*e7be843bSPierre Pronchery[stream 0x0F]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.8
190*e7be843bSPierre Pronchery[max_data]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.9
191*e7be843bSPierre Pronchery[max_stream_data]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.10
192*e7be843bSPierre Pronchery[max_streams 0x12]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.11
193*e7be843bSPierre Pronchery[max_streams 0x13]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.11
194*e7be843bSPierre Pronchery[data_blocked]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.12
195*e7be843bSPierre Pronchery[stream_data_blocked]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.13
196*e7be843bSPierre Pronchery[streams_blocked 0x16]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.14
197*e7be843bSPierre Pronchery[streams_blocked 0x17]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.14
198*e7be843bSPierre Pronchery[new_connection_id]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.15
199*e7be843bSPierre Pronchery[retire_connection_id]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.16
200*e7be843bSPierre Pronchery[path_challenge]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.17
201*e7be843bSPierre Pronchery[path_response]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.18
202*e7be843bSPierre Pronchery[connection_close 0x1C]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.19
203*e7be843bSPierre Pronchery[connection_close 0x1D]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.19
204*e7be843bSPierre Pronchery[handshake_done]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.20
205*e7be843bSPierre Pronchery[Extension Frames]: https://datatracker.ietf.org/doc/html/rfc9000#section-19.21
206