]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connection: centralize init/deinit of backend elements
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 27 Jul 2023 13:30:07 +0000 (15:30 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 24 Aug 2023 12:44:33 +0000 (14:44 +0200)
A connection contains extra elements which are only used for the backend
side. Regroup their allocation and deallocation in two new functions
named conn_backend_init() and conn_backend_deinit().

No functional change is introduced with this commit. The new functions
are reused in place of manual alloc/dealloc in conn_new() / conn_free().
This patch will be useful for reverse connect support with connection
conversion from backend to frontend side and vice-versa.

src/backend.c
src/connection.c
src/server.c

index 2344645abd477a226e9c2ed4d794610f7d684757..ef132376b5a94b14d1f760e256102ab0072d3c10 100644 (file)
@@ -1602,11 +1602,6 @@ skip_reuse:
                        srv_conn->src = bind_addr;
                        bind_addr = NULL;
 
-                       if (!sockaddr_alloc(&srv_conn->dst, 0, 0)) {
-                               conn_free(srv_conn);
-                               return SF_ERR_RESOURCE;
-                       }
-
                        srv_conn->hash_node->node.key = hash;
                }
        }
index 9c709034af4741574176a80e646a4cd530ba2d1d..b45a23285a5413e868fbab89e1a41eb46fd3a58f 100644 (file)
@@ -437,6 +437,49 @@ void conn_init(struct connection *conn, void *target)
        conn->xprt = NULL;
 }
 
+/* Initialize members used for backend connections.
+ *
+ * Returns 0 on success else non-zero.
+ */
+static int conn_backend_init(struct connection *conn)
+{
+       if (!sockaddr_alloc(&conn->dst, 0, 0))
+               return 1;
+
+       conn->hash_node = conn_alloc_hash_node(conn);
+       if (unlikely(!conn->hash_node))
+               return 1;
+
+       return 0;
+}
+
+/* Release connection elements reserved for backend side usage. It also takes
+ * care to detach it if linked to a session or a server instance.
+ *
+ * This function is useful when freeing a connection or reversing it to the
+ * frontend side.
+ */
+static void conn_backend_deinit(struct connection *conn)
+{
+       /* If the connection is owned by the session, remove it from its list
+        */
+       if (conn_is_back(conn) && LIST_INLIST(&conn->session_list)) {
+               session_unown_conn(conn->owner, conn);
+       }
+       else if (!(conn->flags & CO_FL_PRIVATE)) {
+               if (obj_type(conn->target) == OBJ_TYPE_SERVER)
+                       srv_release_conn(__objt_server(conn->target), conn);
+       }
+
+       /* Make sure the connection is not left in the idle connection tree */
+       if (conn->hash_node != NULL)
+               BUG_ON(conn->hash_node->node.node.leaf_p != NULL);
+
+       pool_free(pool_head_conn_hash_node, conn->hash_node);
+       conn->hash_node = NULL;
+
+}
+
 /* Tries to allocate a new connection and initialized its main fields. The
  * connection is returned on success, NULL on failure. The connection must
  * be released using pool_free() or conn_free().
@@ -444,7 +487,6 @@ void conn_init(struct connection *conn, void *target)
 struct connection *conn_new(void *target)
 {
        struct connection *conn;
-       struct conn_hash_node *hash_node;
 
        conn = pool_alloc(pool_head_connection);
        if (unlikely(!conn))
@@ -456,13 +498,10 @@ struct connection *conn_new(void *target)
                if (obj_type(target) == OBJ_TYPE_SERVER)
                        srv_use_conn(__objt_server(target), conn);
 
-               hash_node = conn_alloc_hash_node(conn);
-               if (unlikely(!hash_node)) {
-                       pool_free(pool_head_connection, conn);
+               if (conn_backend_init(conn)) {
+                       conn_free(conn);
                        return NULL;
                }
-
-               conn->hash_node = hash_node;
        }
 
        return conn;
@@ -471,15 +510,8 @@ struct connection *conn_new(void *target)
 /* Releases a connection previously allocated by conn_new() */
 void conn_free(struct connection *conn)
 {
-       /* If the connection is owned by the session, remove it from its list
-        */
-       if (conn_is_back(conn) && LIST_INLIST(&conn->session_list)) {
-               session_unown_conn(conn->owner, conn);
-       }
-       else if (!(conn->flags & CO_FL_PRIVATE)) {
-               if (obj_type(conn->target) == OBJ_TYPE_SERVER)
-                       srv_release_conn(__objt_server(conn->target), conn);
-       }
+       if (conn_is_back(conn))
+               conn_backend_deinit(conn);
 
        /* Remove the conn from toremove_list.
         *
@@ -498,13 +530,6 @@ void conn_free(struct connection *conn)
        pool_free(pool_head_uniqueid, istptr(conn->proxy_unique_id));
        conn->proxy_unique_id = IST_NULL;
 
-       /* Make sure the connection is not left in the idle connection tree */
-       if (conn->hash_node != NULL)
-               BUG_ON(conn->hash_node->node.node.leaf_p != NULL);
-
-       pool_free(pool_head_conn_hash_node, conn->hash_node);
-       conn->hash_node = NULL;
-
        conn_force_unsubscribe(conn);
        pool_free(pool_head_connection, conn);
 }
index b1bbc3838c9a461cac174737eecace8186736c6e..1118a2d4afad54f21ed952ea577614d081c91d04 100644 (file)
@@ -5926,10 +5926,12 @@ void srv_release_conn(struct server *srv, struct connection *conn)
        }
 
        /* Remove the connection from any tree (safe, idle or available) */
-       HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
-       conn_delete_from_tree(&conn->hash_node->node);
-       conn->flags &= ~CO_FL_LIST_MASK;
-       HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+       if (conn->hash_node) {
+               HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+               conn_delete_from_tree(&conn->hash_node->node);
+               conn->flags &= ~CO_FL_LIST_MASK;
+               HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+       }
 }
 
 /* retrieve a connection from its <hash> in <tree>