MINOR: session: Add src and dst addresses to the session

For now, these addresses are never set. But the idea is to be able to set
client source and destination addresses at the session level without
updating the connection ones.

Functions to fill these addresses have been added: sess_get_src() and
sess_get_dst(). If not already set, these functions relies on
conn_get_src() and conn_get_dst() to fill session addresses.

And just like for conncetions, sess_src() and sess_dst() may be used to get
source and destination addresses. However, if not set, the corresponding
address from the underlying client connection is returned. When this
happens, the addresses is filled in the connection object.
This commit is contained in:
Christopher Faulet 2021-10-22 15:41:57 +02:00
parent cc6fc26bfe
commit f46e1ea1ad
3 changed files with 91 additions and 0 deletions

View File

@ -39,6 +39,8 @@
enum {
SESS_FL_NONE = 0x00000000, /* nothing */
SESS_FL_PREFER_LAST = 0x00000001, /* NTML authent, we should reuse last conn */
SESS_FL_ADDR_FROM_SET = 0x00000002,
SESS_FL_ADDR_TO_SET = 0x00000004,
};
/* max number of idle server connections kept attached to a session */
@ -58,6 +60,8 @@ struct session {
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 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 {

View File

@ -23,6 +23,7 @@
#define _HAPROXY_SESSION_H
#include <haproxy/api.h>
#include <haproxy/connection.h>
#include <haproxy/global-t.h>
#include <haproxy/obj_type-t.h>
#include <haproxy/pool.h>
@ -232,6 +233,88 @@ static inline struct connection *session_get_conn(struct session *sess, void *ta
return srv_conn;
}
/* Returns the source address of the session and fallbacks on the client
* connection if not set. It returns a const address on succes or NULL on
* failure.
*/
static inline const struct sockaddr_storage *sess_src(struct session *sess)
{
struct connection *cli_conn = objt_conn(sess->origin);
if (sess->flags & SESS_FL_ADDR_FROM_SET)
return sess->src;
if (cli_conn && conn_get_src(cli_conn))
return conn_src(cli_conn);
return NULL;
}
/* Returns the destination address of the session and fallbacks on the client
* connection if not set. It returns a const address on succes or NULL on
* failure.
*/
static inline const struct sockaddr_storage *sess_dst(struct session *sess)
{
struct connection *cli_conn = objt_conn(sess->origin);
if (sess->flags & SESS_FL_ADDR_TO_SET)
return sess->dst;
if (cli_conn && conn_get_dst(cli_conn))
return conn_dst(cli_conn);
return NULL;
}
/* Retrieves the source address of the session <sess>. Returns non-zero on
* success or zero on failure. The operation is only performed once and the
* address is stored in the session for future use. On the first call, the
* session source address is copied from the client connection one.
*/
static inline int sess_get_src(struct session *sess)
{
struct connection *cli_conn = objt_conn(sess->origin);
const struct sockaddr_storage *src = NULL;
if (sess->flags & SESS_FL_ADDR_FROM_SET)
return 1;
if (cli_conn && conn_get_src(cli_conn))
src = conn_src(cli_conn);
if (!src)
return 0;
if (!sockaddr_alloc(&sess->src, src, sizeof(*src)))
return 0;
sess->flags |= SESS_FL_ADDR_FROM_SET;
return 1;
}
/* Retrieves the destination address of the session <sess>. Returns non-zero on
* success or zero on failure. The operation is only performed once and the
* address is stored in the session for future use. On the first call, the
* session destination address is copied from the client connection one.
*/
static inline int sess_get_dst(struct session *sess)
{
struct connection *cli_conn = objt_conn(sess->origin);
const struct sockaddr_storage *dst = NULL;
if (sess->flags & SESS_FL_ADDR_TO_SET)
return 1;
if (cli_conn && conn_get_dst(cli_conn))
dst = conn_dst(cli_conn);
if (!dst)
return 0;
if (!sockaddr_alloc(&sess->dst, dst, sizeof(*dst)))
return 0;
sess->flags |= SESS_FL_ADDR_TO_SET;
return 1;
}
#endif /* _HAPROXY_SESSION_H */
/*

View File

@ -56,6 +56,8 @@ struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type
LIST_INIT(&sess->srv_list);
sess->idle_conns = 0;
sess->flags = SESS_FL_NONE;
sess->src = NULL;
sess->dst = NULL;
}
return sess;
}
@ -90,6 +92,8 @@ void session_free(struct session *sess)
}
pool_free(pool_head_sess_srv_list, srv_list);
}
sockaddr_free(&sess->src);
sockaddr_free(&sess->dst);
pool_free(pool_head_session, sess);
_HA_ATOMIC_DEC(&jobs);
}