c-ares draft wrapper and draft build rules

This commit is contained in:
Arthur Passos 2022-07-08 17:52:14 -03:00
parent 6c987fb28e
commit 4f4acfabe5
16 changed files with 186 additions and 69 deletions

9
.gitmodules vendored
View File

@ -274,9 +274,6 @@
[submodule "contrib/base-x"]
path = contrib/base-x
url = https://github.com/ClickHouse/base-x.git
[submodule "contrib/udns"]
path = contrib/udns
url = https://github.com/ClickHouse/udns
[submodule "contrib/cpp-dns"]
path = contrib/cpp-dns
url = https://github.com/ClickHouse/cpp-dns
[submodule "contrib/c-ares"]
path = contrib/c-ares
url = https://github.com/ClickHouse/c-ares

View File

@ -156,8 +156,7 @@ endif()
add_contrib (sqlite-cmake sqlite-amalgamation)
add_contrib (s2geometry-cmake s2geometry)
add_contrib (base-x-cmake base-x)
add_contrib (udns-cmake udns)
add_contrib (cpp-dns-cmake cpp-dns)
add_contrib(c-ares-cmake c-ares)
# Put all targets defined here and in subdirectories under "contrib/<immediate-subdir>" folders in GUI-based IDEs.
# Some of third-party projects may override CMAKE_FOLDER or FOLDER property of their targets, so they would not appear

1
contrib/c-ares vendored Submodule

@ -0,0 +1 @@
Subproject commit afee6748b0b99acf4509d42fa37ac8422262f91b

View File

