You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by al...@apache.org on 2017/07/07 17:25:28 UTC
kudu git commit: [net_util] fix reporting getaddrinfo() error
Repository: kudu
Updated Branches:
refs/heads/master 2fc07eb81 -> a3773b42c
[net_util] fix reporting getaddrinfo() error
An example of error output:
on Linux, prior to this fix:
Network error: Unable to lookup FQDN: Success (error 0)
on Linux, after this fix:
Network error: unable to look up canonical hostname for \
localhost 'mega.turbo': Name or service not known
Change-Id: I2d5ba87b9ea050724367610461bae22c9471a103
Reviewed-on: http://gerrit.cloudera.org:8080/7368
Tested-by: Alexey Serbin <as...@cloudera.com>
Reviewed-by: Dan Burkert <da...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/a3773b42
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/a3773b42
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/a3773b42
Branch: refs/heads/master
Commit: a3773b42c41d3208dcc8fb26f4d9ff106e3e8cfe
Parents: 2fc07eb
Author: Alexey Serbin <as...@cloudera.com>
Authored: Thu Jul 6 15:48:19 2017 -0700
Committer: Alexey Serbin <as...@cloudera.com>
Committed: Fri Jul 7 17:23:03 2017 +0000
----------------------------------------------------------------------
src/kudu/util/net/net_util.cc | 75 ++++++++++++++++++++++----------------
1 file changed, 44 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kudu/blob/a3773b42/src/kudu/util/net/net_util.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/net/net_util.cc b/src/kudu/util/net/net_util.cc
index aca1ae2..dbd1285 100644
--- a/src/kudu/util/net/net_util.cc
+++ b/src/kudu/util/net/net_util.cc
@@ -22,14 +22,16 @@
#include <sys/socket.h>
#include <algorithm>
-#include <boost/functional/hash.hpp>
-#include <gflags/gflags.h>
+#include <functional>
+#include <memory>
#include <unordered_set>
#include <utility>
#include <vector>
+#include <boost/functional/hash.hpp>
+#include <gflags/gflags.h>
+
#include "kudu/gutil/endian.h"
-#include "kudu/gutil/gscoped_ptr.h"
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/strings/join.h"
#include "kudu/gutil/strings/numbers.h"
@@ -56,20 +58,43 @@
DEFINE_bool(fail_dns_resolution, false, "Whether to fail all dns resolution, for tests.");
TAG_FLAG(fail_dns_resolution, hidden);
+using std::function;
using std::unordered_set;
+using std::unique_ptr;
using std::vector;
using strings::Substitute;
namespace kudu {
namespace {
-struct AddrinfoDeleter {
- void operator()(struct addrinfo* info) {
- freeaddrinfo(info);
+
+using AddrInfo = unique_ptr<addrinfo, function<void(addrinfo*)>>;
+
+// An utility wrapper around getaddrinfo() call to convert the return code
+// of the libc library function into Status.
+Status GetAddrInfo(const string& hostname,
+ const addrinfo& hints,
+ const string& op_description,
+ 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 (info != nullptr) {
+ info->swap(result);
+ }
+ return Status::OK();
+ }
+ const string err_msg = Substitute("unable to $0", op_description);
+ if (rc == EAI_SYSTEM) {
+ return Status::NetworkError(err_msg, ErrnoToString(err), err);
}
-};
+ return Status::NetworkError(err_msg, gai_strerror(rc));
}
+} // anonymous namespace
+
HostPort::HostPort()
: host_(""),
port_(0) {
@@ -123,21 +148,14 @@ Status HostPort::ResolveAddresses(vector<Sockaddr>* addresses) const {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
- struct addrinfo* res = nullptr;
- int rc;
- LOG_SLOW_EXECUTION(WARNING, 200,
- Substitute("resolving address for $0", host_)) {
- rc = getaddrinfo(host_.c_str(), nullptr, &hints, &res);
+ AddrInfo result;
+ const string op_description = Substitute("resolve address for $0", host_);
+ LOG_SLOW_EXECUTION(WARNING, 200, op_description) {
+ RETURN_NOT_OK(GetAddrInfo(host_, hints, op_description, &result));
}
- if (rc != 0) {
- return Status::NetworkError(
- StringPrintf("Unable to resolve address '%s'", host_.c_str()),
- gai_strerror(rc));
- }
- gscoped_ptr<addrinfo, AddrinfoDeleter> scoped_res(res);
- for (; res != nullptr; res = res->ai_next) {
- CHECK_EQ(res->ai_family, AF_INET);
- struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(res->ai_addr);
+ for (const addrinfo* ai = result.get(); ai != nullptr; ai = ai->ai_next) {
+ CHECK_EQ(ai->ai_family, AF_INET);
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(ai->ai_addr);
addr->sin_port = htons(port_);
Sockaddr sockaddr(*addr);
if (addresses) {
@@ -300,20 +318,15 @@ Status GetFQDN(string* hostname) {
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_CANONNAME;
-
- struct addrinfo* result;
- LOG_SLOW_EXECUTION(WARNING, 200,
- Substitute("looking up canonical hostname for localhost "
- "(eventual result was $0)", *hostname)) {
+ AddrInfo result;
+ const string op_description =
+ Substitute("look up canonical hostname for localhost '$0'", *hostname);
+ LOG_SLOW_EXECUTION(WARNING, 200, op_description) {
TRACE_EVENT0("net", "getaddrinfo");
- int rc = getaddrinfo(hostname->c_str(), nullptr, &hints, &result);
- if (rc != 0) {
- return Status::NetworkError("Unable to lookup FQDN", ErrnoToString(errno), errno);
- }
+ RETURN_NOT_OK(GetAddrInfo(*hostname, hints, op_description, &result));
}
*hostname = result->ai_canonname;
- freeaddrinfo(result);
return Status::OK();
}