mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-26 14:42:21 +00:00
MINOR: connection: Send out generic, user-defined server TLVs
To follow-up the implementation of the new set-proxy-v2-tlv-fmt keyword in the server, the connection is updated to use the previously allocated TLVs. If no value was specified, we send out an empty TLV. As the feature is fully working with this commit, documentation and a test for the server and default-server are added as well.
This commit is contained in:
parent
6f4bfed3a2
commit
ce7501de79
@ -16742,6 +16742,22 @@ send-proxy-v2
|
||||
of this version of the protocol. See also the "no-send-proxy-v2" option of
|
||||
this section and send-proxy" option of the "bind" keyword.
|
||||
|
||||
set-proxy-v2-tlv-fmt(<id>) <fmt>
|
||||
The "set-proxy-v2-tlv-fmt" parameter is used to send arbitrary PROXY protocol
|
||||
version 2 TLVs. For the type (<id>) range of the defined TLV type please refer
|
||||
to section 2.2.8. of the proxy protocol specification. However, the value can
|
||||
be chosen freely as long as it does not exceed the maximum length of 65,535
|
||||
bytes. It can also be used for forwarding TLVs by using the fetch "fc_pp_tlv"
|
||||
to retrieve a received TLV from the frontend. It may be used as a server or
|
||||
a default-server option. It must be used in combination with send-proxy-v2
|
||||
such that PPv2 TLVs are actually sent out.
|
||||
|
||||
Example:
|
||||
server srv1 192.168.1.1:80 send-proxy-v2 set-proxy-v2-tlv-fmt(0x20) %[fc_pp_tlv(0x20)]
|
||||
|
||||
In this case, we fetch the TLV with the type 0x20 as a string and set as the value
|
||||
of a newly created TLV that also has the type 0x20.
|
||||
|
||||
proxy-v2-options <option>[,<option>]*
|
||||
The "proxy-v2-options" parameter add options to send in PROXY protocol
|
||||
version 2 when "send-proxy-v2" is used. Options available are:
|
||||
|
74
reg-tests/connection/proxy_protocol_send_generic.vtc
Normal file
74
reg-tests/connection/proxy_protocol_send_generic.vtc
Normal file
@ -0,0 +1,74 @@
|
||||
varnishtest "Check that generic TLV IDs are sent properly"
|
||||
|
||||
#REQUIRE_VERSION=2.2
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
haproxy h1 -conf {
|
||||
defaults
|
||||
mode http
|
||||
log global
|
||||
|
||||
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
|
||||
listen sender
|
||||
bind "fd@${feS}"
|
||||
server example ${h1_feR_addr}:${h1_feR_port} send-proxy-v2 set-proxy-v2-tlv-fmt(0xE1) %[str("foo")] set-proxy-v2-tlv-fmt(0xE2)
|
||||
|
||||
listen receiver
|
||||
bind "fd@${feR}" accept-proxy
|
||||
|
||||
# Check that the TLV value is set in the backend.
|
||||
http-request set-var(txn.custom_tlv_a) fc_pp_tlv(0xE1)
|
||||
http-after-response set-header proxy_custom_tlv_a %[var(txn.custom_tlv_a)]
|
||||
|
||||
# Check that TLVs without an value are sent out.
|
||||
http-request set-var(txn.custom_tlv_b) fc_pp_tlv(0xE2)
|
||||
http-after-response set-header proxy_custom_tlv_b %[var(txn.custom_tlv_b)]
|
||||
|
||||
# Note that we do not check for an invalid TLV ID as that would result in an
|
||||
# parser error anway.
|
||||
|
||||
http-request return status 200
|
||||
} -start
|
||||
|
||||
|
||||
client c1 -connect ${h1_feS_sock} {
|
||||
txreq -url "/"
|
||||
rxresp
|
||||
expect resp.http.proxy_custom_tlv_a == "foo"
|
||||
expect resp.http.proxy_custom_tlv_b == ""
|
||||
} -run
|
||||
|
||||
# Ensure that we achieve the same via a default-server.
|
||||
haproxy h2 -conf {
|
||||
defaults
|
||||
mode http
|
||||
log global
|
||||
|
||||
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
|
||||
listen sender
|
||||
bind "fd@${feS}"
|
||||
default-server send-proxy-v2 set-proxy-v2-tlv-fmt(0xE1) %[str("bar")]
|
||||
server example ${h1_feR_addr}:${h1_feR_port}
|
||||
|
||||
listen receiver
|
||||
bind "fd@${feR}" accept-proxy
|
||||
|
||||
http-request set-var(txn.custom_tlv_a) fc_pp_tlv(0xE1)
|
||||
http-after-response set-header proxy_custom_tlv_a %[var(txn.custom_tlv_a)]
|
||||
|
||||
http-request return status 200
|
||||
} -start
|
||||
|
||||
|
||||
client c2 -connect ${h2_feS_sock} {
|
||||
txreq -url "/"
|
||||
rxresp
|
||||
expect resp.http.proxy_custom_tlv_a == "bar"
|
||||
} -run
|
@ -1927,10 +1927,11 @@ static int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct
|
||||
int ret = 0;
|
||||
struct proxy_hdr_v2 *hdr = (struct proxy_hdr_v2 *)buf;
|
||||
struct sockaddr_storage null_addr = { .ss_family = 0 };
|
||||
struct srv_pp_tlv_list *srv_tlv = NULL;
|
||||
const struct sockaddr_storage *src = &null_addr;
|
||||
const struct sockaddr_storage *dst = &null_addr;
|
||||
const char *value;
|
||||
int value_len;
|
||||
const char *value = "";
|
||||
int value_len = 0;
|
||||
|
||||
if (buf_len < PP2_HEADER_LEN)
|
||||
return 0;
|
||||
@ -2000,6 +2001,37 @@ static int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct
|
||||
}
|
||||
}
|
||||
|
||||
if (strm) {
|
||||
struct buffer *replace = NULL;
|
||||
|
||||
list_for_each_entry(srv_tlv, &srv->pp_tlvs, list) {
|
||||
replace = NULL;
|
||||
|
||||
/* Users will always need to provide a value, in case of forwarding, they should use fc_pp_tlv.
|
||||
* for generic types. Otherwise, we will send an empty TLV.
|
||||
*/
|
||||
if (!LIST_ISEMPTY(&srv_tlv->fmt)) {
|
||||
replace = alloc_trash_chunk();
|
||||
if (unlikely(!replace))
|
||||
return 0;
|
||||
|
||||
replace->data = build_logline(strm, replace->area, replace->size, &srv_tlv->fmt);
|
||||
|
||||
if (unlikely((buf_len - ret) < sizeof(struct tlv))) {
|
||||
free_trash_chunk(replace);
|
||||
return 0;
|
||||
}
|
||||
ret += make_tlv(&buf[ret], (buf_len - ret), srv_tlv->type, replace->data, replace->area);
|
||||
free_trash_chunk(replace);
|
||||
}
|
||||
else {
|
||||
/* Create empty TLV as no value was specified */
|
||||
ret += make_tlv(&buf[ret], (buf_len - ret), srv_tlv->type, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle predefined TLVs as usual */
|
||||
if (srv->pp_opts & SRV_PP_V2_CRC32C) {
|
||||
uint32_t zero_crc32c = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user