From 57cbb3d0196b5dafc4dee1ecd1a7d0c3afe861a6 Mon Sep 17 00:00:00 2001 From: Jack Bates Date: Fri, 13 Jan 2017 14:17:48 -0700 Subject: [PATCH] Replace gethostbyname_r() and gethostbyaddr_r() Fixes #1312 --- build/network.m4 | 69 ---------------------------- cmd/traffic_layout/traffic_layout.cc | 1 - configure.ac | 1 - iocore/cluster/ClusterMachine.cc | 33 +++++++------ lib/ts/ink_config.h.in | 1 - lib/ts/ink_inet.cc | 53 --------------------- lib/ts/ink_inet.h | 39 ---------------- 7 files changed, 20 insertions(+), 177 deletions(-) diff --git a/build/network.m4 b/build/network.m4 index a71390e7652..78dae1c207b 100644 --- a/build/network.m4 +++ b/build/network.m4 @@ -18,75 +18,6 @@ dnl ----------------------------------------------------------------- dnl network.m4: Trafficserver's autoconf macros for testing network support dnl -dnl -dnl Checks the definition of gethostbyname_r and gethostbyaddr_r -dnl which are different for glibc, solaris and assorted other operating -dnl systems -dnl -dnl Note that this test is executed too early to see if we have all of -dnl the headers. -AC_DEFUN([TS_CHECK_GETHOSTBYNAME_R_STYLE], [ - -dnl Try and compile a glibc2 gethostbyname_r piece of code, and set the -dnl style of the routines to glibc2 on success -AC_CACHE_CHECK([style of gethostbyname_r routine], ac_cv_gethostbyname_r_style, -TS_TRY_COMPILE_NO_WARNING([ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -],[ -int tmp = gethostbyname_r((const char *) 0, (struct hostent *) 0, - (char *) 0, 0, (struct hostent **) 0, &tmp); -/* use tmp to suppress the warning */ -tmp=0; -], ac_cv_gethostbyname_r_style=glibc2, ac_cv_gethostbyname_r_style=none)) - -if test "$ac_cv_gethostbyname_r_style" = "glibc2"; then - gethostbyname_r_glibc2=1 - AC_DEFINE(GETHOSTBYNAME_R_GLIBC2, 1, [Define if gethostbyname_r has the glibc style]) -else - gethostbyname_r_glibc2=0 -fi - -AC_CACHE_CHECK([3rd argument to the gethostbyname_r routines], ac_cv_gethostbyname_r_arg, -TS_TRY_COMPILE_NO_WARNING([ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -],[ -int tmp = gethostbyname_r((const char *) 0, (struct hostent *) 0, - (struct hostent_data *) 0); -/* use tmp to suppress the warning */ -tmp=0; -], ac_cv_gethostbyname_r_arg=hostent_data, ac_cv_gethostbyname_r_arg=char)) - -AC_SUBST(gethostbyname_r_glibc2) -]) - dnl dnl TS_CHECK_LOOPBACK_IFACE: try to figure out default loopback interface dnl diff --git a/cmd/traffic_layout/traffic_layout.cc b/cmd/traffic_layout/traffic_layout.cc index f10fc17b924..463e079050b 100644 --- a/cmd/traffic_layout/traffic_layout.cc +++ b/cmd/traffic_layout/traffic_layout.cc @@ -103,7 +103,6 @@ produce_features(bool json) print_feature("TS_USE_LINUX_NATIVE_AIO", TS_USE_LINUX_NATIVE_AIO, json); print_feature("TS_HAS_SO_PEERCRED", TS_HAS_SO_PEERCRED, json); print_feature("TS_USE_REMOTE_UNWINDING", TS_USE_REMOTE_UNWINDING, json); - print_feature("GETHOSTBYNAME_R_GLIBC2", GETHOSTBYNAME_R_GLIBC2, json); print_feature("SIZEOF_VOID_POINTER", SIZEOF_VOID_POINTER, json); print_feature("TS_IP_TRANSPARENT", TS_IP_TRANSPARENT, json); print_feature("TS_HAS_128BIT_CAS", TS_HAS_128BIT_CAS, json); diff --git a/configure.ac b/configure.ac index e7b29edb5ce..0bb4bcf0287 100644 --- a/configure.ac +++ b/configure.ac @@ -1811,7 +1811,6 @@ AC_SUBST(has_ip_tos) AC_SUBST(has_so_peercred) TS_CHECK_LOOPBACK_IFACE -TS_CHECK_GETHOSTBYNAME_R_STYLE TS_CHECK_MACRO_IN6_IS_ADDR_UNSPECIFIED AC_CHECK_TYPE([struct tcp_info], diff --git a/iocore/cluster/ClusterMachine.cc b/iocore/cluster/ClusterMachine.cc index f809b25b78e..c1b3de5ccad 100644 --- a/iocore/cluster/ClusterMachine.cc +++ b/iocore/cluster/ClusterMachine.cc @@ -104,20 +104,24 @@ ClusterMachine::ClusterMachine(char *ahostname, unsigned int aip, int aport) Debug("cluster_note", "[Machine::Machine] Cluster IP addr: %s", clusterIP); ip = inet_addr(clusterIP); } else { - ink_gethostbyname_r_data data; - struct hostent *r = ink_gethostbyname_r(ahostname, &data); - if (!r) { - Warning("unable to DNS %s: %d", ahostname, data.herrno); + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + struct addrinfo *result, *rp; + int err = getaddrinfo(ahostname, nullptr, &hints, &result); + if (err != 0) { + Warning("unable to DNS %s: %s", ahostname, gai_strerror(err)); ip = 0; } else { // lowest IP address ip = (unsigned int)-1; // 0xFFFFFFFF - for (int i = 0; r->h_addr_list[i]; i++) - if (ip > *(unsigned int *)r->h_addr_list[i]) - ip = *(unsigned int *)r->h_addr_list[i]; + for (rp = result; rp != nullptr; rp = rp->ai_next) + if (ip > reinterpret_cast(rp->ai_addr)->sin_addr.s_addr) + ip = reinterpret_cast(rp->ai_addr)->sin_addr.s_addr; if (ip == (unsigned int)-1) ip = 0; + freeaddrinfo(result); } // ip = htonl(ip); for the alpha! } @@ -125,15 +129,18 @@ ClusterMachine::ClusterMachine(char *ahostname, unsigned int aip, int aport) } else { ip = aip; - ink_gethostbyaddr_r_data data; - struct hostent *r = ink_gethostbyaddr_r((char *)&ip, sizeof(int), AF_INET, &data); - - if (r == nullptr) { + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_addr.s_addr = ip; + char hbuf[NI_MAXHOST]; + int err = getnameinfo(reinterpret_cast(&addr), sizeof(addr), hbuf, sizeof(hbuf), nullptr, 0, 0); + if (err != 0) { Alias32 x; memcpy(&x.u32, &ip, sizeof(x.u32)); - Debug("machine_debug", "unable to reverse DNS %u.%u.%u.%u: %d", x.byte[0], x.byte[1], x.byte[2], x.byte[3], data.herrno); + Debug("machine_debug", "unable to reverse DNS %u.%u.%u.%u: %s", x.byte[0], x.byte[1], x.byte[2], x.byte[3], + gai_strerror(err)); } else - hostname = ats_strdup(r->h_name); + hostname = ats_strdup(hbuf); } if (hostname) hostname_len = strlen(hostname); diff --git a/lib/ts/ink_config.h.in b/lib/ts/ink_config.h.in index 9e93687c683..45cfbcc48fc 100644 --- a/lib/ts/ink_config.h.in +++ b/lib/ts/ink_config.h.in @@ -84,7 +84,6 @@ #define TS_HAS_SO_PEERCRED @has_so_peercred@ /* OS API definitions */ -#define GETHOSTBYNAME_R_GLIBC2 @gethostbyname_r_glibc2@ #define SIZEOF_VOID_POINTER @ac_cv_sizeof_voidp@ #define TS_IP_TRANSPARENT @ip_transparent@ #define TS_HAS_128BIT_CAS @has_128bit_cas@ diff --git a/lib/ts/ink_inet.cc b/lib/ts/ink_inet.cc index b5791b3ad64..2e67e2e5f03 100644 --- a/lib/ts/ink_inet.cc +++ b/lib/ts/ink_inet.cc @@ -30,61 +30,8 @@ #include "ts/TestBox.h" #include "ts/TextBuffer.h" -#if defined(darwin) -extern "C" { -struct hostent *gethostbyname_r(const char *name, struct hostent *result, char *buffer, int buflen, int *h_errnop); -struct hostent *gethostbyaddr_r(const char *name, size_t size, int type, struct hostent *result, char *buffer, int buflen, - int *h_errnop); -} -#endif - IpAddr const IpAddr::INVALID; -struct hostent * -ink_gethostbyname_r(char *hostname, ink_gethostbyname_r_data *data) -{ -#ifdef RENTRENT_GETHOSTBYNAME - struct hostent *r = gethostbyname(hostname); - if (r) - data->ent = *r; - data->herrno = errno; - -#else // RENTRENT_GETHOSTBYNAME -#if GETHOSTBYNAME_R_GLIBC2 - - struct hostent *addrp = nullptr; - int res = gethostbyname_r(hostname, &data->ent, data->buf, INK_GETHOSTBYNAME_R_DATA_SIZE, &addrp, &data->herrno); - struct hostent *r = nullptr; - if (!res && addrp) - r = addrp; - -#else - struct hostent *r = gethostbyname_r(hostname, &data->ent, data->buf, INK_GETHOSTBYNAME_R_DATA_SIZE, &data->herrno); -#endif -#endif - return r; -} - -struct hostent * -ink_gethostbyaddr_r(char *ip, int len, int type, ink_gethostbyaddr_r_data *data) -{ -#if GETHOSTBYNAME_R_GLIBC2 - struct hostent *r = nullptr; - struct hostent *addrp = nullptr; - int res = gethostbyaddr_r((char *)ip, len, type, &data->ent, data->buf, INK_GETHOSTBYNAME_R_DATA_SIZE, &addrp, &data->herrno); - if (!res && addrp) - r = addrp; -#else -#ifdef RENTRENT_GETHOSTBYADDR - struct hostent *r = gethostbyaddr((const void *)ip, len, type); - -#else - struct hostent *r = gethostbyaddr_r((char *)ip, len, type, &data->ent, data->buf, INK_GETHOSTBYNAME_R_DATA_SIZE, &data->herrno); -#endif -#endif // LINUX - return r; -} - uint32_t ink_inet_addr(const char *s) { diff --git a/lib/ts/ink_inet.h b/lib/ts/ink_inet.h index 7264e50136f..ce1b1327ab9 100644 --- a/lib/ts/ink_inet.h +++ b/lib/ts/ink_inet.h @@ -32,9 +32,6 @@ #include "ts/ink_apidefs.h" #include "ts/TsBuffer.h" -#define INK_GETHOSTBYNAME_R_DATA_SIZE 1024 -#define INK_GETHOSTBYADDR_R_DATA_SIZE 1024 - #if !TS_HAS_IN6_IS_ADDR_UNSPECIFIED #if defined(IN6_IS_ADDR_UNSPECIFIED) #undef IN6_IS_ADDR_UNSPECIFIED @@ -112,42 +109,6 @@ union IpEndpoint { operator sockaddr const *() const { return &sa; } }; -struct ink_gethostbyname_r_data { - int herrno; - struct hostent ent; - char buf[INK_GETHOSTBYNAME_R_DATA_SIZE]; -}; - -struct ink_gethostbyaddr_r_data { - int herrno; - struct hostent ent; - char buf[INK_GETHOSTBYADDR_R_DATA_SIZE]; -}; - -/** - Wrapper for gethostbyname_r(). If successful, returns a pointer - to the hostent structure. Returns nullptr and sets data->herrno to - the appropriate error code on failure. - - @param hostname null-terminated host name string - @param data pointer to ink_gethostbyname_r_data allocated by the caller - -*/ -struct hostent *ink_gethostbyname_r(char *hostname, ink_gethostbyname_r_data *data); - -/** - Wrapper for gethostbyaddr_r(). If successful, returns a pointer - to the hostent structure. Returns nullptr and sets data->herrno to - the appropriate error code on failure. - - @param ip IP address of the host - @param len length of the buffer indicated by ip - @param type family of the address - @param data pointer to ink_gethostbyname_r_data allocated by the caller - -*/ -struct hostent *ink_gethostbyaddr_r(char *ip, int len, int type, ink_gethostbyaddr_r_data *data); - /** Return the detected maximum listen(2) backlog for TCP. */ int ats_tcp_somaxconn();