]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: mux-quic: complete flow-control for uni streams
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 21 Oct 2022 15:02:18 +0000 (17:02 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 21 Oct 2022 15:31:18 +0000 (17:31 +0200)
Max stream data was not enforced and respect for local/remote uni
streams. Previously, qcs instances incorrectly reused the limit defined
from bidirectional ones.

This is now fixed. Two fields are added in qcc structure connection :
* value for local flow control to enforce on remote uni streams
* value for remote flow control to respect on local uni streams

These two values can be reused to properly initialized msd field of a
qcs instance in qcs_new(). The rest of the code is similar.

This must be backported up to 2.6.

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

index eaedce4e6b0630d8c2681cd17fbc6e91784438d2..a55f3db26df84c6c1a35e180ec738537db869714 100644 (file)
@@ -61,8 +61,9 @@ struct qcc {
 
                uint64_t ms_uni; /* max sub-ID of uni 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 msd_bidi_l; /* initial max-stream-data on local bidi streams */
+               uint64_t msd_bidi_r; /* initial max-stream-data on remote bidi streams */
+               uint64_t msd_uni_r; /* initial max-stream-data on remote uni streams */
 
                uint64_t md; /* current max-data allowed for the peer */
                uint64_t md_init; /* initial max-data */
@@ -73,8 +74,9 @@ struct qcc {
        /* flow-control fields set by the peer which we must respect. */
        struct {
                uint64_t md; /* connection flow control limit updated on MAX_DATA frames reception */
-               uint64_t msd_bidi_l; /* initial max-stream-data for peer local streams */
-               uint64_t msd_bidi_r; /* initial max-stream-data for peer remote streams */
+               uint64_t msd_bidi_l; /* initial max-stream-data from peer on local bidi streams */
+               uint64_t msd_bidi_r; /* initial max-stream-data from peer on remote bidi streams */
+               uint64_t msd_uni_l; /* initial max-stream-data from peer on local uni streams */
        } rfctl;
 
        struct {
index 3baab767f4cca4a7ebd449ffbb5077d6aaf9a6f8..f28bd690ca3a59f068b8dfb55a2fc04509f4c1c9 100644 (file)
@@ -85,17 +85,25 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type)
        qcc->strms[type].nb_streams++;
 
        /* If stream is local, use peer remote-limit, or else the opposite. */
-       /* TODO use uni limit for unidirectional streams */
-       qcs->tx.msd = quic_stream_is_local(qcc, id) ? qcc->rfctl.msd_bidi_r :
-                                                     qcc->rfctl.msd_bidi_l;
+       if (quic_stream_is_bidi(id)) {
+               qcs->tx.msd = quic_stream_is_local(qcc, id) ? qcc->rfctl.msd_bidi_r :
+                                                             qcc->rfctl.msd_bidi_l;
+       }
+       else if (quic_stream_is_local(qcc, id)) {
+               qcs->tx.msd = qcc->rfctl.msd_uni_l;
+       }
 
        qcs->rx.ncbuf = NCBUF_NULL;
        qcs->rx.app_buf = BUF_NULL;
        qcs->rx.offset = qcs->rx.offset_max = 0;
 
-       /* 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;
+       if (quic_stream_is_bidi(id)) {
+               qcs->rx.msd = quic_stream_is_local(qcc, id) ? qcc->lfctl.msd_bidi_l :
+                                                             qcc->lfctl.msd_bidi_r;
+       }
+       else if (quic_stream_is_remote(qcc, id)) {
+               qcs->rx.msd = qcc->lfctl.msd_uni_r;
+       }
        qcs->rx.msd_init = qcs->rx.msd;
 
        qcs->tx.buf = BUF_NULL;
@@ -1943,6 +1951,7 @@ static int qc_init(struct connection *conn, struct proxy *prx,
        qcc->lfctl.ms_uni = lparams->initial_max_streams_uni;
        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.msd_uni_r = lparams->initial_max_stream_data_uni;
        qcc->lfctl.cl_bidi_r = 0;
 
        qcc->lfctl.md = qcc->lfctl.md_init = lparams->initial_max_data;
@@ -1952,6 +1961,7 @@ static int qc_init(struct connection *conn, struct proxy *prx,
        qcc->rfctl.md = rparams->initial_max_data;
        qcc->rfctl.msd_bidi_l = rparams->initial_max_stream_data_bidi_local;
        qcc->rfctl.msd_bidi_r = rparams->initial_max_stream_data_bidi_remote;
+       qcc->rfctl.msd_uni_l = rparams->initial_max_stream_data_uni;
 
        if (conn_is_back(conn)) {
                qcc->next_bidi_l    = 0x00;