summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2015-01-11 12:59:07 +0100
committerMattes D <github@xoft.cz>2015-01-22 20:12:45 +0100
commit251c96952bb80c57f24d243def2677e3ee94efe1 (patch)
treef515b91116bd04f0ea638be1dd31b3b9ce89d33d
parentcNetwork: Implemented HostnameToIP lookups. (diff)
downloadcuberite-251c96952bb80c57f24d243def2677e3ee94efe1.tar
cuberite-251c96952bb80c57f24d243def2677e3ee94efe1.tar.gz
cuberite-251c96952bb80c57f24d243def2677e3ee94efe1.tar.bz2
cuberite-251c96952bb80c57f24d243def2677e3ee94efe1.tar.lz
cuberite-251c96952bb80c57f24d243def2677e3ee94efe1.tar.xz
cuberite-251c96952bb80c57f24d243def2677e3ee94efe1.tar.zst
cuberite-251c96952bb80c57f24d243def2677e3ee94efe1.zip
-rw-r--r--src/OSSupport/Network.cpp122
-rw-r--r--tests/Network/NameLookup.cpp19
2 files changed, 130 insertions, 11 deletions
diff --git a/src/OSSupport/Network.cpp b/src/OSSupport/Network.cpp
index 8e2d060b4..392fb586e 100644
--- a/src/OSSupport/Network.cpp
+++ b/src/OSSupport/Network.cpp
@@ -123,7 +123,7 @@ public:
////////////////////////////////////////////////////////////////////////////////
// Class definitions:
-/** Holds information about an in-progress hostname lookup. */
+/** Holds information about an in-progress Hostname-to-IP lookup. */
class cHostnameLookup
{
/** 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. */
class cTCPLinkImpl:
public cTCPLink
@@ -236,6 +257,7 @@ typedef std::vector<cServerHandleImplPtr> cServerHandleImplPtrs;
class cNetworkSingleton
{
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
public:
@@ -305,6 +327,9 @@ protected:
/** Container for all pending hostname lookups. */
cHostnameLookupPtrs m_HostnameLookups;
+ /** Container for all pending IP lookups. */
+ cIPLookupPtrs m_IPLookups;
+
/** Initializes the LibEvent internals. */
cNetworkSingleton(void);
@@ -315,8 +340,13 @@ protected:
/** Implements the thread that runs LibEvent's event dispatcher loop. */
static void RunEventLoop(cNetworkSingleton * a_Self);
- /** Removes the specified hostname lookup from m_HostnameLookups. */
- void RemoveHostnameLookup(cHostnameLookup * a_HostnameLookup);
+ /** Removes the specified hostname lookup from m_HostnameLookups.
+ 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:
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:
bool HasResolved = false;
+ evutil_addrinfo * OrigAddr = a_Addr;
for (;a_Addr != nullptr; a_Addr = a_Addr->ai_next)
{
char IP[128];
@@ -395,6 +426,7 @@ void cHostnameLookup::Callback(int a_ErrCode, struct evutil_addrinfo * a_Addr, v
{
Self->m_Callbacks->OnFinished();
}
+ evutil_freeaddrinfo(OrigAddr);
cNetworkSingleton::Get().RemoveHostnameLookup(Self);
}
@@ -403,6 +435,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::cTCPLinkImpl(cTCPLink::cCallbacksPtr a_LinkCallbacks):
@@ -842,9 +925,15 @@ bool cNetworkSingleton::IPToHostName(
cNetwork::cResolveNameCallbacksPtr a_Callbacks
)
{
- // TODO
- ASSERT(!"Not implemented yet!");
- return false;
+ try
+ {
+ 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)
{
@@ -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[]
+}
+
+
+
+
diff --git a/tests/Network/NameLookup.cpp b/tests/Network/NameLookup.cpp
index daa72a3cb..74a57258c 100644
--- a/tests/Network/NameLookup.cpp
+++ b/tests/Network/NameLookup.cpp
@@ -25,7 +25,7 @@ class cFinishLookupCallbacks:
virtual void OnError(int a_ErrorCode) override
{
LOGD("Error %d while performing lookup!", a_ErrorCode);
- abort();
+ exit(a_ErrorCode);
}
virtual void OnFinished(void) override
@@ -49,15 +49,28 @@ int main()
{
cEvent evtFinish;
+ // Look up google.com (has multiple IP addresses):
LOGD("Network test: Looking up google.com");
if (!cNetwork::HostnameToIP("google.com", std::make_shared<cFinishLookupCallbacks>(evtFinish)))
{
- LOGWARNING("Cannot resolve google.com");
+ LOGWARNING("Cannot resolve google.com to IP");
abort();
}
LOGD("Name lookup has been successfully queued");
-
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");
return 0;
}