]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: session: Add src and dst addresses to the session
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 22 Oct 2021 13:41:57 +0000 (15:41 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 27 Oct 2021 09:34:21 +0000 (11:34 +0200)
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.

include/haproxy/session-t.h
include/haproxy/session.h
src/session.c

index 45b820cb395dcc6d69e78148a241d82805353087..1afb3c857168fc2137fe4a0ad19fa65ccfdfdf5e 100644 (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 {
index d838fd99bfb5c83f8525f48129bb6da10d72ccfa..f4abcc33360c9297954fa5b2b48f8e320615d5fd 100644 (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 */
 
 /*
index d913d567df83d1c996ef519ec78c7b59698b2083..06ace8a0f64bf2fa0a7d35203f4b7454c8498b27 100644 (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);
 }