MEDIUM: connection: implement passive reverse

Define a new method conn_reverse(). This method is used to reverse a
connection from frontend to backend or vice-versa depending on its
initial status.

For the moment, passive reverse only is implemented. This covers the
transition from frontend to backend side. The connection is detached
from its owner session which can then be freed. Then the connection is
linked to the server instance.

only for passive connection on
frontend to transfer them on the backend side. This requires to free the
connection session after detaching it from.
This commit is contained in:
Amaury Denoyelle 2023-07-27 15:56:34 +02:00
parent d8d9122a02
commit 1f76b8ae07
3 changed files with 59 additions and 0 deletions

View File

@ -543,6 +543,11 @@ struct connection {
* thus only present if conn.target is of type OBJ_TYPE_SERVER
*/
struct conn_hash_node *hash_node;
/* Members used if connection must be reversed. */
struct {
enum obj_type *target; /* Server for passive reverse. */
} reverse;
};
/* node for backend connection in the idle trees for http-reuse

View File

@ -100,6 +100,9 @@ void conn_hash_update(char *buf, size_t *idx,
enum conn_hash_params_t type);
uint64_t conn_hash_digest(char *buf, size_t bufsize,
enum conn_hash_params_t flags);
int conn_reverse(struct connection *conn);
const char *conn_err_code_str(struct connection *c);
int xprt_add_hs(struct connection *conn);
void register_mux_proto(struct mux_proto_list *list);

View File

@ -435,6 +435,7 @@ void conn_init(struct connection *conn, void *target)
conn->proxy_unique_id = IST_NULL;
conn->hash_node = NULL;
conn->xprt = NULL;
conn->reverse.target = NULL;
}
/* Initialize members used for backend connections.
@ -2433,6 +2434,56 @@ uint64_t conn_calculate_hash(const struct conn_hash_params *params)
return hash;
}
/* Reverse a <conn> connection instance. This effectively moves the connection
* from frontend to backend side or vice-versa depending on its initial status.
*
* For passive reversal, 'reverse' member points to the server used as the new
* connection target. Once transition is completed, the connection appears as a
* normal backend connection.
*
* Returns 0 on success else non-zero.
*/
int conn_reverse(struct connection *conn)
{
struct conn_hash_params hash_params;
int64_t hash = 0;
struct session *sess = conn->owner;
if (!conn_is_back(conn)) {
/* srv must have been set by a previous 'attach-srv' rule. */
struct server *srv = objt_server(conn->reverse.target);
BUG_ON(!srv);
if (conn_backend_init(conn))
return 1;
/* Initialize hash value for usage as idle conns. */
memset(&hash_params, 0, sizeof(hash_params));
hash_params.target = srv;
hash = conn_calculate_hash(&hash_params);
conn->hash_node->node.key = hash;
conn->target = &srv->obj_type;
srv_use_conn(srv, conn);
/* Free the session after detaching the connection from it. */
session_unown_conn(sess, conn);
sess->origin = NULL;
session_free(sess);
conn_set_owner(conn, NULL, NULL);
}
else {
ABORT_NOW();
}
/* Invert source and destination addresses if already set. */
SWAP(conn->src, conn->dst);
conn->reverse.target = NULL;
return 0;
}
/* Handler of the task of mux_stopping_data.
* Called on soft-stop.
*/