ApiListener: Add support for dynamic port handling

This commit is contained in:
Markus Frosch 2018-08-02 08:38:42 +02:00 committed by Michael Friedrich
parent a80c825921
commit 20269a89d0
5 changed files with 73 additions and 24 deletions

View File

@ -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<String, String>& 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<String, String> 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<String, String> Socket::GetClientAddressDetails()
{
boost::mutex::scoped_lock lock(m_SocketMutex);
@ -175,22 +185,32 @@ String Socket::GetClientAddress()
#endif /* _WIN32 */
}
String address;
std::pair<String, String> 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<String, String> Socket::GetPeerAddressDetails()
{
boost::mutex::scoped_lock lock(m_SocketMutex);
@ -215,14 +235,24 @@ String Socket::GetPeerAddress()
#endif /* _WIN32 */
}
String address;
std::pair<String, String> 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));
}

View File

@ -45,7 +45,9 @@ public:
void Close();
std::pair<String, String> GetClientAddressDetails();
String GetClientAddress();
std::pair<String, String> 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<String, String> GetDetailsFromSockaddr(sockaddr *address, socklen_t len);
static String GetHumanReadableAddress(const std::pair<String, String>& socketDetails);
};
class socket_error : virtual public std::exception, virtual public boost::exception { };

View File

@ -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<String, String> details = socket->GetClientAddressDetails();
Utility::SaveJsonFile(path, 0644, new Dictionary({
{"host", details.first},
{"port", details.second}
}));
}

View File

@ -114,6 +114,8 @@ protected:
void Start(bool runtimeCreated) override;
void Stop(bool runtimeDeleted) override;
void UpdateStatusFile(TcpSocket::Ptr socket);
void ValidateTlsProtocolmin(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
private:

View File

@ -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;