MINOR: session: rename private conns elements

By default, backend connections are attached to a server instance. This
allows to implement connection reuse. However, in some particular cases,
connection cannot be shared accross several clients. These connections
are considered and private and are attached to the session instance
instead.

These private connections are also indexed by the target server to not
mix them. All of this is implemented via a dedicated structure
previously named struct sess_srv_list.

Rename it to better reflect its usage to struct sess_priv_conns. Also
rename its internal members and all of the associated functions.

This commit is only a renaming, thus no functional impact is expected.
This commit is contained in:
Amaury Denoyelle 2024-03-14 11:24:10 +01:00
parent f31a4e302e
commit 5ad801c058
9 changed files with 53 additions and 50 deletions

View File

@ -547,7 +547,7 @@ struct connection {
struct mt_list toremove_list; /* list element when idle connection is ready to be purged */ struct mt_list toremove_list; /* list element when idle connection is ready to be purged */
}; };
union { union {
struct list session_list; /* used by backend conns, list of attached connections to a session */ struct list sess_el; /* used by private backend conns, list elem into session */
struct list stopping_list; /* used by frontend conns, attach point in mux stopping list */ struct list stopping_list; /* used by frontend conns, attach point in mux stopping list */
}; };
union conn_handle handle; /* connection handle at the socket layer */ union conn_handle handle; /* connection handle at the socket layer */

View File

@ -57,15 +57,16 @@ struct session {
long t_idle; /* idle duration, -1 if never occurs */ long t_idle; /* idle duration, -1 if never occurs */
int idle_conns; /* Number of connections we're currently responsible for that we are not using */ int idle_conns; /* Number of connections we're currently responsible for that we are not using */
unsigned int flags; /* session flags, SESS_FL_* */ unsigned int flags; /* session flags, SESS_FL_* */
struct list srv_list; /* List of servers and the connections the session is currently responsible for */ struct list priv_conns; /* list of private conns */
struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */ struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */
struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */ struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */
}; };
struct sess_srv_list { /* List of private conns managed by a session, indexed by server */
void *target; struct sess_priv_conns {
void *target; /* Server or dispatch used for indexing */
struct list conn_list; /* Head of the connections list */ struct list conn_list; /* Head of the connections list */
struct list srv_list; /* Next element of the server list */ struct list sess_el; /* Element of session.priv_conns */
}; };
#endif /* _HAPROXY_SESSION_T_H */ #endif /* _HAPROXY_SESSION_T_H */

View File

