From f7b87098857bd22ad2a2c6b233b45ba1dc3f0c80 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 29 Mar 2016 20:51:07 +0300 Subject: [PATCH] Fixed error (after update of Poco) with local replicas optimization [#METR-20654]. --- dbms/CMakeLists.txt | 1 + dbms/include/DB/Common/isLocalAddress.h | 36 ++++++++++++------------- dbms/src/Common/isLocalAddress.cpp | 34 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 dbms/src/Common/isLocalAddress.cpp diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index c737a48f63b..c5bee882948 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -561,6 +561,7 @@ add_library (dbms src/Common/ConfigProcessor.cpp src/Common/Exception.cpp src/Common/ShellCommand.cpp + src/Common/isLocalAddress.cpp src/Common/getNumberOfPhysicalCPUCores.cpp src/Core/Field.cpp diff --git a/dbms/include/DB/Common/isLocalAddress.h b/dbms/include/DB/Common/isLocalAddress.h index 62318b34ba6..6d168021d45 100644 --- a/dbms/include/DB/Common/isLocalAddress.h +++ b/dbms/include/DB/Common/isLocalAddress.h @@ -1,27 +1,25 @@ #pragma once -#include -#include -#include -#include + +namespace Poco +{ + namespace Net + { + class SocketAddress; + } +} namespace DB { -inline bool isLocalAddress(const Poco::Net::SocketAddress & address) -{ - const UInt16 clickhouse_port = Poco::Util::Application::instance().config().getInt("tcp_port", 0); - static auto interfaces = Poco::Net::NetworkInterface::list(); - - if (clickhouse_port == address.port()) - { - return interfaces.end() != std::find_if(interfaces.begin(), interfaces.end(), - [&] (const Poco::Net::NetworkInterface & interface) { - return interface.address() == address.host(); - }); - } - - return false; -} + /** Позволяет проверить, похож ли адрес на localhost. + * Цель этой проверки обычно состоит в том, чтобы сделать предположение, + * что при хождении на этот адрес через интернет, мы попадём на себя. + * Следует иметь ввиду, что эта проверка делается неточно: + * - адрес просто сравнивается с адресами сетевых интерфейсов; + * - для каждого сетевого интерфейса берётся только первый адрес; + * - не проверяются правила маршрутизации, которые влияют, через какой сетевой интерфейс мы пойдём на заданный адрес. + */ + bool isLocalAddress(const Poco::Net::SocketAddress & address); } diff --git a/dbms/src/Common/isLocalAddress.cpp b/dbms/src/Common/isLocalAddress.cpp new file mode 100644 index 00000000000..ea830bc4fb1 --- /dev/null +++ b/dbms/src/Common/isLocalAddress.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +#include + + +namespace DB +{ + +bool isLocalAddress(const Poco::Net::SocketAddress & address) +{ + const UInt16 clickhouse_port = Poco::Util::Application::instance().config().getInt("tcp_port", 0); + static auto interfaces = Poco::Net::NetworkInterface::list(); + + if (clickhouse_port == address.port()) + { + return interfaces.end() != std::find_if(interfaces.begin(), interfaces.end(), + [&] (const Poco::Net::NetworkInterface & interface) + { + /** Сравниваем адреса без учёта scope. + * Теоретически, это может быть неверно - зависит от настройки route + * - через какой интерфейс мы на самом деле будем обращаться к заданному адресу. + */ + return interface.address().length() == address.host().length() + && 0 == memcmp(interface.address().addr(), address.host().addr(), address.host().length()); + }); + } + + return false; +} + +}