[icinga-checkins] icinga.org: icinga2/next: Error Messages: Deal with socket exceptions.

git at icinga.org git at icinga.org
Thu Jun 5 18:29:54 CEST 2014


Module: icinga2
Branch: next
Commit: f1e77a057992eba48c59f6372e8aac67c598727e
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=f1e77a057992eba48c59f6372e8aac67c598727e

Author: Michael Friedrich <michael.friedrich at netways.de>
Date:   Thu Jun  5 14:08:01 2014 +0200

Error Messages: Deal with socket exceptions.

Refs #6070

---

 components/livestatus/livestatuslistener.cpp |   14 +++++++++++--
 lib/base/tcpsocket.cpp                       |   19 ++++++++++++++++++
 lib/base/utility.cpp                         |   27 ++++++++++++++++++++++++++
 lib/base/utility.hpp                         |    1 +
 4 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/components/livestatus/livestatuslistener.cpp b/components/livestatus/livestatuslistener.cpp
index 857a234..655f5af 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<TcpSocket>();
-		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<UnixSocket>();
-		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 8ce5f57..24fc230 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 <boost/exception/errinfo_api_function.hpp>
 #include <boost/exception/errinfo_errno.hpp>
+#include <iostream>
 
 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 7c1b63b..9d7e518 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 bf4f049..f6e4189 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



More information about the icinga-checkins mailing list