From: Amaury Denoyelle Date: Tue, 26 Apr 2022 09:21:10 +0000 (+0200) Subject: MINOR: mux-quic: count local flow-control stream limit on reception X-Git-Tag: v2.6-dev8~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=44d0912f7bf7dc70281fb3ec0b03b81f4bbc95b0;p=thirdparty%2Fhaproxy.git MINOR: mux-quic: count local flow-control stream limit on reception Add new qcs fields to count the sum of bytes received for each stream. This is necessary to enforce flow-control for reception on the peer. For the moment, the implementation is partial. No MAX_STREAM_DATA or FLOW_CONTROL_ERROR are emitted. BUG_ON statements are here as a remainder. This means that for the moment we do not support POST payloads greater that the initial max-stream-data announced (256k currently). At least, we now ensure that we never buffer a frame which overflows the flow-control limit : this ensures that the memory consumption per stream should stay under control. --- diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index d95e9dc0d2..1b6a4c8cbd 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -52,6 +52,8 @@ struct qcc { struct { uint64_t ms_bidi_init; /* max initial sub-ID of bidi stream allowed for the peer */ uint64_t ms_bidi; /* max sub-ID of bidi stream allowed for the peer */ + 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 */ } lfctl; @@ -102,6 +104,7 @@ struct qcs { uint64_t offset; /* the current offset of received data */ struct buffer buf; /* receive buffer, always valid (buf_empty or real buffer) */ struct buffer app_buf; /* receive buffer used by conn_stream layer */ + uint64_t msd; /* fctl bytes limit to enforce */ } rx; struct { uint64_t offset; /* last offset of data ready to be sent */ diff --git a/src/mux_quic.c b/src/mux_quic.c index 3d1eb8c382..46681968e8 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -152,6 +152,10 @@ struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type) qcs->rx.offset = 0; qcs->rx.frms = EB_ROOT_UNIQUE; + /* TODO use uni limit for unidirectional streams */ + qcs->rx.msd = quic_stream_is_local(qcc, id) ? qcc->lfctl.msd_bidi_l : + qcc->lfctl.msd_bidi_r; + qcs->tx.buf = BUF_NULL; qcs->tx.offset = 0; qcs->tx.sent_offset = 0; @@ -360,6 +364,8 @@ int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, /* Last frame already handled for this stream. */ BUG_ON(qcs->flags & QC_SF_FIN_RECV); + /* TODO initial max-stream-data overflow. Implement FLOW_CONTROL_ERROR emission. */ + BUG_ON(offset + len > qcs->rx.msd); if (!qc_get_buf(qcs, &qcs->rx.buf)) { /* TODO should mark qcs as full */ @@ -387,10 +393,12 @@ int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, qcs->rx.offset += total; + /* TODO initial max-stream-data reached. Implement MAX_STREAM_DATA emission. */ + BUG_ON(qcs->rx.offset == qcs->rx.msd); + if (fin) qcs->flags |= QC_SF_FIN_RECV; - out: TRACE_LEAVE(QMUX_EV_QCC_RECV, qcc->conn); return 0; } @@ -1130,6 +1138,8 @@ static int qc_init(struct connection *conn, struct proxy *prx, qcc->strms[QCS_SRV_UNI].tx.max_data = 0; qcc->lfctl.ms_bidi = qcc->lfctl.ms_bidi_init = lparams->initial_max_streams_bidi; + qcc->lfctl.msd_bidi_l = lparams->initial_max_stream_data_bidi_local; + qcc->lfctl.msd_bidi_r = lparams->initial_max_stream_data_bidi_remote; qcc->lfctl.cl_bidi_r = 0; rparams = &conn->handle.qc->tx.params;