]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: remove unnecessary quic_session_accept()
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 29 Sep 2022 16:31:24 +0000 (18:31 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 26 Oct 2022 16:16:20 +0000 (18:16 +0200)
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.

src/cfgparse.c
src/mux_quic.c
src/quic_sock.c
src/xprt_quic.c

index 21648804784b6192ea2eb44f8e8de76621fc8376..f80008c2599745fb3ddb9df838af6dfda5b300a0 100644 (file)
@@ -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
index f28bd690ca3a59f068b8dfb55a2fc04509f4c1c9..142b4e4624ce5ed5f9c0de6573bb74d3ac57275a 100644 (file)
@@ -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);
index 29f30ccbe03ec184b3cba0d373830079a6617806..0f8185a4a4d15f33e0d80733d7f853f61b31ed3a 100644 (file)
 #include <haproxy/task.h>
 #include <haproxy/tools.h>
 
-/* 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:
index 8f316898ccb69af073f16240f74438ab7ac5e40e..e90892535192b632abebfe6063a80cbf5f235be9 100644 (file)
@@ -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;