From 20269a89d01a434192e0eee287b158d56d5e965a Mon Sep 17 00:00:00 2001 From: Markus Frosch Date: Thu, 2 Aug 2018 08:38:42 +0200 Subject: [PATCH] ApiListener: Add support for dynamic port handling --- lib/base/socket.cpp | 65 +++++++++++++++++++++++++++----------- lib/base/socket.hpp | 5 ++- lib/remote/apilistener.cpp | 19 +++++++++-- lib/remote/apilistener.hpp | 2 ++ lib/remote/apilistener.ti | 6 ++-- 5 files changed, 73 insertions(+), 24 deletions(-) diff --git a/lib/base/socket.cpp b/lib/base/socket.cpp index 97946f5ee..17d35778b 100644 --- a/lib/base/socket.cpp +++ b/lib/base/socket.cpp @@ -114,9 +114,21 @@ int Socket::GetError() const /** * Formats a sockaddr in a human-readable way. * - * @returns A String describing the sockaddr. + * @returns A pair of host and service. */ -String Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len) +String Socket::GetHumanReadableAddress(const std::pair& socketDetails) +{ + std::ostringstream s; + s << "[" << socketDetails.first << "]:" << socketDetails.second; + return s.str(); +} + +/** + * Returns host and service as pair. + * + * @returns A pair with host and service. + */ +std::pair Socket::GetDetailsFromSockaddr(sockaddr *address, socklen_t len) { char host[NI_MAXHOST]; char service[NI_MAXSERV]; @@ -140,17 +152,15 @@ String Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len) #endif /* _WIN32 */ } - std::ostringstream s; - s << "[" << host << "]:" << service; - return s.str(); + return std::make_pair(host, service); } /** - * Returns a String describing the local address of the socket. + * Returns a pair describing the local host and service of the socket. * - * @returns A String describing the local address. + * @returns A pair describing the local host and service. */ -String Socket::GetClientAddress() +std::pair Socket::GetClientAddressDetails() { boost::mutex::scoped_lock lock(m_SocketMutex); @@ -175,22 +185,32 @@ String Socket::GetClientAddress() #endif /* _WIN32 */ } - String address; + std::pair details; try { - address = GetAddressFromSockaddr((sockaddr *)&sin, len); + details = GetDetailsFromSockaddr((sockaddr *)&sin, len); } catch (const std::exception&) { /* already logged */ } - return address; + return details; } /** - * Returns a String describing the peer address of the socket. + * Returns a String describing the local address of the socket. * - * @returns A String describing the peer address. + * @returns A String describing the local address. */ -String Socket::GetPeerAddress() +String Socket::GetClientAddress() +{ + return GetHumanReadableAddress(GetClientAddressDetails()); +} + +/** + * Returns a pair describing the peer host and service of the socket. + * + * @returns A pair describing the peer host and service. + */ +std::pair Socket::GetPeerAddressDetails() { boost::mutex::scoped_lock lock(m_SocketMutex); @@ -215,14 +235,24 @@ String Socket::GetPeerAddress() #endif /* _WIN32 */ } - String address; + std::pair details; try { - address = GetAddressFromSockaddr((sockaddr *)&sin, len); + details = GetDetailsFromSockaddr((sockaddr *)&sin, len); } catch (const std::exception&) { /* already logged */ } - return address; + return details; +} + +/** + * Returns a String describing the peer address of the socket. + * + * @returns A String describing the peer address. + */ +String Socket::GetPeerAddress() +{ + return GetHumanReadableAddress(GetPeerAddressDetails()); } /** @@ -415,4 +445,3 @@ void Socket::SocketPair(SOCKET s[2]) << boost::errinfo_api_function("socketpair") << boost::errinfo_errno(errno)); } - diff --git a/lib/base/socket.hpp b/lib/base/socket.hpp index 89147c57d..7de915bbe 100644 --- a/lib/base/socket.hpp +++ b/lib/base/socket.hpp @@ -45,7 +45,9 @@ public: void Close(); + std::pair GetClientAddressDetails(); String GetClientAddress(); + std::pair GetPeerAddressDetails(); String GetPeerAddress(); size_t Read(void *buffer, size_t size); @@ -70,7 +72,8 @@ protected: private: SOCKET m_FD{INVALID_SOCKET}; /**< The socket descriptor. */ - static String GetAddressFromSockaddr(sockaddr *address, socklen_t len); + static std::pair GetDetailsFromSockaddr(sockaddr *address, socklen_t len); + static String GetHumanReadableAddress(const std::pair& socketDetails); }; class socket_error : virtual public std::exception, virtual public boost::exception { }; diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index c7ba834b4..84931086f 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -318,9 +318,6 @@ bool ApiListener::AddListener(const String& node, const String& service) return false; } - Log(LogInformation, "ApiListener") - << "Adding new listener on port '" << service << "'"; - TcpSocket::Ptr server = new TcpSocket(); try { @@ -331,11 +328,16 @@ bool ApiListener::AddListener(const String& node, const String& service) return false; } + Log(LogInformation, "ApiListener") + << "Started new listener on '" << server->GetClientAddress() << "'"; + std::thread thread(std::bind(&ApiListener::ListenerThreadProc, this, server)); thread.detach(); m_Servers.insert(server); + UpdateStatusFile(server); + return true; } @@ -1469,3 +1471,14 @@ String ApiListener::GetFromZoneName(const Zone::Ptr& fromZone) return fromZoneName; } + +void ApiListener::UpdateStatusFile(TcpSocket::Ptr socket) +{ + String path = Application::GetConst("CacheDir") + "/api-state.json"; + std::pair details = socket->GetClientAddressDetails(); + + Utility::SaveJsonFile(path, 0644, new Dictionary({ + {"host", details.first}, + {"port", details.second} + })); +} diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index b3894992a..8b46c4cb3 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -114,6 +114,8 @@ protected: void Start(bool runtimeCreated) override; void Stop(bool runtimeDeleted) override; + void UpdateStatusFile(TcpSocket::Ptr socket); + void ValidateTlsProtocolmin(const Lazy& lvalue, const ValidationUtils& utils) override; private: diff --git a/lib/remote/apilistener.ti b/lib/remote/apilistener.ti index e04fa0185..04e483270 100644 --- a/lib/remote/apilistener.ti +++ b/lib/remote/apilistener.ti @@ -41,9 +41,11 @@ class ApiListener : ConfigObject default {{{ return "TLSv1"; }}} }; - [config] String bind_host; + [config] String bind_host { + default {{{ return Application::GetConst("ApiBindHost"); }}} + }; [config] String bind_port { - default {{{ return "5665"; }}} + default {{{ return Application::GetConst("ApiBindPort", "5665"); }}} }; [config] bool accept_config;