From: Emeric Brun Date: Thu, 5 Jan 2017 14:11:44 +0000 (+0100) Subject: MINOR: connection: add sample fetch "fc_rcvd_proxy" X-Git-Tag: v1.8-dev1~179 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f60301235ca1d35d51a49f15981706dd1ab67a0;p=thirdparty%2Fhaproxy.git MINOR: connection: add sample fetch "fc_rcvd_proxy" fc_rcvd_proxy : boolean Returns true if the client initiated the connection with a PROXY protocol header. A flag is added on the struct connection if a PROXY header is successfully parsed. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 132873d7d3..2cbf90dcf1 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -13149,6 +13149,10 @@ dst_port : integer a same server, or to pass the destination port information to a server using an HTTP header. +fc_rcvd_proxy : boolean + Returns true if the client initiated the connection with a PROXY protocol + header. + fc_rtt() : integer Returns the Round Trip Time (RTT) measured by the kernel for the client connection. is facultative, by default the unit is milliseconds. diff --git a/include/types/connection.h b/include/types/connection.h index 0d7fe27b76..c644dd55bb 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -127,7 +127,10 @@ enum { /* This connection may not be shared between clients */ CO_FL_PRIVATE = 0x10000000, - /* unused : 0x20000000, 0x40000000 */ + /* This flag is used to know that a PROXY protocol header was sent by the client */ + CO_FL_RCVD_PROXY = 0x20000000, + + /* unused : 0x40000000 */ /* This last flag indicates that the transport layer is used (for instance * by logs) and must not be cleared yet. The last call to conn_xprt_close() diff --git a/src/connection.c b/src/connection.c index 093b8a963e..054823b139 100644 --- a/src/connection.c +++ b/src/connection.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef USE_OPENSSL #include @@ -603,6 +604,7 @@ int conn_recv_proxy(struct connection *conn, int flag) } while (0); conn->flags &= ~flag; + conn->flags |= CO_FL_RCVD_PROXY; return 1; missing: @@ -1040,3 +1042,41 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec return ret; } + +/* fetch if the received connection used a PROXY protocol header */ +int smp_fetch_fc_rcvd_proxy(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct connection *conn; + + conn = objt_conn(smp->sess->origin); + if (!conn) + return 0; + + if (!(conn->flags & CO_FL_CONNECTED)) { + smp->flags |= SMP_F_MAY_CHANGE; + return 0; + } + + smp->flags = 0; + smp->data.type = SMP_T_BOOL; + smp->data.u.sint = (conn->flags & CO_FL_RCVD_PROXY) ? 1 : 0; + + return 1; +} + +/* Note: must not be declared as its list will be overwritten. + * Note: fetches that may return multiple types must be declared as the lowest + * common denominator, the type that can be casted into all other ones. For + * instance v4/v6 must be declared v4. + */ +static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { + { "fc_rcvd_proxy", smp_fetch_fc_rcvd_proxy, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI }, + { /* END */ }, +}}; + + +__attribute__((constructor)) +static void __connection_init(void) +{ + sample_register_fetches(&sample_fetch_keywords); +}