diff --git a/include/haproxy/mux_quic.h b/include/haproxy/mux_quic.h index 3db440676..ea6986c58 100644 --- a/include/haproxy/mux_quic.h +++ b/include/haproxy/mux_quic.h @@ -22,6 +22,7 @@ void qcs_notify_send(struct qcs *qcs); int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, char fin, char *data, struct qcs **out_qcs); +int qcc_recv_max_data(struct qcc *qcc, uint64_t max); int qcc_recv_max_stream_data(struct qcc *qcc, uint64_t id, uint64_t max); int qcc_decode_qcs(struct qcc *qcc, struct qcs *qcs); void qcc_streams_sent_done(struct qcs *qcs, uint64_t data, uint64_t offset); diff --git a/src/mux_quic.c b/src/mux_quic.c index e3a43f5b7..3242d8f8d 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -253,6 +253,24 @@ int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, return 0; } +/* Handle a new MAX_DATA frame. must contains the maximum data field of + * the frame. + * + * Returns 0 on success else non-zero. + */ +int qcc_recv_max_data(struct qcc *qcc, uint64_t max) +{ + if (qcc->rfctl.md < max) { + qcc->rfctl.md = max; + + if (qcc->flags & QC_CF_BLK_MFCTL) { + qcc->flags &= ~QC_CF_BLK_MFCTL; + tasklet_wakeup(qcc->wait_event.tasklet); + } + } + return 0; +} + /* Handle a new MAX_STREAM_DATA frame. must contains the maximum data * field of the frame and is the identifier of the QUIC stream. * diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 799621ba8..9a1e9eb5c 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -2455,6 +2455,11 @@ static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct ssl_sock_ctx *ct break; } case QUIC_FT_MAX_DATA: + if (qc->mux_state == QC_MUX_READY) { + struct quic_max_data *data = &frm.max_data; + qcc_recv_max_data(qc->qcc, data->max_data); + } + break; case QUIC_FT_MAX_STREAM_DATA: if (qc->mux_state == QC_MUX_READY) { struct quic_max_stream_data *data = &frm.max_stream_data;