diff --git a/components/livestatus/livestatuslistener.cpp b/components/livestatus/livestatuslistener.cpp index 857a23489..655f5af5c 100644 --- a/components/livestatus/livestatuslistener.cpp +++ b/components/livestatus/livestatuslistener.cpp @@ -70,7 +70,12 @@ void LivestatusListener::Start(void) if (GetSocketType() == "tcp") { TcpSocket::Ptr socket = make_shared(); - socket->Bind(GetBindHost(), GetBindPort(), AF_UNSPEC); + try { + socket->Bind(GetBindHost(), GetBindPort(), AF_UNSPEC); + } catch (std::exception&) { + Log(LogCritical, "LivestatusListener", "Cannot bind tcp socket on host '" + GetBindHost() + "' port '" + GetBindPort() + "'."); + return; + } boost::thread thread(boost::bind(&LivestatusListener::ServerThreadProc, this, socket)); thread.detach(); @@ -79,7 +84,12 @@ void LivestatusListener::Start(void) else if (GetSocketType() == "unix") { #ifndef _WIN32 UnixSocket::Ptr socket = make_shared(); - socket->Bind(GetSocketPath()); + try { + socket->Bind(GetSocketPath()); + } catch (std::exception&) { + Log(LogCritical, "LivestatusListener", "Cannot bind unix socket in '" + GetSocketPath() + "'."); + return; + } /* group must be able to write */ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; diff --git a/lib/base/tcpsocket.cpp b/lib/base/tcpsocket.cpp index 8ce5f575f..24fc230f0 100644 --- a/lib/base/tcpsocket.cpp +++ b/lib/base/tcpsocket.cpp @@ -18,9 +18,12 @@ ******************************************************************************/ #include "base/tcpsocket.hpp" +#include "base/logger_fwd.hpp" +#include "base/utility.hpp" #include "base/exception.hpp" #include #include +#include using namespace icinga; @@ -59,6 +62,10 @@ void TcpSocket::Bind(const String& node, const String& service, int family) service.CStr(), &hints, &result); if (rc != 0) { + std::ostringstream msgbuf; + msgbuf << "getaddrinfo() failed with return code " << rc << "('" << Utility::FormatErrorNumber(rc) << "')"; + Log(LogCritical, "TcpSocket", msgbuf.str()); + BOOST_THROW_EXCEPTION(socket_error() << boost::errinfo_api_function("getaddrinfo") << errinfo_getaddrinfo_error(rc)); @@ -111,6 +118,10 @@ void TcpSocket::Bind(const String& node, const String& service, int family) freeaddrinfo(result); if (GetFD() == INVALID_SOCKET) { + std::ostringstream msgbuf; + msgbuf << "Invalid socket: " << Utility::FormatErrorNumber(error); + Log(LogCritical, "TcpSocket", msgbuf.str()); + #ifndef _WIN32 BOOST_THROW_EXCEPTION(socket_error() << boost::errinfo_api_function(func) @@ -144,6 +155,10 @@ void TcpSocket::Connect(const String& node, const String& service) int rc = getaddrinfo(node.CStr(), service.CStr(), &hints, &result); if (rc != 0) { + std::ostringstream msgbuf; + msgbuf << "getaddrinfo() failed with return code " << rc << "('" << Utility::FormatErrorNumber(rc) << "')"; + Log(LogCritical, "TcpSocket", msgbuf.str()); + BOOST_THROW_EXCEPTION(socket_error() << boost::errinfo_api_function("getaddrinfo") << errinfo_getaddrinfo_error(rc)); @@ -188,6 +203,10 @@ void TcpSocket::Connect(const String& node, const String& service) freeaddrinfo(result); if (GetFD() == INVALID_SOCKET) { + std::ostringstream msgbuf; + msgbuf << "Invalid socket: " << Utility::FormatErrorNumber(error); + Log(LogCritical, "TcpSocket", msgbuf.str()); + #ifndef _WIN32 BOOST_THROW_EXCEPTION(socket_error() << boost::errinfo_api_function(func) diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 7c1b63bd0..9d7e5184a 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -807,6 +807,33 @@ String Utility::FormatDateTime(const char *format, double ts) return timestamp; } +String Utility::FormatErrorNumber(int code) { + std::ostringstream msgbuf; + +#ifdef _WIN32 + char *message; + String result = "Unknown error."; + + DWORD rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message, + 0, NULL); + + if (rc != 0) { + result = String(message); + LocalFree(message); + + /* remove trailing new-line characters */ + boost::algorithm::trim_right(result); + } + + msgbuf << code << ", \"" << result << "\""; + return tmp.str(); +#else + msgbuf << gai_strerror(code) << std::endl; +#endif + return msgbuf.str(); +} + String Utility::EscapeShellCmd(const String& s) { String result; diff --git a/lib/base/utility.hpp b/lib/base/utility.hpp index bf4f0498d..f6e418928 100644 --- a/lib/base/utility.hpp +++ b/lib/base/utility.hpp @@ -88,6 +88,7 @@ public: static String FormatDuration(int duration); static String FormatDateTime(const char *format, double ts); + static String FormatErrorNumber(int code); static #ifdef _WIN32