Skip to content

Commit

Permalink
Fix crash when proxy protocol receives an address type that isn't
Browse files Browse the repository at this point in the history
supported by the operating system

Fix [CVE-2024-23325](GHSA-5m7c-mrwr-pm26)

Signed-off-by: Greg Greenway <ggreenway@apple.com>
Signed-off-by: Ryan Northey <ryan@synca.io>
  • Loading branch information
ggreenway authored and phlax committed Feb 9, 2024
1 parent 843f9e6 commit bacd310
Show file tree
Hide file tree
Showing 14 changed files with 225 additions and 64 deletions.
9 changes: 9 additions & 0 deletions changelogs/current.yaml
Expand Up @@ -58,6 +58,15 @@ bug_fixes:
- area: http
change: |
Fixed crash when HTTP request idle and per try timeouts occurs within backoff interval.
- area: proxy_protocol
change: |
Fix crash due to uncaught exception when the operating system does not support an address type (such as IPv6) that is
received in a proxy protocol header. Connections will instead be dropped/reset.
- area: tls
change: |
Fix crash due to uncaught exception when the operating system does not support an address type (such as IPv6) that is
received in an mTLS client cert IP SAN. These SANs will be ignored. This applies only when using formatter
``%DOWNSTREAM_PEER_IP_SAN%``.
removed_config_or_runtime:
# *Normally occurs at the end of the* :ref:`deprecation period <deprecated>`
Expand Down
1 change: 1 addition & 0 deletions source/common/network/BUILD
Expand Up @@ -20,6 +20,7 @@ envoy_cc_library(
":socket_interface_lib",
"//envoy/network:address_interface",
"//source/common/common:assert_lib",
"//source/common/common:cleanup_lib",
"//source/common/common:safe_memcpy_lib",
"//source/common/common:statusor_lib",
"//source/common/common:thread_lib",
Expand Down
24 changes: 22 additions & 2 deletions source/common/network/address_impl.cc
Expand Up @@ -212,9 +212,19 @@ std::string Ipv4Instance::sockaddrToString(const sockaddr_in& addr) {
return {start, end};
}

namespace {
bool force_ipv4_unsupported_for_test = false;
}

Cleanup Ipv4Instance::forceProtocolUnsupportedForTest(bool new_val) {
bool old_val = force_ipv4_unsupported_for_test;
force_ipv4_unsupported_for_test = new_val;
return Cleanup([old_val]() { force_ipv4_unsupported_for_test = old_val; });
}

absl::Status Ipv4Instance::validateProtocolSupported() {
static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET);
if (supported) {
if (supported && !force_ipv4_unsupported_for_test) {
return absl::OkStatus();
}
return absl::FailedPreconditionError("IPv4 addresses are not supported on this machine");
Expand Down Expand Up @@ -324,9 +334,19 @@ Ipv6Instance::Ipv6Instance(absl::Status& status, const sockaddr_in6& address, bo
initHelper(address, v6only);
}

namespace {
bool force_ipv6_unsupported_for_test = false;
}

Cleanup Ipv6Instance::forceProtocolUnsupportedForTest(bool new_val) {
bool old_val = force_ipv6_unsupported_for_test;
force_ipv6_unsupported_for_test = new_val;
return Cleanup([old_val]() { force_ipv6_unsupported_for_test = old_val; });
}

absl::Status Ipv6Instance::validateProtocolSupported() {
static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET6);
if (supported) {
if (supported && !force_ipv6_unsupported_for_test) {
return absl::OkStatus();
}
return absl::FailedPreconditionError("IPv6 addresses are not supported on this machine");
Expand Down
16 changes: 16 additions & 0 deletions source/common/network/address_impl.h
Expand Up @@ -11,12 +11,16 @@
#include "envoy/network/socket.h"

#include "source/common/common/assert.h"
#include "source/common/common/cleanup.h"
#include "source/common/common/statusor.h"

namespace Envoy {
namespace Network {
namespace Address {

// Add an address-specific version for easier searching.
#define TRY_NEEDS_AUDIT_ADDRESS TRY_NEEDS_AUDIT

/**
* Check whether we are a) on Android or an Apple platform and b) configured via runtime to always
* use v6 sockets.
Expand Down Expand Up @@ -144,6 +148,12 @@ class Ipv4Instance : public InstanceBase {
// given address if not.
static absl::Status validateProtocolSupported();

/**
* For use in tests only.
* Force validateProtocolSupported() to return false for IPv4.
*/
static Envoy::Cleanup forceProtocolUnsupportedForTest(bool new_val);

private:
/**
* Construct from an existing unix IPv4 socket address (IP v4 address and port).
Expand Down Expand Up @@ -226,6 +236,12 @@ class Ipv6Instance : public InstanceBase {
// Validate that IPv6 is supported on this platform
static absl::Status validateProtocolSupported();

/**
* For use in tests only.
* Force validateProtocolSupported() to return false for IPv6.
*/
static Envoy::Cleanup forceProtocolUnsupportedForTest(bool new_val);

private:
/**
* Construct from an existing unix IPv6 socket address (IP v6 address and port).
Expand Down
38 changes: 28 additions & 10 deletions source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc
Expand Up @@ -276,11 +276,21 @@ bool Filter::parseV2Header(const char* buf) {
la4.sin_family = AF_INET;
la4.sin_port = v4->dst_port;
la4.sin_addr.s_addr = v4->dst_addr;
proxy_protocol_header_.emplace(
WireHeader{PROXY_PROTO_V2_HEADER_LEN, hdr_addr_len, PROXY_PROTO_V2_ADDR_LEN_INET,
hdr_addr_len - PROXY_PROTO_V2_ADDR_LEN_INET, Network::Address::IpVersion::v4,
std::make_shared<Network::Address::Ipv4Instance>(&ra4),
std::make_shared<Network::Address::Ipv4Instance>(&la4)});

TRY_NEEDS_AUDIT_ADDRESS {
// TODO(ggreenway): make this work without requiring operating system support for an
// address family.
proxy_protocol_header_.emplace(WireHeader{
PROXY_PROTO_V2_HEADER_LEN, hdr_addr_len, PROXY_PROTO_V2_ADDR_LEN_INET,
hdr_addr_len - PROXY_PROTO_V2_ADDR_LEN_INET, Network::Address::IpVersion::v4,
std::make_shared<Network::Address::Ipv4Instance>(&ra4),
std::make_shared<Network::Address::Ipv4Instance>(&la4)});
}
END_TRY CATCH(const EnvoyException& e, {
ENVOY_LOG(debug, "Proxy protocol failure: {}", e.what());
return false;
});

return true;
} else if (((proto_family & 0xf0) >> 4) == PROXY_PROTO_V2_AF_INET6) {
PACKED_STRUCT(struct pp_ipv6_addr {
Expand All @@ -302,11 +312,19 @@ bool Filter::parseV2Header(const char* buf) {
la6.sin6_port = v6->dst_port;
safeMemcpy(&(la6.sin6_addr.s6_addr), &(v6->dst_addr));

proxy_protocol_header_.emplace(WireHeader{
PROXY_PROTO_V2_HEADER_LEN, hdr_addr_len, PROXY_PROTO_V2_ADDR_LEN_INET6,
hdr_addr_len - PROXY_PROTO_V2_ADDR_LEN_INET6, Network::Address::IpVersion::v6,
std::make_shared<Network::Address::Ipv6Instance>(ra6),
std::make_shared<Network::Address::Ipv6Instance>(la6)});
TRY_NEEDS_AUDIT_ADDRESS {
proxy_protocol_header_.emplace(WireHeader{
PROXY_PROTO_V2_HEADER_LEN, hdr_addr_len, PROXY_PROTO_V2_ADDR_LEN_INET6,
hdr_addr_len - PROXY_PROTO_V2_ADDR_LEN_INET6, Network::Address::IpVersion::v6,
std::make_shared<Network::Address::Ipv6Instance>(ra6),
std::make_shared<Network::Address::Ipv6Instance>(la6)});
}
END_TRY CATCH(const EnvoyException& e, {
// TODO(ggreenway): make this work without requiring operating system support for an
// address family.
ENVOY_LOG(debug, "Proxy protocol failure: {}", e.what());
return false;
});
return true;
}
}
Expand Down
Expand Up @@ -185,7 +185,7 @@ absl::Span<const std::string> ConnectionInfoImplBase::ipSansPeerCertificate() co
ASSERT(cached_ip_san_peer_certificate_.empty());
return cached_ip_san_peer_certificate_;
}
cached_ip_san_peer_certificate_ = Utility::getSubjectAltNames(*cert, GEN_IPADD);
cached_ip_san_peer_certificate_ = Utility::getSubjectAltNames(*cert, GEN_IPADD, true);
return cached_ip_san_peer_certificate_;
}

Expand Down
12 changes: 10 additions & 2 deletions source/extensions/transport_sockets/tls/utility.cc
Expand Up @@ -167,7 +167,7 @@ std::string Utility::getSerialNumberFromCertificate(X509& cert) {
return "";
}

std::vector<std::string> Utility::getSubjectAltNames(X509& cert, int type) {
std::vector<std::string> Utility::getSubjectAltNames(X509& cert, int type, bool skip_unsupported) {
std::vector<std::string> subject_alt_names;
bssl::UniquePtr<GENERAL_NAMES> san_names(
static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(&cert, NID_subject_alt_name, nullptr, nullptr)));
Expand All @@ -176,7 +176,15 @@ std::vector<std::string> Utility::getSubjectAltNames(X509& cert, int type) {
}
for (const GENERAL_NAME* san : san_names.get()) {
if (san->type == type) {
subject_alt_names.push_back(generalNameAsString(san));
if (skip_unsupported) {
// An IP SAN for an unsupported IP version will throw an exception.
// TODO(ggreenway): remove this when IP address construction no longer throws.
TRY_NEEDS_AUDIT_ADDRESS { subject_alt_names.push_back(generalNameAsString(san)); }
END_TRY CATCH(const EnvoyException& e,
{ ENVOY_LOG_MISC(debug, "Error reading SAN, value skipped: {}", e.what()); });
} else {
subject_alt_names.push_back(generalNameAsString(san));
}
}
}
return subject_alt_names;
Expand Down
4 changes: 3 additions & 1 deletion source/extensions/transport_sockets/tls/utility.h
Expand Up @@ -52,9 +52,11 @@ std::string getSerialNumberFromCertificate(X509& cert);
* Retrieves the subject alternate names of a certificate.
* @param cert the certificate
* @param type type of subject alternate name
* @param skip_unsupported If true and a name is for an unsupported (on this host) IP version,
* omit that name from the return value. If false, an exception will be thrown in this situation.
* @return std::vector returns the list of subject alternate names.
*/
std::vector<std::string> getSubjectAltNames(X509& cert, int type);
std::vector<std::string> getSubjectAltNames(X509& cert, int type, bool skip_unsupported = false);

/**
* Converts the Subject Alternate Name to string.
Expand Down
2 changes: 2 additions & 0 deletions test/config/integration/certs/clientcert.cfg
Expand Up @@ -39,3 +39,5 @@ URI.1 = spiffe://lyft.com/frontend-team
URI.2 = http://frontend.lyft.com
DNS.1 = lyft.com
DNS.2 = www.lyft.com
IP.1 = 1.2.3.4
IP.2 = 0:1:2:3::4
38 changes: 19 additions & 19 deletions test/config/integration/certs/clientcert.pem
@@ -1,27 +1,27 @@
-----BEGIN CERTIFICATE-----
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
ahwsslCKM3xGY4ax9Q==
Lmx5ZnQuY29thwQBAgMEhxAAAAABAAIAAwAAAAAAAAAEMB0GA1UdDgQWBBTl8J5P
CF97S4cY6TytejTb3sngmTAfBgNVHSMEGDAWgBQdDTmYdOz7TqwMpoOli3Dmj78y
gjANBgkqhkiG9w0BAQsFAAOCAQEAsMuSPKvSx/uDRIHWNQhUWSHfa4nfonyGBmnV
VvC7Xatq3kZ1MCedzxHbqOOdlO4cSVq+eOHlVzWJUsJSj1J8hcVh3vZp6GFoRZgU
F93g2dlgkmEEqEFB4qI71PwjC6amEV+xY21v/QPEouI1VumUnMnAV81G5uJDzPtn
gmNyM6hnvKGufpaovZFeXsB0ZUnYPz+4QdKwHTErsV8uUdeJUhFHg1NjCmrqQAmm
PG0G9JOi/dY/X5/LfGomAb7E+wuJFKHFP7gE6JvWi5M1Y1IlW1tCgN3dSCdCaUZm
JPKWR3x+gYOFHfKNpdG/zRwOrClgISmDzZiXXFSHCn95tFocXA==
-----END CERTIFICATE-----
4 changes: 2 additions & 2 deletions test/config/integration/certs/clientcert_hash.h
@@ -1,5 +1,5 @@
#pragma once

// NOLINT(namespace-envoy)
constexpr char TEST_CLIENT_CERT_HASH[] = "4A:FD:3A:AE:4B:36:08:A6:CB:41:4F:20:8A:86:1F:3B:43:6F:2F:"
"12:49:82:8D:9F:F6:FA:53:4D:23:26:FB:43";
constexpr char TEST_CLIENT_CERT_HASH[] = "F6:31:41:AA:8E:E3:D7:AC:AE:A8:AF:AD:C9:11:CD:0A:83:72:03:"
"6D:4B:B3:72:4F:6F:71:E1:ED:18:5B:92:AA";
55 changes: 28 additions & 27 deletions test/config/integration/certs/clientkey.pem
@@ -1,27 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA7A5D3pTadhwD6VXl4WYerCRRUf9vnCf8VeAAsF9PapKfanMy
aqPdEd5uo3gju6JEY+aTt5UfGS1b/K0UN2T4DBsYQ4/y9aX3NHvem94pyEdVJ1I0
nhGRemAMtlgMMOP8lDE3MPA8Pjd4hTD1IqP4zD2dNG/SGbf2GGGGMGa859t1aNA8
yy5IOoQA8YTTo+mKtN3Bk1Ky4GN++jrN2cnFODN38J/Uog11rg/GSXD0z0K4pAx4
vBV/AwM14ja4nuSfV2mw6FIMFTssSV5JYYYCVzJwPMu7L/n+spx0430wpQr7zasn
5wwToj4NipLU3P7Bj23x9qtcu4YrjWfQbiqvUwIDAQABAoIBAQDKY5ixODLuXSrF
Xo6QaLwXn7PReA67dlUVU8+DaNRwbXIdFNO/NuuOLIXzxkfs0j2M4d744fQd5BQg
Wk0hCYLa7kgpdTw8faWr7CB6x0pPm0lZQ1Q1yp5OrBd6J5ecO30NmfzWCsO8HFdK
6yTiJHBmvNUSZmVfA6kOUl95FD0XFB7J/4MPmE0UqEg5IhoWxpH9cEV8yll/bZZL
FHzA1cfwjtcHp5kHm/7IYlWqpShpdsquMmZt8vHFaoGvT5pms/AtAFjjDcW5dFpZ
GipS5D/3oPMXWbhrzMoIe8ERVBmlKPVoUmxUNIomgRSTP6/+mgcgojRRqcLW3l0W
KXi4i1dhAoGBAPmgVd+2K5vox09EbYaD1KAZpwuW61PQ6RI3wU5YCf84FoNAzK+e
KHSI+5Vo7JkwwiP7MSIJhiODG9VRnfou06NPEY4jllcMXp73PVGhOzsnHTqsbgps
Yg9tXsX5jQDx60yIOHf7halAz3vpEldQ6YecLscYV0Oz5i84gl/jee5JAoGBAPIV
Ofuf88WjErvuAxqIJWx85afr4B8YfChKHIVEx1eI6o89xuB16FjFzKAhHe9SJdfk
YVOwYD/9MRZ5+ZZAsRrKTHbD3VX20c0ECX9++/Sz2LGMewgvqiscpfGzDTsTJIVA
Ep31IAXmAUsmBAQAbuXxtbpKgU8Wi3mSp4nFzKC7AoGAUlpgGkbqSixYnMERdSBG
5G6yGnO2vVcdnWIBhwwqeCWT38df/8wowpFylo8gB0X7to0nX3hO5aZaZ1zexmvu
bGEohIEfFybAjKc6dpS/irtTvEiooQ2yqC5H5v52U0p8eyoxnvu+0+DK0rFI2L+b
255eHFbeazqNhSSadnIAhukCgYEAtfKAPv/sb0nupbLxQDq9rfl9fqVJMPXtMzbo
kr2r+b2dVgW/eSsFc9tOvbfGUP50FPzAre7tmIqLH3KTxXtf4VvU9pqlu5uj+iwj
m2Dsq/GUV3XXbsKsanTAwJWrxw/PLhuHIpN++w/xPvMWp49PyqHNzXN8Ft5B/CDe
rS0ubEsCgYA5kvmEDFYLF4TU7xg3QJ08+6+tJ+HZdvCBzE7RGJD8l5ZfpJuE6s9E
aW09E+65hSMaE85MpiM/s08quiMQeR6i7UWeN4GwoQznH1f9zUAuyP1J1Iv2knj7
lZ+oGk0EgnjkiIxo3ppAoKGz2/9Oi09lsEbdIBHvC56DAu44uOP50A==
-----END RSA PRIVATE KEY-----
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC9K5Xk1JJlLO4P
zwPbJLlmaGukaCvzX8MHwlp4ioIl/skWXAcvf/+h5Tg94y3sw+rafrJodVMyLt6+
vf69Hg4wPj7MUCgxR+vSye+Amhbcfa42qWN1TcLhN4zXJXCsw54zVR67zQ/mACJC
4UW18gaoN5+09QtsLVSLOczsu/Yrve71bl++OCA7CLllFj6RSJn4HRC3gAckavCD
d9945Y0396Tdxn4w3/WiizOo0xkYrTVT2Npjnui6ZFJ7R7ONsHlAQmdgd/XPKJV1
nhKAiS9+RDbifyZcaWpj/jpSv3koaK7BRPlB/LWETHjZG/GRHRR6IWEBjvFieVQc
OHeO5aEbAgMBAAECggEARVEny2KDRFSq5RsPyCjUUOy5aNSNKlBwSDMU8K+cUizi
5XESZvrpopq6OZ850FTYBXlAiZtYQX7AOzemlQji3RWp8Db9C1XV2XcKbl7IOsJI
6Jm4Kp80Zk9zKdD70SqbGSc7LEjPZxGsfEJMx4donhJH0MisB1cy8BNdfm+/nDYK
NsezfOYAD4UkX1NcrdfwLsWimZHPifwxL+va5cV3FiWO3S861/aE0pLhh+AJFYGI
3lEZxr6Gh+uaARcV4YNZPogYbrc8wJWP/6uR8pDwjqS8aUTBfyo1wUDd6bTvlQDv
+nKBiVjmWPgY6TlZ/Okp+H28fO3zqoXExE6KJamxmQKBgQDzV5jIemNDUrxodc1i
AQIchTbchvGiSpLyS2PY1W0vyYpyc5mugvzgaHPVEtaQTtR+QHWrYEFksOBZeIqX
rQGTDk6jGWBzI7qa/itqr9jydZsMYgJ7eqGpiSsiD0ka65xO+Ho6FkZAV11+qPyE
QmPD3Izj/58pSod4PADFQSP18wKBgQDHAp9Sd9fGCn/RHRVyf1nao2ZeKCQUDyyj
g+uCIswhE8lT7C5K76FPxZrV6enpTkLjEnMdRrPl4fQ5xl0SPAR/gaZXhM1U4sjo
w0dWITeMHwR7HqwbpumNbMccZMGA7o1Ua/k7GPIyD2UE7hiJyJRNyfeN09/cC18p
EjHcSs4qOQKBgCwU0jh+8zxe4IKL1IjMZfWErEuGpn8fwz7hKVU+VGkzuUDCcDSM
xgJg6ZrPrs61eQjl5GsHJNF4uSt8Cp8vV/mrvdMN5cr1zfgF0xegg0xowY2cs5Zq
wJ5Vmtqwqi2WQNqNaJbdMhy1ttobAqNy41+3tE4ZIFv6hE/jjsAs7LbBAoGAXy64
5uec0wKYiXqglGemoTS/tE78mn97eSWSUWa1PSjKhRIUPhEIlS/M030SPF0LDrH3
TsxPJKcCeVOPljYQbK+k0H0a+/uP3gvwJZiziZgYO467AGq/j720Kbdi+XifLf6K
cKKIzDqitU3vfI7rp5zugu4QRp1FwU4LfPJmUrkCgYAzzBz3K7jg4JPdY7Od22SQ
F/eToChPu60B9uQciR6gGwR1ry2sVSlK0Y1DMFMBCFEqPfJFO4OwZP0NWbRd13X1
9nUvpVoGxxJ51fIdMrPPm0G6f8HS79JhOGUp9tYsQ+LPCcnrrH2ZDGQYxZsSXqbe
5qc2rk4Sgt8Ua/oVrxghzA==
-----END PRIVATE KEY-----
Expand Up @@ -11,6 +11,7 @@
#include "source/common/buffer/buffer_impl.h"
#include "source/common/event/dispatcher_impl.h"
#include "source/common/listener_manager/connection_handler_impl.h"
#include "source/common/network/address_impl.h"
#include "source/common/network/connection_balancer_impl.h"
#include "source/common/network/listen_socket_impl.h"
#include "source/common/network/proxy_protocol_filter_state.h"
Expand Down Expand Up @@ -236,6 +237,20 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ProxyProtocolTest,
testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
TestUtility::ipTestParamsToString);

TEST_P(ProxyProtocolTest, V1UnsupportedIPv4) {
connect(false);
Cleanup cleaner = Network::Address::Ipv4Instance::forceProtocolUnsupportedForTest(true);
write("PROXY TCP4 1.2.3.4 253.253.253.253 65535 1234\r\nmore data");
expectProxyProtoError();
}

TEST_P(ProxyProtocolTest, V1UnsupportedIPv6) {
connect(false);
Cleanup cleaner = Network::Address::Ipv6Instance::forceProtocolUnsupportedForTest(true);
write("PROXY TCP6 1:2:3::4 5:6::7:8 65535 1234\r\nmore data");
expectProxyProtoError();
}

TEST_P(ProxyProtocolTest, V1Basic) {
connect();
write("PROXY TCP4 1.2.3.4 253.253.253.253 65535 1234\r\nmore data");
Expand Down Expand Up @@ -390,6 +405,34 @@ TEST_P(ProxyProtocolTest, V2BasicV6) {
disconnect();
}

TEST_P(ProxyProtocolTest, V2UnsupportedIPv4) {
// A well-formed ipv4/tcp message, no extensions
constexpr uint8_t buffer[] = {0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x51, 0x55, 0x49,
0x54, 0x0a, 0x21, 0x11, 0x00, 0x0c, 0x01, 0x02, 0x03, 0x04,
0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x02, 'm', 'o',
'r', 'e', ' ', 'd', 'a', 't', 'a'};

connect(false);
Cleanup cleaner = Network::Address::Ipv4Instance::forceProtocolUnsupportedForTest(true);
write(buffer, sizeof(buffer));
expectProxyProtoError();
}

TEST_P(ProxyProtocolTest, V2UnsupportedIPv6) {
// A well-formed ipv6/tcp message, no extensions
constexpr uint8_t buffer[] = {0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x51, 0x55, 0x49, 0x54,
0x0a, 0x21, 0x22, 0x00, 0x24, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 'm', 'o', 'r',
'e', ' ', 'd', 'a', 't', 'a'};

connect(false);
Cleanup cleaner = Network::Address::Ipv6Instance::forceProtocolUnsupportedForTest(true);
write(buffer, sizeof(buffer));
expectProxyProtoError();
}

TEST_P(ProxyProtocolTest, V2UnsupportedAF) {
// A well-formed message with an unsupported address family
constexpr uint8_t buffer[] = {0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x51, 0x55, 0x49,
Expand Down

0 comments on commit bacd310

Please sign in to comment.