struct mt_list toremove_list; /* list element when idle connection is ready to be purged */
};
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 */
};
union conn_handle handle; /* connection handle at the socket layer */
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 */
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 *dst; /* destination address (pool), when known, otherwise NULL */
};
-struct sess_srv_list {
- void *target;
+/* List of private conns managed by a session, indexed by server */
+struct sess_priv_conns {
+ void *target; /* Server or dispatch used for indexing */
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 */
#include <haproxy/stick_table.h>
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);
void session_free(struct session *sess);
__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)
{
- struct sess_srv_list *srv_list = NULL;
+ struct sess_priv_conns *pconns = NULL;
BUG_ON(objt_listener(conn->target));
* conn->owner that points to a dead session, but in this case the
* element is not linked.
*/
- if (!LIST_INLIST(&conn->session_list))
+ if (!LIST_INLIST(&conn->sess_el))
return;
if (conn->flags & CO_FL_SESS_IDLE)
sess->idle_conns--;
- LIST_DEL_INIT(&conn->session_list);
+ LIST_DEL_INIT(&conn->sess_el);
conn->owner = NULL;
- list_for_each_entry(srv_list, &sess->srv_list, srv_list) {
- if (srv_list->target == conn->target) {
- if (LIST_ISEMPTY(&srv_list->conn_list)) {
- LIST_DELETE(&srv_list->srv_list);
- pool_free(pool_head_sess_srv_list, srv_list);
+ list_for_each_entry(pconns, &sess->priv_conns, sess_el) {
+ if (pconns->target == conn->target) {
+ if (LIST_ISEMPTY(&pconns->conn_list)) {
+ LIST_DELETE(&pconns->sess_el);
+ pool_free(pool_head_sess_priv_conns, pconns);
}
break;
}
}
}
-/* Add the connection <conn> to the server list of the session <sess>. This
- * function is called only if the connection is private. Nothing is performed if
- * the connection is already in the session sever list or if the session does
- * not own the connection.
+/* 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 the connection is already in the session list or if the session does not
+ * owned the connection.
*/
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;
BUG_ON(objt_listener(conn->target));
/* 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;
- list_for_each_entry(srv_list, &sess->srv_list, srv_list) {
- if (srv_list->target == target) {
+ list_for_each_entry(pconns, &sess->priv_conns, sess_el) {
+ if (pconns->target == target) {
found = 1;
break;
}
}
if (!found) {
/* The session has no connection for the server, create a new entry */
- srv_list = pool_alloc(pool_head_sess_srv_list);
- if (!srv_list)
+ pconns = pool_alloc(pool_head_sess_priv_conns);
+ if (!pconns)
return 0;
- srv_list->target = target;
- LIST_INIT(&srv_list->conn_list);
- LIST_APPEND(&sess->srv_list, &srv_list->srv_list);
+ pconns->target = target;
+ LIST_INIT(&pconns->conn_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;
}
static inline struct connection *session_get_conn(struct session *sess, void *target, int64_t hash)
{
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) {
- if (srv_list->target == target) {
- list_for_each_entry(srv_conn, &srv_list->conn_list, session_list) {
+ list_for_each_entry(pconns, &sess->priv_conns, sess_el) {
+ if (pconns->target == target) {
+ list_for_each_entry(srv_conn, &pconns->conn_list, sess_el) {
if ((srv_conn->hash_node && srv_conn->hash_node->node.key == hash) &&
srv_conn->mux &&
(srv_conn->mux->avail_streams(srv_conn) > 0) &&
if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI &&
((s->sess->flags & SESS_FL_PREFER_LAST) ||
(s->be->options & PR_O_PREF_LAST))) {
- struct sess_srv_list *srv_list;
- list_for_each_entry(srv_list, &s->sess->srv_list, srv_list) {
- struct server *tmpsrv = objt_server(srv_list->target);
+ struct sess_priv_conns *pconns;
+ list_for_each_entry(pconns, &s->sess->priv_conns, sess_el) {
+ struct server *tmpsrv = objt_server(pconns->target);
if (tmpsrv && tmpsrv->proxy == s->be &&
((s->sess->flags & SESS_FL_PREFER_LAST) ||
server_has_room(tmpsrv) || (
tmpsrv->queue.length + 1 < s->be->max_ka_queue))) &&
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)) {
srv = tmpsrv;
s->target = &srv->obj_type;
conn->proxy_netns = NULL;
MT_LIST_INIT(&conn->toremove_list);
if (conn_is_back(conn))
- LIST_INIT(&conn->session_list);
+ LIST_INIT(&conn->sess_el);
else
LIST_INIT(&conn->stopping_list);
LIST_INIT(&conn->tlv_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);
}
else if (!(conn->flags & CO_FL_PRIVATE)) {
}
else if (!fconn->conn->hash_node->node.node.leaf_p &&
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);
}
}
}
else if (!h2c->conn->hash_node->node.node.leaf_p &&
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);
}
}
DECLARE_POOL(pool_head_session, "session", sizeof(struct session));
-DECLARE_POOL(pool_head_sess_srv_list, "session server list",
- sizeof(struct sess_srv_list));
+DECLARE_POOL(pool_head_sess_priv_conns, "session priv conns list",
+ sizeof(struct sess_priv_conns));
int conn_complete_session(struct connection *conn);
sess->t_idle = -1;
_HA_ATOMIC_INC(&totalconn);
_HA_ATOMIC_INC(&jobs);
- LIST_INIT(&sess->srv_list);
+ LIST_INIT(&sess->priv_conns);
sess->idle_conns = 0;
sess->flags = SESS_FL_NONE;
sess->src = NULL;
void session_free(struct session *sess)
{
struct connection *conn, *conn_back;
- struct sess_srv_list *srv_list, *srv_list_back;
+ struct sess_priv_conns *pconns, *pconns_back;
if (sess->listener)
listener_release(sess->listener);
conn = objt_conn(sess->origin);
if (conn != NULL && conn->mux)
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(conn, conn_back, &srv_list->conn_list, session_list) {
- LIST_DEL_INIT(&conn->session_list);
+ list_for_each_entry_safe(pconns, pconns_back, &sess->priv_conns, sess_el) {
+ list_for_each_entry_safe(conn, conn_back, &pconns->conn_list, sess_el) {
+ LIST_DEL_INIT(&conn->sess_el);
if (conn->mux) {
conn->owner = NULL;
conn->flags &= ~CO_FL_SESS_IDLE;
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->dst);
if (!sess && strm)
sess = strm->sess;
- else if (!sess && conn && LIST_INLIST(&conn->session_list))
+ else if (!sess && conn && LIST_INLIST(&conn->sess_el))
sess = conn->owner;
else if (!sess && check)
sess = check->sess;