]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic: count local flow-control stream limit on reception
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 26 Apr 2022 09:21:10 +0000 (11:21 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 28 Apr 2022 12:56:14 +0000 (14:56 +0200)
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.

include/haproxy/mux_quic-t.h
src/mux_quic.c

index d95e9dc0d22def7ceef7959be93ee9f62549d7c7..1b6a4c8cbd088d27365e65a2a3eafbf53a2c5df7 100644 (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 */
index 3d1eb8c382d7126c7e6677148322629171dcddbb..46681968e86b1ab4e7c5a70472d0897af855c7ac 100644 (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;