Skip to content

Commit a786286

Browse files
monadbobodutor
authored andcommitted
Modify the toHostAddr interface to support host resolved (gethostbyname). (#935)
* Issue #931 the "meta_server_addrs" in the configuration support the host name. Modify the toHostAddr interface to support host resolved (gethostbyname). * replace the gethostbyname with getaddrinfo. * Refactoring part of the code.
1 parent 6669a45 commit a786286

File tree

4 files changed

+103
-41
lines changed

4 files changed

+103
-41
lines changed

src/common/network/NetworkUtils.cpp

+66-21
Original file line numberDiff line numberDiff line change
@@ -267,28 +267,51 @@ std::string NetworkUtils::intToIPv4(IPv4 ip) {
267267
return buf;
268268
}
269269

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());
274281
}
275-
return std::make_pair(ipV4, port);
276-
}
277282

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);
282298
}
283299

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());
289304
}
290305

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);
292315
}
293316

294317
StatusOr<std::vector<HostAddr>> NetworkUtils::toHosts(const std::string& peersStr) {
@@ -297,11 +320,34 @@ StatusOr<std::vector<HostAddr>> NetworkUtils::toHosts(const std::string& peersSt
297320
folly::split(",", peersStr, peers, true);
298321
hosts.reserve(peers.size());
299322
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());
303327
}
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();
305351
}
306352
return hosts;
307353
}
@@ -346,4 +392,3 @@ StatusOr<std::string> NetworkUtils::getLocalIP(std::string defaultIP) {
346392

347393
} // namespace network
348394
} // namespace nebula
349-

src/common/network/NetworkUtils.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@ class NetworkUtils final {
3737
// So don't use it in production code.
3838
static uint16_t getAvailablePort();
3939

40-
// Convert the given IP (must be in the form of "xx.xx.xx.xx") and Port to a HostAddr
41-
static StatusOr<HostAddr> toHostAddr(folly::StringPiece ip, int32_t port);
42-
// Convert the given IP/Port (must be in the form of "xx.xx.xx.xx:pp") to a HostAddr
43-
static StatusOr<HostAddr> toHostAddr(folly::StringPiece ipPort);
40+
static StatusOr<std::vector<HostAddr>> resolveHost(const std::string &host, int32_t port);
41+
// Convert the given IP/HOST and Port to a HostAddr
42+
static StatusOr<HostAddr> toHostAddr(const std::string &ip, int32_t port);
4443
// Retrieve the string-form IP from the given HostAddr
4544
static std::string ipFromHostAddr(const HostAddr& host);
4645
// Retrieve the port number from the given HostAddr
@@ -72,4 +71,3 @@ class NetworkUtils final {
7271
} // namespace nebula
7372

7473
#endif // COMMON_NETWORK_NETWORKUTILS_H_
75-

src/common/network/test/NetworkUtilsTest.cpp

+33-14
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,42 @@ TEST(NetworkUtils, getAvailablePort) {
8787
ASSERT_GT(port, 0);
8888
}
8989

90+
TEST(NetworkUtils, toHostAddr) {
91+
auto s = NetworkUtils::resolveHost("localhost", 1200);
92+
ASSERT_TRUE(s.ok());
93+
auto addr = s.value();
94+
IPv4 ip;
95+
ASSERT_TRUE(NetworkUtils::ipv4ToInt("127.0.0.1", ip));
96+
ASSERT_EQ(addr[0].first, ip);
97+
ASSERT_EQ(addr[0].second, 1200);
98+
99+
auto s2 = NetworkUtils::toHostAddr("8.8.8.8", 1300);
100+
ASSERT_TRUE(s2.ok());
101+
auto addr2 = s2.value();
102+
103+
ASSERT_TRUE(NetworkUtils::ipv4ToInt("8.8.8.8", ip));
104+
ASSERT_EQ(addr2.first, ip);
105+
ASSERT_EQ(addr2.second, 1300);
106+
107+
s2 = NetworkUtils::toHostAddr("a.b.c.d:a23", 1200);
108+
ASSERT_FALSE(s2.ok());
109+
}
90110

91111
TEST(NetworkUtils, toHosts) {
92-
std::string hostsString = "192.168.1.1:10001, 192.168.1.2:10002, 192.168.1.3:10003";
93-
auto addresRet = NetworkUtils::toHosts(hostsString);
94-
ASSERT_TRUE(addresRet.ok());
95-
std::vector<HostAddr> hosts = std::move(addresRet.value());
96-
EXPECT_EQ(3, hosts.size());
112+
auto s = NetworkUtils::toHosts("localhost:1200, 127.0.0.1:1200");
113+
ASSERT_TRUE(s.ok());
114+
auto addr = s.value();
115+
97116
IPv4 ip;
98-
NetworkUtils::ipv4ToInt("192.168.1.1", ip);
99-
int32_t count = 0;
100-
for (auto& host : hosts) {
101-
EXPECT_EQ(ip + count, host.first);
102-
EXPECT_EQ(10001 + count, host.second);
103-
count++;
104-
}
105-
EXPECT_STREQ(hostsString.c_str(), NetworkUtils::toHosts(hosts).c_str());
117+
ASSERT_TRUE(NetworkUtils::ipv4ToInt("127.0.0.1", ip));
118+
ASSERT_EQ(addr[0].first, ip);
119+
ASSERT_EQ(addr[0].second, 1200);
120+
121+
ASSERT_EQ(addr[1].first, ip);
122+
ASSERT_EQ(addr[1].second, 1200);
123+
124+
s = NetworkUtils::toHosts("1.1.2.3:123, a.b.c.d:a23");
125+
ASSERT_FALSE(s.ok());
106126
}
107127

108128
} // namespace network
@@ -116,4 +136,3 @@ int main(int argc, char** argv) {
116136

117137
return RUN_ALL_TESTS();
118138
}
119-

src/daemons/MetaDaemon.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ int main(int argc, char *argv[]) {
214214
return EXIT_FAILURE;
215215
}
216216

217-
auto kvstore = initKV(peersRet.value(), hostAddrRet.value());
217+
auto kvstore = initKV(peersRet.value(), localhost);
218218
if (kvstore == nullptr) {
219219
LOG(ERROR) << "Init kv failed!";
220220
return EXIT_FAILURE;

0 commit comments

Comments
 (0)