Skip to content

Commit

Permalink
Require getaddrinfo() on all systems
Browse files Browse the repository at this point in the history
Every reasonably current system support getaddrinfo() so get rid
of the legacy fallbacks.
  • Loading branch information
CendioOssman committed Mar 17, 2015
1 parent acd195d commit cfb2116
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 141 deletions.
12 changes: 0 additions & 12 deletions CMakeLists.txt
Expand Up @@ -252,18 +252,6 @@ if(ENABLE_PAM)
endif() endif()
set(HAVE_PAM ${ENABLE_PAM}) set(HAVE_PAM ${ENABLE_PAM})


# Check for socket functions
if(WIN32)
# check_function_exists() cannot handle stdcall, so just define things
set(HAVE_GETADDRINFO 1)
else()
if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
set(CMAKE_REQUIRED_LIBRARIES socket)
endif()
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
set(CMAKE_REQUIRED_LIBRARIES)
endif()

# Generate config.h and make sure the source finds it # Generate config.h and make sure the source finds it
configure_file(config.h.in config.h) configure_file(config.h.in config.h)
add_definitions(-DHAVE_CONFIG_H) add_definitions(-DHAVE_CONFIG_H)
Expand Down
123 changes: 1 addition & 122 deletions common/network/TcpSocket.cxx
Expand Up @@ -57,7 +57,7 @@
#define INADDR_LOOPBACK ((unsigned long)0x7F000001) #define INADDR_LOOPBACK ((unsigned long)0x7F000001)
#endif #endif


#if defined(HAVE_GETADDRINFO) && !defined(IN6_ARE_ADDR_EQUAL) #ifndef IN6_ARE_ADDR_EQUAL
#define IN6_ARE_ADDR_EQUAL(a,b) \ #define IN6_ARE_ADDR_EQUAL(a,b) \
(memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)) == 0) (memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)) == 0)
#endif #endif
Expand All @@ -73,9 +73,7 @@ using namespace rdr;
static rfb::LogWriter vlog("TcpSocket"); static rfb::LogWriter vlog("TcpSocket");


static rfb::BoolParameter UseIPv4("UseIPv4", "Use IPv4 for incoming and outgoing connections.", true); static rfb::BoolParameter UseIPv4("UseIPv4", "Use IPv4 for incoming and outgoing connections.", true);
#ifdef HAVE_GETADDRINFO
static rfb::BoolParameter UseIPv6("UseIPv6", "Use IPv6 for incoming and outgoing connections.", true); static rfb::BoolParameter UseIPv6("UseIPv6", "Use IPv6 for incoming and outgoing connections.", true);
#endif


/* Tunnelling support. */ /* Tunnelling support. */
int network::findFreeTcpPort (void) int network::findFreeTcpPort (void)
Expand Down Expand Up @@ -150,14 +148,11 @@ TcpSocket::TcpSocket(const char *host, int port)
int sock, err, result, family; int sock, err, result, family;
vnc_sockaddr_t sa; vnc_sockaddr_t sa;
socklen_t salen; socklen_t salen;
#ifdef HAVE_GETADDRINFO
struct addrinfo *ai, *current, hints; struct addrinfo *ai, *current, hints;
#endif


// - Create a socket // - Create a socket
initSockets(); initSockets();


#ifdef HAVE_GETADDRINFO
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
Expand Down Expand Up @@ -198,37 +193,10 @@ TcpSocket::TcpSocket(const char *host, int port)
else else
sa.u.sin6.sin6_port = htons(port); sa.u.sin6.sin6_port = htons(port);


#else /* HAVE_GETADDRINFO */
if (!UseIPv4)
throw Exception("Only IPv4 available but it is disabled");

family = AF_INET;
salen = sizeof(struct sockaddr_in);

/* Try processing the host as an IP address */
memset(&sa, 0, sizeof(sa));
sa.u.sin.sin_family = AF_INET;
sa.u.sin.sin_addr.s_addr = inet_addr((char *)host);
sa.u.sin.sin_port = htons(port);
if ((int)sa.u.sin.sin_addr.s_addr == -1) {
/* Host was not an IP address - try resolving as DNS name */
struct hostent *hostinfo;
hostinfo = gethostbyname((char *)host);
if (hostinfo && hostinfo->h_addr) {
sa.u.sin.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr)->s_addr;
} else {
err = errorNumber;
throw SocketException("unable to resolve host by name", err);
}
}
#endif /* HAVE_GETADDRINFO */

