From: Amaury Denoyelle Date: Thu, 29 Sep 2022 16:31:24 +0000 (+0200) Subject: MINOR: quic: remove unnecessary quic_session_accept() X-Git-Tag: v2.7-dev9~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0aba11e9e;p=thirdparty%2Fhaproxy.git MINOR: quic: remove unnecessary quic_session_accept() A specialized listener accept was previously used for QUIC. This is now unneeded and we can revert to the default one session_accept_fd(). One change of importance is that the call order between conn_xprt_start() and conn_complete_session() is now reverted to the default one. This means that MUX instance is now NULL during qc_xprt_start() and its app-ops layer cannot be set here. This operation has been delayed to qc_init() to prevent a segfault. This should be backported up to 2.6. --- diff --git a/src/cfgparse.c b/src/cfgparse.c index 2164880478..f80008c259 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -4326,7 +4326,7 @@ init_proxies_list_stage2: if (listener->flags & LI_F_QUIC_LISTENER) { if (!global.cluster_secret) diag_no_cluster_secret = 1; - listener->accept = quic_session_accept; + li_init_per_thr(listener); } #endif diff --git a/src/mux_quic.c b/src/mux_quic.c index f28bd690ca..142b4e4624 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -1915,6 +1915,12 @@ static int qc_init(struct connection *conn, struct proxy *prx, qcc->flags = 0; qcc->app_ops = NULL; + if (qcc_install_app_ops(qcc, conn->handle.qc->app_ops)) { + TRACE_PROTO("Cannot install app layer", QMUX_EV_QCC_NEW, qcc->conn); + /* prepare a CONNECTION_CLOSE frame */ + quic_set_connection_close(conn->handle.qc, quic_err_transport(QC_ERR_APPLICATION_ERROR)); + goto fail_no_tasklet; + } qcc->streams_by_id = EB_ROOT_UNIQUE; @@ -2024,6 +2030,8 @@ static int qc_init(struct connection *conn, struct proxy *prx, fail_no_timeout_task: tasklet_free(qcc->wait_event.tasklet); fail_no_tasklet: + if (qcc->app_ops && qcc->app_ops->release) + qcc->app_ops->release(qcc->ctx); pool_free(pool_head_qcc, qcc); fail_no_qcc: TRACE_LEAVE(QMUX_EV_QCC_NEW); diff --git a/src/quic_sock.c b/src/quic_sock.c index 29f30ccbe0..0f8185a4a4 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -38,76 +38,6 @@ #include #include -/* This function is called from the protocol layer accept() in order to - * instantiate a new session on behalf of a given listener and frontend. It - * returns a positive value upon success, 0 if the connection can be ignored, - * or a negative value upon critical failure. The accepted connection is - * closed if we return <= 0. If no handshake is needed, it immediately tries - * to instantiate a new stream. The connection must already have been filled - * with the incoming connection handle (a fd), a target (the listener) and a - * source address. - */ -int quic_session_accept(struct connection *cli_conn) -{ - struct listener *l = __objt_listener(cli_conn->target); - struct proxy *p = l->bind_conf->frontend; - struct session *sess; - - cli_conn->proxy_netns = l->rx.settings->netns; - /* This flag is ordinarily set by conn_ctrl_init() which cannot - * be called for now. - */ - cli_conn->flags |= CO_FL_CTRL_READY; - - /* wait for a PROXY protocol header */ - if (l->options & LI_O_ACC_PROXY) - cli_conn->flags |= CO_FL_ACCEPT_PROXY; - - /* wait for a NetScaler client IP insertion protocol header */ - if (l->options & LI_O_ACC_CIP) - cli_conn->flags |= CO_FL_ACCEPT_CIP; - - /* Add the handshake pseudo-XPRT */ - if (cli_conn->flags & (CO_FL_ACCEPT_PROXY | CO_FL_ACCEPT_CIP)) { - if (xprt_add_hs(cli_conn) != 0) - goto out_free_conn; - } - - sess = session_new(p, l, &cli_conn->obj_type); - if (!sess) - goto out_free_conn; - - conn_set_owner(cli_conn, sess, NULL); - - if (conn_complete_session(cli_conn) < 0) - goto out_free_sess; - - if (conn_xprt_start(cli_conn) < 0) { - /* conn_complete_session has succeeded : conn is the owner of - * the session and the MUX is initialized. - * Let the MUX free all resources on error. - */ - cli_conn->mux->destroy(cli_conn->ctx); - return -1; - } - - return 1; - - out_free_sess: - /* prevent call to listener_release during session_free. It will be - * done below, for all errors. */ - sess->listener = NULL; - session_free(sess); - out_free_conn: - cli_conn->handle.qc->conn = NULL; - conn_stop_tracking(cli_conn); - conn_xprt_close(cli_conn); - conn_free(cli_conn); - out: - - return -1; -} - /* Retrieve a connection's source address. Returns -1 on failure. */ int quic_sock_get_src(struct connection *conn, struct sockaddr *addr, socklen_t len) { @@ -182,12 +112,6 @@ static int new_quic_cli_conn(struct quic_conn *qc, struct listener *l, cli_conn->target = &l->obj_type; - /* We need the xprt context before accepting (->accept()) the connection: - * we may receive packet before this connection acception. - */ - if (conn_prepare(cli_conn, l->rx.proto, l->bind_conf->xprt) < 0) - goto out_free_conn; - return 1; out_free_conn: diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 8f316898cc..e908925351 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -121,12 +121,6 @@ static int qc_xprt_start(struct connection *conn, void *ctx) qc = conn->handle.qc; TRACE_ENTER(QUIC_EV_CONN_NEW, qc); - if (qcc_install_app_ops(qc->qcc, qc->app_ops)) { - TRACE_PROTO("Cannot install app layer", QUIC_EV_CONN_LPKT, qc); - /* prepare a CONNECTION_CLOSE frame */ - quic_set_connection_close(qc, quic_err_transport(QC_ERR_APPLICATION_ERROR)); - goto out; - } /* mux-quic can now be considered ready. */ qc->mux_state = QC_MUX_READY;