]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: h3: send SETTINGS before STREAM frames
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 9 Jan 2023 09:34:25 +0000 (10:34 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 10 Jan 2023 16:49:50 +0000 (17:49 +0100)
Complete qcc_send_stream() function to allow to specify if the stream
should be handled in priority. Internally this will insert the qcs
instance in front of <qcc.send_list> to be able to treat it before other
streams.

This functionality is useful when some QUIC streams should be sent
before others. Most notably, this is used to guarantee that H3 SETTINGS
is done first via the control stream.

This must be backported up to 2.7.

include/haproxy/mux_quic.h
src/h3.c
src/mux_quic.c

index 1d374b0b0cbc8eb0dbb95cf11712044b19de8e86..1d5b962c0ab8aa3613ed1124eaf6a3005807e139 100644 (file)
@@ -21,7 +21,7 @@ void qcs_notify_send(struct qcs *qcs);
 
 void qcc_emit_cc_app(struct qcc *qcc, int err, int immediate);
 void qcc_reset_stream(struct qcs *qcs, int err);
-void qcc_send_stream(struct qcs *qcs);
+void qcc_send_stream(struct qcs *qcs, int urg);
 void qcc_abort_stream_read(struct qcs *qcs);
 int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset,
              char fin, char *data);
index e8404485716fd1465a4da2f2e7dc56fcdbde7d14..d51e35ff8eb2a977969c3c3b0ff492323888e148 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -1034,7 +1034,7 @@ static int h3_control_send(struct qcs *qcs, void *ctx)
        ret = b_force_xfer(res, &pos, b_data(&pos));
        if (ret > 0) {
                /* Register qcs for sending before other streams. */
-               qcc_send_stream(qcs);
+               qcc_send_stream(qcs, 1);
                h3c->flags |= H3_CF_SETTINGS_SENT;
        }
 
index 6a324acf52819bc93fe86aa81c7baf38fbb7e879..bb30f588ad53f74c8d91fe63b22162b28a2cf02f 100644 (file)
@@ -821,8 +821,11 @@ void qcc_reset_stream(struct qcs *qcs, int err)
        tasklet_wakeup(qcc->wait_event.tasklet);
 }
 
-/* Register <qcs> stream for emission of STREAM, STOP_SENDING or RESET_STREAM. */
-void qcc_send_stream(struct qcs *qcs)
+/* Register <qcs> stream for emission of STREAM, STOP_SENDING or RESET_STREAM.
+ * Set <urg> to 1 if stream content should be treated in priority compared to
+ * other streams.
+ */
+void qcc_send_stream(struct qcs *qcs, int urg)
 {
        struct qcc *qcc = qcs->qcc;
 
@@ -831,8 +834,14 @@ void qcc_send_stream(struct qcs *qcs)
        /* Cannot send if already closed. */
        BUG_ON(qcs_is_close_local(qcs));
 
-       if (!LIST_INLIST(&qcs->el_send))
-               LIST_APPEND(&qcs->qcc->send_list, &qcs->el_send);
+       if (urg) {
+               LIST_DEL_INIT(&qcs->el_send);
+               LIST_INSERT(&qcc->send_list, &qcs->el_send);
+       }
+       else {
+               if (!LIST_INLIST(&qcs->el_send))
+                       LIST_APPEND(&qcs->qcc->send_list, &qcs->el_send);
+       }
 
        TRACE_LEAVE(QMUX_EV_QCS_SEND, qcc->conn, qcs);
 }
@@ -2327,7 +2336,7 @@ static size_t qc_send_buf(struct stconn *sc, struct buffer *buf,
                qcs->flags |= QC_SF_FIN_STREAM;
 
        if (ret || fin) {
-               qcc_send_stream(qcs);
+               qcc_send_stream(qcs, 0);
                if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND))
                        tasklet_wakeup(qcs->qcc->wait_event.tasklet);
        }