Skip to content

Commit

Permalink
replace getservbyname_r ifdef hacks with configure check
Browse files Browse the repository at this point in the history
this should make it work automatically on any new platform without
having to add yet another ifdef hack.
should fix issues with android (rofl0r#265).
additionally the code for the systems lacking GNU-compatible getservbyname_r()
is now guarded with a mutex, which prevents possible races, therefore
resolving the ancient "TODO" item.
  • Loading branch information
rofl0r committed Dec 2, 2018
1 parent 2213afb commit 49bf4ba
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
3 changes: 3 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ issolaris() {
$solaris_detected
}

check_compile 'whether we have GNU-style getservbyname_r()' "-DHAVE_GNU_GETSERVBYNAME_R" \
'#define _GNU_SOURCE\n#include <netdb.h>\nint main() {\nstruct servent *se = 0;struct servent se_buf;char buf[1024];\ngetservbyname_r("foo", (void*) 0, &se_buf, buf, sizeof(buf), &se);\nreturn 0;}'

check_define __APPLE__ && {
mac_detected=true
check_define __x86_64__ && mac_64=true
Expand Down
21 changes: 12 additions & 9 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "core.h"
#include "common.h"
#include "allocator_thread.h"
#include "mutex.h"

extern int tcp_read_time_out;
extern int tcp_connect_time_out;
Expand Down Expand Up @@ -728,10 +729,13 @@ int connect_proxy_chain(int sock, ip_type target_ip,
return -1;
}

static pthread_mutex_t servbyname_lock;
void core_initialize(void) {
MUTEX_INIT(&servbyname_lock);
}

void core_unload(void) {
MUTEX_DESTROY(&servbyname_lock);
}

static void gethostbyname_data_setstring(struct gethostbyname_data* data, char* name) {
Expand Down Expand Up @@ -794,18 +798,17 @@ void proxy_freeaddrinfo(struct addrinfo *res) {
free(res);
}

#if defined(IS_MAC) || defined(IS_OPENBSD) || defined(IS_SOLARIS)
#if defined(IS_OPENBSD) || defined(IS_SOLARIS) /* OpenBSD and Solaris has its own incompatible getservbyname_r */
#define getservbyname_r mygetservbyname_r
#endif
/* getservbyname on mac is using thread local storage, so we dont need mutex
TODO: check if the same applies to OpenBSD */
static int getservbyname_r(const char* name, const char* proto, struct servent* result_buf,
static int mygetservbyname_r(const char* name, const char* proto, struct servent* result_buf,
char* buf, size_t buflen, struct servent** result) {
PFUNC();
#ifdef HAVE_GNU_GETSERVBYNAME_R
PDEBUG("using host getservbyname_r\n");
return getservbyname_r(name, proto, result_buf, buf, buflen, result);
#endif
struct servent *res;
int ret;
(void) buf; (void) buflen;
MUTEX_LOCK(&servbyname_lock);
res = getservbyname(name, proto);
if(res) {
*result_buf = *res;
Expand All @@ -815,9 +818,9 @@ static int getservbyname_r(const char* name, const char* proto, struct servent*
*result = NULL;
ret = ENOENT;
}
MUTEX_UNLOCK(&servbyname_lock);
return ret;
}
#endif

int proxy_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
struct gethostbyname_data ghdata;
Expand Down Expand Up @@ -848,7 +851,7 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
else
goto err2;
}
if(service) getservbyname_r(service, NULL, &se_buf, buf, sizeof(buf), &se);
if(service) mygetservbyname_r(service, NULL, &se_buf, buf, sizeof(buf), &se);

port = se ? se->s_port : htons(atoi(service ? service : "0"));
((struct sockaddr_in *) &space->sockaddr_space)->sin_port = port;
Expand Down

0 comments on commit 49bf4ba

Please sign in to comment.