|
|
@ -3,6 +3,18 @@ |
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H |
|
|
|
|
|
|
|
#include "bitcoin-config.h" |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_INET_PTON |
|
|
|
|
|
|
|
#include <arpa/inet.h> |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_GETADDRINFO_A |
|
|
|
|
|
|
|
#include <netdb.h> |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#include "netbase.h" |
|
|
|
#include "netbase.h" |
|
|
|
|
|
|
|
|
|
|
|
#include "hash.h" |
|
|
|
#include "hash.h" |
|
|
@ -71,9 +83,30 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_GETADDRINFO_A |
|
|
|
|
|
|
|
struct in_addr ipv4_addr; |
|
|
|
|
|
|
|
#ifdef HAVE_INET_PTON |
|
|
|
|
|
|
|
if (inet_pton(AF_INET, pszName, &ipv4_addr) > 0) { |
|
|
|
|
|
|
|
vIP.push_back(CNetAddr(ipv4_addr)); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct in6_addr ipv6_addr; |
|
|
|
|
|
|
|
if (inet_pton(AF_INET6, pszName, &ipv6_addr) > 0) { |
|
|
|
|
|
|
|
vIP.push_back(CNetAddr(ipv6_addr)); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
ipv4_addr.s_addr = inet_addr(pszName); |
|
|
|
|
|
|
|
if (ipv4_addr.s_addr != INADDR_NONE) { |
|
|
|
|
|
|
|
vIP.push_back(CNetAddr(ipv4_addr)); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
struct addrinfo aiHint; |
|
|
|
struct addrinfo aiHint; |
|
|
|
memset(&aiHint, 0, sizeof(struct addrinfo)); |
|
|
|
memset(&aiHint, 0, sizeof(struct addrinfo)); |
|
|
|
|
|
|
|
|
|
|
|
aiHint.ai_socktype = SOCK_STREAM; |
|
|
|
aiHint.ai_socktype = SOCK_STREAM; |
|
|
|
aiHint.ai_protocol = IPPROTO_TCP; |
|
|
|
aiHint.ai_protocol = IPPROTO_TCP; |
|
|
|
aiHint.ai_family = AF_UNSPEC; |
|
|
|
aiHint.ai_family = AF_UNSPEC; |
|
|
@ -82,8 +115,33 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign |
|
|
|
#else |
|
|
|
#else |
|
|
|
aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; |
|
|
|
aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
struct addrinfo *aiRes = NULL; |
|
|
|
struct addrinfo *aiRes = NULL; |
|
|
|
|
|
|
|
#ifdef HAVE_GETADDRINFO_A |
|
|
|
|
|
|
|
struct gaicb gcb, *query = &gcb; |
|
|
|
|
|
|
|
memset(query, 0, sizeof(struct gaicb)); |
|
|
|
|
|
|
|
gcb.ar_name = pszName; |
|
|
|
|
|
|
|
gcb.ar_request = &aiHint; |
|
|
|
|
|
|
|
int nErr = getaddrinfo_a(GAI_NOWAIT, &query, 1, NULL); |
|
|
|
|
|
|
|
if (nErr) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
|
|
|
// Should set the timeout limit to a resonable value to avoid
|
|
|
|
|
|
|
|
// generating unnecessary checking call during the polling loop,
|
|
|
|
|
|
|
|
// while it can still response to stop request quick enough.
|
|
|
|
|
|
|
|
// 2 seconds looks fine in our situation.
|
|
|
|
|
|
|
|
struct timespec ts = { 2, 0 }; |
|
|
|
|
|
|
|
gai_suspend(&query, 1, &ts); |
|
|
|
|
|
|
|
boost::this_thread::interruption_point(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nErr = gai_error(query); |
|
|
|
|
|
|
|
if (0 == nErr) |
|
|
|
|
|
|
|
aiRes = query->ar_result; |
|
|
|
|
|
|
|
} while (nErr == EAI_INPROGRESS); |
|
|
|
|
|
|
|
#else |
|
|
|
int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); |
|
|
|
int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); |
|
|
|
|
|
|
|
#endif |
|
|
|
if (nErr) |
|
|
|
if (nErr) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|