From 4f4acfabe5ff40e8552c509cd48ccec10ccf43a7 Mon Sep 17 00:00:00 2001 From: Arthur Passos Date: Fri, 8 Jul 2022 17:52:14 -0300 Subject: [PATCH] c-ares draft wrapper and draft build rules --- .gitmodules | 9 ++-- contrib/CMakeLists.txt | 3 +- contrib/c-ares | 1 + contrib/c-ares-cmake/CMakeLists.txt | 37 ++++++++++++++ contrib/cpp-dns | 1 - contrib/cpp-dns-cmake/CMakeLists.txt | 11 ----- contrib/grpc-cmake/CMakeLists.txt | 5 ++ contrib/udns | 1 - contrib/udns-cmake/CMakeLists.txt | 26 ---------- src/CMakeLists.txt | 4 +- src/Common/CARESPTRResolver.cpp | 69 +++++++++++++++++++++++++++ src/Common/CARESPTRResolver.h | 26 ++++++++++ src/Common/DNSPTRResolver.h | 14 ++++++ src/Common/DNSPTRResolverProvider.cpp | 12 +++++ src/Common/DNSPTRResolverProvider.h | 13 +++++ src/Common/DNSResolver.cpp | 23 ++------- 16 files changed, 186 insertions(+), 69 deletions(-) create mode 160000 contrib/c-ares create mode 100644 contrib/c-ares-cmake/CMakeLists.txt delete mode 160000 contrib/cpp-dns delete mode 100644 contrib/cpp-dns-cmake/CMakeLists.txt delete mode 160000 contrib/udns delete mode 100644 contrib/udns-cmake/CMakeLists.txt create mode 100644 src/Common/CARESPTRResolver.cpp create mode 100644 src/Common/CARESPTRResolver.h create mode 100644 src/Common/DNSPTRResolver.h create mode 100644 src/Common/DNSPTRResolverProvider.cpp create mode 100644 src/Common/DNSPTRResolverProvider.h diff --git a/.gitmodules b/.gitmodules index 0b813722c60..7f88dd3c714 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 \ No newline at end of file +[submodule "contrib/c-ares"] + path = contrib/c-ares + url = https://github.com/ClickHouse/c-ares diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 06e90dedb5b..460a1d7a3ee 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -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/" 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 diff --git a/contrib/c-ares b/contrib/c-ares new file mode 160000 index 00000000000..afee6748b0b --- /dev/null +++ b/contrib/c-ares @@ -0,0 +1 @@ +Subproject commit afee6748b0b99acf4509d42fa37ac8422262f91b diff --git a/contrib/c-ares-cmake/CMakeLists.txt b/contrib/c-ares-cmake/CMakeLists.txt new file mode 100644 index 00000000000..87f2b96fac3 --- /dev/null +++ b/contrib/c-ares-cmake/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/contrib/cpp-dns b/contrib/cpp-dns deleted file mode 160000 index 0ce2dbd40dc..00000000000 --- a/contrib/cpp-dns +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0ce2dbd40dce456bde1732c4d8f70008f0079db0 diff --git a/contrib/cpp-dns-cmake/CMakeLists.txt b/contrib/cpp-dns-cmake/CMakeLists.txt deleted file mode 100644 index 20e6eb04088..00000000000 --- a/contrib/cpp-dns-cmake/CMakeLists.txt +++ /dev/null @@ -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) \ No newline at end of file diff --git a/contrib/grpc-cmake/CMakeLists.txt b/contrib/grpc-cmake/CMakeLists.txt index 520e04d198e..9609b922840 100644 --- a/contrib/grpc-cmake/CMakeLists.txt +++ b/contrib/grpc-cmake/CMakeLists.txt @@ -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) diff --git a/contrib/udns b/contrib/udns deleted file mode 160000 index f535fbe9b39..00000000000 --- a/contrib/udns +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f535fbe9b39f6bbbf91475834cfefef9c7edab75 diff --git a/contrib/udns-cmake/CMakeLists.txt b/contrib/udns-cmake/CMakeLists.txt deleted file mode 100644 index 1266ea2b847..00000000000 --- a/contrib/udns-cmake/CMakeLists.txt +++ /dev/null @@ -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) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dfff3bcfa1d..7f5b97cc52b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/Common/CARESPTRResolver.cpp b/src/Common/CARESPTRResolver.cpp new file mode 100644 index 00000000000..eac390c92c5 --- /dev/null +++ b/src/Common/CARESPTRResolver.cpp @@ -0,0 +1,69 @@ +#include +#include "CARESPTRResolver.h" +#include "netdb.h" + +namespace DB { + static void callback(void * arg, int status, int, struct hostent * host) { + auto * ptr_records = reinterpret_cast*>(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 CARESPTRResolver::resolve(const std::string & ip) { + std::vector 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 & response) { + in_addr addr; + inet_aton(ip.c_str(), &addr); + + ares_gethostbyaddr(channel, reinterpret_cast(&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); + } + } +} diff --git a/src/Common/CARESPTRResolver.h b/src/Common/CARESPTRResolver.h new file mode 100644 index 00000000000..645723e9da1 --- /dev/null +++ b/src/Common/CARESPTRResolver.h @@ -0,0 +1,26 @@ +#pragma once + +#include "DNSPTRResolver.h" +#include "ares.h" + +namespace DB { + class CARESPTRResolver : public DNSPTRResolver { + + public: + CARESPTRResolver(); + ~CARESPTRResolver() override; + + std::vector resolve(const std::string & ip) override; + + private: + + void init(); + void deinit(); + void wait(); + + void resolve(const std::string & ip, std::vector & response); + + ares_channel channel; + }; +} + diff --git a/src/Common/DNSPTRResolver.h b/src/Common/DNSPTRResolver.h new file mode 100644 index 00000000000..20a5422767a --- /dev/null +++ b/src/Common/DNSPTRResolver.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +namespace DB { + struct DNSPTRResolver { + + virtual ~DNSPTRResolver() = default; + + virtual std::vector resolve(const std::string & ip) = 0; + + }; +} diff --git a/src/Common/DNSPTRResolverProvider.cpp b/src/Common/DNSPTRResolverProvider.cpp new file mode 100644 index 00000000000..ef19024495f --- /dev/null +++ b/src/Common/DNSPTRResolverProvider.cpp @@ -0,0 +1,12 @@ +#include "DNSPTRResolverProvider.h" +#include "CARESPTRResolver.h" + +namespace DB { + + std::shared_ptr DNSPTRResolverProvider::get() + { + static auto cares_resolver = std::make_shared(); + return cares_resolver; + } + +} diff --git a/src/Common/DNSPTRResolverProvider.h b/src/Common/DNSPTRResolverProvider.h new file mode 100644 index 00000000000..17764d8c91d --- /dev/null +++ b/src/Common/DNSPTRResolverProvider.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include "DNSPTRResolver.h" + +namespace DB { + class DNSPTRResolverProvider + { + public: + static std::shared_ptr get(); + }; +} + diff --git a/src/Common/DNSResolver.cpp b/src/Common/DNSResolver.cpp index dff1f8e7521..4c32dbf3341 100644 --- a/src/Common/DNSResolver.cpp +++ b/src/Common/DNSResolver.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include "DNSPTRResolverProvider.h" namespace ProfileEvents { @@ -142,25 +142,8 @@ static DNSResolver::IPAddresses resolveIPAddressImpl(const std::string & host) static std::vector reverseResolveImpl(const Poco::Net::IPAddress & address) { - boost::asio::io_service io_service; - YukiWorkshop::DNSResolver resolver(io_service); - - std::vector 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