From 9560e6381d01cb219b9efc02b56e5b48bcdc9872 Mon Sep 17 00:00:00 2001 From: Jim Wang Date: Tue, 26 Feb 2019 18:01:08 +0800 Subject: [PATCH 1/3] Fixed this issue that cann't set namesrv with hostname --- src/transport/TcpTransport.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/transport/TcpTransport.cpp b/src/transport/TcpTransport.cpp index 2c148e7c0..d25cee515 100644 --- a/src/transport/TcpTransport.cpp +++ b/src/transport/TcpTransport.cpp @@ -65,6 +65,22 @@ tcpConnectStatus TcpTransport::connect(const string &strServerURL, memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr(hostName.c_str()); + + if (sin.sin_addr.s_addr == INADDR_NONE) { + struct hostent *host = gethostbyname(hostName.c_str()); + if (!host) { + string info = "Get IP address error: " + hostName; + THROW_MQEXCEPTION(MQClientException, info, -1); + } + + for (int i = 0; host->h_addr_list[i]; i++) { + sin.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*)host->h_addr_list[i])); + if (sin.sin_addr.s_addr != INADDR_NONE) { + break; + } + } + } + sin.sin_port = htons(portNumber); m_eventBase = event_base_new(); From 5cf9843f4f783e351da95e151590aa3fdf6b2481 Mon Sep 17 00:00:00 2001 From: Jim Wang Date: Tue, 26 Feb 2019 21:14:48 +0800 Subject: [PATCH 2/3] Use evutil_getaddrinfo resolve domain name --- src/transport/TcpTransport.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/transport/TcpTransport.cpp b/src/transport/TcpTransport.cpp index d25cee515..0a54967ba 100644 --- a/src/transport/TcpTransport.cpp +++ b/src/transport/TcpTransport.cpp @@ -67,16 +67,35 @@ tcpConnectStatus TcpTransport::connect(const string &strServerURL, sin.sin_addr.s_addr = inet_addr(hostName.c_str()); if (sin.sin_addr.s_addr == INADDR_NONE) { - struct hostent *host = gethostbyname(hostName.c_str()); - if (!host) { - string info = "Get IP address error: " + hostName; + struct evutil_addrinfo hints; + struct evutil_addrinfo *answer = NULL; + /* Build the hints to tell getaddrinfo how to act. */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ + /* Look up the hostname. */ + int err = evutil_getaddrinfo(hostName.c_str(), NULL, &hints, &answer); + if (err != 0) { + string info = "Error while resolving " + hostName + ":" + evutil_gai_strerror(err); THROW_MQEXCEPTION(MQClientException, info, -1); } - for (int i = 0; host->h_addr_list[i]; i++) { - sin.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*)host->h_addr_list[i])); - if (sin.sin_addr.s_addr != INADDR_NONE) { - break; + struct evutil_addrinfo *ai; + for (ai = answer; ai; ai = ai->ai_next){ + char buf[128]; + const char *s = NULL; + if (ai->ai_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in*)ai->ai_addr; + s = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, 128); + } + else if (ai->ai_family == AF_INET6){ + struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; + s = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 128); + } + if (s){ + sin.sin_addr.s_addr = inet_addr(s); + if (sin.sin_addr.s_addr != INADDR_NONE) { + break; + } } } } From cc0d7c19c8205a6764d7b14e289cbf6785366a96 Mon Sep 17 00:00:00 2001 From: Jim Wang Date: Thu, 28 Feb 2019 13:24:16 +0800 Subject: [PATCH 3/3] Extract getInetAddr to deal domain name and IP --- src/transport/TcpTransport.cpp | 78 +++++++++++++++++++--------------- src/transport/TcpTransport.h | 1 + 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/transport/TcpTransport.cpp b/src/transport/TcpTransport.cpp index 0a54967ba..bbebc372c 100644 --- a/src/transport/TcpTransport.cpp +++ b/src/transport/TcpTransport.cpp @@ -64,41 +64,7 @@ tcpConnectStatus TcpTransport::connect(const string &strServerURL, struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; - sin.sin_addr.s_addr = inet_addr(hostName.c_str()); - - if (sin.sin_addr.s_addr == INADDR_NONE) { - struct evutil_addrinfo hints; - struct evutil_addrinfo *answer = NULL; - /* Build the hints to tell getaddrinfo how to act. */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ - /* Look up the hostname. */ - int err = evutil_getaddrinfo(hostName.c_str(), NULL, &hints, &answer); - if (err != 0) { - string info = "Error while resolving " + hostName + ":" + evutil_gai_strerror(err); - THROW_MQEXCEPTION(MQClientException, info, -1); - } - - struct evutil_addrinfo *ai; - for (ai = answer; ai; ai = ai->ai_next){ - char buf[128]; - const char *s = NULL; - if (ai->ai_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in*)ai->ai_addr; - s = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, 128); - } - else if (ai->ai_family == AF_INET6){ - struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; - s = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 128); - } - if (s){ - sin.sin_addr.s_addr = inet_addr(s); - if (sin.sin_addr.s_addr != INADDR_NONE) { - break; - } - } - } - } + sin.sin_addr.s_addr = getInetAddr(hostName); sin.sin_port = htons(portNumber); @@ -164,6 +130,48 @@ void TcpTransport::setTcpConnectEvent(tcpConnectStatus connectStatus) { } } +u_long TcpTransport::getInetAddr(string &hostname) +{ + u_long addr = inet_addr(hostname.c_str()); + + if (INADDR_NONE == addr) { + constexpr size_t length = 128; + struct evutil_addrinfo hints; + struct evutil_addrinfo *answer = NULL; + /* Build the hints to tell getaddrinfo how to act. */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ + //Look up the hostname. + int err = evutil_getaddrinfo(hostname.c_str(), NULL, &hints, &answer); + if (err != 0) { + string info = "Failed to resolve host name(" + hostname + "): " + evutil_gai_strerror(err); + THROW_MQEXCEPTION(MQClientException, info, -1); + } + + struct evutil_addrinfo *addressInfo; + for (addressInfo = answer; addressInfo; addressInfo = addressInfo->ai_next) { + char buf[length]; + const char *address = NULL; + if (addressInfo->ai_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in*)addressInfo->ai_addr; + address = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, length); + } + else if (addressInfo->ai_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)addressInfo->ai_addr; + address = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, length); + } + if (address) { + addr = inet_addr(address); + if (addr != INADDR_NONE) { + break; + } + } + } + } + + return addr; +} + void TcpTransport::disconnect(const string &addr) { boost::lock_guard lock(m_socketLock); if (getTcpConnectStatus() != e_connectInit) { diff --git a/src/transport/TcpTransport.h b/src/transport/TcpTransport.h index 544e14a76..fa4da85b4 100755 --- a/src/transport/TcpTransport.h +++ b/src/transport/TcpTransport.h @@ -68,6 +68,7 @@ class TcpTransport { void freeBufferEvent(); void exitBaseDispatch(); void setTcpConnectEvent(tcpConnectStatus connectStatus); + u_long getInetAddr(std::string &hostname); private: uint64_t m_startTime;