Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

From b453f10 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
  • Loading branch information...
commit 9b5179627264e1c2494325bbc4b575a7836c0cf4 1 parent 762fb3b
kurtis.heimerl authored

Showing 2 changed files with 38 additions and 11 deletions. Show diff stats Hide diff stats

  1. +34 11 CommonLibs/Sockets.cpp
  2. +4 0 configure.ac
45 CommonLibs/Sockets.cpp
@@ -25,6 +25,7 @@
25 25
26 26
27 27
  28 +#include <config.h>
28 29 #include <unistd.h>
29 30 #include <fcntl.h>
30 31 #include <cstdio>
@@ -40,9 +41,6 @@
40 41 #include <stdlib.h>
41 42
42 43
43   -//mutex for protecting non-thread safe gethostbyname
44   -static Mutex sgGethostbynameLock;
45   -
46 44 bool resolveAddress(struct sockaddr_in *address, const char *hostAndPort)
47 45 {
48 46 assert(address);
@@ -62,16 +60,41 @@ bool resolveAddress(struct sockaddr_in *address, const char *host, unsigned shor
62 60 {
63 61 assert(address);
64 62 assert(host);
65   - //gethostbyname not thread safe
66   - ScopedLock lock(sgGethostbynameLock);
67 63 // FIXME -- Need to ignore leading/trailing spaces in hostname.
68   - struct hostent *hp = gethostbyname(host);
69   - if (hp==NULL) {
70   - CERR("WARNING -- gethostbyname() failed for " << host << ", " << hstrerror(h_errno));
  64 + struct hostent *hp;
  65 + int h_errno_local;
  66 +#ifdef HAVE_GETHOSTBYNAME2_R
  67 + struct hostent hostData;
  68 + char tmpBuffer[2048];
  69 +
  70 + // There are different flavors of gethostbyname_r(), but
  71 + // latest Linux use the following form:
  72 + if (gethostbyname2_r(host, AF_INET, &hostData, tmpBuffer, sizeof(tmpBuffer), &hp, &h_errno_local)!=0) {
  73 + CERR("WARNING -- gethostbyname2_r() failed for " << host << ", " << hstrerror(h_errno_local));
  74 + return false;
  75 + }
  76 +#else
  77 + static Mutex sGethostbynameMutex;
  78 + // gethostbyname() is NOT thread-safe, so we should use a mutex here.
  79 + // Ideally it should be a global mutex for all non thread-safe socket
  80 + // operations and it should protect access to variables such as
  81 + // global h_errno.
  82 + sGethostbynameMutex.lock();
  83 + hp = gethostbyname(host);
  84 + h_errno_local = h_errno;
  85 + sGethostbynameMutex.unlock();
  86 +#endif
  87 + if (hp==NULL) {
  88 + CERR("WARNING -- gethostbyname() failed for " << host << ", " << hstrerror(h_errno_local));
71 89 return false;
72 90 }
73   - address->sin_family = AF_INET;
74   - bcopy(hp->h_addr, &(address->sin_addr), hp->h_length);
  91 + if (hp->h_addrtype != AF_INET) {
  92 + CERR("WARNING -- gethostbyname() resolved " << host << " to something other then AF_INET");
  93 + return false;
  94 + }
  95 + address->sin_family = hp->h_addrtype;
  96 + assert(sizeof(address->sin_addr) == hp->h_length);
  97 + memcpy(&(address->sin_addr), hp->h_addr_list[0], hp->h_length);
75 98 address->sin_port = htons(port);
76 99 return true;
77 100 }
@@ -80,7 +103,7 @@ bool resolveAddress(struct sockaddr_in *address, const char *host, unsigned shor
80 103
81 104 DatagramSocket::DatagramSocket()
82 105 {
83   - bzero(mDestination,sizeof(mDestination));
  106 + memset(mDestination, 0, sizeof(mDestination));
84 107 }
85 108
86 109
4 configure.ac
@@ -130,6 +130,10 @@ PKG_CHECK_MODULES(LIBUSB, libusb-1.0)
130 130 # Prepends -lreadline to LIBS and defines HAVE_LIBREADLINE in config.h
131 131 AC_CHECK_LIB(readline, readline)
132 132
  133 +# Check for glibc-specific network functions
  134 +AC_CHECK_FUNC(gethostbyname_r, [AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1, Define if libc implements gethostbyname_r)])
  135 +AC_CHECK_FUNC(gethostbyname2_r, [AC_DEFINE(HAVE_GETHOSTBYNAME2_R, 1, Define if libc implements gethostbyname2_r)])
  136 +
133 137 dnl Output files
134 138 AC_CONFIG_FILES([\
135 139 Makefile \

0 comments on commit 9b51796

Please sign in to comment.
Something went wrong with that request. Please try again.