MINOR: connection: centralize init/deinit of backend elements

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.
This commit is contained in:
Amaury Denoyelle 2023-07-27 15:30:07 +02:00
parent fbe35afaa4
commit d8d9122a02
3 changed files with 53 additions and 31 deletions

View 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;
}
}

View 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);
}

View 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>