Skip to content

Commit c86edef

Browse files
author
Kevin Dorosh
committed
Add another test and fix for v2 followed by v1 signature bytes
Signed-off-by: Kevin Dorosh <kevin.dorosh@solo.io>
1 parent 85706e6 commit c86edef

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc

+12-7
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,18 @@ ReadOrParseState Filter::readProxyHeader(Network::ListenerFilterBuffer& buffer)
458458
for (; search_index_ < raw_slice.len_; search_index_++) {
459459
if (buf[search_index_] == '\n' && buf[search_index_ - 1] == '\r') {
460460
if (search_index_ == 1) {
461+
if (config_.get()->allowRequestsWithoutProxyProtocol()) {
462+
// we need to check if what we have already could be v2 proxy protocol;
463+
// if it cannot be, then we might as well forward now
464+
auto matchv2 = !memcmp(buf, PROXY_PROTO_V2_SIGNATURE,
465+
std::min<size_t>(PROXY_PROTO_V2_SIGNATURE_LEN, raw_slice.len_));
466+
if (!matchv2) {
467+
// the bytes we have seen so far do not match v1 or v2 proxy protocol, so we can
468+
// safely short-circuit
469+
ENVOY_LOG(debug, "request does not use v1 or v2 proxy protocol, forwarding as is");
470+
return ReadOrParseState::SkipFilter;
471+
}
472+
}
461473
// There is not enough data to determine if it contains the v2 protocol signature, so wait
462474
// for more data.
463475
break;
@@ -469,13 +481,6 @@ ReadOrParseState Filter::readProxyHeader(Network::ListenerFilterBuffer& buffer)
469481
} else if (config_.get()->allowRequestsWithoutProxyProtocol()) {
470482
if (search_index_ < PROXY_PROTO_V1_SIGNATURE_LEN &&
471483
buf[search_index_] != PROXY_PROTO_V1_SIGNATURE[search_index_]) {
472-
possibly_v1_ = false;
473-
}
474-
if (search_index_ < PROXY_PROTO_V2_SIGNATURE_LEN &&
475-
buf[search_index_] != PROXY_PROTO_V2_SIGNATURE[search_index_]) {
476-
possibly_v2_ = false;
477-
}
478-
if (!possibly_v1_ && !possibly_v2_) {
479484
// the bytes we have seen so far do not match v1 or v2 proxy protocol, so we can safely
480485
// short-circuit
481486
ENVOY_LOG(debug, "request does not use v1 or v2 proxy protocol, forwarding as is");

source/extensions/filters/listener/proxy_protocol/proxy_protocol.h

-3
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,6 @@ class Filter : public Network::ListenerFilter, Logger::Loggable<Logger::Id::filt
127127
// The index in buf_ where the search for '\r\n' should continue from
128128
size_t search_index_{1};
129129

130-
bool possibly_v1_{true};
131-
bool possibly_v2_{true};
132-
133130
ProxyProtocolVersion header_version_{Unknown};
134131

135132
ConfigSharedPtr config_;

test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc

+22-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ TEST_P(ProxyProtocolTest, AllowTinyNoProxyProtocol) {
251251
disconnect();
252252
}
253253

254-
TEST_P(ProxyProtocolTest, AllowTinyNoProxyProtocolPartialMatches) {
254+
TEST_P(ProxyProtocolTest, AllowTinyNoProxyProtocolPartialMatchesV1First) {
255255
// allows a small request (less bytes than v1/v2 signature) through even though it doesn't use
256256
// proxy protocol v1/v2 (but it does match parts of both signatures)
257257
envoy::extensions::filters::listener::proxy_protocol::v3::ProxyProtocol proto_config;
@@ -272,6 +272,27 @@ TEST_P(ProxyProtocolTest, AllowTinyNoProxyProtocolPartialMatches) {
272272
disconnect();
273273
}
274274

275+
TEST_P(ProxyProtocolTest, AllowTinyNoProxyProtocolPartialMatchesV2First) {
276+
// allows a small request (less bytes than v1/v2 signature) through even though it doesn't use
277+
// proxy protocol v1/v2 (but it does match parts of both signatures)
278+
envoy::extensions::filters::listener::proxy_protocol::v3::ProxyProtocol proto_config;
279+
proto_config.set_allow_requests_without_proxy_protocol(true);
280+
connect(true, &proto_config);
281+
282+
// first two bytes proxy protocol v2, second two bytes proxy protocol v1.
283+
// this ensures our byte by byte parsing (search_index_) has persistence built-in to
284+
// remember whether the previous bytes were also valid for the signature
285+
std::string msg = "\r\nOX";
286+
EXPECT_GT(PROXY_PROTO_V1_SIGNATURE_LEN, msg.length());
287+
EXPECT_GT(PROXY_PROTO_V2_SIGNATURE_LEN, msg.length());
288+
289+
write(msg);
290+
291+
expectData(msg);
292+
293+
disconnect();
294+
}
295+
275296
TEST_P(ProxyProtocolTest, AllowLargeNoProxyProtocol) {
276297
// allows a large request (more bytes than v1/v2 signature) through even though it doesn't use
277298
// proxy protocol

0 commit comments

Comments
 (0)