From 5a0d0a17178816f9cb274c08f0ec79643d7b394d Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 17 May 2021 18:31:44 +0300 Subject: [PATCH 1/4] Much simplier isLocalAddress --- src/Common/isLocalAddress.cpp | 75 +++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/src/Common/isLocalAddress.cpp b/src/Common/isLocalAddress.cpp index 8da281e3051..741942a877b 100644 --- a/src/Common/isLocalAddress.cpp +++ b/src/Common/isLocalAddress.cpp @@ -1,29 +1,80 @@ #include +#include #include #include +#include #include #include +#include #include namespace DB { +namespace ErrorCodes +{ + extern const int SYSTEM_ERROR; +} + +namespace +{ + +struct NetworkInterfaces +{ + ifaddrs * ifaddr; + NetworkInterfaces() + { + if (getifaddrs(&ifaddr) == -1) + { + throwFromErrno("Cannot getifaddrs", ErrorCodes::SYSTEM_ERROR); + } + } + + bool hasAddress(const Poco::Net::IPAddress & address) const + { + ifaddrs * iface; + for (iface = ifaddr; iface != nullptr; iface = iface->ifa_next) + { + auto family = iface->ifa_addr->sa_family; + std::optional interface_address; + switch (family) + { + /// We interested only in IP-adresses + case AF_INET: + { + interface_address.emplace(*(iface->ifa_addr)); + break; + } + case AF_INET6: + { + interface_address.emplace(&reinterpret_cast(iface->ifa_addr)->sin6_addr, sizeof(struct in6_addr)); + break; + } + default: + continue; + } + if (interface_address->length() == address.length() + && 0 == memcmp(interface_address->addr(), address.addr(), address.length())) + return true; + } + return false; + } + + ~NetworkInterfaces() + { + freeifaddrs(ifaddr); + } +}; + +} + + bool isLocalAddress(const Poco::Net::IPAddress & address) { - static auto interfaces = Poco::Net::NetworkInterface::list(); - - return interfaces.end() != std::find_if(interfaces.begin(), interfaces.end(), - [&] (const Poco::Net::NetworkInterface & interface) - { - /** Compare the addresses without taking into account `scope`. - * Theoretically, this may not be correct - depends on `route` setting - * - through which interface we will actually access the specified address. - */ - return interface.address().length() == address.length() - && 0 == memcmp(interface.address().addr(), address.addr(), address.length()); - }); + NetworkInterfaces interfaces; + return interfaces.hasAddress(address); } bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port) From b4f07a017c1342fce68d088927cfdda199193c22 Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 17 May 2021 18:32:34 +0300 Subject: [PATCH 2/4] Space --- src/Common/isLocalAddress.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Common/isLocalAddress.cpp b/src/Common/isLocalAddress.cpp index 741942a877b..60de569dffe 100644 --- a/src/Common/isLocalAddress.cpp +++ b/src/Common/isLocalAddress.cpp @@ -55,6 +55,7 @@ struct NetworkInterfaces default: continue; } + if (interface_address->length() == address.length() && 0 == memcmp(interface_address->addr(), address.addr(), address.length())) return true; From acaf260a2ec8c75171667459968019d674c8948f Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 17 May 2021 19:18:38 +0300 Subject: [PATCH 3/4] Better --- src/Common/isLocalAddress.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Common/isLocalAddress.cpp b/src/Common/isLocalAddress.cpp index 60de569dffe..894f61cae65 100644 --- a/src/Common/isLocalAddress.cpp +++ b/src/Common/isLocalAddress.cpp @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include #include @@ -37,19 +35,19 @@ struct NetworkInterfaces ifaddrs * iface; for (iface = ifaddr; iface != nullptr; iface = iface->ifa_next) { - auto family = iface->ifa_addr->sa_family; + auto family = iface->ifa_addr->sa_family; std::optional interface_address; switch (family) { /// We interested only in IP-adresses case AF_INET: { - interface_address.emplace(*(iface->ifa_addr)); + interface_address.emplace(*(iface->ifa_addr)); break; } case AF_INET6: { - interface_address.emplace(&reinterpret_cast(iface->ifa_addr)->sin6_addr, sizeof(struct in6_addr)); + interface_address.emplace(&reinterpret_cast(iface->ifa_addr)->sin6_addr, sizeof(struct in6_addr)); break; } default: From 6127ba901e75bf65025d8a04cb92491b8ae14676 Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 17 May 2021 19:29:11 +0300 Subject: [PATCH 4/4] Small improvements --- src/Common/isLocalAddress.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Common/isLocalAddress.cpp b/src/Common/isLocalAddress.cpp index 894f61cae65..cecff489a22 100644 --- a/src/Common/isLocalAddress.cpp +++ b/src/Common/isLocalAddress.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,10 @@ struct NetworkInterfaces continue; } + /** Compare the addresses without taking into account `scope`. + * Theoretically, this may not be correct - depends on `route` setting + * - through which interface we will actually access the specified address. + */ if (interface_address->length() == address.length() && 0 == memcmp(interface_address->addr(), address.addr(), address.length())) return true;