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