@ -0,0 +1,37 @@
if(NOT TARGET c-ares)
# Choose to build static or shared library for c-ares.
if (USE_STATIC_LIBRARIES)
set(CARES_STATIC ON CACHE BOOL "" FORCE)
set(CARES_SHARED OFF CACHE BOOL "" FORCE)
else ()
set(CARES_STATIC OFF CACHE BOOL "" FORCE)
set(CARES_SHARED ON CACHE BOOL "" FORCE)
endif ()
# Disable looking for libnsl on a platforms that has gethostbyname in glibc
#
# c-ares searching for gethostbyname in the libnsl library, however in the
# version that shipped with gRPC it doing it wrong [1], since it uses
# CHECK_LIBRARY_EXISTS(), which will return TRUE even if the function exists in
# another dependent library. The upstream already contains correct macro [2],
# but it is not included in gRPC (even upstream gRPC, not the one that is
# shipped with clickhousee).
#
# [1]: https://github.com/c-ares/c-ares/blob/e982924acee7f7313b4baa4ee5ec000c5e373c30/CMakeLists.txt#L125
# [2]: https://github.com/c-ares/c-ares/blob/44fbc813685a1fa8aa3f27fcd7544faf612d376a/CMakeLists.txt#L146
#
# And because if you by some reason have libnsl [3] installed, clickhouse will
# reject to start w/o it. While this is completelly different library.
#
# [3]: https://packages.debian.org/bullseye/libnsl2
if (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(HAVE_LIBNSL OFF CACHE BOOL "" FORCE)
endif()
add_subdirectory("../c-ares/" "../c-ares/")
add_library(ch_contrib::c-ares ALIAS c-ares)
target_link_libraries(c-ares PRIVATE resolv)
endif()

1
contrib/cpp-dns vendored

@ -1 +0,0 @@
Subproject commit 0ce2dbd40dce456bde1732c4d8f70008f0079db0

View File

@ -1,11 +0,0 @@
set(LIBRARY_DIR "${ClickHouse_SOURCE_DIR}/contrib/cpp-dns")
set(SRCS "${LIBRARY_DIR}/DNSResolver.cpp")
add_library(_cpp-dns ${SRCS})
target_link_libraries(_cpp-dns boost::system boost::headers_only ch_contrib::udns)
target_include_directories(_cpp-dns SYSTEM BEFORE PUBLIC ${LIBRARY_DIR})
add_library(ch_contrib::cpp-dns ALIAS _cpp-dns)

View File

@ -92,7 +92,12 @@ if(gRPC_USE_UNSECURE_LIBRARIES)
else()
set(gRPC_LIBRARIES grpc grpc++)
endif()
target_compile_options(c-ares PRIVATE -Wno-reserved-macro-identifier)
add_library(_ch_contrib_grpc INTERFACE)
target_link_libraries(_ch_contrib_grpc INTERFACE ${gRPC_LIBRARIES})
target_include_directories(_ch_contrib_grpc SYSTEM INTERFACE ${gRPC_INCLUDE_DIRS})
add_library(ch_contrib::grpc ALIAS _ch_contrib_grpc)
target_compile_options(grpc PRIVATE -Wno-reserved-macro-identifier)

1
contrib/udns vendored

@ -1 +0,0 @@
Subproject commit f535fbe9b39f6bbbf91475834cfefef9c7edab75

View File

@ -1,26 +0,0 @@
set(LIBRARY_DIR "${ClickHouse_SOURCE_DIR}/contrib/udns")
add_library(_udns
"${LIBRARY_DIR}/udns_bl.c"
"${LIBRARY_DIR}/udns_codes.c"
"${LIBRARY_DIR}/udns_dntosp.c"
"${LIBRARY_DIR}/udns_init.c"
"${LIBRARY_DIR}/udns_jran.c"
"${LIBRARY_DIR}/udns_misc.c"
"${LIBRARY_DIR}/udns_parse.c"
"${LIBRARY_DIR}/udns_resolver.c"
"${LIBRARY_DIR}/udns_rr_a.c"
"${LIBRARY_DIR}/udns_rr_mx.c"
"${LIBRARY_DIR}/udns_rr_naptr.c"
"${LIBRARY_DIR}/udns_rr_ptr.c"
"${LIBRARY_DIR}/udns_rr_srv.c"
"${LIBRARY_DIR}/udns_rr_txt.c"
"${LIBRARY_DIR}/udns_XtoX.c"
"${LIBRARY_DIR}/udns_dn.c"
)
target_compile_definitions(_udns PRIVATE -DHAVE_CONFIG_H)
target_include_directories(_udns SYSTEM BEFORE PUBLIC ${LIBRARY_DIR})
add_library(ch_contrib::udns ALIAS _udns)

View File

@ -439,8 +439,8 @@ if (TARGET ch_contrib::avrocpp)
dbms_target_link_libraries(PRIVATE ch_contrib::avrocpp)
endif ()
target_link_libraries (clickhouse_common_io PRIVATE ch_contrib::udns)
target_link_libraries (clickhouse_common_io PRIVATE ch_contrib::cpp-dns)
target_compile_options(clickhouse_common_io PRIVATE -Wno-reserved-identifier)
target_link_libraries (clickhouse_common_io PRIVATE ch_contrib::c-ares)
if (TARGET OpenSSL::Crypto)
dbms_target_link_libraries (PRIVATE OpenSSL::Crypto)

View File

@ -0,0 +1,69 @@
#include <arpa/inet.h>
#include "CARESPTRResolver.h"
#include "netdb.h"
namespace DB {
static void callback(void * arg, int status, int, struct hostent * host) {
auto * ptr_records = reinterpret_cast<std::vector<std::string>*>(arg);
if (status == ARES_SUCCESS) {
int i = 0;
while (auto ptr_record = host->h_aliases[i]) {
ptr_records->emplace_back(ptr_record);
i++;
}
}
}
CARESPTRResolver::CARESPTRResolver() {
init();
}
CARESPTRResolver::~CARESPTRResolver() {
deinit();
}
std::vector<std::string> CARESPTRResolver::resolve(const std::string & ip) {
std::vector<std::string> ptr_records;
resolve(ip, ptr_records);
wait();
return ptr_records;
}
void CARESPTRResolver::init() {
if (ares_init(&channel) != ARES_SUCCESS){
throw std::exception {};
}
}
void CARESPTRResolver::deinit() {
ares_destroy(channel);
ares_library_cleanup();
}
void CARESPTRResolver::resolve(const std::string & ip, std::vector<std::string> & response) {
in_addr addr;
inet_aton(ip.c_str(), &addr);
ares_gethostbyaddr(channel, reinterpret_cast<const char*>(&addr), sizeof(addr), AF_INET, callback, &response);
}
void CARESPTRResolver::wait() {
for(;;) {
timeval * tvp, tv;
fd_set read_fds, write_fds;
int nfds;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
nfds = ares_fds(channel, &read_fds, &write_fds);
if(nfds == 0){
break;
}
tvp = ares_timeout(channel, nullptr, &tv);
select(nfds, &read_fds, &write_fds, nullptr, tvp);
ares_process(channel, &read_fds, &write_fds);
}
}
}

View File

@ -0,0 +1,26 @@
#pragma once
#include "DNSPTRResolver.h"
#include "ares.h"
namespace DB {
class CARESPTRResolver : public DNSPTRResolver {
public:
CARESPTRResolver();
~CARESPTRResolver() override;
std::vector<std::string> resolve(const std::string & ip) override;
private:
void init();
void deinit();
void wait();
void resolve(const std::string & ip, std::vector<std::string> & response);
ares_channel channel;
};
}

View File

@ -0,0 +1,14 @@
#pragma once
#include <string>
#include <vector>
namespace DB {
struct DNSPTRResolver {
virtual ~DNSPTRResolver() = default;
virtual std::vector<std::string> resolve(const std::string & ip) = 0;
};
}

View File

@ -0,0 +1,12 @@
#include "DNSPTRResolverProvider.h"
#include "CARESPTRResolver.h"
namespace DB {
std::shared_ptr<DNSPTRResolver> DNSPTRResolverProvider::get()
{
static auto cares_resolver = std::make_shared<CARESPTRResolver>();
return cares_resolver;
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include <memory>
#include "DNSPTRResolver.h"
namespace DB {
class DNSPTRResolverProvider
{
public:
static std::shared_ptr<DNSPTRResolver> get();
};
}

View File

@ -13,7 +13,7 @@
#include <optional>
#include <string_view>
#include <boost/asio.hpp>
#include <DNSResolver.hpp>
#include "DNSPTRResolverProvider.h"
namespace ProfileEvents
{
@ -142,25 +142,8 @@ static DNSResolver::IPAddresses resolveIPAddressImpl(const std::string & host)
static std::vector<String> reverseResolveImpl(const Poco::Net::IPAddress & address)
{
boost::asio::io_service io_service;
YukiWorkshop::DNSResolver resolver(io_service);
std::vector<std::string> ptr_records;
resolver.resolve_a4ptr(boost::asio::ip::address_v4::from_string(address.toString()), [&](int err, auto & hosts, auto &, auto &, uint) {
if (err) {
throw Exception("Cannot resolve: " + address.toString() + YukiWorkshop::DNSResolver::error_string(err), ErrorCodes::DNS_ERROR);
}
for (auto & it : hosts) {
ptr_records.emplace_back(it);
}
});
io_service.run();
return ptr_records;
auto ptr_resolver = DB::DNSPTRResolverProvider::get();
return ptr_resolver->resolve(address.toString());
}
struct DNSResolver::Impl