Fixed error (after update of Poco) with local replicas optimization [#METR-20654].

This commit is contained in:
Alexey Milovidov 2016-03-29 20:51:07 +03:00
parent 34f6887a28
commit f7b8709885
3 changed files with 52 additions and 19 deletions

View File

@ -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

View File

@ -1,27 +1,25 @@
#pragma once
#include <DB/Core/Types.h>
#include <Poco/Util/Application.h>
#include <Poco/Net/NetworkInterface.h>
#include <Poco/Net/SocketAddress.h>
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);
}

View File

@ -0,0 +1,34 @@
#include <DB/Core/Types.h>
#include <Poco/Util/Application.h>
#include <Poco/Net/NetworkInterface.h>
#include <Poco/Net/SocketAddress.h>
#include <DB/Common/isLocalAddress.h>
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;
}
}