Browse Source

Merge pull request #4421

caf6150 Use async name resolving to improve net thread responsiveness (Huang Le)
0.10
Wladimir J. van der Laan 11 years ago
parent
commit
e81e2e8f7c
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 2
      configure.ac
  2. 60
      src/netbase.cpp

2
configure.ac

@ -370,6 +370,8 @@ if test x$TARGET_OS = xdarwin; then
fi fi
AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h]) AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h])
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,, AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
[#if HAVE_ENDIAN_H [#if HAVE_ENDIAN_H

60
src/netbase.cpp

@ -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;

Loading…
Cancel
Save