From 3cbad24f0ee3639ac2ce2d06d61e97386df6f94b Mon Sep 17 00:00:00 2001 From: Roland Levillain Date: Mon, 25 Jan 2016 19:17:14 +0000 Subject: [PATCH] Improve gethostbyname_r use in art::JDWP::JdwpSocketState::Establish. Try a range of values for the work buffer size, instead of using a fixed size. Also, turn a couple of constants defined as macros into constexprs. Change-Id: I2354bfb51935bb0cad775c13d6cae06902b4a934 --- runtime/jdwp/jdwp_socket.cc | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/runtime/jdwp/jdwp_socket.cc b/runtime/jdwp/jdwp_socket.cc index 1bc58ac4e..8d59cc1d1 100644 --- a/runtime/jdwp/jdwp_socket.cc +++ b/runtime/jdwp/jdwp_socket.cc @@ -30,13 +30,29 @@ #include "base/stringprintf.h" #include "jdwp/jdwp_priv.h" -#define kBasePort 8000 -#define kMaxPort 8040 - namespace art { namespace JDWP { +static constexpr uint16_t kBasePort = 8000; +static constexpr uint16_t kMaxPort = 8040; + +// Initial size of the work buffer used in gethostbyname_r. +// +// The call to gethostbyname_r below requires a user-allocated buffer, +// the size of which depends on the system. The initial implementation +// used to use a 128-byte buffer, but that was not enough on some +// systems (maybe because of IPv6), causing failures in JDWP host +// testing; thus it was increased to 256. +// +// However, we should not use a fixed size: gethostbyname_r's +// documentation states that if the work buffer is too small (i.e. if +// gethostbyname_r returns `ERANGE`), then the function should be +// called again with a bigger buffer. Which we do now, starting with +// an initial 256-byte buffer, and doubling it until gethostbyname_r +// accepts this size. +static constexpr size_t kInitialAuxBufSize = 256; + /* * JDWP network state. * @@ -276,15 +292,16 @@ bool JdwpSocketState::Establish(const JdwpOptions* options) { */ #if defined(__linux__) hostent he; - // The size of the work buffer used in the gethostbyname_r call - // below. It used to be 128, but this was not enough on some - // configurations (maybe because of IPv6?), causing failures in JDWP - // host testing; thus it was increased to 256. - static constexpr size_t kAuxBufSize = 256; - char auxBuf[kAuxBufSize]; + std::vector auxBuf(kInitialAuxBufSize); int error; - int cc = gethostbyname_r(options->host.c_str(), &he, auxBuf, sizeof(auxBuf), &pEntry, &error); - if (cc != 0) { + int cc; + while ((cc = gethostbyname_r( + options->host.c_str(), &he, auxBuf.data(), auxBuf.size(), &pEntry, &error)) + == ERANGE) { + // The work buffer `auxBuf` is too small; enlarge it. + auxBuf.resize(auxBuf.size() * 2); + } + if (cc != 0 || pEntry == nullptr) { LOG(WARNING) << "gethostbyname_r('" << options->host << "') failed: " << hstrerror(error); return false; } -- 2.11.0