MEDIUM: quic: do not ack packet with invalid STREAM
If the MUX cannot handle immediately nor buffer a STREAM frame, the packet containing it must not be acknowledge. This is in conformance with the RFC9000. qcc_recv() return codes have been adjusted to differentiate an invalid frame with an already fully received offset which must be acknowledged.
This commit is contained in:
parent
d46e335683
commit
74cf237ecd
@ -345,7 +345,7 @@ struct qcs *qcc_get_qcs(struct qcc *qcc, uint64_t id)
|
||||
* to process the frame content.
|
||||
*
|
||||
* Returns a code indicating how the frame was handled.
|
||||
* - 0: frame received completly and can be dropped.
|
||||
* - 0: frame received completely and can be dropped.
|
||||
* - 1: frame not received but can be dropped.
|
||||
* - 2: frame cannot be handled, either partially or not at all. <done>
|
||||
* indicated the number of bytes handled. The rest should be buffered.
|
||||
@ -374,7 +374,7 @@ int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset,
|
||||
|
||||
if (offset + len <= qcs->rx.offset) {
|
||||
TRACE_DEVEL("leaving on already received offset", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Last frame already handled for this stream. */
|
||||
|
@ -2255,14 +2255,16 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
|
||||
strm_frm->offset.key, strm_frm->fin,
|
||||
(char *)strm_frm->data, &qcs, &done);
|
||||
|
||||
/* invalid or already received frame */
|
||||
/* invalid frame */
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
|
||||
/* already fully received offset */
|
||||
if (ret == 0 && done == 0)
|
||||
return 1;
|
||||
|
||||
/* frame not handled (partially or completely) must be buffered */
|
||||
if (ret == 2) {
|
||||
/* frame cannot be parsed at the moment and should be
|
||||
* buffered.
|
||||
*/
|
||||
frm = new_quic_rx_strm_frm(strm_frm, pkt);
|
||||
if (!frm) {
|
||||
TRACE_PROTO("Could not alloc RX STREAM frame",
|
||||
@ -2270,6 +2272,7 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* frame partially handled by the MUX */
|
||||
if (done) {
|
||||
BUG_ON(done >= frm->len); /* must never happen */
|
||||
frm->len -= done;
|
||||
@ -2305,6 +2308,8 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
|
||||
frm->offset_node.key, frm->fin,
|
||||
(char *)frm->data, &qcs, &done);
|
||||
|
||||
BUG_ON(ret == 1); /* must never happen for buffered frames */
|
||||
|
||||
/* interrupt the parsing if the frame cannot be handled
|
||||
* entirely for the moment only.
|
||||
*/
|
||||
@ -2423,10 +2428,22 @@ static int qc_handle_uni_strm_frm(struct quic_rx_packet *pkt,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns 1 on success or 0 on error. On error, the packet containing the
|
||||
* frame must not be acknowledged.
|
||||
*/
|
||||
static inline int qc_handle_strm_frm(struct quic_rx_packet *pkt,
|
||||
struct quic_stream *strm_frm,
|
||||
struct quic_conn *qc)
|
||||
{
|
||||
/* RFC9000 13.1. Packet Processing
|
||||
*
|
||||
* A packet MUST NOT be acknowledged until packet protection has been
|
||||
* successfully removed and all frames contained in the packet have
|
||||
* been processed. For STREAM frames, this means the data has been
|
||||
* enqueued in preparation to be received by the application protocol,
|
||||
* but it does not require that data be delivered and consumed.
|
||||
*/
|
||||
|
||||
if (strm_frm->id & QCS_ID_DIR_BIT)
|
||||
return qc_handle_uni_strm_frm(pkt, strm_frm, qc);
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user