diff --git a/src/messagedirector/message_director.cpp b/src/messagedirector/message_director.cpp index 28827b8..b780077 100644 --- a/src/messagedirector/message_director.cpp +++ b/src/messagedirector/message_director.cpp @@ -4,6 +4,7 @@ #ifdef ARDOS_WANT_DB_SERVER #include "../database/database.h" #endif +#include "../net/address_utils.h" #include "../stateserver/state_server.h" #include "../util/config.h" #include "../util/globals.h" @@ -96,7 +97,8 @@ MessageDirector::MessageDirector() { // Start connecting/listening! _listenHandle->bind(_host, _port); - _connectHandle->connect(rHost, rPort); + _connectHandle->connect(AddressUtils::resolve_host(g_loop, rHost, rPort), + rPort); } /** diff --git a/src/net/address_utils.cpp b/src/net/address_utils.cpp new file mode 100644 index 0000000..8162413 --- /dev/null +++ b/src/net/address_utils.cpp @@ -0,0 +1,51 @@ +#include "address_utils.h" + +#include "../util/logger.h" + +namespace Ardos { + +std::string AddressUtils::resolve_host(const std::shared_ptr &loop, + const std::string &host, + unsigned int port) { + // First, test if we have a valid IPv4 address. + sockaddr_in sockaddr; + if (uv_ip4_addr(host.c_str(), port, &sockaddr) == 0) { + return host; + } + + // Next, test if we have a valid IPv6 address. + sockaddr_in6 sockaddr6; + if (uv_ip6_addr(host.c_str(), port, &sockaddr6) == 0) { + return host; + } + + // We don't, lets try to resolve an IP via DNS. + auto dnsRequest = loop->resource(); + auto dnsResult = dnsRequest->addr_info_sync(host, std::to_string(port)); + if (!dnsResult.first) { + Logger::Error( + std::format("[NET] Failed to resolve host address: {}:{}", host, port)); + exit(1); + } + + char addr[INET6_ADDRSTRLEN]; + if (inet_ntop(dnsResult.second->ai_family, + get_in_addr(dnsResult.second->ai_addr), addr, + dnsResult.second->ai_addrlen)) { + return std::string(addr); + } + + Logger::Error( + std::format("[NET] Failed to parse host address: {}:{}", host, port)); + exit(1); +} + +void *AddressUtils::get_in_addr(struct sockaddr *sa) { + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in *)sa)->sin_addr); + } + + return &(((struct sockaddr_in6 *)sa)->sin6_addr); +} + +} // namespace Ardos diff --git a/src/net/address_utils.h b/src/net/address_utils.h new file mode 100644 index 0000000..7509e5b --- /dev/null +++ b/src/net/address_utils.h @@ -0,0 +1,23 @@ +#ifndef ARDOS_ADDRESS_UTILS_H +#define ARDOS_ADDRESS_UTILS_H + +#include +#include + +#include + +namespace Ardos { + +class AddressUtils { +public: + static std::string resolve_host(const std::shared_ptr &loop, + const std::string &host, + unsigned int port = 0); + +private: + static void *get_in_addr(struct sockaddr *sa); +}; + +} // namespace Ardos + +#endif // ARDOS_ADDRESS_UTILS_H