diff --git a/lib/base/tcpsocket.cpp b/lib/base/tcpsocket.cpp index a9390e5a7..1ad0e23a8 100644 --- a/lib/base/tcpsocket.cpp +++ b/lib/base/tcpsocket.cpp @@ -1,9 +1,12 @@ /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ +#include "base/io-engine.hpp" #include "base/tcpsocket.hpp" #include "base/logger.hpp" #include "base/utility.hpp" #include "base/exception.hpp" +#include +#include #include #include #include @@ -209,3 +212,38 @@ void TcpSocket::Connect(const String& node, const String& service) #endif /* _WIN32 */ } } + +void icinga::Connect(AsioTcpSocket& socket, const String& node, const String& service, boost::asio::yield_context* yc) +{ + using boost::asio::ip::tcp; + + tcp::resolver resolver (IoEngine::Get().GetIoContext()); + tcp::resolver::query query (node, service); + auto result (yc ? resolver.async_resolve(query, *yc) : resolver.resolve(query)); + auto current (result.begin()); + + for (;;) { + try { + socket.open(current->endpoint().protocol()); + socket.set_option(tcp::socket::keep_alive(true)); + + if (yc) { + socket.async_connect(current->endpoint(), *yc); + } else { + socket.connect(current->endpoint()); + } + + break; + } catch (const std::exception& ex) { + auto se (dynamic_cast(&ex)); + + if (se && se->code() == boost::asio::error::operation_aborted || ++current == result.end()) { + throw; + } + + if (socket.is_open()) { + socket.close(); + } + } + } +} diff --git a/lib/base/tcpsocket.hpp b/lib/base/tcpsocket.hpp index b7caeb11b..13c19ee91 100644 --- a/lib/base/tcpsocket.hpp +++ b/lib/base/tcpsocket.hpp @@ -4,12 +4,9 @@ #define TCPSOCKET_H #include "base/i2-base.hpp" -#include "base/io-engine.hpp" #include "base/socket.hpp" -#include #include #include -#include namespace icinga { @@ -30,55 +27,21 @@ public: void Connect(const String& node, const String& service); }; +typedef boost::asio::ip::tcp::socket::lowest_layer_type AsioTcpSocket; + /** * TCP Connect based on Boost ASIO. * * @ingroup base */ -template -void Connect(Socket& socket, const String& node, const String& service, boost::asio::yield_context* yc) -{ - using boost::asio::ip::tcp; +void Connect(AsioTcpSocket& socket, const String& node, const String& service, boost::asio::yield_context* yc); - tcp::resolver resolver (IoEngine::Get().GetIoContext()); - tcp::resolver::query query (node, service); - auto result (yc ? resolver.async_resolve(query, *yc) : resolver.resolve(query)); - auto current (result.begin()); - - for (;;) { - try { - socket.open(current->endpoint().protocol()); - socket.set_option(tcp::socket::keep_alive(true)); - - if (yc) { - socket.async_connect(current->endpoint(), *yc); - } else { - socket.connect(current->endpoint()); - } - - break; - } catch (const std::exception& ex) { - auto se (dynamic_cast(&ex)); - - if (se && se->code() == boost::asio::error::operation_aborted || ++current == result.end()) { - throw; - } - - if (socket.is_open()) { - socket.close(); - } - } - } -} - -template -inline void Connect(Socket& socket, const String& node, const String& service) +inline void Connect(AsioTcpSocket& socket, const String& node, const String& service) { Connect(socket, node, service, nullptr); } -template -inline void Connect(Socket& socket, const String& node, const String& service, boost::asio::yield_context yc) +inline void Connect(AsioTcpSocket& socket, const String& node, const String& service, boost::asio::yield_context yc) { Connect(socket, node, service, &yc); }