mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-11-20 06:28:06 +00:00
From b453f10d65dd1ff1df0dd3747adf63f4e1fd7d30 Mon Sep 17 00:00:00 2001
From: Alexander Chemeris <Alexander.Chemeris@gmail.com> Date: Sun, 16 Dec 2012 17:44:10 +0400 Subject: [PATCH] Use gethostbyname2_r() instead of gethostbyname() if available. gethostbyname() is not thread-safe. It's recommended to use gethostbyname_r() or gethostbyname2_r() instead. --- CommonLibs/Sockets.cpp | 44 +++++++++++++++++++++++++++++++++----------- configure.ac | 4 ++++ 2 files changed, 37 insertions(+), 11 deletions(-) git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@4637 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@@ -40,9 +41,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
//mutex for protecting non-thread safe gethostbyname
|
|
||||||
static Mutex sgGethostbynameLock;
|
|
||||||
|
|
||||||
bool resolveAddress(struct sockaddr_in *address, const char *hostAndPort)
|
bool resolveAddress(struct sockaddr_in *address, const char *hostAndPort)
|
||||||
{
|
{
|
||||||
assert(address);
|
assert(address);
|
||||||
@@ -62,16 +60,41 @@ bool resolveAddress(struct sockaddr_in *address, const char *host, unsigned shor
|
|||||||
{
|
{
|
||||||
assert(address);
|
assert(address);
|
||||||
assert(host);
|
assert(host);
|
||||||
//gethostbyname not thread safe
|
|
||||||
ScopedLock lock(sgGethostbynameLock);
|
|
||||||
// FIXME -- Need to ignore leading/trailing spaces in hostname.
|
// FIXME -- Need to ignore leading/trailing spaces in hostname.
|
||||||
struct hostent *hp = gethostbyname(host);
|
struct hostent *hp;
|
||||||
if (hp==NULL) {
|
int h_errno_local;
|
||||||
CERR("WARNING -- gethostbyname() failed for " << host << ", " << hstrerror(h_errno));
|
#ifdef HAVE_GETHOSTBYNAME2_R
|
||||||
|
struct hostent hostData;
|
||||||
|
char tmpBuffer[2048];
|
||||||
|
|
||||||
|
// There are different flavors of gethostbyname_r(), but
|
||||||
|
// latest Linux use the following form:
|
||||||
|
if (gethostbyname2_r(host, AF_INET, &hostData, tmpBuffer, sizeof(tmpBuffer), &hp, &h_errno_local)!=0) {
|
||||||
|
CERR("WARNING -- gethostbyname2_r() failed for " << host << ", " << hstrerror(h_errno_local));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
address->sin_family = AF_INET;
|
#else
|
||||||
bcopy(hp->h_addr, &(address->sin_addr), hp->h_length);
|
static Mutex sGethostbynameMutex;
|
||||||
|
// gethostbyname() is NOT thread-safe, so we should use a mutex here.
|
||||||
|
// Ideally it should be a global mutex for all non thread-safe socket
|
||||||
|
// operations and it should protect access to variables such as
|
||||||
|
// global h_errno.
|
||||||
|
sGethostbynameMutex.lock();
|
||||||
|
hp = gethostbyname(host);
|
||||||
|
h_errno_local = h_errno;
|
||||||
|
sGethostbynameMutex.unlock();
|
||||||
|
#endif
|
||||||
|
if (hp==NULL) {
|
||||||
|
CERR("WARNING -- gethostbyname() failed for " << host << ", " << hstrerror(h_errno_local));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (hp->h_addrtype != AF_INET) {
|
||||||
|
CERR("WARNING -- gethostbyname() resolved " << host << " to something other then AF_INET");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
address->sin_family = hp->h_addrtype;
|
||||||
|
assert(sizeof(address->sin_addr) == hp->h_length);
|
||||||
|
memcpy(&(address->sin_addr), hp->h_addr_list[0], hp->h_length);
|
||||||
address->sin_port = htons(port);
|
address->sin_port = htons(port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -80,7 +103,7 @@ bool resolveAddress(struct sockaddr_in *address, const char *host, unsigned shor
|
|||||||
|
|
||||||
DatagramSocket::DatagramSocket()
|
DatagramSocket::DatagramSocket()
|
||||||
{
|
{
|
||||||
bzero(mDestination,sizeof(mDestination));
|
memset(mDestination, 0, sizeof(mDestination));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,10 @@ PKG_CHECK_MODULES(LIBUSB, libusb-1.0)
|
|||||||
# Prepends -lreadline to LIBS and defines HAVE_LIBREADLINE in config.h
|
# Prepends -lreadline to LIBS and defines HAVE_LIBREADLINE in config.h
|
||||||
AC_CHECK_LIB(readline, readline)
|
AC_CHECK_LIB(readline, readline)
|
||||||
|
|
||||||
|
# Check for glibc-specific network functions
|
||||||
|
AC_CHECK_FUNC(gethostbyname_r, [AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1, Define if libc implements gethostbyname_r)])
|
||||||
|
AC_CHECK_FUNC(gethostbyname2_r, [AC_DEFINE(HAVE_GETHOSTBYNAME2_R, 1, Define if libc implements gethostbyname2_r)])
|
||||||
|
|
||||||
dnl Output files
|
dnl Output files
|
||||||
AC_CONFIG_FILES([\
|
AC_CONFIG_FILES([\
|
||||||
Makefile \
|
Makefile \
|
||||||
|
|||||||
Reference in New Issue
Block a user