diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index aa29c00b7..abf00bfc3 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -29,6 +29,7 @@ enum qcs_type { #define QC_CF_CC_EMIT 0x00000001 /* A CONNECTION_CLOSE is set by the MUX */ #define QC_CF_BLK_MFCTL 0x00000002 /* sending blocked due to connection flow-control */ #define QC_CF_CONN_FULL 0x00000004 /* no stream buffers available on connection */ +#define QC_CF_APP_FINAL 0x00000008 /* The application layer was finalized */ struct qcc { struct connection *conn; diff --git a/src/h3.c b/src/h3.c index e42089d21..6c6764851 100644 --- a/src/h3.c +++ b/src/h3.c @@ -819,11 +819,8 @@ static int h3_control_send(struct qcs *qcs, void *ctx) } ret = b_force_xfer(res, &pos, b_data(&pos)); - if (ret > 0) { + if (ret > 0) h3c->flags |= H3_CF_SETTINGS_SENT; - if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND)) - tasklet_wakeup(qcs->qcc->wait_event.tasklet); - } TRACE_LEAVE(H3_EV_TX_SETTINGS, qcs->qcc->conn, qcs); return ret; diff --git a/src/mux_quic.c b/src/mux_quic.c index a8ebe2be4..bf91750c5 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -897,9 +897,6 @@ int qcc_install_app_ops(struct qcc *qcc, const struct qcc_app_ops *app_ops) TRACE_PROTO("application layer initialized", QMUX_EV_QCC_NEW, qcc->conn); - if (qcc->app_ops->finalize) - qcc->app_ops->finalize(qcc->ctx); - TRACE_LEAVE(QMUX_EV_QCC_NEW, qcc->conn); return 0; @@ -1609,6 +1606,15 @@ static int qc_send(struct qcc *qcc) if (qcc->flags & QC_CF_BLK_MFCTL) return 0; + if (!(qcc->flags & QC_CF_APP_FINAL) && !eb_is_empty(&qcc->streams_by_id) && + qcc->app_ops->finalize) { + /* Finalize the application layer before sending any stream. + * For h3 this consists in preparing the control stream data (SETTINGS h3). + */ + qcc->app_ops->finalize(qcc->ctx); + qcc->flags |= QC_CF_APP_FINAL; + } + /* loop through all streams, construct STREAM frames if data available. * TODO optimize the loop to favor streams which are not too heavy. */