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.
diff --git a/include/haproxy/session-t.h b/include/haproxy/session-t.h
index 45b820c..1afb3c8 100644
--- a/include/haproxy/session-t.h
+++ b/include/haproxy/session-t.h
@@ -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 @@
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 {
diff --git a/include/haproxy/session.h b/include/haproxy/session.h
index d838fd9..f4abcc3 100644
--- a/include/haproxy/session.h
+++ b/include/haproxy/session.h
@@ -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 @@
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 */
/*
diff --git a/src/session.c b/src/session.c
index d913d56..06ace8a 100644
--- a/src/session.c
+++ b/src/session.c
@@ -56,6 +56,8 @@
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 @@
}
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);
}