Skip to content

Commit

Permalink
syscall: add getifaddrs to os syscalls (#18513)
Browse files Browse the repository at this point in the history
Commit Message: syscall - add getifaddrs to os syscalls
Additional Description: formalize getifaddrs into os syscalls.
Risk Level: low
Testing: existing calling code and UT over that code.

Signed-off-by: Jose Nino <jnino@lyft.com>
  • Loading branch information
junr03 authored Oct 9, 2021
1 parent 351c0ca commit fc04382
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 32 deletions.
15 changes: 15 additions & 0 deletions envoy/api/os_sys_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,21 @@ class OsSysCalls {
* @see man TCP_INFO. Get the tcp info for the socket.
*/
virtual SysCallBoolResult socketTcpInfo(os_fd_t sockfd, EnvoyTcpInfo* tcp_info) PURE;

/**
* return true if the OS supports getifaddrs.
*/
virtual bool supportsGetifaddrs() const PURE;

/**
* @see man getifaddrs
*/
virtual SysCallIntResult getifaddrs(ifaddrs** ifap) PURE;

/**
* @see man getifaddrs
*/
virtual void freeifaddrs(ifaddrs* ifp) PURE;
};

using OsSysCallsPtr = std::unique_ptr<OsSysCalls>;
Expand Down
22 changes: 12 additions & 10 deletions envoy/common/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,17 +293,19 @@ struct mmsghdr {
};
#endif

#define SUPPORTS_GETIFADDRS
#ifdef WIN32
#undef SUPPORTS_GETIFADDRS
#endif

// https://android.googlesource.com/platform/prebuilts/ndk/+/dev/platform/sysroot/usr/include/ifaddrs.h
#ifdef __ANDROID_API__
#if __ANDROID_API__ < 24
#undef SUPPORTS_GETIFADDRS
#endif // __ANDROID_API__ < 24
#endif // ifdef __ANDROID_API__
#if defined(WIN32) || (defined(__ANDROID_API__) && __ANDROID_API__ < 24)
// Posix structure necessary for getifaddrs definition.
struct ifaddrs {
struct ifaddrs* ifa_next;
char* ifa_name;
unsigned int ifa_flags;
struct sockaddr* ifa_addr;
struct sockaddr* ifa_netmask;
struct sockaddr* ifa_dstaddr;
void* ifa_data;
};
#endif

// TODO: Remove once bazel supports NDKs > 21
#define SUPPORTS_CPP_17_CONTIGUOUS_ITERATOR
Expand Down
15 changes: 15 additions & 0 deletions source/common/api/posix/os_sys_calls_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -282,5 +282,20 @@ SysCallBoolResult OsSysCallsImpl::socketTcpInfo([[maybe_unused]] os_fd_t sockfd,
return {false, EOPNOTSUPP};
}

bool OsSysCallsImpl::supportsGetifaddrs() const {
// https://android.googlesource.com/platform/prebuilts/ndk/+/dev/platform/sysroot/usr/include/ifaddrs.h
#if defined(__ANDROID_API__) && __ANDROID_API__ < 24
return false;
#endif
return true;
}

SysCallIntResult OsSysCallsImpl::getifaddrs(struct ifaddrs** ifap) {
const int rc = ::getifaddrs(ifap);
return {rc, rc != -1 ? 0 : errno};
}

void OsSysCallsImpl::freeifaddrs(struct ifaddrs* ifp) { ::freeifaddrs(ifp); }

} // namespace Api
} // namespace Envoy
3 changes: 3 additions & 0 deletions source/common/api/posix/os_sys_calls_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class OsSysCallsImpl : public OsSysCalls {
SysCallSocketResult duplicate(os_fd_t oldfd) override;
SysCallSocketResult accept(os_fd_t socket, sockaddr* addr, socklen_t* addrlen) override;
SysCallBoolResult socketTcpInfo(os_fd_t sockfd, EnvoyTcpInfo* tcp_info) override;
bool supportsGetifaddrs() const override;
SysCallIntResult getifaddrs(struct ifaddrs** ifap) override;
void freeifaddrs(struct ifaddrs* ifp) override;
};

using OsSysCallsSingleton = ThreadSafeSingleton<OsSysCallsImpl>;
Expand Down
4 changes: 4 additions & 0 deletions source/common/api/win32/os_sys_calls_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -404,5 +404,9 @@ SysCallBoolResult OsSysCallsImpl::socketTcpInfo([[maybe_unused]] os_fd_t sockfd,
return {false, WSAEOPNOTSUPP};
}

SysCallIntResult OsSysCallsImpl::getifaddrs(struct ifaddrs**) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; }

void OsSysCallsImpl::freeifaddrs(struct ifaddrs*) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; }

} // namespace Api
} // namespace Envoy
3 changes: 3 additions & 0 deletions source/common/api/win32/os_sys_calls_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class OsSysCallsImpl : public OsSysCalls {
SysCallSocketResult duplicate(os_fd_t oldfd) override;
SysCallSocketResult accept(os_fd_t socket, sockaddr* addr, socklen_t* addrlen) override;
SysCallBoolResult socketTcpInfo(os_fd_t sockfd, EnvoyTcpInfo* tcp_info) override;
bool supportsGetifaddrs() const override { return false; }
SysCallIntResult getifaddrs(struct ifaddrs** ifap) override;
void freeifaddrs(struct ifaddrs* ifp) override;
};

using OsSysCallsSingleton = ThreadSafeSingleton<OsSysCallsImpl>;
Expand Down
45 changes: 23 additions & 22 deletions source/common/network/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,35 +239,36 @@ void Utility::throwWithMalformedIp(absl::string_view ip_address) {
// need to be updated in the future. Discussion can be found at Github issue #939.
Address::InstanceConstSharedPtr Utility::getLocalAddress(const Address::IpVersion version) {
Address::InstanceConstSharedPtr ret;
#ifdef SUPPORTS_GETIFADDRS
struct ifaddrs* ifaddr;
struct ifaddrs* ifa;
if (Api::OsSysCallsSingleton::get().supportsGetifaddrs()) {
struct ifaddrs* ifaddr;
struct ifaddrs* ifa;

const int rc = getifaddrs(&ifaddr);
RELEASE_ASSERT(!rc, "");
const Api::SysCallIntResult rc = Api::OsSysCallsSingleton::get().getifaddrs(&ifaddr);
RELEASE_ASSERT(!rc.return_value_, fmt::format("getiffaddrs error: {}", rc.errno_));

// man getifaddrs(3)
for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) {
continue;
}
// man getifaddrs(3)
for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) {
continue;
}

if ((ifa->ifa_addr->sa_family == AF_INET && version == Address::IpVersion::v4) ||
(ifa->ifa_addr->sa_family == AF_INET6 && version == Address::IpVersion::v6)) {
const struct sockaddr_storage* addr =
reinterpret_cast<const struct sockaddr_storage*>(ifa->ifa_addr);
ret = Address::addressFromSockAddrOrThrow(
*addr, (version == Address::IpVersion::v4) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6));
if (!isLoopbackAddress(*ret)) {
break;
if ((ifa->ifa_addr->sa_family == AF_INET && version == Address::IpVersion::v4) ||
(ifa->ifa_addr->sa_family == AF_INET6 && version == Address::IpVersion::v6)) {
const struct sockaddr_storage* addr =
reinterpret_cast<const struct sockaddr_storage*>(ifa->ifa_addr);
ret = Address::addressFromSockAddrOrThrow(*addr, (version == Address::IpVersion::v4)
? sizeof(sockaddr_in)
: sizeof(sockaddr_in6));
if (!isLoopbackAddress(*ret)) {
break;
}
}
}
}

if (ifaddr) {
freeifaddrs(ifaddr);
if (ifaddr) {
Api::OsSysCallsSingleton::get().freeifaddrs(ifaddr);
}
}
#endif

// If the local address is not found above, then return the loopback address by default.
if (ret == nullptr) {
Expand Down
2 changes: 2 additions & 0 deletions tools/spelling/spelling_dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ALS
AMZ
APC
API
ARRAYSIZE
ARN
ASAN
ASCII
Expand Down Expand Up @@ -814,6 +815,7 @@ megamiss
mem
memcmp
memcpy
memset
memoize
mergeable
messagename
Expand Down

0 comments on commit fc04382

Please sign in to comment.