diff --git a/lib/base/tcpsocket.hpp b/lib/base/tcpsocket.hpp index e0f502256..471ad8d23 100644 --- a/lib/base/tcpsocket.hpp +++ b/lib/base/tcpsocket.hpp @@ -6,8 +6,10 @@ #include "base/i2-base.hpp" #include "base/io-engine.hpp" #include "base/socket.hpp" +#include #include #include +#include namespace icinga { @@ -50,8 +52,10 @@ void Connect(Socket& socket, const String& node, const String& service) socket.connect(current->endpoint()); break; - } catch (const std::exception&) { - if (++current == result.end()) { + } catch (const std::exception& ex) { + auto se (dynamic_cast(&ex)); + + if (se && se->code() == boost::asio::error::operation_aborted || ++current == result.end()) { throw; } @@ -79,8 +83,10 @@ void Connect(Socket& socket, const String& node, const String& service, boost::a socket.async_connect(current->endpoint(), yc); break; - } catch (const std::exception&) { - if (++current == result.end()) { + } catch (const std::exception& ex) { + auto se (dynamic_cast(&ex)); + + if (se && se->code() == boost::asio::error::operation_aborted || ++current == result.end()) { throw; } diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index c40933de8..2daf8e251 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -734,46 +734,8 @@ void ApiListener::NewClientHandlerInternal( ClientType ctype; - if (role == RoleClient) { - JsonRpc::SendMessage(client, new Dictionary({ - { "jsonrpc", "2.0" }, - { "method", "icinga::Hello" }, - { "params", new Dictionary({ - { "version", (double)l_AppVersionInt }, - { "capabilities", (double)l_MyCapabilities } - }) } - }), yc); - - client->async_flush(yc); - - ctype = ClientJsonRpc; - } else { - { - boost::system::error_code ec; - - if (client->async_fill(yc[ec]) == 0u) { - if (identity.IsEmpty()) { - Log(LogInformation, "ApiListener") - << "No data received on new API connection " << conninfo << ". " - << "Ensure that the remote endpoints are properly configured in a cluster setup."; - } else { - Log(LogWarning, "ApiListener") - << "No data received on new API connection " << conninfo << " for identity '" << identity << "'. " - << "Ensure that the remote endpoints are properly configured in a cluster setup."; - } - - return; - } - } - - char firstByte = 0; - - { - asio::mutable_buffer firstByteBuf (&firstByte, 1); - client->peek(firstByteBuf); - } - - if (firstByte >= '0' && firstByte <= '9') { + try { + if (role == RoleClient) { JsonRpc::SendMessage(client, new Dictionary({ { "jsonrpc", "2.0" }, { "method", "icinga::Hello" }, @@ -787,8 +749,54 @@ void ApiListener::NewClientHandlerInternal( ctype = ClientJsonRpc; } else { - ctype = ClientHttp; + { + boost::system::error_code ec; + + if (client->async_fill(yc[ec]) == 0u) { + if (identity.IsEmpty()) { + Log(LogInformation, "ApiListener") + << "No data received on new API connection " << conninfo << ". " + << "Ensure that the remote endpoints are properly configured in a cluster setup."; + } else { + Log(LogWarning, "ApiListener") + << "No data received on new API connection " << conninfo << " for identity '" << identity << "'. " + << "Ensure that the remote endpoints are properly configured in a cluster setup."; + } + + return; + } + } + + char firstByte = 0; + + { + asio::mutable_buffer firstByteBuf (&firstByte, 1); + client->peek(firstByteBuf); + } + + if (firstByte >= '0' && firstByte <= '9') { + JsonRpc::SendMessage(client, new Dictionary({ + { "jsonrpc", "2.0" }, + { "method", "icinga::Hello" }, + { "params", new Dictionary({ + { "version", (double)l_AppVersionInt }, + { "capabilities", (double)l_MyCapabilities } + }) } + }), yc); + + client->async_flush(yc); + + ctype = ClientJsonRpc; + } else { + ctype = ClientHttp; + } } + } catch (const boost::system::system_error& systemError) { + if (systemError.code() == boost::asio::error::operation_aborted) { + shutDownIfNeeded.Cancel(); + } + + throw; } if (ctype == ClientJsonRpc) {