Cuberite
A lightweight, fast and extensible game server for Minecraft
HostnameLookup.cpp
Go to the documentation of this file.
1 
2 // HostnameLookup.cpp
3 
4 // Implements the cHostnameLookup class representing an in-progress hostname-to-IP lookup
5 
6 #include "Globals.h"
7 #include "HostnameLookup.h"
8 #include "NetworkSingleton.h"
9 #include "GetAddressInfoError.h"
10 
11 
12 
13 
14 
16 // cHostnameLookup:
17 
19  m_Callbacks(std::move(a_Callbacks)),
20  m_Hostname(a_Hostname)
21 {
22 }
23 
24 
25 
26 
27 
29 {
30  // Cannot use std::make_shared here, constructor is not accessible
31  cHostnameLookupPtr Lookup{ new cHostnameLookup(a_Hostname, std::move(a_Callbacks)) };
32 
33  // Note the Lookup object is owned solely by this lambda which is destroyed after it runs
35  {
36  // Start the lookup:
37  addrinfo hints;
38  memset(&hints, 0, sizeof(hints));
39  hints.ai_protocol = IPPROTO_TCP;
40  hints.ai_socktype = SOCK_STREAM;
41  hints.ai_family = AF_UNSPEC;
42  hints.ai_flags = AI_CANONNAME;
43 
44  addrinfo * Result;
45  int ErrCode = getaddrinfo(Lookup->m_Hostname.c_str(), nullptr, &hints, &Result);
46 
47  Lookup->Callback(ErrCode, Result);
48  });
49 }
50 
51 
52 
53 
54 
55 void cHostnameLookup::Callback(int a_ErrCode, addrinfo * a_Addr)
56 {
57  // If an error has occurred, notify the error callback:
58  if (a_ErrCode != 0)
59  {
60  m_Callbacks->OnError(a_ErrCode, ErrorString(a_ErrCode));
61  return;
62  }
63 
64  // Call the success handler for each entry received:
65  bool HasResolved = false;
66  addrinfo * OrigAddr = a_Addr;
67  for (;a_Addr != nullptr; a_Addr = a_Addr->ai_next)
68  {
69  char IP[128];
70  switch (a_Addr->ai_family)
71  {
72  case AF_INET: // IPv4
73  {
74  sockaddr_in * sin = reinterpret_cast<sockaddr_in *>(a_Addr->ai_addr);
75  if (!m_Callbacks->OnNameResolvedV4(m_Hostname, sin))
76  {
77  // Callback indicated that the IP shouldn't be serialized to a string, just continue with the next address:
78  HasResolved = true;
79  continue;
80  }
81  evutil_inet_ntop(AF_INET, &(sin->sin_addr), IP, sizeof(IP));
82  break;
83  }
84  case AF_INET6: // IPv6
85  {
86  sockaddr_in6 * sin = reinterpret_cast<sockaddr_in6 *>(a_Addr->ai_addr);
87  if (!m_Callbacks->OnNameResolvedV6(m_Hostname, sin))
88  {
89  // Callback indicated that the IP shouldn't be serialized to a string, just continue with the next address:
90  HasResolved = true;
91  continue;
92  }
93  evutil_inet_ntop(AF_INET6, &(sin->sin6_addr), IP, sizeof(IP));
94  break;
95  }
96  default:
97  {
98  // Unknown address family, handle as if this entry wasn't received
99  continue; // for (a_Addr)
100  }
101  }
102  m_Callbacks->OnNameResolved(m_Hostname, IP);
103  HasResolved = true;
104  } // for (a_Addr)
105 
106  // If only unsupported families were reported, call the Error handler:
107  if (!HasResolved)
108  {
109  m_Callbacks->OnError(EAI_NONAME, ErrorString(EAI_NONAME));
110  }
111  else
112  {
113  m_Callbacks->OnFinished();
114  }
115  freeaddrinfo(OrigAddr);
116 }
117 
118 
119 
120 
121 
123 // cNetwork API:
124 
126  const AString & a_Hostname,
128 )
129 {
130  cHostnameLookup::Lookup(a_Hostname, std::move(a_Callbacks));
131  return true;
132 }
133 
134 
135 
136 
AString ErrorString(int a_ErrorCode)
Returns the readable form of a getaddressinfo type error code.
std::shared_ptr< cHostnameLookup > cHostnameLookupPtr
std::string AString
Definition: StringUtils.h:11
Definition: FastNBT.h:132
cHostnameLookup(const AString &a_Hostname, cNetwork::cResolveNameCallbacksPtr a_Callbacks)
Creates the lookup object.
static void Lookup(const AString &a_Hostname, cNetwork::cResolveNameCallbacksPtr a_Callbacks)
Creates a lookup object and schedules the lookup.
AString m_Hostname
The hostname that was queried (needed for the callbacks).
cNetwork::cResolveNameCallbacksPtr m_Callbacks
The callbacks to call for resolved names / errors.
void Callback(int a_ErrCode, struct addrinfo *a_Addr)
static bool HostnameToIP(const AString &a_Hostname, cResolveNameCallbacksPtr a_Callbacks)
Queues a DNS query to resolve the specified hostname to IP address.
std::shared_ptr< cResolveNameCallbacks > cResolveNameCallbacksPtr
Definition: Network.h:309
void ScheduleLookup(std::function< void()> a_Lookup)
Schedule a lookup task for execution.
static cNetworkSingleton & Get(void)
Returns the singleton instance of this class.
cNetworkLookup & GetLookupThread()
Returns the thread used to perform hostname and IP lookups.