This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git
The following commit(s) were added to refs/heads/master by this push:
new f022c81d0 feat: use getaddrinfo() instead of gethostbyname() (#1869)
f022c81d0 is described below
commit f022c81d0ca7171f8613fccfc9b57b568654ed9f
Author: Guohao Li <[email protected]>
AuthorDate: Tue Jan 30 16:12:58 2024 +0800
feat: use getaddrinfo() instead of gethostbyname() (#1869)
---
src/runtime/rpc/rpc_address.cpp | 52 +++++++++++++++++++++++++++------------
src/runtime/rpc/rpc_address.h | 7 ++++++
src/runtime/rpc/rpc_host_port.cpp | 34 ++-----------------------
src/utils/test/lock.std.cpp | 2 +-
4 files changed, 46 insertions(+), 49 deletions(-)
diff --git a/src/runtime/rpc/rpc_address.cpp b/src/runtime/rpc/rpc_address.cpp
index 1eb8b8c44..75173bbfb 100644
--- a/src/runtime/rpc/rpc_address.cpp
+++ b/src/runtime/rpc/rpc_address.cpp
@@ -27,44 +27,64 @@
#include "runtime/rpc/rpc_address.h"
#include <arpa/inet.h>
+#include <errno.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
+#include "absl/strings/string_view.h"
#include "runtime/rpc/group_address.h"
+#include "utils/error_code.h"
#include "utils/fixed_size_buffer_pool.h"
#include "utils/fmt_logging.h"
#include "utils/ports.h"
+#include "utils/safe_strerror_posix.h"
#include "utils/string_conv.h"
-#include "absl/strings/string_view.h"
#include "utils/strings.h"
namespace dsn {
+/*static*/
+error_s rpc_address::GetAddrInfo(const std::string &hostname, const addrinfo
&hints, AddrInfo *info)
+{
+ addrinfo *res = nullptr;
+ const int rc = getaddrinfo(hostname.c_str(), nullptr, &hints, &res);
+ const int err = errno; // preserving the errno from the getaddrinfo() call
+ AddrInfo result(res, ::freeaddrinfo);
+ if (dsn_unlikely(rc != 0)) {
+ if (rc == EAI_SYSTEM) {
+ const auto &err_msg = utils::safe_strerror(err);
+ LOG_ERROR("getaddrinfo failed, name = {}, err = {}", hostname,
err_msg);
+ return error_s::make(ERR_NETWORK_FAILURE, err_msg);
+ }
+ LOG_ERROR("getaddrinfo failed, name = {}, err = {}", hostname,
gai_strerror(rc));
+ return error_s::make(ERR_NETWORK_FAILURE, gai_strerror(rc));
+ }
+
+ if (info != nullptr) {
+ info->swap(result);
+ }
+ return error_s::ok();
+}
const rpc_address rpc_address::s_invalid_address;
/*static*/
uint32_t rpc_address::ipv4_from_host(const char *name)
{
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
-
- addr.sin_family = AF_INET;
- if ((addr.sin_addr.s_addr = inet_addr(name)) == (unsigned int)(-1)) {
- // TODO(yingchun): use getaddrinfo instead
- hostent *hp = ::gethostbyname(name);
- if (dsn_unlikely(hp == nullptr)) {
- LOG_ERROR("gethostbyname failed, name = {}, err = {}", name,
hstrerror(h_errno));
- return 0;
- }
-
- memcpy((void *)&(addr.sin_addr.s_addr), (const void *)hp->h_addr,
(size_t)hp->h_length);
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ AddrInfo result;
+ if (dsn_unlikely(!GetAddrInfo(name, hints, &result).is_ok())) {
+ return 0;
}
-
+ CHECK_EQ(result.get()->ai_family, AF_INET);
+ auto *ipv4 = reinterpret_cast<struct sockaddr_in *>(result.get()->ai_addr);
// converts from network byte order to host byte order
- return (uint32_t)ntohl(addr.sin_addr.s_addr);
+ return ntohl(ipv4->sin_addr.s_addr);
}
/*static*/
diff --git a/src/runtime/rpc/rpc_address.h b/src/runtime/rpc/rpc_address.h
index e5afd7270..a2d002a5d 100644
--- a/src/runtime/rpc/rpc_address.h
+++ b/src/runtime/rpc/rpc_address.h
@@ -31,12 +31,16 @@
#include <cstdint>
// IWYU pragma: no_include <experimental/string_view>
#include <functional>
+#include <memory>
#include <sstream>
#include <string>
#include <string_view>
+#include "utils/errors.h"
#include "utils/fmt_utils.h"
+struct addrinfo;
+
namespace apache {
namespace thrift {
namespace protocol {
@@ -54,6 +58,8 @@ USER_DEFINED_ENUM_FORMATTER(dsn_host_type_t)
namespace dsn {
+using AddrInfo = std::unique_ptr<addrinfo, std::function<void(addrinfo *)>>;
+
class rpc_group_address;
class rpc_address
@@ -64,6 +70,7 @@ public:
static bool is_site_local_address(uint32_t ip_net);
static uint32_t ipv4_from_host(const char *hostname);
static uint32_t ipv4_from_network_interface(const char *network_interface);
+ static error_s GetAddrInfo(const std::string &hostname, const addrinfo
&hints, AddrInfo *info);
~rpc_address();
diff --git a/src/runtime/rpc/rpc_host_port.cpp
b/src/runtime/rpc/rpc_host_port.cpp
index 8be334fd2..359cf5a3b 100644
--- a/src/runtime/rpc/rpc_host_port.cpp
+++ b/src/runtime/rpc/rpc_host_port.cpp
@@ -17,7 +17,6 @@
* under the License.
*/
-#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
@@ -31,7 +30,6 @@
#include "runtime/rpc/rpc_host_port.h"
#include "utils/error_code.h"
#include "utils/ports.h"
-#include "utils/safe_strerror_posix.h"
#include "utils/string_conv.h"
#include "utils/utils.h"
@@ -39,30 +37,6 @@ namespace dsn {
const host_port host_port::s_invalid_host_port;
-namespace {
-
-using AddrInfo = std::unique_ptr<addrinfo, std::function<void(addrinfo *)>>;
-
-error_s GetAddrInfo(const std::string &hostname, const addrinfo &hints,
AddrInfo *info)
-{
- addrinfo *res = nullptr;
- const int rc = getaddrinfo(hostname.c_str(), nullptr, &hints, &res);
- const int err = errno; // preserving the errno from the getaddrinfo() call
- AddrInfo result(res, ::freeaddrinfo);
- if (rc != 0) {
- if (rc == EAI_SYSTEM) {
- return error_s::make(ERR_NETWORK_FAILURE,
utils::safe_strerror(err));
- }
- return error_s::make(ERR_NETWORK_FAILURE, gai_strerror(rc));
- }
-
- if (info != nullptr) {
- info->swap(result);
- }
- return error_s::ok();
-}
-}
-
host_port::host_port(std::string host, uint16_t port)
: _host(std::move(host)), _port(port), _type(HOST_TYPE_IPV4)
{
@@ -100,11 +74,7 @@ bool host_port::from_string(const std::string &s)
return false;
}
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- if (dsn_unlikely(!GetAddrInfo(_host, hints, nullptr))) {
+ if (dsn_unlikely(rpc_address::ipv4_from_host(_host.c_str()) == 0)) {
return false;
}
@@ -197,7 +167,7 @@ error_s
host_port::resolve_addresses(std::vector<rpc_address> &addresses) const
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
AddrInfo result;
- RETURN_NOT_OK(GetAddrInfo(_host, hints, &result));
+ RETURN_NOT_OK(rpc_address::GetAddrInfo(_host, hints, &result));
// DNS may return the same host multiple times. We want to return only the
unique
// addresses, but in the same order as DNS returned them. To do so, we
keep track
diff --git a/src/utils/test/lock.std.cpp b/src/utils/test/lock.std.cpp
index 18aef80bd..6f54a1299 100644
--- a/src/utils/test/lock.std.cpp
+++ b/src/utils/test/lock.std.cpp
@@ -28,7 +28,7 @@
#include <thread>
#include "gtest/gtest.h"
-#include "runtime/rpc/rpc_address.h"
+#include "utils/enum_helper.h"
#include "utils/lockp.std.h"
using namespace dsn;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]