[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [torsocks/master] Add support for gethostbyaddr_r(3)
commit 450abaddbef2b51ca4b845e6ad86c89051ab17d2
Author: David Goulet <dgoulet@xxxxxxxxx>
Date: Mon Jul 15 01:57:33 2013 -0400
Add support for gethostbyaddr_r(3)
Signed-off-by: David Goulet <dgoulet@xxxxxxxxx>
---
src/lib/gethostbyname.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++
src/lib/torsocks.h | 16 ++++
2 files changed, 211 insertions(+)
diff --git a/src/lib/gethostbyname.c b/src/lib/gethostbyname.c
index 3e89e9b..af47e73 100644
--- a/src/lib/gethostbyname.c
+++ b/src/lib/gethostbyname.c
@@ -26,6 +26,98 @@
#include "torsocks.h"
/*
+ * Free the given hostent structure and all pointers contained inside.
+ */
+static void free_hostent(struct hostent *he)
+{
+ if (!he) {
+ return;
+ }
+
+ if (he->h_name) {
+ free(he->h_name);
+ }
+
+ if (he->h_aliases) {
+ int i = 0;
+
+ while (he->h_aliases[i] != NULL) {
+ free(he->h_aliases[i]);
+ i++;
+ }
+ }
+
+ if (he->h_addr_list) {
+ int i = 0;
+
+ while (he->h_addr_list[i] != NULL) {
+ free(he->h_addr_list[i]);
+ i++;
+ }
+ }
+
+ free(he);
+}
+
+/*
+ * Allocate a hostent structure with the given type.
+ *
+ * On error, return NULL.
+ */
+static struct hostent *alloc_hostent(int af)
+{
+ void *addr = NULL;
+ char **addr_list = NULL, **aliases = NULL;
+ struct hostent *he = NULL;
+ size_t addrlen;
+
+ if (af != AF_INET && af != AF_INET6) {
+ goto error;
+ }
+
+ he = zmalloc(sizeof(*he));
+ addr_list = zmalloc(sizeof(*addr_list) * 2);
+ aliases = zmalloc(sizeof(*aliases));
+ if (!he || !addr_list || !aliases) {
+ PERROR("zmalloc hostent");
+ goto error;
+ }
+
+ switch (af) {
+ case AF_INET:
+ addr = zmalloc(sizeof(struct in_addr));
+ addrlen = sizeof(struct in_addr);
+ break;
+ case AF_INET6:
+ addr = zmalloc(sizeof(struct in6_addr));
+ addrlen = sizeof(struct in6_addr);
+ break;
+ default:
+ assert(0);
+ goto error;
+ }
+ if (!addr) {
+ PERROR("zmalloc addr");
+ goto error;
+ }
+
+ he->h_name = NULL;
+ he->h_addr_list = addr_list;
+ he->h_addr_list[0] = addr;
+ he->h_addr_list[1] = NULL;
+ he->h_aliases = aliases;
+ he->h_aliases[0] = NULL;
+ he->h_length = addrlen;
+ he->h_addrtype = af;
+
+ return he;
+
+error:
+ free_hostent(he);
+ return NULL;
+}
+
+/*
* Torsocks call for gethostbyname(3).
*
* NOTE: This call is OBSOLETE in the glibc.
@@ -179,3 +271,106 @@ LIBC_GETHOSTBYADDR_DECL
{
return tsocks_gethostbyaddr(LIBC_GETHOSTBYADDR_ARGS);
}
+
+/*
+ * Torsocks call for gethostbyaddr_r(3).
+ *
+ * NOTE: GNU extension. Reentrant version.
+ */
+LIBC_GETHOSTBYADDR_R_RET_TYPE tsocks_gethostbyaddr_r(LIBC_GETHOSTBYADDR_R_SIG)
+{
+ int ret;
+ struct hostent *he = NULL;
+
+ struct data {
+ char *hostname;
+ char *addr_list[2];
+ char padding[];
+ } *data;
+
+ if (__buflen < sizeof(struct data)) {
+ ret = ERANGE;
+ goto error;
+ }
+ data = (struct data *) __buf;
+ memset(data, 0, sizeof(*data));
+
+ /*
+ * Tor does not allow to resolve to an IPv6 pointer so only accept inet
+ * return address.
+ */
+ if (!__addr || __type != AF_INET) {
+ ret = HOST_NOT_FOUND;
+ if (__h_errnop) {
+ *__h_errnop = HOST_NOT_FOUND;
+ }
+ goto error;
+ }
+
+ DBG("[gethostbyaddr_r] Requesting address %s of len %d and type %d",
+ inet_ntoa(*((struct in_addr *) __addr)), __len, __type);
+
+ /* This call allocates hostname. On error, it's untouched. */
+ ret = tsocks_tor_resolve_ptr(__addr, &data->hostname, __type);
+ if (ret < 0) {
+ const char *ret_str;
+
+ ret_str = inet_ntop(__type, __addr, __buf, __buflen);
+ if (!ret_str) {
+ ret = HOST_NOT_FOUND;
+ if (errno == ENOSPC) {
+ ret = ERANGE;
+ }
+ if (__h_errnop) {
+ *__h_errnop = HOST_NOT_FOUND;
+ }
+ goto error;
+ }
+ }
+
+ /* Ease our life a bit. */
+ he = __ret;
+
+ if (!he) {
+ ret = NO_RECOVERY;
+ if (__h_errnop) {
+ *__h_errnop = NO_RECOVERY;
+ }
+ goto error;
+ }
+
+ if (data->hostname) {
+ he->h_name = data->hostname;
+ } else {
+ ret = NO_RECOVERY;
+ if (__h_errnop) {
+ *__h_errnop = NO_RECOVERY;
+ }
+ goto error;
+ }
+
+ he->h_aliases = NULL;
+ he->h_length = strlen(he->h_name);
+ /* Assign the address list within the data of the given buffer. */
+ data->addr_list[0] = (char *) __addr;
+ data->addr_list[1] = NULL;
+ he->h_addr_list = data->addr_list;
+
+ if (__result) {
+ *__result = he;
+ }
+
+ /* Everything went good. */
+ ret = 0;
+
+error:
+ return ret;
+}
+
+/*
+ * Libc hijacked symbol gethostbyaddr_r(3).
+ */
+LIBC_GETHOSTBYADDR_R_DECL
+{
+ return tsocks_gethostbyaddr_r(LIBC_GETHOSTBYADDR_R_ARGS);
+}
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index 4acacff..3cd51d0 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -90,6 +90,16 @@ char tsocks_he_name[255];
#define LIBC_GETHOSTBYADDR_SIG const void *__addr, socklen_t __len, int __type
#define LIBC_GETHOSTBYADDR_ARGS __addr, __len, __type
+/* GNU extension. Reentrant version. */
+#define LIBC_GETHOSTBYADDR_R_NAME gethostbyaddr_r
+#define LIBC_GETHOSTBYADDR_R_NAME_STR XSTR(LIBC_GETHOSTBYADDR_R_NAME)
+#define LIBC_GETHOSTBYADDR_R_RET_TYPE int
+#define LIBC_GETHOSTBYADDR_R_SIG const void *__addr, socklen_t __len, int __type, \
+ struct hostent *__ret, char *__buf, size_t __buflen, \
+ struct hostent **__result, int *__h_errnop
+#define LIBC_GETHOSTBYADDR_R_ARGS __addr, __len, __type, __ret, __buf, \
+ __buflen, __result, __h_errnop
+
/* getaddrinfo(3) */
#include <netdb.h>
@@ -138,6 +148,12 @@ TSOCKS_LIBC_DECL(gethostbyaddr, LIBC_GETHOSTBYADDR_RET_TYPE,
#define LIBC_GETHOSTBYADDR_DECL LIBC_GETHOSTBYADDR_RET_TYPE \
LIBC_GETHOSTBYADDR_NAME(LIBC_GETHOSTBYADDR_SIG)
+/* gethostbyaddr_r(3) */
+TSOCKS_LIBC_DECL(gethostbyaddr_r, LIBC_GETHOSTBYADDR_R_RET_TYPE,
+ LIBC_GETHOSTBYADDR_R_SIG)
+#define LIBC_GETHOSTBYADDR_R_DECL LIBC_GETHOSTBYADDR_R_RET_TYPE \
+ LIBC_GETHOSTBYADDR_R_NAME(LIBC_GETHOSTBYADDR_R_SIG)
+
/* getaddrinfo(3) */
TSOCKS_LIBC_DECL(getaddrinfo, LIBC_GETADDRINFO_RET_TYPE,
LIBC_GETADDRINFO_SIG)
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits