diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-07-04 08:38:25 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-07-04 08:40:01 +0200 |
commit | e81e2e8f7cdee307227f150a6a2408c01fcafbf2 (patch) | |
tree | d181908dfdf893362b7cd5eae164f65b2fa05d57 /src | |
parent | 81efcd76e644d52e2296fd95c594ab49b7b3fca5 (diff) | |
parent | caf6150e9785da408f1e603ae70eae25b5202d98 (diff) |
Merge pull request #4421
caf6150 Use async name resolving to improve net thread responsiveness (Huang Le)
Diffstat (limited to 'src')
-rw-r--r-- | src/netbase.cpp | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/netbase.cpp b/src/netbase.cpp index 3c50174e75..f47b0f3563 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -3,6 +3,18 @@ // Distributed under the MIT/X11 software license, see the accompanying // 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 "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; memset(&aiHint, 0, sizeof(struct addrinfo)); - aiHint.ai_socktype = SOCK_STREAM; aiHint.ai_protocol = IPPROTO_TCP; aiHint.ai_family = AF_UNSPEC; @@ -82,8 +115,33 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign #else aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; #endif + 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); +#endif if (nErr) return false; |