MINOR: tcp_samples: Add samples to get src/dst info of the backend connection

This patch adds 4 new sample fetches to get the source and the destination
info (ip address and port) of the backend connection :

 * bc_dst      : Returns the destination address of the backend connection
 * bc_dst_port : Returns the destination port of the backend connection
 * bc_src      : Returns the source address of the backend connection
 * bc_src_port : Returns the source port of the backend connection

The configuration manual was updated accordingly.
This commit is contained in:
Christopher Faulet 2021-04-15 09:38:37 +02:00
parent 6f97a611c8
commit 7d081f02a4
2 changed files with 61 additions and 26 deletions

View File

@ -17247,11 +17247,31 @@ table may be specified with the "sc*" form, in which case the currently
tracked key will be looked up into this alternate table instead of the table
currently being tracked.
bc_dst : ip
This is the destination ip address of the connection on the server side,
which is the server address HAProxy connected to. It is of type IP and works
on both IPv4 and IPv6 tables. On IPv6 tables, IPv4 address is mapped to its
IPv6 equivalent, according to RFC 4291.
bc_dst_port : integer
Returns an integer value corresponding to the destination TCP port of the
connection on the server side, which is the port HAproxy connected to.
bc_http_major : integer
Returns the backend connection's HTTP major version encoding, which may be 1
for HTTP/0.9 to HTTP/1.1 or 2 for HTTP/2. Note, this is based on the on-wire
encoding and not the version present in the request header.
bc_src : ip
This is the source ip address of the connection on the server side, which is
the server address haproxy connected from. It is of type IP and works on both
IPv4 and IPv6 tables. On IPv6 tables, IPv4 addresses are mapped to their IPv6
equivalent, according to RFC 4291.
bc_src_port : integer
Returns an integer value corresponding to the TCP source port of the
connection on the server side, which is the port HAproxy connected from.
be_id : integer
Returns an integer containing the current backend's id. It can be used in
frontends with responses to check which backend processed the request. It can

View File

@ -41,27 +41,28 @@
#include <haproxy/tools.h>
/* Fetch the connection's source IPv4/IPv6 address. Note that this is also
* directly called by stick_table.c and as such must remain publicly visible.
/* Fetch the connection's source IPv4/IPv6 address. Depending on the keyword, it
* may be the frontend or the backend connection.
*/
static int
smp_fetch_src(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct connection *cli_conn = objt_conn(smp->sess->origin);
struct connection *conn = (kw[0] != 'b') ? objt_conn(smp->sess->origin) :
smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
if (!cli_conn)
if (!conn)
return 0;
if (!conn_get_src(cli_conn))
if (!conn_get_src(conn))
return 0;
switch (cli_conn->src->ss_family) {
switch (conn->src->ss_family) {
case AF_INET:
smp->data.u.ipv4 = ((struct sockaddr_in *)cli_conn->src)->sin_addr;
smp->data.u.ipv4 = ((struct sockaddr_in *)conn->src)->sin_addr;
smp->data.type = SMP_T_IPV4;
break;
case AF_INET6:
smp->data.u.ipv6 = ((struct sockaddr_in6 *)cli_conn->src)->sin6_addr;
smp->data.u.ipv6 = ((struct sockaddr_in6 *)conn->src)->sin6_addr;
smp->data.type = SMP_T_IPV6;
break;
default:
@ -72,45 +73,51 @@ smp_fetch_src(const struct arg *args, struct sample *smp, const char *kw, void *
return 1;
}
/* set temp integer to the connection's source port */
/* set temp integer to the connection's source port. Depending on the
* keyword, it may be the frontend or the backend connection.
*/
static int
smp_fetch_sport(const struct arg *args, struct sample *smp, const char *k, void *private)
smp_fetch_sport(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct connection *cli_conn = objt_conn(smp->sess->origin);
struct connection *conn = (kw[0] != 'b') ? objt_conn(smp->sess->origin) :
smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
if (!cli_conn)
if (!conn)
return 0;
if (!conn_get_src(cli_conn))
if (!conn_get_src(conn))
return 0;
smp->data.type = SMP_T_SINT;
if (!(smp->data.u.sint = get_host_port(cli_conn->src)))
if (!(smp->data.u.sint = get_host_port(conn->src)))
return 0;
smp->flags = 0;
return 1;
}
/* fetch the connection's destination IPv4/IPv6 address */
/* fetch the connection's destination IPv4/IPv6 address. Depending on the
* keyword, it may be the frontend or the backend connection.
*/
static int
smp_fetch_dst(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct connection *cli_conn = objt_conn(smp->sess->origin);
struct connection *conn = (kw[0] != 'b') ? objt_conn(smp->sess->origin) :
smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
if (!cli_conn)
if (!conn)
return 0;
if (!conn_get_dst(cli_conn))
if (!conn_get_dst(conn))
return 0;
switch (cli_conn->dst->ss_family) {
switch (conn->dst->ss_family) {
case AF_INET:
smp->data.u.ipv4 = ((struct sockaddr_in *)cli_conn->dst)->sin_addr;
smp->data.u.ipv4 = ((struct sockaddr_in *)conn->dst)->sin_addr;
smp->data.type = SMP_T_IPV4;
break;
case AF_INET6:
smp->data.u.ipv6 = ((struct sockaddr_in6 *)cli_conn->dst)->sin6_addr;
smp->data.u.ipv6 = ((struct sockaddr_in6 *)conn->dst)->sin6_addr;
smp->data.type = SMP_T_IPV6;
break;
default:
@ -161,20 +168,23 @@ int smp_fetch_src_is_local(const struct arg *args, struct sample *smp, const cha
return smp->data.u.sint >= 0;
}
/* set temp integer to the frontend connexion's destination port */
/* set temp integer to the connexion's destination port. Depending on the
* keyword, it may be the frontend or the backend connection.
*/
static int
smp_fetch_dport(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct connection *cli_conn = objt_conn(smp->sess->origin);
struct connection *conn = (kw[0] != 'b') ? objt_conn(smp->sess->origin) :
smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
if (!cli_conn)
if (!conn)
return 0;
if (!conn_get_dst(cli_conn))
if (!conn_get_dst(conn))
return 0;
smp->data.type = SMP_T_SINT;
if (!(smp->data.u.sint = get_host_port(cli_conn->dst)))
if (!(smp->data.u.sint = get_host_port(conn->dst)))
return 0;
smp->flags = 0;
@ -383,6 +393,11 @@ smp_fetch_fc_reordering(const struct arg *args, struct sample *smp, const char *
* instance v4/v6 must be declared v4.
*/
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "bc_dst", smp_fetch_dst, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV },
{ "bc_dst_port", smp_fetch_dport, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV },
{ "bc_src", smp_fetch_src, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV },
{ "bc_src_port", smp_fetch_sport, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV },
{ "dst", smp_fetch_dst, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI },
{ "dst_is_local", smp_fetch_dst_is_local, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI },
{ "dst_port", smp_fetch_dport, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI },