diff --git a/src/common/network/NetworkUtils.cpp b/src/common/network/NetworkUtils.cpp index 10209047905..e82aa481ad4 100644 --- a/src/common/network/NetworkUtils.cpp +++ b/src/common/network/NetworkUtils.cpp @@ -306,5 +306,32 @@ std::string NetworkUtils::toHostsStr(const std::vector& hosts) { return hostsString; } +Status NetworkUtils::validateHostOrIp(const std::string& hostOrIp) { + if (hostOrIp.empty()) { + return Status::Error("local_ip is empty, need to config it through config file."); + } + const std::regex ipv4( + "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}" + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"); + if (std::regex_match(hostOrIp, ipv4)) { + const std::regex loopbackOrAny( + "^127(?:\\.[0-9]+){0,2}\\.[0-9]+$|^(?:0*\\:)*?:?0*1$|(0\\.){3}0"); + if (std::regex_match(hostOrIp, loopbackOrAny)) { + return Status::OK(); + } + auto ipsStatus = listIPv4s(); + NG_RETURN_IF_ERROR(ipsStatus); + const auto& ips = ipsStatus.value(); + auto result = std::find(ips.begin(), ips.end(), hostOrIp); + if (result == ips.end()) { + return Status::Error("%s is not a valid ip in current host, candidates: %s", + hostOrIp.c_str(), + folly::join(",", ips).c_str()); + } + } else { + NG_RETURN_IF_ERROR(resolveHost(hostOrIp, 0)); + } + return Status::OK(); +} } // namespace network } // namespace nebula diff --git a/src/common/network/NetworkUtils.h b/src/common/network/NetworkUtils.h index 72236215d17..9d97a52fe48 100644 --- a/src/common/network/NetworkUtils.h +++ b/src/common/network/NetworkUtils.h @@ -51,6 +51,8 @@ class NetworkUtils final { static StatusOr> toHosts(const std::string& peersStr); static std::string toHostsStr(const std::vector& hosts); + static Status validateHostOrIp(const std::string& HostOrIp); + private: }; diff --git a/src/common/network/test/NetworkUtilsTest.cpp b/src/common/network/test/NetworkUtilsTest.cpp index dd80de363fe..8e227055b03 100644 --- a/src/common/network/test/NetworkUtilsTest.cpp +++ b/src/common/network/test/NetworkUtilsTest.cpp @@ -86,6 +86,40 @@ TEST(NetworkUtils, toHosts) { ASSERT_FALSE(s.ok()); } +TEST(NetworkUtils, ValidateHostOrIp) { + std::string hostOrIp = "127.0.0.1"; + auto result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_TRUE(result.ok()); + + hostOrIp = "127.0.1.1"; + result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_TRUE(result.ok()); + + hostOrIp = "0.0.0.0"; + result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_TRUE(result.ok()); + + hostOrIp = "000.000.000.000"; + result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_FALSE(result.ok()); + + hostOrIp = "0.0.0.0.0"; + result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_FALSE(result.ok()); + + hostOrIp = "127.0.0.0.1"; + result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_FALSE(result.ok()); + + hostOrIp = "localhost"; + result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_TRUE(result.ok()); + + hostOrIp = "NonvalidHostName"; + result = NetworkUtils::validateHostOrIp(hostOrIp); + EXPECT_FALSE(result.ok()); +} + } // namespace network } // namespace nebula diff --git a/src/daemons/GraphDaemon.cpp b/src/daemons/GraphDaemon.cpp index 34f5850292a..2efa800ee73 100644 --- a/src/daemons/GraphDaemon.cpp +++ b/src/daemons/GraphDaemon.cpp @@ -106,12 +106,12 @@ int main(int argc, char *argv[]) { } } - // Get the IPv4 address the server will listen on - if (FLAGS_local_ip.empty()) { - LOG(ERROR) << "local_ip is empty, need to config it through config file"; + // Validate the IPv4 address or hostname + status = NetworkUtils::validateHostOrIp(FLAGS_local_ip); + if (!status.ok()) { + LOG(ERROR) << status; return EXIT_FAILURE; } - // TODO: Check the ip is valid nebula::HostAddr localhost{FLAGS_local_ip, FLAGS_port}; // Initialize the global timezone, it's only used for datetime type compute diff --git a/src/daemons/MetaDaemon.cpp b/src/daemons/MetaDaemon.cpp index 83bdb2e9643..0174859311d 100644 --- a/src/daemons/MetaDaemon.cpp +++ b/src/daemons/MetaDaemon.cpp @@ -36,6 +36,7 @@ using nebula::operator<<; using nebula::ProcessUtils; using nebula::Status; using nebula::StatusOr; +using nebula::network::NetworkUtils; using nebula::web::PathParams; DEFINE_string(local_ip, "", "Local ip specified for NetworkUtils::getLocalIP"); @@ -247,10 +248,19 @@ int main(int argc, char* argv[]) { } } - auto hostIdentity = - FLAGS_local_ip == "" ? nebula::network::NetworkUtils::getHostname() : FLAGS_local_ip; - nebula::HostAddr localhost{hostIdentity, FLAGS_port}; - LOG(INFO) << "identify myself as " << localhost; + std::string hostName; + if (FLAGS_local_ip.empty()) { + hostName = nebula::network::NetworkUtils::getHostname(); + } else { + status = NetworkUtils::validateHostOrIp(FLAGS_local_ip); + if (!status.ok()) { + LOG(ERROR) << status; + return EXIT_FAILURE; + } + hostName = FLAGS_local_ip; + } + nebula::HostAddr localhost{hostName, FLAGS_port}; + LOG(INFO) << "localhost = " << localhost; auto peersRet = nebula::network::NetworkUtils::toHosts(FLAGS_meta_server_addrs); if (!peersRet.ok()) { LOG(ERROR) << "Can't get peers address, status:" << peersRet.status(); diff --git a/src/daemons/StorageDaemon.cpp b/src/daemons/StorageDaemon.cpp index 58603620e1a..f1bbf752cd6 100644 --- a/src/daemons/StorageDaemon.cpp +++ b/src/daemons/StorageDaemon.cpp @@ -111,10 +111,19 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - auto hostName = - FLAGS_local_ip != "" ? FLAGS_local_ip : nebula::network::NetworkUtils::getHostname(); - HostAddr host(hostName, FLAGS_port); - LOG(INFO) << "host = " << host; + std::string hostName; + if (FLAGS_local_ip.empty()) { + hostName = nebula::network::NetworkUtils::getHostname(); + } else { + status = NetworkUtils::validateHostOrIp(FLAGS_local_ip); + if (!status.ok()) { + LOG(ERROR) << status; + return EXIT_FAILURE; + } + hostName = FLAGS_local_ip; + } + nebula::HostAddr localhost{hostName, FLAGS_port}; + LOG(INFO) << "localhost = " << localhost; auto metaAddrsRet = nebula::network::NetworkUtils::toHosts(FLAGS_meta_server_addrs); if (!metaAddrsRet.ok() || metaAddrsRet.value().empty()) { LOG(ERROR) << "Can't get metaServer address, status:" << metaAddrsRet.status() @@ -148,7 +157,7 @@ int main(int argc, char *argv[]) { } gStorageServer = std::make_unique( - host, metaAddrsRet.value(), paths, FLAGS_wal_path, FLAGS_listener_path); + localhost, metaAddrsRet.value(), paths, FLAGS_wal_path, FLAGS_listener_path); if (!gStorageServer->start()) { LOG(ERROR) << "Storage server start failed"; gStorageServer->stop();