MEDIUM: xprt-quic: finalize app layer initialization after ALPN nego
The app layer is initialized after the handshake completion by the XPRT
stack. Call the finalize operation just after that.
Remove the erroneous call to finalize by the mux in the TPs callback as
the app layer is not yet initialized at this stage.
This should fix the missing H3 settings currently not emitted by
haproxy.
diff --git a/src/mux_quic.c b/src/mux_quic.c
index b15f1f7..64990e4 100644
--- a/src/mux_quic.c
+++ b/src/mux_quic.c
@@ -498,12 +498,6 @@
qcc->strms[QCS_SRV_BIDI].rx.max_data = srv_params->initial_max_stream_data_bidi_local;
qcc->strms[QCS_SRV_UNI].rx.max_data = srv_params->initial_max_stream_data_uni;
}
-
- /* Now that we have all the flow control information, we can finalize the application
- * context.
- */
- if (qcc->app_ops)
- qcc->app_ops->finalize(qcc->ctx);
}
/* Initialize the mux once it's attached. For outgoing connections, the context
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index c7056c0..0ed7336 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -1827,6 +1827,7 @@
{
int ssl_err, state;
struct quic_conn *qc;
+ const struct qcc_app_ops *app_ops;
const char *alpn;
int alpn_len;
@@ -1887,12 +1888,10 @@
conn_get_alpn(ctx->conn, &alpn, &alpn_len);
if (alpn_len >= 2 && memcmp(alpn, "h3", 2) == 0) {
- qc->qcc->app_ops = &h3_ops;
- if (!qc->qcc->app_ops->init(qc->qcc))
- goto err;
+ app_ops = qc->qcc->app_ops = &h3_ops;
}
else if (alpn_len >= 10 && memcmp(alpn, "hq-interop", 10) == 0) {
- qc->qcc->app_ops = &hq_interop_ops;
+ app_ops = qc->qcc->app_ops = &hq_interop_ops;
}
else {
/* TODO RFC9001 8.1. Protocol Negotiation
@@ -1902,6 +1901,14 @@
goto err;
}
+ if (app_ops->init) {
+ if (!app_ops->init(qc->qcc))
+ goto err;
+ }
+
+ if (app_ops->finalize)
+ app_ops->finalize(qc->qcc->ctx);
+
out:
TRACE_LEAVE(QUIC_EV_CONN_SSLDATA, ctx->conn);
return 1;