sock = socket (family, SOCK_STREAM, 0); sock = socket (family, SOCK_STREAM, 0);
if (sock == -1) { if (sock == -1) {
err = errorNumber; err = errorNumber;
#ifdef HAVE_GETADDRINFO
freeaddrinfo(ai); freeaddrinfo(ai);
#endif /* HAVE_GETADDRINFO */
throw SocketException("unable to create socket", err); throw SocketException("unable to create socket", err);
} }


Expand All @@ -243,7 +211,6 @@ TcpSocket::TcpSocket(const char *host, int port)
break; break;
} }


#ifdef HAVE_GETADDRINFO
if (result == 0) if (result == 0)
break; break;
} }
Expand All @@ -252,7 +219,6 @@ TcpSocket::TcpSocket(const char *host, int port)


if (current == NULL) if (current == NULL)
throw Exception("No useful address for host"); throw Exception("No useful address for host");
#endif /* HAVE_GETADDRINFO */


if (result == -1) if (result == -1)
throw SocketException("unable connect to socket", err); throw SocketException("unable connect to socket", err);
Expand Down Expand Up @@ -289,7 +255,6 @@ char* TcpSocket::getPeerAddress() {
return rfb::strDup(""); return rfb::strDup("");
} }


#if defined(HAVE_GETADDRINFO)
if (sa.u.sa.sa_family == AF_INET6) { if (sa.u.sa.sa_family == AF_INET6) {
char buffer[INET6_ADDRSTRLEN + 2]; char buffer[INET6_ADDRSTRLEN + 2];
int ret; int ret;
Expand All @@ -308,7 +273,6 @@ char* TcpSocket::getPeerAddress() {


return rfb::strDup(buffer); return rfb::strDup(buffer);
} }
#endif


if (sa.u.sa.sa_family == AF_INET) { if (sa.u.sa.sa_family == AF_INET) {
char *name; char *name;
Expand All @@ -333,10 +297,8 @@ int TcpSocket::getPeerPort() {
getpeername(getFd(), &sa.u.sa, &sa_size); getpeername(getFd(), &sa.u.sa, &sa_size);


switch (sa.u.sa.sa_family) { switch (sa.u.sa.sa_family) {
#ifdef HAVE_GETADDRINFO
case AF_INET6: case AF_INET6:
return ntohs(sa.u.sin6.sin6_port); return ntohs(sa.u.sin6.sin6_port);
#endif /* HAVE_GETADDRINFO */
case AF_INET: case AF_INET:
return ntohs(sa.u.sin.sin_port); return ntohs(sa.u.sin.sin_port);
default: default:
Expand Down Expand Up @@ -369,12 +331,9 @@ bool TcpSocket::sameMachine() {
if (peeraddr.u.sa.sa_family != myaddr.u.sa.sa_family) if (peeraddr.u.sa.sa_family != myaddr.u.sa.sa_family)
return false; return false;


#ifdef HAVE_GETADDRINFO
if (peeraddr.u.sa.sa_family == AF_INET6) if (peeraddr.u.sa.sa_family == AF_INET6)
return IN6_ARE_ADDR_EQUAL(&peeraddr.u.sin6.sin6_addr, return IN6_ARE_ADDR_EQUAL(&peeraddr.u.sin6.sin6_addr,
&myaddr.u.sin6.sin6_addr); &myaddr.u.sin6.sin6_addr);
#endif

if (peeraddr.u.sa.sa_family == AF_INET) if (peeraddr.u.sa.sa_family == AF_INET)
return (peeraddr.u.sin.sin_addr.s_addr == myaddr.u.sin.sin_addr.s_addr); return (peeraddr.u.sin.sin_addr.s_addr == myaddr.u.sin.sin_addr.s_addr);


Expand Down Expand Up @@ -432,11 +391,8 @@ int TcpSocket::getSockPort(int sock)
return 0; return 0;


switch (sa.u.sa.sa_family) { switch (sa.u.sa.sa_family) {
#ifdef HAVE_GETADDRINFO
case AF_INET6: case AF_INET6:
return ntohs(sa.u.sin6.sin6_port); return ntohs(sa.u.sin6.sin6_port);
#endif /* HAVE_GETADDRINFO */

default: default:
return ntohs(sa.u.sin.sin_port); return ntohs(sa.u.sin.sin_port);
} }
Expand Down Expand Up @@ -551,7 +507,6 @@ TcpListener::accept() {
} }


void TcpListener::getMyAddresses(std::list<char*>* result) { void TcpListener::getMyAddresses(std::list<char*>* result) {
#if defined(HAVE_GETADDRINFO)
struct addrinfo *ai, *current, hints; struct addrinfo *ai, *current, hints;


initSockets(); initSockets();
Expand Down Expand Up @@ -591,21 +546,6 @@ void TcpListener::getMyAddresses(std::list<char*>* result) {
} }


freeaddrinfo(ai); freeaddrinfo(ai);
#else
const hostent* addrs = gethostbyname(0);
if (!UseIPv4)
return;
if (addrs == 0)
throw rdr::SystemException("gethostbyname", errorNumber);
if (addrs->h_addrtype != AF_INET)
throw rdr::Exception("getMyAddresses: bad family");
for (int i=0; addrs->h_addr_list[i] != 0; i++) {
const char* addrC = inet_ntoa(*((struct in_addr*)addrs->h_addr_list[i]));
char* addr = new char[strlen(addrC)+1];
strcpy(addr, addrC);
result->push_back(addr);
}
#endif /* defined(HAVE_GETADDRINFO) */
} }


int TcpListener::getMyPort() { int TcpListener::getMyPort() {
Expand All @@ -621,7 +561,6 @@ void network::createLocalTcpListeners(std::list<TcpListener> *listeners,


initSockets(); initSockets();


#ifdef HAVE_GETADDRINFO
if (UseIPv6) { if (UseIPv6) {
sa.u.sin6.sin6_family = AF_INET6; sa.u.sin6.sin6_family = AF_INET6;
sa.u.sin6.sin6_port = htons (port); sa.u.sin6.sin6_port = htons (port);
Expand All @@ -636,7 +575,6 @@ void network::createLocalTcpListeners(std::list<TcpListener> *listeners,
throw; throw;
} }
} }
#endif /* HAVE_GETADDRINFO */
if (UseIPv4) { if (UseIPv4) {
sa.u.sin.sin_family = AF_INET; sa.u.sin.sin_family = AF_INET;
sa.u.sin.sin_port = htons (port); sa.u.sin.sin_port = htons (port);
Expand Down Expand Up @@ -665,7 +603,6 @@ void network::createTcpListeners(std::list<TcpListener> *listeners,
{ {
std::list<TcpListener> new_listeners; std::list<TcpListener> new_listeners;


#ifdef HAVE_GETADDRINFO
struct addrinfo *ai, *current, hints; struct addrinfo *ai, *current, hints;
char service[16]; char service[16];
int result; int result;
Expand Down Expand Up @@ -716,53 +653,6 @@ void network::createTcpListeners(std::list<TcpListener> *listeners,
} }
} }
freeaddrinfo(ai); freeaddrinfo(ai);
#else
const hostent* addrs;
if (addr) {
/* Bind to specific address */
addrs = gethostbyname(addr);
if (addrs == 0)
throw rdr::SystemException("gethostbyname", errorNumber);
if (addrs->h_addrtype != AF_INET)
throw rdr::Exception("createTcpListeners: bad family");
for (int i=0; addrs->h_addr_list[i] != 0; i++) {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
memcpy (&addr.sin_addr, addrs->h_addr_list[i], addrs->h_length);
addr.sin_port = htons(port);
try {
new_listeners.push_back(TcpListener ((struct sockaddr*)&addr,
addrs->h_length));
} catch (SocketException& e) {
// Ignore this if it is due to lack of address family support
// on the interface or on the system
if (e.err != EADDRNOTAVAIL && e.err != EAFNOSUPPORT) {
// Otherwise, report the error
freeaddrinfo(ai);
throw;
}
}
}
} else {
/* Bind to any address */
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
try {
new_listeners.push_back(TcpListener ((struct sockaddr*)&addr,
sizeof (struct sockaddr_in)));
} catch (SocketException& e) {
// Ignore this if it is due to lack of address family support on
// the interface or on the system
if (e.err != EADDRNOTAVAIL && e.err != EAFNOSUPPORT) {
// Otherwise, report the error
freeaddrinfo(ai);
throw;
}
}
}
#endif /* defined(HAVE_GETADDRINFO) */


if (new_listeners.empty ()) if (new_listeners.empty ())
throw SocketException("createTcpListeners: no addresses available", throw SocketException("createTcpListeners: no addresses available",
Expand Down Expand Up @@ -885,7 +775,6 @@ TcpFilter::Pattern TcpFilter::parsePattern(const char* p) {
pattern.address.u.sa.sa_family = AF_UNSPEC; pattern.address.u.sa.sa_family = AF_UNSPEC;
pattern.prefixlen = 0; pattern.prefixlen = 0;
} else { } else {
#ifdef HAVE_GETADDRINFO
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *ai; struct addrinfo *ai;
char *p = addr.buf; char *p = addr.buf;
Expand All @@ -910,10 +799,6 @@ TcpFilter::Pattern TcpFilter::parsePattern(const char* p) {


memcpy (&pattern.address.u.sa, ai->ai_addr, ai->ai_addrlen); memcpy (&pattern.address.u.sa, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo (ai); freeaddrinfo (ai);
#else
pattern.address.u.sa.sa_family = AF_INET;
pattern.address.u.sin.sin_addr.s_addr = inet_addr(addr.buf);
#endif /* HAVE_GETADDRINFO */


family = pattern.address.u.sa.sa_family; family = pattern.address.u.sa.sa_family;


Expand Down Expand Up @@ -987,7 +872,6 @@ TcpFilter::Pattern TcpFilter::parsePattern(const char* p) {


char* TcpFilter::patternToStr(const TcpFilter::Pattern& p) { char* TcpFilter::patternToStr(const TcpFilter::Pattern& p) {
rfb::CharArray addr; rfb::CharArray addr;
#ifdef HAVE_GETADDRINFO
char buffer[INET6_ADDRSTRLEN + 2]; char buffer[INET6_ADDRSTRLEN + 2];


if (p.address.u.sa.sa_family == AF_INET) { if (p.address.u.sa.sa_family == AF_INET) {
Expand All @@ -1002,11 +886,6 @@ char* TcpFilter::patternToStr(const TcpFilter::Pattern& p) {
addr.buf = rfb::strDup(buffer); addr.buf = rfb::strDup(buffer);
} else if (p.address.u.sa.sa_family == AF_UNSPEC) } else if (p.address.u.sa.sa_family == AF_UNSPEC)
addr.buf = rfb::strDup(""); addr.buf = rfb::strDup("");
#else
in_addr tmp;
tmp.s_addr = p.address.u.sin.sin_addr.s_addr;
addr.buf = rfb::strDup(inet_ntoa(tmp));
#endif /* HAVE_GETADDRINFO */


char action; char action;
switch (p.action) { switch (p.action) {
Expand Down
6 changes: 0 additions & 6 deletions common/network/TcpSocket.h
Expand Up @@ -28,10 +28,6 @@
#ifndef __NETWORK_TCP_SOCKET_H__ #ifndef __NETWORK_TCP_SOCKET_H__
#define __NETWORK_TCP_SOCKET_H__ #define __NETWORK_TCP_SOCKET_H__


#ifdef HAVE_CONFIG_H
#include <config.h> /* for HAVE_GETADDRINFO */
#endif

#include <network/Socket.h> #include <network/Socket.h>


#ifdef WIN32 #ifdef WIN32
Expand Down Expand Up @@ -101,9 +97,7 @@ namespace network {
union { union {
sockaddr sa; sockaddr sa;
sockaddr_in sin; sockaddr_in sin;
#ifdef HAVE_GETADDRINFO
sockaddr_in6 sin6; sockaddr_in6 sin6;
#endif
} u; } u;
} vnc_sockaddr_t; } vnc_sockaddr_t;


Expand Down
1 change: 0 additions & 1 deletion config.h.in
@@ -1,7 +1,6 @@
#define PACKAGE_NAME "@CMAKE_PROJECT_NAME@" #define PACKAGE_NAME "@CMAKE_PROJECT_NAME@"
#define PACKAGE_VERSION "@VERSION@" #define PACKAGE_VERSION "@VERSION@"


#cmakedefine HAVE_GETADDRINFO
#cmakedefine HAVE_ACTIVE_DESKTOP_H #cmakedefine HAVE_ACTIVE_DESKTOP_H
#cmakedefine HAVE_ACTIVE_DESKTOP_L #cmakedefine HAVE_ACTIVE_DESKTOP_L
#cmakedefine ENABLE_NLS 1 #cmakedefine ENABLE_NLS 1
Expand Down

0 comments on commit cfb2116

Please sign in to comment.