3
3
// Distributed under the MIT/X11 software license, see the accompanying
4
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
5
6
+ #ifdef HAVE_CONFIG_H
7
+ #include " bitcoin-config.h"
8
+ #endif
9
+
10
+ #ifdef HAVE_INET_PTON
11
+ #include < arpa/inet.h>
12
+ #endif
13
+
14
+ #ifdef HAVE_GETADDRINFO_A
15
+ #include < netdb.h>
16
+ #endif
17
+
6
18
#include " netbase.h"
7
19
8
20
#include " hash.h"
@@ -71,9 +83,30 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
71
83
}
72
84
}
73
85
86
+ #ifdef HAVE_GETADDRINFO_A
87
+ struct in_addr ipv4_addr;
88
+ #ifdef HAVE_INET_PTON
89
+ if (inet_pton (AF_INET, pszName, &ipv4_addr) > 0 ) {
90
+ vIP.push_back (CNetAddr (ipv4_addr));
91
+ return true ;
92
+ }
93
+
94
+ struct in6_addr ipv6_addr;
95
+ if (inet_pton (AF_INET6, pszName, &ipv6_addr) > 0 ) {
96
+ vIP.push_back (CNetAddr (ipv6_addr));
97
+ return true ;
98
+ }
99
+ #else
100
+ ipv4_addr.s_addr = inet_addr (pszName);
101
+ if (ipv4_addr.s_addr != INADDR_NONE) {
102
+ vIP.push_back (CNetAddr (ipv4_addr));
103
+ return true ;
104
+ }
105
+ #endif
106
+ #endif
107
+
74
108
struct addrinfo aiHint;
75
109
memset (&aiHint, 0 , sizeof (struct addrinfo ));
76
-
77
110
aiHint.ai_socktype = SOCK_STREAM;
78
111
aiHint.ai_protocol = IPPROTO_TCP;
79
112
aiHint.ai_family = AF_UNSPEC;
@@ -82,8 +115,33 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
82
115
#else
83
116
aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
84
117
#endif
118
+
85
119
struct addrinfo *aiRes = NULL ;
120
+ #ifdef HAVE_GETADDRINFO_A
121
+ struct gaicb gcb, *query = &gcb;
122
+ memset (query, 0 , sizeof (struct gaicb ));
123
+ gcb.ar_name = pszName;
124
+ gcb.ar_request = &aiHint;
125
+ int nErr = getaddrinfo_a (GAI_NOWAIT, &query, 1 , NULL );
126
+ if (nErr)
127
+ return false ;
128
+
129
+ do {
130
+ // Should set the timeout limit to a resonable value to avoid
131
+ // generating unnecessary checking call during the polling loop,
132
+ // while it can still response to stop request quick enough.
133
+ // 2 seconds looks fine in our situation.
134
+ struct timespec ts = { 2 , 0 };
135
+ gai_suspend (&query, 1 , &ts);
136
+ boost::this_thread::interruption_point ();
137
+
138
+ nErr = gai_error (query);
139
+ if (0 == nErr)
140
+ aiRes = query->ar_result ;
141
+ } while (nErr == EAI_INPROGRESS);
142
+ #else
86
143
int nErr = getaddrinfo (pszName, NULL , &aiHint, &aiRes);
144
+ #endif
87
145
if (nErr)
88
146
return false ;
89
147
0 commit comments