mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
MINOR: proxy_protocol: Ingest PP2_TYPE_UNIQUE_ID on incoming connections
This patch reads a proxy protocol v2 provided unique ID and makes it available using the `fc_pp_unique_id` fetch.
This commit is contained in:
parent
b435f77620
commit
d1b15b6e9b
@ -15131,6 +15131,10 @@ fc_pp_authority : string
|
||||
Returns the authority TLV sent by the client in the PROXY protocol header,
|
||||
if any.
|
||||
|
||||
fc_pp_unique_id : string
|
||||
Returns the unique ID TLV sent by the client in the PROXY protocol header,
|
||||
if any.
|
||||
|
||||
fc_rcvd_proxy : boolean
|
||||
Returns true if the client initiated the connection with a PROXY protocol
|
||||
header.
|
||||
|
@ -325,6 +325,7 @@ static inline void conn_init(struct connection *conn)
|
||||
conn->src = NULL;
|
||||
conn->dst = NULL;
|
||||
conn->proxy_authority = NULL;
|
||||
conn->proxy_unique_id = IST_NULL;
|
||||
}
|
||||
|
||||
/* sets <owner> as the connection's owner */
|
||||
@ -458,6 +459,10 @@ static inline void conn_free(struct connection *conn)
|
||||
pool_free(pool_head_authority, conn->proxy_authority);
|
||||
conn->proxy_authority = NULL;
|
||||
}
|
||||
if (isttest(conn->proxy_unique_id)) {
|
||||
pool_free(pool_head_uniqueid, conn->proxy_unique_id.ptr);
|
||||
conn->proxy_unique_id = IST_NULL;
|
||||
}
|
||||
|
||||
/* By convention we always place a NULL where the ctx points to if the
|
||||
* mux is null. It may have been used to store the connection as a
|
||||
|
@ -469,6 +469,7 @@ struct connection {
|
||||
char *proxy_authority; /* Value of authority TLV received via PROXYv2 */
|
||||
unsigned int idle_time; /* Time the connection was added to the idle list, or 0 if not in the idle list */
|
||||
uint8_t proxy_authority_len; /* Length of authority TLV received via PROXYv2 */
|
||||
struct ist proxy_unique_id; /* Value of the unique ID TLV received via PROXYv2 */
|
||||
};
|
||||
|
||||
/* PROTO token registration */
|
||||
|
38
reg-tests/stream/unique-id-from-proxy.vtc
Normal file
38
reg-tests/stream/unique-id-from-proxy.vtc
Normal file
@ -0,0 +1,38 @@
|
||||
varnishtest "Check that we are able to read a unique-id from PROXYv2"
|
||||
|
||||
#REQUIRE_VERSION=2.2
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
haproxy h1 -conf {
|
||||
defaults
|
||||
mode http
|
||||
timeout connect 1s
|
||||
timeout client 1s
|
||||
timeout server 1s
|
||||
|
||||
frontend echo
|
||||
bind "fd@${fe1}" accept-proxy
|
||||
http-after-response set-header echo %[fc_pp_unique_id,hex]
|
||||
http-request return status 200
|
||||
} -start
|
||||
|
||||
client c1 -connect ${h1_fe1_sock} {
|
||||
# PROXY v2 signature
|
||||
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
|
||||
# version + PROXY
|
||||
sendhex "21"
|
||||
# TCP4
|
||||
sendhex "11"
|
||||
# length of the address (12) + length of the TLV (8)
|
||||
sendhex "00 14"
|
||||
# 127.0.0.1 42 127.0.0.1 1337
|
||||
sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39"
|
||||
# PP2_TYPE_UNIQUE_ID + length of the value + "12345"
|
||||
sendhex "05 00 05 31 32 33 34 35"
|
||||
|
||||
txreq -url "/"
|
||||
rxresp
|
||||
expect resp.status == 200
|
||||
expect resp.http.echo == "3132333435"
|
||||
} -run
|
@ -755,6 +755,22 @@ int conn_recv_proxy(struct connection *conn, int flag)
|
||||
conn->proxy_authority_len = tlv_len;
|
||||
break;
|
||||
}
|
||||
case PP2_TYPE_UNIQUE_ID: {
|
||||
const struct ist tlv = ist2((const char *)tlv_packet->value, tlv_len);
|
||||
|
||||
if (tlv.len > UNIQUEID_LEN)
|
||||
goto bad_header;
|
||||
conn->proxy_unique_id.ptr = pool_alloc(pool_head_uniqueid);
|
||||
if (!isttest(conn->proxy_unique_id))
|
||||
goto fail;
|
||||
if (istcpy(&conn->proxy_unique_id, tlv, UNIQUEID_LEN) < 0) {
|
||||
/* This is technically unreachable, because we verified above
|
||||
* that the TLV value fits.
|
||||
*/
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1586,6 +1602,31 @@ int smp_fetch_fc_pp_authority(const struct arg *args, struct sample *smp, const
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fetch the unique ID TLV from a PROXY protocol header */
|
||||
int smp_fetch_fc_pp_unique_id(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_WAIT_XPRT) {
|
||||
smp->flags |= SMP_F_MAY_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!isttest(conn->proxy_unique_id))
|
||||
return 0;
|
||||
|
||||
smp->flags = 0;
|
||||
smp->data.type = SMP_T_STR;
|
||||
smp->data.u.str.area = conn->proxy_unique_id.ptr;
|
||||
smp->data.u.str.data = conn->proxy_unique_id.len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Note: must not be declared <const> 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
|
||||
@ -1596,6 +1637,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
{ "bc_http_major", smp_fetch_fc_http_major, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV },
|
||||
{ "fc_rcvd_proxy", smp_fetch_fc_rcvd_proxy, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI },
|
||||
{ "fc_pp_authority", smp_fetch_fc_pp_authority, 0, NULL, SMP_T_STR, SMP_USE_L4CLI },
|
||||
{ "fc_pp_unique_id", smp_fetch_fc_pp_unique_id, 0, NULL, SMP_T_STR, SMP_USE_L4CLI },
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user