cNetwork: Implemented IP-to-hostname lookup.
This commit is contained in:
parent
fde44cba08
commit
251c96952b
@ -123,7 +123,7 @@ public:
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Class definitions:
|
// Class definitions:
|
||||||
|
|
||||||
/** Holds information about an in-progress hostname lookup. */
|
/** Holds information about an in-progress Hostname-to-IP lookup. */
|
||||||
class cHostnameLookup
|
class cHostnameLookup
|
||||||
{
|
{
|
||||||
/** The callbacks to call for resolved names / errors. */
|
/** The callbacks to call for resolved names / errors. */
|
||||||
@ -144,6 +144,27 @@ typedef std::vector<cHostnameLookupPtr> cHostnameLookupPtrs;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Holds information about an in-progress IP-to-Hostname lookup. */
|
||||||
|
class cIPLookup
|
||||||
|
{
|
||||||
|
/** The callbacks to call for resolved names / errors. */
|
||||||
|
cNetwork::cResolveNameCallbacksPtr m_Callbacks;
|
||||||
|
|
||||||
|
/** The IP that was queried (needed for the callbacks). */
|
||||||
|
AString m_IP;
|
||||||
|
|
||||||
|
static void Callback(int a_Result, char a_Type, int a_Count, int a_Ttl, void * a_Addresses, void * a_Self);
|
||||||
|
|
||||||
|
public:
|
||||||
|
cIPLookup(const AString & a_IP, cNetwork::cResolveNameCallbacksPtr a_Callbacks);
|
||||||
|
};
|
||||||
|
typedef SharedPtr<cIPLookup> cIPLookupPtr;
|
||||||
|
typedef std::vector<cIPLookupPtr> cIPLookupPtrs;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Implements the cTCPLink details so that it can represent the single connection between two endpoints. */
|
/** Implements the cTCPLink details so that it can represent the single connection between two endpoints. */
|
||||||
class cTCPLinkImpl:
|
class cTCPLinkImpl:
|
||||||
public cTCPLink
|
public cTCPLink
|
||||||
@ -236,6 +257,7 @@ typedef std::vector<cServerHandleImplPtr> cServerHandleImplPtrs;
|
|||||||
class cNetworkSingleton
|
class cNetworkSingleton
|
||||||
{
|
{
|
||||||
friend class cHostnameLookup; // Needs access to m_DNSBase
|
friend class cHostnameLookup; // Needs access to m_DNSBase
|
||||||
|
friend class cIPLookup; // Needs access to m_DNSBase
|
||||||
friend class cTCPLinkImpl; // Needs access to m_EventBase and m_DNSBase
|
friend class cTCPLinkImpl; // Needs access to m_EventBase and m_DNSBase
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -305,6 +327,9 @@ protected:
|
|||||||
/** Container for all pending hostname lookups. */
|
/** Container for all pending hostname lookups. */
|
||||||
cHostnameLookupPtrs m_HostnameLookups;
|
cHostnameLookupPtrs m_HostnameLookups;
|
||||||
|
|
||||||
|
/** Container for all pending IP lookups. */
|
||||||
|
cIPLookupPtrs m_IPLookups;
|
||||||
|
|
||||||
|
|
||||||
/** Initializes the LibEvent internals. */
|
/** Initializes the LibEvent internals. */
|
||||||
cNetworkSingleton(void);
|
cNetworkSingleton(void);
|
||||||
@ -315,8 +340,13 @@ protected:
|
|||||||
/** Implements the thread that runs LibEvent's event dispatcher loop. */
|
/** Implements the thread that runs LibEvent's event dispatcher loop. */
|
||||||
static void RunEventLoop(cNetworkSingleton * a_Self);
|
static void RunEventLoop(cNetworkSingleton * a_Self);
|
||||||
|
|
||||||
/** Removes the specified hostname lookup from m_HostnameLookups. */
|
/** Removes the specified hostname lookup from m_HostnameLookups.
|
||||||
void RemoveHostnameLookup(cHostnameLookup * a_HostnameLookup);
|
Used by the underlying lookup implementation when the lookup is finished. */
|
||||||
|
void RemoveHostnameLookup(const cHostnameLookup * a_HostnameLookup);
|
||||||
|
|
||||||
|
/** Removes the specified IP lookup from m_IPLookups.
|
||||||
|
Used by the underlying lookup implementation when the lookup is finished. */
|
||||||
|
void RemoveIPLookup(const cIPLookup * a_IPLookup);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -343,7 +373,7 @@ cHostnameLookup::cHostnameLookup(const AString & a_Hostname, cNetwork::cResolveN
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cHostnameLookup::Callback(int a_ErrCode, struct evutil_addrinfo * a_Addr, void * a_Self)
|
void cHostnameLookup::Callback(int a_ErrCode, evutil_addrinfo * a_Addr, void * a_Self)
|
||||||
{
|
{
|
||||||
// Get the Self class:
|
// Get the Self class:
|
||||||
cHostnameLookup * Self = reinterpret_cast<cHostnameLookup *>(a_Self);
|
cHostnameLookup * Self = reinterpret_cast<cHostnameLookup *>(a_Self);
|
||||||
@ -359,6 +389,7 @@ void cHostnameLookup::Callback(int a_ErrCode, struct evutil_addrinfo * a_Addr, v
|
|||||||
|
|
||||||
// Call the success handler for each entry received:
|
// Call the success handler for each entry received:
|
||||||
bool HasResolved = false;
|
bool HasResolved = false;
|
||||||
|
evutil_addrinfo * OrigAddr = a_Addr;
|
||||||
for (;a_Addr != nullptr; a_Addr = a_Addr->ai_next)
|
for (;a_Addr != nullptr; a_Addr = a_Addr->ai_next)
|
||||||
{
|
{
|
||||||
char IP[128];
|
char IP[128];
|
||||||
@ -395,6 +426,7 @@ void cHostnameLookup::Callback(int a_ErrCode, struct evutil_addrinfo * a_Addr, v
|
|||||||
{
|
{
|
||||||
Self->m_Callbacks->OnFinished();
|
Self->m_Callbacks->OnFinished();
|
||||||
}
|
}
|
||||||
|
evutil_freeaddrinfo(OrigAddr);
|
||||||
cNetworkSingleton::Get().RemoveHostnameLookup(Self);
|
cNetworkSingleton::Get().RemoveHostnameLookup(Self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +434,57 @@ void cHostnameLookup::Callback(int a_ErrCode, struct evutil_addrinfo * a_Addr, v
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cIPLookup:
|
||||||
|
|
||||||
|
cIPLookup::cIPLookup(const AString & a_IP, cNetwork::cResolveNameCallbacksPtr a_Callbacks):
|
||||||
|
m_Callbacks(a_Callbacks),
|
||||||
|
m_IP(a_IP)
|
||||||
|
{
|
||||||
|
sockaddr_storage sa;
|
||||||
|
int salen = static_cast<int>(sizeof(sa));
|
||||||
|
evutil_parse_sockaddr_port(a_IP.c_str(), reinterpret_cast<sockaddr *>(&sa), &salen);
|
||||||
|
switch (sa.ss_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
sockaddr_in * sa4 = reinterpret_cast<sockaddr_in *>(&sa);
|
||||||
|
evdns_base_resolve_reverse(cNetworkSingleton::Get().m_DNSBase, &(sa4->sin_addr), 0, Callback, this);
|
||||||
|
}
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cIPLookup::Callback(int a_Result, char a_Type, int a_Count, int a_Ttl, void * a_Addresses, void * a_Self)
|
||||||
|
{
|
||||||
|
// Get the Self class:
|
||||||
|
cIPLookup * Self = reinterpret_cast<cIPLookup *>(a_Self);
|
||||||
|
ASSERT(Self != nullptr);
|
||||||
|
|
||||||
|
if ((a_Result != 0) || (a_Addresses == nullptr))
|
||||||
|
{
|
||||||
|
// An error has occurred, notify the error callback:
|
||||||
|
Self->m_Callbacks->OnError(a_Result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Call the success handler::
|
||||||
|
Self->m_Callbacks->OnNameResolved(*(reinterpret_cast<char **>(a_Addresses)), Self->m_IP);
|
||||||
|
Self->m_Callbacks->OnFinished();
|
||||||
|
}
|
||||||
|
cNetworkSingleton::Get().RemoveIPLookup(Self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cTCPLinkImpl:
|
// cTCPLinkImpl:
|
||||||
|
|
||||||
@ -842,9 +925,15 @@ bool cNetworkSingleton::IPToHostName(
|
|||||||
cNetwork::cResolveNameCallbacksPtr a_Callbacks
|
cNetwork::cResolveNameCallbacksPtr a_Callbacks
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// TODO
|
try
|
||||||
ASSERT(!"Not implemented yet!");
|
{
|
||||||
return false;
|
m_IPLookups.push_back(std::make_shared<cIPLookup>(a_IP, a_Callbacks));
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -878,7 +967,8 @@ void cNetworkSingleton::RunEventLoop(cNetworkSingleton * a_Self)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cNetworkSingleton::RemoveHostnameLookup(cHostnameLookup * a_HostnameLookup)
|
|
||||||
|
void cNetworkSingleton::RemoveHostnameLookup(const cHostnameLookup * a_HostnameLookup)
|
||||||
{
|
{
|
||||||
for (auto itr = m_HostnameLookups.begin(), end = m_HostnameLookups.end(); itr != end; ++itr)
|
for (auto itr = m_HostnameLookups.begin(), end = m_HostnameLookups.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
@ -893,3 +983,19 @@ void cNetworkSingleton::RemoveHostnameLookup(cHostnameLookup * a_HostnameLookup)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cNetworkSingleton::RemoveIPLookup(const cIPLookup * a_IPLookup)
|
||||||
|
{
|
||||||
|
for (auto itr = m_IPLookups.begin(), end = m_IPLookups.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (itr->get() == a_IPLookup)
|
||||||
|
{
|
||||||
|
m_IPLookups.erase(itr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} // for itr - m_HostnameLookups[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class cFinishLookupCallbacks:
|
|||||||
virtual void OnError(int a_ErrorCode) override
|
virtual void OnError(int a_ErrorCode) override
|
||||||
{
|
{
|
||||||
LOGD("Error %d while performing lookup!", a_ErrorCode);
|
LOGD("Error %d while performing lookup!", a_ErrorCode);
|
||||||
abort();
|
exit(a_ErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnFinished(void) override
|
virtual void OnFinished(void) override
|
||||||
@ -49,15 +49,28 @@ int main()
|
|||||||
{
|
{
|
||||||
cEvent evtFinish;
|
cEvent evtFinish;
|
||||||
|
|
||||||
|
// Look up google.com (has multiple IP addresses):
|
||||||
LOGD("Network test: Looking up google.com");
|
LOGD("Network test: Looking up google.com");
|
||||||
if (!cNetwork::HostnameToIP("google.com", std::make_shared<cFinishLookupCallbacks>(evtFinish)))
|
if (!cNetwork::HostnameToIP("google.com", std::make_shared<cFinishLookupCallbacks>(evtFinish)))
|
||||||
{
|
{
|
||||||
LOGWARNING("Cannot resolve google.com");
|
LOGWARNING("Cannot resolve google.com to IP");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
LOGD("Name lookup has been successfully queued");
|
LOGD("Name lookup has been successfully queued");
|
||||||
|
|
||||||
evtFinish.Wait();
|
evtFinish.Wait();
|
||||||
|
LOGD("Lookup finished.");
|
||||||
|
|
||||||
|
// Look up 8.8.8.8 (Google free DNS):
|
||||||
|
LOGD("Network test: Looking up IP 8.8.8.8");
|
||||||
|
if (!cNetwork::IPToHostName("8.8.8.8", std::make_shared<cFinishLookupCallbacks>(evtFinish)))
|
||||||
|
{
|
||||||
|
LOGWARNING("Cannot resolve 8.8.8.8 to name");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
LOGD("IP lookup has been successfully queued");
|
||||||
|
evtFinish.Wait();
|
||||||
|
LOGD("IP lookup finished.");
|
||||||
|
|
||||||
LOGD("Network test finished");
|
LOGD("Network test finished");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user