diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 7a9d09a01..12b66eb23 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -56,6 +56,10 @@ struct qcc { uint64_t msd_bidi_l; /* initial max-stream-data on local streams */ uint64_t msd_bidi_r; /* initial max-stream-data on remote streams */ uint64_t cl_bidi_r; /* total count of closed remote bidi stream since last MAX_STREAMS emission */ + + uint64_t md; /* current max-data allowed for the peer */ + uint64_t md_init; /* initial max-data */ + uint64_t sent_offsets; /* sum of all offsets received */ } lfctl; /* flow-control fields set by the peer which we must respect. */ diff --git a/src/mux_quic.c b/src/mux_quic.c index 2d34a7adf..68b2bd8a5 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -314,6 +314,21 @@ void qcs_consume(struct qcs *qcs, uint64_t bytes) LIST_APPEND(&qcc->lfctl.frms, &frm->list); tasklet_wakeup(qcc->wait_event.tasklet); } + + qcc->lfctl.sent_offsets += bytes; + if (qcc->lfctl.md - qcc->lfctl.sent_offsets < qcc->lfctl.md_init / 2) { + frm = pool_zalloc(pool_head_quic_frame); + BUG_ON(!frm); /* TODO handle this properly */ + + qcc->lfctl.md = qcc->lfctl.sent_offsets + qcc->lfctl.md_init; + + LIST_INIT(&frm->reflist); + frm->type = QUIC_FT_MAX_DATA; + frm->max_data.max_data = qcc->lfctl.md; + + LIST_APPEND(&qcs->qcc->lfctl.frms, &frm->list); + tasklet_wakeup(qcs->qcc->wait_event.tasklet); + } } /* Retrieve as an ebtree node the stream with as ID, possibly allocates @@ -1249,6 +1264,9 @@ static int qc_init(struct connection *conn, struct proxy *prx, qcc->lfctl.msd_bidi_r = lparams->initial_max_stream_data_bidi_remote; qcc->lfctl.cl_bidi_r = 0; + qcc->lfctl.md = qcc->lfctl.md_init = lparams->initial_max_data; + qcc->lfctl.sent_offsets = 0; + rparams = &conn->handle.qc->tx.params; qcc->rfctl.md = rparams->initial_max_data; qcc->rfctl.msd_bidi_l = rparams->initial_max_stream_data_bidi_local;