This is an automated email from the ASF dual-hosted git repository.
maskit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 2021eda2a1 Add a setting to adjust the maximum PP header size (#12961)
2021eda2a1 is described below
commit 2021eda2a1bfbe61fdf564395ed6325d5baa1e88
Author: Masakazu Kitajo <[email protected]>
AuthorDate: Fri Mar 20 22:04:47 2026 -0600
Add a setting to adjust the maximum PP header size (#12961)
Add a setting to adjust the maximum PP header size
The original hard coded size is too small if PP version2 is used and the
header contains many TLV fields.
This adds a new setting proxy.config.proxy_protocol.max_header_size to read
a larger but limited amount of data to parse PP header.
This also adds a quick check to detect whether PP header exists. The check
avoids copying a large amount of data if PP is definitely unused.
---
doc/admin-guide/files/records.yaml.en.rst | 13 +++++++++++++
include/iocore/net/NetVConnection.h | 2 +-
include/iocore/net/ProxyProtocol.h | 1 +
include/proxy/http/HttpConfig.h | 1 +
src/iocore/net/NetVConnection.cc | 14 +++++++++++---
src/iocore/net/ProxyProtocol.cc | 15 ++++++++++++++-
src/proxy/ProtocolProbeSessionAccept.cc | 6 ++++--
src/proxy/http/HttpConfig.cc | 2 ++
src/records/RecordsConfig.cc | 9 ++++++++-
9 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/doc/admin-guide/files/records.yaml.en.rst
b/doc/admin-guide/files/records.yaml.en.rst
index 43bf2ab7bb..46651a5d66 100644
--- a/doc/admin-guide/files/records.yaml.en.rst
+++ b/doc/admin-guide/files/records.yaml.en.rst
@@ -5214,6 +5214,19 @@ UDP Configuration
Enables (``1``) or disables (``0``) UDP GRO. When enabled, |TS| will try to
use it
when reading the UDP socket.
+
+PROXY protocol Configuration
+=============================
+
+.. ts:cv:: CONFIG proxy.config.proxy_protocol.max_header_size INT 109
+ :reloadable:
+
+ Sets the maximum size of PROXY protocol header to receive.
+ The default size is enough for PROXY protocol version 1. The size needs to
be increased
+ if the version 2 is used with many TLV fields. Although you can set a
number up to 65535,
+ setting a large number can affect performance.
+
+
Plug-in Configuration
=====================
diff --git a/include/iocore/net/NetVConnection.h
b/include/iocore/net/NetVConnection.h
index fedb7328ad..4da6053539 100644
--- a/include/iocore/net/NetVConnection.h
+++ b/include/iocore/net/NetVConnection.h
@@ -505,7 +505,7 @@ public:
void set_proxy_protocol_info(const ProxyProtocol &src);
const ProxyProtocol &get_proxy_protocol_info() const;
- bool has_proxy_protocol(IOBufferReader *);
+ bool has_proxy_protocol(IOBufferReader *, int max_header_size);
bool has_proxy_protocol(char *, int64_t *);
template <typename S> S *get_service() const;
diff --git a/include/iocore/net/ProxyProtocol.h
b/include/iocore/net/ProxyProtocol.h
index 5513ad4fcd..d3a7c73671 100644
--- a/include/iocore/net/ProxyProtocol.h
+++ b/include/iocore/net/ProxyProtocol.h
@@ -145,6 +145,7 @@ private:
const size_t PPv1_CONNECTION_HEADER_LEN_MAX = 108;
const size_t PPv2_CONNECTION_HEADER_LEN = 16;
+extern bool proxy_protocol_detect(swoc::TextView tv);
extern size_t proxy_protocol_parse(ProxyProtocol *pp_info,
swoc::TextView tv);
extern size_t proxy_protocol_build(uint8_t *buf, size_t
max_buf_len, const ProxyProtocol &pp_info,
ProxyProtocolVersion
force_version = ProxyProtocolVersion::UNDEFINED);
diff --git a/include/proxy/http/HttpConfig.h b/include/proxy/http/HttpConfig.h
index 86d3411512..b18dd5581e 100644
--- a/include/proxy/http/HttpConfig.h
+++ b/include/proxy/http/HttpConfig.h
@@ -888,6 +888,7 @@ public:
MgmtInt http_request_line_max_size = 65535;
MgmtInt http_hdr_field_max_size = 131070;
+ MgmtInt pp_hdr_max_size = 109;
MgmtByte http_host_sni_policy = 0;
MgmtByte scheme_proto_mismatch_policy = 2;
diff --git a/src/iocore/net/NetVConnection.cc b/src/iocore/net/NetVConnection.cc
index 9453584301..bacfc0e354 100644
--- a/src/iocore/net/NetVConnection.cc
+++ b/src/iocore/net/NetVConnection.cc
@@ -51,11 +51,19 @@ DbgCtl dbg_ctl_ssl{"ssl"};
If the buffer has PROXY Protocol, it will be consumed by this function.
*/
bool
-NetVConnection::has_proxy_protocol(IOBufferReader *reader)
+NetVConnection::has_proxy_protocol(IOBufferReader *reader, int max_header_size)
{
- char buf[PPv1_CONNECTION_HEADER_LEN_MAX + 1];
swoc::TextView tv;
- tv.assign(buf, reader->memcpy(buf, sizeof(buf), 0));
+
+ char preface[PPv2_CONNECTION_HEADER_LEN];
+ tv.assign(preface, reader->memcpy(preface, sizeof(preface), 0));
+ if (!proxy_protocol_detect(tv)) {
+ return false;
+ }
+
+ int bufsize = max_header_size;
+ char buf[bufsize];
+ tv.assign(buf, reader->memcpy(buf, bufsize, 0));
size_t len = proxy_protocol_parse(&this->pp_info, tv);
diff --git a/src/iocore/net/ProxyProtocol.cc b/src/iocore/net/ProxyProtocol.cc
index 472f544354..1b475c96c5 100644
--- a/src/iocore/net/ProxyProtocol.cc
+++ b/src/iocore/net/ProxyProtocol.cc
@@ -22,6 +22,7 @@
*/
#include "iocore/net/ProxyProtocol.h"
+#include "tscore/Diags.h"
#include "tscore/ink_assert.h"
#include "tscore/ink_string.h"
#include "tscore/ink_inet.h"
@@ -237,7 +238,7 @@ proxy_protocol_v2_parse(ProxyProtocol *pp_info, const
swoc::TextView &msg)
uint16_t tlv_len = 0;
if (msg.size() < total_len) {
- Dbg(dbg_ctl_proxyprotocol_v2, "The amount of available data is smaller
than the expected size");
+ Error("The size of PP header received (%zu) is smaller than the expected
size (%zu)", msg.size(), total_len);
return 0;
}
@@ -453,6 +454,18 @@ proxy_protocol_v2_build(uint8_t *buf, size_t max_buf_len,
const ProxyProtocol &p
} // namespace
+bool
+proxy_protocol_detect(swoc::TextView tv)
+{
+ if (tv.size() >= PPv1_CONNECTION_HEADER_LEN_MIN &&
tv.starts_with(PPv1_CONNECTION_PREFACE)) {
+ return true;
+ } else if (tv.size() >= PPv2_CONNECTION_HEADER_LEN &&
tv.starts_with(PPv2_CONNECTION_PREFACE)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
/**
PROXY Protocol Parser
*/
diff --git a/src/proxy/ProtocolProbeSessionAccept.cc
b/src/proxy/ProtocolProbeSessionAccept.cc
index 40ff286ea0..3ba94633f2 100644
--- a/src/proxy/ProtocolProbeSessionAccept.cc
+++ b/src/proxy/ProtocolProbeSessionAccept.cc
@@ -127,8 +127,10 @@ struct ProtocolProbeTrampoline : public Continuation,
public ProtocolProbeSessio
"ioCompletionEvent: proxy protocol DOES NOT have a configured
allowlist of trusted IPs but proxy protocol is "
"ernabled on this port - processing all connections");
}
-
- if (netvc->has_proxy_protocol(reader)) {
+ HttpConfigParams *param = HttpConfig::acquire();
+ int max_header_size = param->pp_hdr_max_size;
+ HttpConfig::release(param);
+ if (netvc->has_proxy_protocol(reader, max_header_size)) {
Dbg(dbg_ctl_proxyprotocol, "ioCompletionEvent: http has proxy protocol
header");
} else {
Dbg(dbg_ctl_proxyprotocol, "ioCompletionEvent: proxy protocol was
enabled, but Proxy Protocol header was not present");
diff --git a/src/proxy/http/HttpConfig.cc b/src/proxy/http/HttpConfig.cc
index 7b0d167957..adcb6e8b86 100644
--- a/src/proxy/http/HttpConfig.cc
+++ b/src/proxy/http/HttpConfig.cc
@@ -963,6 +963,7 @@ HttpConfig::startup()
HttpEstablishStaticConfigLongLong(c.http_request_line_max_size,
"proxy.config.http.request_line_max_size");
HttpEstablishStaticConfigLongLong(c.http_hdr_field_max_size,
"proxy.config.http.header_field_max_size");
+ HttpEstablishStaticConfigLongLong(c.pp_hdr_max_size,
"proxy.config.proxy_protocol.max_header_size");
HttpEstablishStaticConfigByte(c.disable_ssl_parenting,
"proxy.config.http.parent_proxy.disable_connect_tunneling");
HttpEstablishStaticConfigByte(c.oride.forward_connect_method,
"proxy.config.http.forward_connect_method");
@@ -1275,6 +1276,7 @@ HttpConfig::reconfigure()
params->http_request_line_max_size = m_master.http_request_line_max_size;
params->http_hdr_field_max_size = m_master.http_hdr_field_max_size;
+ params->pp_hdr_max_size = m_master.pp_hdr_max_size;
if (params->oride.connection_tracker_config.server_max > 0 &&
params->oride.connection_tracker_config.server_max <
params->oride.connection_tracker_config.server_min) {
diff --git a/src/records/RecordsConfig.cc b/src/records/RecordsConfig.cc
index d042a8d153..f2c85649a7 100644
--- a/src/records/RecordsConfig.cc
+++ b/src/records/RecordsConfig.cc
@@ -1544,7 +1544,14 @@ static constexpr RecordElement RecordsConfig[] =
//# Thread watchdog
//#
//###########
- {RECT_CONFIG, "proxy.config.exec_thread.watchdog.timeout_ms", RECD_INT, "0",
RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-10000]", RECA_NULL}
+ {RECT_CONFIG, "proxy.config.exec_thread.watchdog.timeout_ms", RECD_INT, "0",
RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-10000]", RECA_NULL},
+
+ //###########
+ //#
+ //# PROXY protocol
+ //#
+ //###########
+ {RECT_CONFIG, "proxy.config.proxy_protocol.max_header_size", RECD_INT,
"109", RECU_DYNAMIC, RR_NULL, RECC_INT, "[109-65535]", RECA_NULL},
};
// clang-format on