@@ -267,28 +267,51 @@ std::string NetworkUtils::intToIPv4(IPv4 ip) {
267
267
return buf;
268
268
}
269
269
270
- StatusOr<HostAddr> NetworkUtils::toHostAddr (folly::StringPiece ip, int32_t port) {
271
- IPv4 ipV4;
272
- if (!ipv4ToInt (ip.toString (), ipV4)) {
273
- return Status::Error (" Bad ip format:%s" , ip.start ());
270
+ StatusOr<std::vector<HostAddr>> NetworkUtils::resolveHost (const std::string& host, int32_t port) {
271
+ std::vector<HostAddr> addrs;
272
+ struct addrinfo hints, *res, *rp;
273
+ ::memset (&hints, 0 , sizeof (struct addrinfo ));
274
+
275
+ hints.ai_family = AF_UNSPEC;
276
+ hints.ai_socktype = SOCK_STREAM;
277
+ hints.ai_flags = AI_ADDRCONFIG;
278
+
279
+ if (getaddrinfo (host.c_str (), nullptr , &hints, &res) != 0 ) {
280
+ return Status::Error (" host not found:%s" , host.c_str ());
274
281
}
275
- return std::make_pair (ipV4, port);
276
- }
277
282
278
- StatusOr<HostAddr> NetworkUtils::toHostAddr (folly::StringPiece ipPort) {
279
- auto pos = ipPort.find (' :' );
280
- if (pos == folly::StringPiece::npos) {
281
- return Status::Error (" Bad peer format: %s" , ipPort.start ());
283
+ for (rp = res; rp != nullptr ; rp = rp->ai_next ) {
284
+ switch (rp->ai_family ) {
285
+ case AF_INET:
286
+ break ;
287
+ case AF_INET6:
288
+ VLOG (1 ) << " Currently does not support Ipv6 address" ;
289
+ continue ;
290
+ default :
291
+ continue ;
292
+ }
293
+
294
+ auto address = ((struct sockaddr_in *)rp->ai_addr )->sin_addr .s_addr ;
295
+ // We need to match the integer byte order generated by ipv4ToInt, so we need to convert
296
+ // here.
297
+ addrs.emplace_back (htonl (std::move (address)), port);
282
298
}
283
299
284
- int32_t port;
285
- try {
286
- port = folly::to<int32_t >(ipPort.subpiece (pos + 1 ));
287
- } catch (const std::exception & ex) {
288
- return Status::Error (" Bad port number, error: %s" , ex.what ());
300
+ freeaddrinfo (res);
301
+
302
+ if (addrs.empty ()) {
303
+ return Status::Error (" host not found: %s" , host.c_str ());
289
304
}
290
305
291
- return toHostAddr (ipPort.subpiece (0 , pos), port);
306
+ return addrs;
307
+ }
308
+
309
+ StatusOr<HostAddr> NetworkUtils::toHostAddr (const std::string &ip, int32_t port) {
310
+ IPv4 ipV4;
311
+ if (!ipv4ToInt (ip, ipV4)) {
312
+ return Status::Error (" Bad ip format:%s" , ip.c_str ());
313
+ }
314
+ return std::make_pair (ipV4, port);
292
315
}
293
316
294
317
StatusOr<std::vector<HostAddr>> NetworkUtils::toHosts (const std::string& peersStr) {
@@ -297,11 +320,34 @@ StatusOr<std::vector<HostAddr>> NetworkUtils::toHosts(const std::string& peersSt
297
320
folly::split (" ," , peersStr, peers, true );
298
321
hosts.reserve (peers.size ());
299
322
for (auto & peerStr : peers) {
300
- auto hostAddr = network::NetworkUtils::toHostAddr (folly::trimWhitespace (peerStr));
301
- if (!hostAddr.ok ()) {
302
- return hostAddr.status ();
323
+ auto ipPort = folly::trimWhitespace (peerStr);
324
+ auto pos = ipPort.find (' :' );
325
+ if (pos == folly::StringPiece::npos) {
326
+ return Status::Error (" Bad peer format: %s" , ipPort.start ());
303
327
}
304
- hosts.emplace_back (hostAddr.value ());
328
+
329
+ int32_t port;
330
+ try {
331
+ port = folly::to<int32_t >(ipPort.subpiece (pos + 1 ));
332
+ } catch (const std::exception & ex) {
333
+ return Status::Error (" Bad port number, error: %s" , ex.what ());
334
+ }
335
+
336
+ auto ipAddr = ipPort.subpiece (0 , pos).toString ();
337
+ auto hostAddr = toHostAddr (ipAddr, port);
338
+ if (hostAddr.ok ()) {
339
+ hosts.emplace_back (hostAddr.value ());
340
+ continue ;
341
+ }
342
+
343
+ auto resolveAddr = resolveHost (ipAddr, port);
344
+ if (resolveAddr.ok ()) {
345
+ hosts.insert (hosts.end (), std::make_move_iterator (resolveAddr.value ().begin ()),
346
+ std::make_move_iterator (resolveAddr.value ().end ()));
347
+ continue ;
348
+ }
349
+
350
+ return resolveAddr.status ();
305
351
}
306
352
return hosts;
307
353
}
@@ -346,4 +392,3 @@ StatusOr<std::string> NetworkUtils::getLocalIP(std::string defaultIP) {
346
392
347
393
} // namespace network
348
394
} // namespace nebula
349
-
0 commit comments