@ -32,7 +32,7 @@
#include <haproxy/stick_table.h> #include <haproxy/stick_table.h>
extern struct pool_head *pool_head_session; extern struct pool_head *pool_head_session;
extern struct pool_head *pool_head_sess_srv_list; extern struct pool_head *pool_head_sess_priv_conns;
struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type *origin); struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type *origin);
void session_free(struct session *sess); void session_free(struct session *sess);
@ -134,10 +134,12 @@ static inline void session_add_glitch_ctr(struct session *sess, uint inc)
__session_add_glitch_ctr(sess, inc); __session_add_glitch_ctr(sess, inc);
} }
/* Remove the connection from the session list, and destroy the srv_list if it's now empty */ /* Remove the connection from the session list, and destroy sess_priv_conns
* element if it's now empty.
*/
static inline void session_unown_conn(struct session *sess, struct connection *conn) static inline void session_unown_conn(struct session *sess, struct connection *conn)
{ {
struct sess_srv_list *srv_list = NULL; struct sess_priv_conns *pconns = NULL;
BUG_ON(objt_listener(conn->target)); BUG_ON(objt_listener(conn->target));
@ -148,56 +150,56 @@ static inline void session_unown_conn(struct session *sess, struct connection *c
* conn->owner that points to a dead session, but in this case the * conn->owner that points to a dead session, but in this case the
* element is not linked. * element is not linked.
*/ */
if (!LIST_INLIST(&conn->session_list)) if (!LIST_INLIST(&conn->sess_el))
return; return;
if (conn->flags & CO_FL_SESS_IDLE) if (conn->flags & CO_FL_SESS_IDLE)
sess->idle_conns--; sess->idle_conns--;
LIST_DEL_INIT(&conn->session_list); LIST_DEL_INIT(&conn->sess_el);
conn->owner = NULL; conn->owner = NULL;
list_for_each_entry(srv_list, &sess->srv_list, srv_list) { list_for_each_entry(pconns, &sess->priv_conns, sess_el) {
if (srv_list->target == conn->target) { if (pconns->target == conn->target) {
if (LIST_ISEMPTY(&srv_list->conn_list)) { if (LIST_ISEMPTY(&pconns->conn_list)) {
LIST_DELETE(&srv_list->srv_list); LIST_DELETE(&pconns->sess_el);
pool_free(pool_head_sess_srv_list, srv_list); pool_free(pool_head_sess_priv_conns, pconns);
} }
break; break;
} }
} }
} }
/* Add the connection <conn> to the server list of the session <sess>. This /* Add the connection <conn> to the private conns list of session <sess>. This
* function is called only if the connection is private. Nothing is performed if * function is called only if the connection is private. Nothing is performed
* the connection is already in the session sever list or if the session does * if the connection is already in the session list or if the session does not
* not own the connection. * owned the connection.
*/ */
static inline int session_add_conn(struct session *sess, struct connection *conn, void *target) static inline int session_add_conn(struct session *sess, struct connection *conn, void *target)
{ {
struct sess_srv_list *srv_list = NULL; struct sess_priv_conns *pconns = NULL;
int found = 0; int found = 0;
BUG_ON(objt_listener(conn->target)); BUG_ON(objt_listener(conn->target));
/* Already attach to the session or not the connection owner */ /* Already attach to the session or not the connection owner */
if (!LIST_ISEMPTY(&conn->session_list) || (conn->owner && conn->owner != sess)) if (!LIST_ISEMPTY(&conn->sess_el) || (conn->owner && conn->owner != sess))
return 1; return 1;
list_for_each_entry(srv_list, &sess->srv_list, srv_list) { list_for_each_entry(pconns, &sess->priv_conns, sess_el) {
if (srv_list->target == target) { if (pconns->target == target) {
found = 1; found = 1;
break; break;
} }
} }
if (!found) { if (!found) {
/* The session has no connection for the server, create a new entry */ /* The session has no connection for the server, create a new entry */
srv_list = pool_alloc(pool_head_sess_srv_list); pconns = pool_alloc(pool_head_sess_priv_conns);
if (!srv_list) if (!pconns)
return 0; return 0;
srv_list->target = target; pconns->target = target;
LIST_INIT(&srv_list->conn_list); LIST_INIT(&pconns->conn_list);
LIST_APPEND(&sess->srv_list, &srv_list->srv_list); LIST_APPEND(&sess->priv_conns, &pconns->sess_el);
} }
LIST_APPEND(&srv_list->conn_list, &conn->session_list); LIST_APPEND(&pconns->conn_list, &conn->sess_el);
return 1; return 1;
} }
@ -230,11 +232,11 @@ static inline int session_check_idle_conn(struct session *sess, struct connectio
static inline struct connection *session_get_conn(struct session *sess, void *target, int64_t hash) static inline struct connection *session_get_conn(struct session *sess, void *target, int64_t hash)
{ {
struct connection *srv_conn = NULL; struct connection *srv_conn = NULL;
struct sess_srv_list *srv_list; struct sess_priv_conns *pconns;
list_for_each_entry(srv_list, &sess->srv_list, srv_list) { list_for_each_entry(pconns, &sess->priv_conns, sess_el) {
if (srv_list->target == target) { if (pconns->target == target) {
list_for_each_entry(srv_conn, &srv_list->conn_list, session_list) { list_for_each_entry(srv_conn, &pconns->conn_list, sess_el) {
if ((srv_conn->hash_node && srv_conn->hash_node->node.key == hash) && if ((srv_conn->hash_node && srv_conn->hash_node->node.key == hash) &&
srv_conn->mux && srv_conn->mux &&
(srv_conn->mux->avail_streams(srv_conn) > 0) && (srv_conn->mux->avail_streams(srv_conn) > 0) &&

View File

@ -653,9 +653,9 @@ int assign_server(struct stream *s)
if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI && if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI &&
((s->sess->flags & SESS_FL_PREFER_LAST) || ((s->sess->flags & SESS_FL_PREFER_LAST) ||
(s->be->options & PR_O_PREF_LAST))) { (s->be->options & PR_O_PREF_LAST))) {
struct sess_srv_list *srv_list; struct sess_priv_conns *pconns;
list_for_each_entry(srv_list, &s->sess->srv_list, srv_list) { list_for_each_entry(pconns, &s->sess->priv_conns, sess_el) {
struct server *tmpsrv = objt_server(srv_list->target); struct server *tmpsrv = objt_server(pconns->target);
if (tmpsrv && tmpsrv->proxy == s->be && if (tmpsrv && tmpsrv->proxy == s->be &&
((s->sess->flags & SESS_FL_PREFER_LAST) || ((s->sess->flags & SESS_FL_PREFER_LAST) ||
@ -663,7 +663,7 @@ int assign_server(struct stream *s)
server_has_room(tmpsrv) || ( server_has_room(tmpsrv) || (
tmpsrv->queue.length + 1 < s->be->max_ka_queue))) && tmpsrv->queue.length + 1 < s->be->max_ka_queue))) &&
srv_currently_usable(tmpsrv)) { srv_currently_usable(tmpsrv)) {
list_for_each_entry(conn, &srv_list->conn_list, session_list) { list_for_each_entry(conn, &pconns->conn_list, sess_el) {
if (!(conn->flags & CO_FL_WAIT_XPRT)) { if (!(conn->flags & CO_FL_WAIT_XPRT)) {
srv = tmpsrv; srv = tmpsrv;
s->target = &srv->obj_type; s->target = &srv->obj_type;

View File

@ -474,7 +474,7 @@ void conn_init(struct connection *conn, void *target)
conn->proxy_netns = NULL; conn->proxy_netns = NULL;
MT_LIST_INIT(&conn->toremove_list); MT_LIST_INIT(&conn->toremove_list);
if (conn_is_back(conn)) if (conn_is_back(conn))
LIST_INIT(&conn->session_list); LIST_INIT(&conn->sess_el);
else else
LIST_INIT(&conn->stopping_list); LIST_INIT(&conn->stopping_list);
LIST_INIT(&conn->tlv_list); LIST_INIT(&conn->tlv_list);
@ -513,7 +513,7 @@ static void conn_backend_deinit(struct connection *conn)
{ {
/* If the connection is owned by the session, remove it from its list /* If the connection is owned by the session, remove it from its list
*/ */
if (conn_is_back(conn) && LIST_INLIST(&conn->session_list)) { if (conn_is_back(conn) && LIST_INLIST(&conn->sess_el)) {
session_unown_conn(conn->owner, conn); session_unown_conn(conn->owner, conn);
} }
else if (!(conn->flags & CO_FL_PRIVATE)) { else if (!(conn->flags & CO_FL_PRIVATE)) {

View File

@ -3619,7 +3619,7 @@ static void fcgi_detach(struct sedesc *sd)
} }
else if (!fconn->conn->hash_node->node.node.leaf_p && else if (!fconn->conn->hash_node->node.node.leaf_p &&
fcgi_avail_streams(fconn->conn) > 0 && objt_server(fconn->conn->target) && fcgi_avail_streams(fconn->conn) > 0 && objt_server(fconn->conn->target) &&
!LIST_INLIST(&fconn->conn->session_list)) { !LIST_INLIST(&fconn->conn->sess_el)) {
srv_add_to_avail_list(__objt_server(fconn->conn->target), fconn->conn); srv_add_to_avail_list(__objt_server(fconn->conn->target), fconn->conn);
} }
} }

View File

@ -4858,7 +4858,7 @@ static void h2_detach(struct sedesc *sd)
} }
else if (!h2c->conn->hash_node->node.node.leaf_p && else if (!h2c->conn->hash_node->node.node.leaf_p &&
h2_avail_streams(h2c->conn) > 0 && objt_server(h2c->conn->target) && h2_avail_streams(h2c->conn) > 0 && objt_server(h2c->conn->target) &&
!LIST_INLIST(&h2c->conn->session_list)) { !LIST_INLIST(&h2c->conn->sess_el)) {
srv_add_to_avail_list(__objt_server(h2c->conn->target), h2c->conn); srv_add_to_avail_list(__objt_server(h2c->conn->target), h2c->conn);
} }
} }

View File

@ -27,8 +27,8 @@
DECLARE_POOL(pool_head_session, "session", sizeof(struct session)); DECLARE_POOL(pool_head_session, "session", sizeof(struct session));
DECLARE_POOL(pool_head_sess_srv_list, "session server list", DECLARE_POOL(pool_head_sess_priv_conns, "session priv conns list",
sizeof(struct sess_srv_list)); sizeof(struct sess_priv_conns));
int conn_complete_session(struct connection *conn); int conn_complete_session(struct connection *conn);
@ -61,7 +61,7 @@ struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type
sess->t_idle = -1; sess->t_idle = -1;
_HA_ATOMIC_INC(&totalconn); _HA_ATOMIC_INC(&totalconn);
_HA_ATOMIC_INC(&jobs); _HA_ATOMIC_INC(&jobs);
LIST_INIT(&sess->srv_list); LIST_INIT(&sess->priv_conns);
sess->idle_conns = 0; sess->idle_conns = 0;
sess->flags = SESS_FL_NONE; sess->flags = SESS_FL_NONE;
sess->src = NULL; sess->src = NULL;
@ -76,7 +76,7 @@ struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type
void session_free(struct session *sess) void session_free(struct session *sess)
{ {
struct connection *conn, *conn_back; struct connection *conn, *conn_back;
struct sess_srv_list *srv_list, *srv_list_back; struct sess_priv_conns *pconns, *pconns_back;
if (sess->listener) if (sess->listener)
listener_release(sess->listener); listener_release(sess->listener);
@ -86,9 +86,9 @@ void session_free(struct session *sess)
conn = objt_conn(sess->origin); conn = objt_conn(sess->origin);
if (conn != NULL && conn->mux) if (conn != NULL && conn->mux)
conn->mux->destroy(conn->ctx); conn->mux->destroy(conn->ctx);
list_for_each_entry_safe(srv_list, srv_list_back, &sess->srv_list, srv_list) { list_for_each_entry_safe(pconns, pconns_back, &sess->priv_conns, sess_el) {
list_for_each_entry_safe(conn, conn_back, &srv_list->conn_list, session_list) { list_for_each_entry_safe(conn, conn_back, &pconns->conn_list, sess_el) {
LIST_DEL_INIT(&conn->session_list); LIST_DEL_INIT(&conn->sess_el);
if (conn->mux) { if (conn->mux) {
conn->owner = NULL; conn->owner = NULL;
conn->flags &= ~CO_FL_SESS_IDLE; conn->flags &= ~CO_FL_SESS_IDLE;
@ -102,7 +102,7 @@ void session_free(struct session *sess)
conn_free(conn); conn_free(conn);
} }
} }
pool_free(pool_head_sess_srv_list, srv_list); pool_free(pool_head_sess_priv_conns, pconns);
} }
sockaddr_free(&sess->src); sockaddr_free(&sess->src);
sockaddr_free(&sess->dst); sockaddr_free(&sess->dst);

View File

@ -129,7 +129,7 @@ int __trace_enabled(enum trace_level level, uint64_t mask, struct trace_source *
if (!sess && strm) if (!sess && strm)
sess = strm->sess; sess = strm->sess;
else if (!sess && conn && LIST_INLIST(&conn->session_list)) else if (!sess && conn && LIST_INLIST(&conn->sess_el))
sess = conn->owner; sess = conn->owner;
else if (!sess && check) else if (!sess && check)
sess = check->sess; sess = check->sess;