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.
This commit is contained in:
Amaury Denoyelle 2022-04-26 11:21:10 +02:00
parent 17014a64bf
commit 44d0912f7b
2 changed files with 14 additions and 1 deletions

View File

@ -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 */

View File

@ -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;