Skip to content

Commit

Permalink
Resolve IP addresses without touching DNS layer
Browse files Browse the repository at this point in the history
  • Loading branch information
0blu committed Sep 22, 2024
1 parent 89a399f commit c1c4927
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
44 changes: 37 additions & 7 deletions src/shared/IO/Networking/DNS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ std::string IO::Networking::DNS::GetOwnHostname()

std::vector<IO::Networking::IpAddress> IO::Networking::DNS::ResolveDomain(std::string const& domainName, IO::Networking::IpAddress::Type type)
{
MANGOS_ASSERT(type == IpAddress::Type::IPv4);
MANGOS_ASSERT(type == IpAddress::Type::IPv4); // TODO: this function is only tested with IPv4. `inet_ntop` will fail

// Check if we can parse the domain as an IP
nonstd::optional<IpAddress> maybeIp = IpAddress::TryParseFromString(domainName);
if (maybeIp)
{
IpAddress const& ip = maybeIp.value();
MANGOS_ASSERT(ip.GetType() == type);
return { ip }; // The "domain" can be directly parsed as an IP
}

// try to resolve the domain
addrinfo hints = {};
hints.ai_family = type == IpAddress::Type::IPv4 ? AF_INET : AF_INET6;
hints.ai_socktype = SOCK_STREAM;
Expand All @@ -35,17 +45,37 @@ std::vector<IO::Networking::IpAddress> IO::Networking::DNS::ResolveDomain(std::s
addrinfo* dnsResult = nullptr;
if (::getaddrinfo(domainName.c_str(), nullptr, &hints, &dnsResult) != 0)
{
sLog.Out(LogType::LOG_NETWORK, LOG_LVL_ERROR, "IO ERROR: ::getaddrinfo(...): %s", SystemErrorToString(errno).c_str());
MANGOS_ASSERT(false);
sLog.Out(LogType::LOG_NETWORK, LOG_LVL_ERROR, "IO ERROR: ::getaddrinfo(...): %s", SystemErrorToString(
#if defined(WIN32)
::WSAGetLastError()
#else
errno
#endif
).c_str());
return {}; // error occurred, empty return
}

std::vector<IO::Networking::IpAddress> list;
std::vector<IpAddress> list;

for (addrinfo* ptr = dnsResult; ptr != nullptr; ptr = ptr->ai_next)
{
sockaddr_in* sockaddr_ipv4 = reinterpret_cast<sockaddr_in*>(ptr->ai_addr);
IpAddress ip = IO::Networking::Internal::inet_ntop(&(sockaddr_ipv4->sin_addr));
list.emplace_back(ip);
if (ptr->ai_family == AF_INET)
{
sockaddr_in* sockaddr_ipv4 = reinterpret_cast<sockaddr_in*>(ptr->ai_addr);
IpAddress ip = IO::Networking::Internal::inet_ntop(&(sockaddr_ipv4->sin_addr));
list.emplace_back(ip);
}
else if (ptr->ai_family == AF_INET6)
{
// TODO: Add inet_ntop for IPv6
//sockaddr_in6* sockaddr_ipv6 = reinterpret_cast<sockaddr_in6*>(ptr->ai_addr);
//IpAddress ip = IO::Networking::Internal::inet_ntop(&(sockaddr_ipv6->sin_addr));
//list.emplace_back(ip);
}
else
{
std::unexpected();
}
}

freeaddrinfo(dnsResult);
Expand Down
3 changes: 3 additions & 0 deletions src/shared/IO/Networking/DNS.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
namespace IO { namespace Networking { namespace DNS
{
std::string GetOwnHostname();

/// Will also work with IP addresses without touching the DNS layer
/// \warning Will return an empty list if unable to resolve the domain
std::vector<IO::Networking::IpAddress> ResolveDomain(std::string const& domainName, IO::Networking::IpAddress::Type type);
}}} // namespace IO::Networking

Expand Down
3 changes: 2 additions & 1 deletion src/shared/IO/Networking/Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace IO { namespace Networking { namespace Internal
{
/// Converts a native `IN_ADDR` to a `IO::Networking::IpAddress`
IO::Networking::IpAddress inet_ntop(in_addr const* nativeAddress);
// Converts a `IO::Networking::IpAddress` to a native `IN_ADDR`

/// Converts a `IO::Networking::IpAddress` to a native `IN_ADDR`
void inet_pton(IO::Networking::IpAddress const& ipAddress, in_addr* out_dest);

/// Closes a socket
Expand Down

0 comments on commit c1c4927

Please sign in to comment.