From c0cb787c101725a649d26de68fca2632c82830ba Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 18 Jan 2015 11:57:16 +0100 Subject: cNetwork: Split the main cpp file into several files. --- src/OSSupport/HostnameLookup.cpp | 109 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/OSSupport/HostnameLookup.cpp (limited to 'src/OSSupport/HostnameLookup.cpp') diff --git a/src/OSSupport/HostnameLookup.cpp b/src/OSSupport/HostnameLookup.cpp new file mode 100644 index 000000000..9e35f7163 --- /dev/null +++ b/src/OSSupport/HostnameLookup.cpp @@ -0,0 +1,109 @@ + +// HostnameLookup.cpp + +// Implements the cHostnameLookup class representing an in-progress hostname-to-IP lookup + +#include "Globals.h" +#include "HostnameLookup.h" +#include +#include "NetworkSingleton.h" + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cHostnameLookup: + +cHostnameLookup::cHostnameLookup(const AString & a_Hostname, cNetwork::cResolveNameCallbacksPtr a_Callbacks): + m_Callbacks(a_Callbacks), + m_Hostname(a_Hostname) +{ + evutil_addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_protocol = IPPROTO_TCP; + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_UNSPEC; + hints.ai_flags = EVUTIL_AI_CANONNAME; + evdns_getaddrinfo(cNetworkSingleton::Get().GetDNSBase(), a_Hostname.c_str(), nullptr, &hints, Callback, this); +} + + + + + +void cHostnameLookup::Callback(int a_ErrCode, evutil_addrinfo * a_Addr, void * a_Self) +{ + // Get the Self class: + cHostnameLookup * Self = reinterpret_cast(a_Self); + ASSERT(Self != nullptr); + + // If an error has occurred, notify the error callback: + if (a_ErrCode != 0) + { + Self->m_Callbacks->OnError(a_ErrCode); + cNetworkSingleton::Get().RemoveHostnameLookup(Self); + return; + } + + // Call the success handler for each entry received: + bool HasResolved = false; + evutil_addrinfo * OrigAddr = a_Addr; + for (;a_Addr != nullptr; a_Addr = a_Addr->ai_next) + { + char IP[128]; + switch (a_Addr->ai_family) + { + case AF_INET: // IPv4 + { + sockaddr_in * sin = reinterpret_cast(a_Addr->ai_addr); + evutil_inet_ntop(AF_INET, &(sin->sin_addr), IP, sizeof(IP)); + break; + } + case AF_INET6: // IPv6 + { + sockaddr_in6 * sin = reinterpret_cast(a_Addr->ai_addr); + evutil_inet_ntop(AF_INET6, &(sin->sin6_addr), IP, sizeof(IP)); + break; + } + default: + { + // Unknown address family, handle as if this entry wasn't received + continue; // for (a_Addr) + } + } + Self->m_Callbacks->OnNameResolved(Self->m_Hostname, IP); + HasResolved = true; + } // for (a_Addr) + + // If only unsupported families were reported, call the Error handler: + if (!HasResolved) + { + Self->m_Callbacks->OnError(1); + } + else + { + Self->m_Callbacks->OnFinished(); + } + evutil_freeaddrinfo(OrigAddr); + cNetworkSingleton::Get().RemoveHostnameLookup(Self); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cNetwork API: + +bool cNetwork::HostnameToIP( + const AString & a_Hostname, + cNetwork::cResolveNameCallbacksPtr a_Callbacks +) +{ + return cNetworkSingleton::Get().HostnameToIP(a_Hostname, a_Callbacks); +} + + + + -- cgit v1.2.3 From d4682463a1d503c349ac95e275b11d67d402268c Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 18 Jan 2015 12:35:02 +0100 Subject: cNetwork: Fixed race conditions with lookups; proper shutdown. --- src/OSSupport/HostnameLookup.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src/OSSupport/HostnameLookup.cpp') diff --git a/src/OSSupport/HostnameLookup.cpp b/src/OSSupport/HostnameLookup.cpp index 9e35f7163..860e0d88f 100644 --- a/src/OSSupport/HostnameLookup.cpp +++ b/src/OSSupport/HostnameLookup.cpp @@ -15,10 +15,22 @@ //////////////////////////////////////////////////////////////////////////////// // cHostnameLookup: -cHostnameLookup::cHostnameLookup(const AString & a_Hostname, cNetwork::cResolveNameCallbacksPtr a_Callbacks): - m_Callbacks(a_Callbacks), - m_Hostname(a_Hostname) +cHostnameLookup::cHostnameLookup(cNetwork::cResolveNameCallbacksPtr a_Callbacks): + m_Callbacks(a_Callbacks) { +} + + + + + +void cHostnameLookup::Lookup(const AString & a_Hostname) +{ + // Store the hostname for the callback: + m_Hostname = a_Hostname; + + // Start the lookup: + // Note that we don't have to store the LibEvent lookup handle, LibEvent will free it on its own. evutil_addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_protocol = IPPROTO_TCP; @@ -79,7 +91,7 @@ void cHostnameLookup::Callback(int a_ErrCode, evutil_addrinfo * a_Addr, void * a // If only unsupported families were reported, call the Error handler: if (!HasResolved) { - Self->m_Callbacks->OnError(1); + Self->m_Callbacks->OnError(DNS_ERR_NODATA); } else { @@ -101,7 +113,10 @@ bool cNetwork::HostnameToIP( cNetwork::cResolveNameCallbacksPtr a_Callbacks ) { - return cNetworkSingleton::Get().HostnameToIP(a_Hostname, a_Callbacks); + auto Lookup = std::make_shared(a_Callbacks); + cNetworkSingleton::Get().AddHostnameLookup(Lookup); + Lookup->Lookup(a_Hostname); + return true; } -- cgit v1.2.3 From 64855ed340e76779b99f37fbc866a7f5952e11db Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 20 Jan 2015 11:27:05 +0100 Subject: cNetwork: Added error message to error callbacks. --- src/OSSupport/HostnameLookup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/OSSupport/HostnameLookup.cpp') diff --git a/src/OSSupport/HostnameLookup.cpp b/src/OSSupport/HostnameLookup.cpp index 860e0d88f..3a2997ffd 100644 --- a/src/OSSupport/HostnameLookup.cpp +++ b/src/OSSupport/HostnameLookup.cpp @@ -53,7 +53,7 @@ void cHostnameLookup::Callback(int a_ErrCode, evutil_addrinfo * a_Addr, void * a // If an error has occurred, notify the error callback: if (a_ErrCode != 0) { - Self->m_Callbacks->OnError(a_ErrCode); + Self->m_Callbacks->OnError(a_ErrCode, evutil_socket_error_to_string(a_ErrCode)); cNetworkSingleton::Get().RemoveHostnameLookup(Self); return; } @@ -91,7 +91,7 @@ void cHostnameLookup::Callback(int a_ErrCode, evutil_addrinfo * a_Addr, void * a // If only unsupported families were reported, call the Error handler: if (!HasResolved) { - Self->m_Callbacks->OnError(DNS_ERR_NODATA); + Self->m_Callbacks->OnError(DNS_ERR_NODATA, "The name does not resolve to any known address."); } else { -- cgit v1.2.3