From 25968874fba19893e9c35c479c5a073bf99b0343 Mon Sep 17 00:00:00 2001 From: Andrey Bugaevskiy Date: Thu, 5 Jan 2023 16:44:45 +0300 Subject: [PATCH 1/3] Fix getaddrinfo error reporting --- clickhouse/base/socket.cpp | 21 +++++++++++++++++++++ clickhouse/base/socket.h | 12 ++++++++++++ ut/socket_ut.cpp | 10 ++++++++++ 3 files changed, 43 insertions(+) diff --git a/clickhouse/base/socket.cpp b/clickhouse/base/socket.cpp index e62e90df..296afdfb 100644 --- a/clickhouse/base/socket.cpp +++ b/clickhouse/base/socket.cpp @@ -43,6 +43,21 @@ windowsErrorCategory const& windowsErrorCategory::category() { } #endif +#if defined(_unix_) +char const* getaddrinfoErrorCategory::name() const noexcept { + return "getaddrinfoError"; +} + +std::string getaddrinfoErrorCategory::message(int c) const { + return gai_strerror(c); +} + +getaddrinfoErrorCategory const& getaddrinfoErrorCategory::category() { + static getaddrinfoErrorCategory c; + return c; +} +#endif + namespace { class LocalNames : public std::unordered_set { @@ -258,6 +273,12 @@ NetworkAddress::NetworkAddress(const std::string& host, const std::string& port) const int error = getaddrinfo(host.c_str(), port.c_str(), &hints, &info_); +#if defined(_unix_) + if (error != EAI_SYSTEM) { + throw std::system_error(error, getaddrinfoErrorCategory::category()); + } +#endif + if (error) { throw std::system_error(getSocketErrorCode(), getErrorCategory()); } diff --git a/clickhouse/base/socket.h b/clickhouse/base/socket.h index c68f250d..ed8f8a16 100644 --- a/clickhouse/base/socket.h +++ b/clickhouse/base/socket.h @@ -60,6 +60,18 @@ class windowsErrorCategory : public std::error_category { #endif +#if defined(_unix_) + +class getaddrinfoErrorCategory : public std::error_category { +public: + char const* name() const noexcept override final; + std::string message(int c) const override final; + + static getaddrinfoErrorCategory const& category(); +}; + +#endif + class SocketBase { public: diff --git a/ut/socket_ut.cpp b/ut/socket_ut.cpp index 5a263435..581366e6 100644 --- a/ut/socket_ut.cpp +++ b/ut/socket_ut.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -63,6 +64,15 @@ TEST(Socketcase, timeoutrecv) { server.stop(); } +TEST(Socketcase, gaierror) { + try { + NetworkAddress addr("host.invalid", "80"); // never resolves + FAIL(); + } catch (const std::system_error& e) { + ASSERT_EQ(EAI_NONAME, e.code().value()); + } +} + // Test to verify that reading from empty socket doesn't hangs. //TEST(Socketcase, ReadFromEmptySocket) { // const int port = 12345; From bda1c115d4e58ba01fec8bc1c9ade0bfe2d1d5d8 Mon Sep 17 00:00:00 2001 From: Andrey Bugaevskiy Date: Thu, 5 Jan 2023 17:17:39 +0300 Subject: [PATCH 2/3] typo --- clickhouse/base/socket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clickhouse/base/socket.cpp b/clickhouse/base/socket.cpp index 296afdfb..07e81329 100644 --- a/clickhouse/base/socket.cpp +++ b/clickhouse/base/socket.cpp @@ -274,7 +274,7 @@ NetworkAddress::NetworkAddress(const std::string& host, const std::string& port) const int error = getaddrinfo(host.c_str(), port.c_str(), &hints, &info_); #if defined(_unix_) - if (error != EAI_SYSTEM) { + if (error && error != EAI_SYSTEM) { throw std::system_error(error, getaddrinfoErrorCategory::category()); } #endif From a6643314813898c234a763ac996bda4a5ac58ea0 Mon Sep 17 00:00:00 2001 From: Andrey Bugaevskiy Date: Thu, 5 Jan 2023 23:29:50 +0300 Subject: [PATCH 3/3] fix test --- ut/socket_ut.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ut/socket_ut.cpp b/ut/socket_ut.cpp index 581366e6..709d21c3 100644 --- a/ut/socket_ut.cpp +++ b/ut/socket_ut.cpp @@ -4,11 +4,17 @@ #include #include -#include #include #include #include +// for EAI_* error codes +#if defined(_win_) +# include +#else +# include +#endif + using namespace clickhouse; TEST(Socketcase, connecterror) { @@ -69,7 +75,7 @@ TEST(Socketcase, gaierror) { NetworkAddress addr("host.invalid", "80"); // never resolves FAIL(); } catch (const std::system_error& e) { - ASSERT_EQ(EAI_NONAME, e.code().value()); + ASSERT_PRED1([](int error) { return error == EAI_NONAME || error == EAI_AGAIN || error == EAI_FAIL; }, e.code().value()); } }