mirror of
https://github.com/haproxy/haproxy.git
synced 2026-06-10 17:32:03 -04:00
MEDIUM: ssl: allow h3/QMux negotiation without explicit proto
Implements automatic selection of QMux MUX if "h3" ALPN has been negotiated on top of TCP/SSL. The first part of this change is to define "alpn" member of mux_proto_list. This is necessary so that conn_get_best_mux_entry() can select it when "h3" has been chosen. As a side-effect, this also automatically sets a default ALPN to "h3" for bind lines with "proto qmux". The most important change is to adapt the SSL layer. On handshake completion, the eligible MUX is retrieved via conn_select_mux_fe/be() functions. If xprt_qmux is required by it, MUX init is delayed and QMux handshake is started first. This last change is necessary as connection flags CO_FL_QMUX_RECV/SEND are only set if "proto qmux" is explicitely set. In case xprt_qmux is activated via pure ALPN negotiation, these flags are also set on xprt_qmux_init(). This is mandatory to ensure emission/reception of QMux transport parameters will be performed as expected.
This commit is contained in:
parent
e30bcfe6cd
commit
f2b152c95e
3 changed files with 18 additions and 3 deletions
|
|
@ -4814,6 +4814,6 @@ static const struct mux_ops qmux_ops = {
|
|||
|
||||
static struct mux_proto_list mux_proto_qmux =
|
||||
{ .mux_proto = IST("qmux"), .mode = PROTO_MODE_HTTP, .side = PROTO_SIDE_BOTH, .mux = &qmux_ops,
|
||||
.init_xprt = XPRT_QMUX };
|
||||
.alpn = "\002h3", .init_xprt = XPRT_QMUX };
|
||||
|
||||
INITCALL1(STG_REGISTER, register_mux_proto, &mux_proto_qmux);
|
||||
|
|
|
|||
|
|
@ -6962,10 +6962,15 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state)
|
|||
* woke a tasklet already.
|
||||
*/
|
||||
if (ctx->conn->xprt_ctx == ctx) {
|
||||
const struct mux_proto_list *mux;
|
||||
int closed_connection = 0;
|
||||
|
||||
if (!ctx->conn->mux) {
|
||||
if (ctx->conn->flags & (CO_FL_QMUX_RECV|CO_FL_QMUX_SEND)) {
|
||||
mux = !conn_is_back(conn) ?
|
||||
conn_select_mux_fe(conn) : conn_select_mux_be(conn);
|
||||
|
||||
if (ctx->conn->flags & (CO_FL_QMUX_RECV|CO_FL_QMUX_SEND) ||
|
||||
mux->init_xprt == XPRT_QMUX) {
|
||||
const struct xprt_ops *ops = xprt_get(XPRT_QMUX);
|
||||
void *xprt_ctx_hs = NULL;
|
||||
|
||||
|
|
@ -6983,8 +6988,13 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state)
|
|||
ret = conn->xprt->start(conn, xprt_ctx_hs);
|
||||
BUG_ON(ret);
|
||||
}
|
||||
else
|
||||
else {
|
||||
/* TODO MUX selection already performs by conn_select_mux_fe/be().
|
||||
* Implement an alternative to conn_create_mux() to skip this
|
||||
* part and directly init the connection and its MUX.
|
||||
*/
|
||||
ret = conn_create_mux(ctx->conn, &closed_connection);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret >= 0 && ctx->conn->mux && !woke && ctx->conn->mux && ctx->conn->mux->wake) {
|
||||
|
|
|
|||
|
|
@ -300,6 +300,11 @@ static int xprt_qmux_init(struct connection *conn, void **xprt_ctx)
|
|||
ctx->lparams.initial_max_stream_data_bidi_remote = qcm_stream_rx_bufsz();
|
||||
ctx->lparams.initial_max_stream_data_uni = qcm_stream_rx_bufsz();
|
||||
|
||||
/* Ensure the connection flags are set. Necessary when current XPRT is
|
||||
* activated without explicit "proto qmux" configuration.
|
||||
*/
|
||||
conn->flags |= (CO_FL_QMUX_RECV|CO_FL_QMUX_SEND);
|
||||
|
||||
*xprt_ctx = ctx;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue