diff --git a/envoy/api/os_sys_calls.h b/envoy/api/os_sys_calls.h index 0c0071742c6be..094959d239b6f 100644 --- a/envoy/api/os_sys_calls.h +++ b/envoy/api/os_sys_calls.h @@ -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; diff --git a/envoy/common/platform.h b/envoy/common/platform.h index 570713dca67a1..30fc88a3afbb0 100644 --- a/envoy/common/platform.h +++ b/envoy/common/platform.h @@ -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 diff --git a/source/common/api/posix/os_sys_calls_impl.cc b/source/common/api/posix/os_sys_calls_impl.cc index ad2a36dd2af1a..b0afd5a8fae07 100644 --- a/source/common/api/posix/os_sys_calls_impl.cc +++ b/source/common/api/posix/os_sys_calls_impl.cc @@ -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 diff --git a/source/common/api/posix/os_sys_calls_impl.h b/source/common/api/posix/os_sys_calls_impl.h index 77ccb0da2b083..d5c1325ecb846 100644 --- a/source/common/api/posix/os_sys_calls_impl.h +++ b/source/common/api/posix/os_sys_calls_impl.h @@ -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; diff --git a/source/common/api/win32/os_sys_calls_impl.cc b/source/common/api/win32/os_sys_calls_impl.cc index 3766c54a2100c..d6e0c4334e3b9 100644 --- a/source/common/api/win32/os_sys_calls_impl.cc +++ b/source/common/api/win32/os_sys_calls_impl.cc @@ -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 diff --git a/source/common/api/win32/os_sys_calls_impl.h b/source/common/api/win32/os_sys_calls_impl.h index 4dc62e0770d2b..2460f963b222e 100644 --- a/source/common/api/win32/os_sys_calls_impl.h +++ b/source/common/api/win32/os_sys_calls_impl.h @@ -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; diff --git a/source/common/network/utility.cc b/source/common/network/utility.cc index 7cd7b19c00be4..f8b6bd2ff9c44 100644 --- a/source/common/network/utility.cc +++ b/source/common/network/utility.cc @@ -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(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(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) { diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index ca55d7ec2dfdb..60e132505eb79 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -11,6 +11,7 @@ ALS AMZ APC API +ARRAYSIZE ARN ASAN ASCII @@ -812,6 +813,7 @@ megamiss mem memcmp memcpy +memset memoize mergeable messagename