mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 22:31:28 +02:00
BUG/MINOR: quic: support FIN on Rx-buffered STREAM frames
FIN flag on a STREAM frame was not detected if the frame was previously buffered on qcs.rx.frms before being handled. To fix this, copy the fin field from the quic_stream instance to quic_rx_strm_frm. This is required to properly notify the FIN flag on qc_treat_rx_strm_frms for the MUX layer. Without this fix, the request channel might be left opened after the last STREAM frame reception if there is out-of-order frames on the Rx path.
This commit is contained in:
parent
3bf06093dc
commit
3c4303998f
@ -496,6 +496,7 @@ struct quic_rx_strm_frm {
|
|||||||
struct eb64_node offset_node;
|
struct eb64_node offset_node;
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
const unsigned char *data;
|
const unsigned char *data;
|
||||||
|
int fin;
|
||||||
struct quic_rx_packet *pkt;
|
struct quic_rx_packet *pkt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1964,6 +1964,7 @@ struct quic_rx_strm_frm *new_quic_rx_strm_frm(struct quic_stream *stream_frm,
|
|||||||
frm->len = stream_frm->len;
|
frm->len = stream_frm->len;
|
||||||
frm->data = stream_frm->data;
|
frm->data = stream_frm->data;
|
||||||
frm->pkt = pkt;
|
frm->pkt = pkt;
|
||||||
|
frm->fin = stream_frm->fin;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frm;
|
return frm;
|
||||||
@ -2026,14 +2027,15 @@ static size_t qc_treat_rx_strm_frms(struct qcs *qcs)
|
|||||||
size_t diff;
|
size_t diff;
|
||||||
|
|
||||||
frm = eb64_entry(&frm_node->node, struct quic_rx_strm_frm, offset_node);
|
frm = eb64_entry(&frm_node->node, struct quic_rx_strm_frm, offset_node);
|
||||||
if (frm->offset_node.key > qcs->rx.offset)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (frm->offset_node.key + frm->len < qcs->rx.offset) {
|
if (frm->offset_node.key + frm->len < qcs->rx.offset) {
|
||||||
/* fully already received STREAM offset */
|
/* fully already received STREAM offset */
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUG_ON(qcs->flags & QC_SF_FIN_RECV);
|
||||||
|
if (frm->offset_node.key > qcs->rx.offset)
|
||||||
|
break;
|
||||||
|
|
||||||
diff = qcs->rx.offset - frm->offset_node.key;
|
diff = qcs->rx.offset - frm->offset_node.key;
|
||||||
frm->data += diff;
|
frm->data += diff;
|
||||||
frm->len -= diff;
|
frm->len -= diff;
|
||||||
@ -2055,6 +2057,9 @@ static size_t qc_treat_rx_strm_frms(struct qcs *qcs)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frm->fin)
|
||||||
|
qcs->flags |= QC_SF_FIN_RECV;
|
||||||
|
|
||||||
next:
|
next:
|
||||||
frm_node = eb64_next(frm_node);
|
frm_node = eb64_next(frm_node);
|
||||||
quic_rx_packet_refdec(frm->pkt);
|
quic_rx_packet_refdec(frm->pkt);
|
||||||
@ -2117,11 +2122,12 @@ static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
|
|||||||
strm->rx.offset += ret;
|
strm->rx.offset += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
total += qc_treat_rx_strm_frms(strm);
|
|
||||||
/* FIN is set only if all data were copied. */
|
/* FIN is set only if all data were copied. */
|
||||||
if (strm_frm->fin && !strm_frm->len)
|
if (strm_frm->fin && !strm_frm->len)
|
||||||
strm->flags |= QC_SF_FIN_RECV;
|
strm->flags |= QC_SF_FIN_RECV;
|
||||||
|
|
||||||
|
total += qc_treat_rx_strm_frms(strm);
|
||||||
|
|
||||||
if (total && qc->qcc->app_ops->decode_qcs(strm, strm->flags & QC_SF_FIN_RECV, qc->qcc->ctx) < 0) {
|
if (total && qc->qcc->app_ops->decode_qcs(strm, strm->flags & QC_SF_FIN_RECV, qc->qcc->ctx) < 0) {
|
||||||
TRACE_PROTO("Decoding error", QUIC_EV_CONN_PSTRM, qc);
|
TRACE_PROTO("Decoding error", QUIC_EV_CONN_PSTRM, qc);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user