Skip to content

Commit

Permalink
listener/original_dst: add support for TPROXY
Browse files Browse the repository at this point in the history
- use localAddress if sock is transparent
- 7b46bce7
- originally by @tomastigera

more notes:
.rc_ is now .return_value_
update addressProvider => connectionInfoProvider
  • Loading branch information
electricjesus committed May 6, 2024
1 parent a6d1d66 commit 680a700
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
36 changes: 36 additions & 0 deletions source/common/network/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -777,5 +777,41 @@ ResolvedUdpSocketConfig::ResolvedUdpSocketConfig(
}
}

bool Utility::isTransparent(Socket& sock) {
#ifdef SOL_IP

if (sock.addressType() != Address::Type::Ip) {
return false;
}

auto ipVersion = sock.ipVersion();
if (!ipVersion.has_value()) {
return false;
}

int value;
socklen_t value_len = sizeof(value);
int status;
int call;

if (*ipVersion == Address::IpVersion::v4) {
call = IP_TRANSPARENT;
} else {
call = IPV6_TRANSPARENT;
}

status = sock.getSocketOption(SOL_IP, call, &value, &value_len).return_value_;

if (status != 0 || value == 0) {
return false;
}

return true;
#else
UNREFERENCED_PARAMETER(sock);
return false;
#endif
}

} // namespace Network
} // namespace Envoy
7 changes: 7 additions & 0 deletions source/common/network/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,13 @@ class Utility {
TimeSource& time_source, bool prefer_gro,
uint32_t& packets_dropped);

/**
* Retrieve whether the socket is transparent, e.g. has IP_TRANSPARENT option set.
* @param sock is accepted socket
* @return true if the socket is transparent.
*/
static bool isTransparent(Socket& sock);

private:
static void throwWithMalformedIp(absl::string_view ip_address);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@ Network::FilterStatus OriginalDstFilter::onAccept(Network::ListenerFilterCallbac

switch (socket.addressType()) {
case Network::Address::Type::Ip: {
Network::Address::InstanceConstSharedPtr original_local_address = getOriginalDst(socket);
Network::Address::InstanceConstSharedPtr original_local_address;

if (Network::Utility::isTransparent(socket)) {
original_local_address = socket.connectionInfoProvider().localAddress();
} else {
original_local_address = getOriginalDst(socket);
}

// A listener that has the use_original_dst flag set to true can still receive
// connections that are NOT redirected using iptables. If a connection was not redirected,
// the address returned by getOriginalDst() matches the local address of the new socket.
Expand Down

0 comments on commit 680a700

Please sign in to comment.