commit fe7bc53fbc81f012343f38271582fea76cafe4f0 Author: Robert Hogan robert@roberthogan.net Date: Sat Sep 18 12:11:29 2010 +0100
Major refactor of symbol hooking
Patch by alex@ohmantics.net
Make torsocks fully compatible with Snow Leopard OSX. Slim down the symbol hooking code considerably.
Alex's notes:
"http://developer.apple.com/mac/library/releasenotes/Darwin/SymbolVariantsRel... explains the one of the problems that people have run into. 64-bit applications don't have the $UNIX2003 variants. For working 10.6 support, we'll need to conditionalize the UNIX2003 variants off when compiling for 64-bit." --- configure.in | 42 +++++- src/Makefile.am | 2 +- src/darwin_warts.c | 47 ++++++ src/patch_table.h | 114 ++++++++++++++ src/tsocks.c | 443 ++++++++++++++-------------------------------------- 5 files changed, 313 insertions(+), 335 deletions(-)
diff --git a/configure.in b/configure.in index 04703e4..06461ff 100644 --- a/configure.in +++ b/configure.in @@ -292,6 +292,7 @@ fi dnl Find the correct select prototype on this machine AC_MSG_CHECKING(for correct select prototype) PROTO= +NAMES='n, readfds, writefds, exceptfds, timeout' for testproto in 'int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout' do if test "${PROTO}" = ""; then @@ -308,11 +309,13 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([select(${PROTO})]) AC_DEFINE_UNQUOTED([SELECT_SIGNATURE],[${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([SELECT_ARGNAMES],[${NAMES}],[Argument names])
dnl Find the correct connect prototype on this machine AC_MSG_CHECKING(for correct connect prototype) PROTO= -PROTO1='int __fd, const struct sockaddr * __addr, int len' +NAMES='__fd, __addr, __len' +PROTO1='int __fd, const struct sockaddr * __addr, int __len' PROTO2='int __fd, const struct sockaddr_in * __addr, socklen_t __len' PROTO3='int __fd, struct sockaddr * __addr, int __len' PROTO4='int __fd, const struct sockaddr * __addr, socklen_t __len' @@ -334,6 +337,7 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([connect(${PROTO})]) AC_DEFINE_UNQUOTED([CONNECT_SIGNATURE],[${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([CONNECT_ARGNAMES],[${NAMES}],[Argument names])
dnl Pick which of the sockaddr type arguments we need for dnl connect(), we need to cast one of ours to it later @@ -348,6 +352,7 @@ AC_DEFINE_UNQUOTED([CONNECT_SOCKARG],[${SOCKETARG}],[Description]) dnl Find the correct close prototype on this machine AC_MSG_CHECKING(for correct close prototype) PROTO= +NAMES='fd' PROTO1='int fd' for testproto in "${PROTO1}" do @@ -363,11 +368,13 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([close(${PROTO})]) AC_DEFINE_UNQUOTED([CLOSE_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([CLOSE_ARGNAMES],[${NAMES}],[Argument names])
dnl Find the correct res_querydomain prototype on this machine AC_MSG_CHECKING(for correct res_querydomain prototype) PROTO= +NAMES='name, domain, class, type, answer, anslen' PROTO1='const char *name, const char *domain, int class, int type, unsigned char *answer, int anslen' for testproto in "${PROTO1}" do @@ -385,10 +392,12 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([res_querydomain(${PROTO})]) AC_DEFINE_UNQUOTED([RES_QUERYDOMAIN_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([RES_QUERYDOMAIN_ARGNAMES],[${NAMES}],[Argument names])
dnl Find the correct res_send prototype on this machine AC_MSG_CHECKING(for correct res_send prototype) PROTO= +NAMES='msg, msglen, answer, anslen' PROTO1='const char *msg, int msglen, char *answer, int anslen' PROTO2='const unsigned char *msg, int msglen, unsigned char *answer, int anslen' for testproto in "${PROTO1}" \ @@ -408,13 +417,15 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([res_send(${PROTO})]) AC_DEFINE_UNQUOTED([RES_SEND_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([RES_SEND_ARGNAMES],[${NAMES}],[Argument names])
dnl Find the correct res_search prototype on this machine AC_MSG_CHECKING(for correct res_search prototype) PROTO= -PROTO1='const char *dname, int class, int type,unsigned char *answer, int anslen' -for testproto in "${PROTO1}" +NAMES='dname, class, type, answer, anslen' +PROTO1='const char *dname, int class, int type, unsigned char *answer, int anslen' +for testproto in "${PROTO1}" do if test "${PROTO}" = ""; then AC_TRY_COMPILE([ @@ -430,13 +441,15 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([res_search(${PROTO})]) AC_DEFINE_UNQUOTED([RES_SEARCH_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([RES_SEARCH_ARGNAMES],[${NAMES}],[Argument names])
dnl Find the correct res_query prototype on this machine AC_MSG_CHECKING(for correct res_query prototype) PROTO= -PROTO1='const char *dname, int class, int type,unsigned char *answer, int anslen' -for testproto in "${PROTO1}" +NAMES='dname, class, type, answer, anslen' +PROTO1='const char *dname, int class, int type, unsigned char *answer, int anslen' +for testproto in "${PROTO1}" do if test "${PROTO}" = ""; then AC_TRY_COMPILE([ @@ -452,10 +465,12 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([res_query(${PROTO})]) AC_DEFINE_UNQUOTED([RES_QUERY_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([RES_QUERY_ARGNAMES],[${NAMES}],[Argument names])
dnl Find the correct getpeername prototype on this machine AC_MSG_CHECKING(for correct getpeername prototype) PROTO= +NAMES='__fd, __name, __namelen' PROTO1='int __fd, const struct sockaddr * __name, int *__namelen' PROTO2='int __fd, const struct sockaddr_in * __name, socklen_t *__namelen' PROTO3='int __fd, struct sockaddr * __name, socklen_t *__namelen' @@ -478,14 +493,16 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([getpeername(${PROTO})]) AC_DEFINE_UNQUOTED(GETPEERNAME_SIGNATURE, [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([GETPEERNAME_ARGNAMES],[${NAMES}],[Argument names])
dnl Find the correct poll prototype on this machine AC_MSG_CHECKING(for correct poll prototype) PROTO= +NAMES='ufds, nfds, timeout' for testproto in 'struct pollfd *ufds, unsigned long nfds, int timeout' \ 'struct pollfd *ufds, nfds_t nfds, int timeout' \ - 'struct pollfd *pfd, unsigned int nfds, int timeout' + 'struct pollfd *ufds, unsigned int nfds, int timeout' do if test "${PROTO}" = ""; then AC_TRY_COMPILE([ @@ -499,30 +516,43 @@ if test "${PROTO}" = ""; then fi AC_MSG_RESULT([poll(${PROTO})]) AC_DEFINE_UNQUOTED([POLL_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([POLL_ARGNAMES],[${NAMES}],[Argument names])
dnl Emit signature for gethostbyname PROTO="const char *name" +NAMES='name' AC_DEFINE_UNQUOTED([GETHOSTBYNAME_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([GETHOSTBYNAME_ARGNAMES],[${NAMES}],[Argument names])
dnl Emit signature for getaddrinfo PROTO="const char *node, const char *service, void *hints, void *res" +NAMES='node, service, hints, res' AC_DEFINE_UNQUOTED([GETADDRINFO_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([GETADDRINFO_ARGNAMES],[${NAMES}],[Argument names])
dnl Emit signature for getipnodebyname PROTO="const char *name, int af, int flags, int *error_num" +NAMES='name, af, flags, error_num' AC_DEFINE_UNQUOTED([GETIPNODEBYNAME_SIGNATURE], [${PROTO}],[Description]) +AC_DEFINE_UNQUOTED([GETIPNODEBYNAME_ARGNAMES],[${NAMES}],[Argument names])
dnl Emit signature for gethostbyaddr PROTO="const void *addr, socklen_t len, int type" +NAMES='addr, len, type' AC_DEFINE_UNQUOTED(GETHOSTBYADDR_SIGNATURE, [${PROTO}], [Description]) +AC_DEFINE_UNQUOTED([GETHOSTBYADDR_ARGNAMES],[${NAMES}],[Argument names])
dnl Emit signature for sendto PROTO="int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen" +NAMES='s, buf, len, flags, to, tolen' AC_DEFINE_UNQUOTED(SENDTO_SIGNATURE, [${PROTO}], [Description]) +AC_DEFINE_UNQUOTED([SENDTO_ARGNAMES],[${NAMES}],[Argument names])
dnl Emit signature for sendmsg PROTO="int s, const struct msghdr *msg, int flags" +NAMES='s, msg, flags' AC_DEFINE_UNQUOTED(SENDMSG_SIGNATURE, [${PROTO}], [Description]) +AC_DEFINE_UNQUOTED([SENDMSG_ARGNAMES],[${NAMES}],[Argument names])
dnl Output the special librarys (libdl etc needed for tsocks) SPECIALLIBS=${LIBS} diff --git a/src/Makefile.am b/src/Makefile.am index 8e7bb96..d5d1239 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,7 @@ torsocksconfmanpage_DATA = torsocks.conf.5
# Install main library to $(prefix)/lib/tor (must match torsocks.in) lib_LTLIBRARIES = libtorsocks.la -libtorsocks_la_SOURCES = tsocks.c common.c parser.c dead_pool.c +libtorsocks_la_SOURCES = tsocks.c common.c parser.c dead_pool.c darwin_warts.c libtorsocks_la_LDFLAGS = -version-info 1:0:0 #libtorsocks_la_CFLAGS = -nostartfiles
diff --git a/src/darwin_warts.c b/src/darwin_warts.c new file mode 100644 index 0000000..c35ed8b --- /dev/null +++ b/src/darwin_warts.c @@ -0,0 +1,47 @@ +/* Mac OS X 10.6 forces any function named "select" to be named "_select$1050" + * in the output to the assembler. We need to patch select as well, so this + * isolated code exists without tripping over the Darwin header that causes the + * probkem. + */ + +#if defined(__APPLE__) || defined(__darwin__) + +#include <AvailabilityMacros.h> + +#if defined(MAC_OS_X_VERSION_10_6) + +#include <stddef.h> +#include <stdint.h> +#include <dlfcn.h> +#include "common.h" + +#define LOAD_ERROR(s,l) { \ + char *error; \ + error = dlerror(); \ + show_msg(l, "The symbol %s() was not found in any shared " \ + "library. The error reported was: %s!\n", s, \ + (error)?error:"not found"); \ + dlerror(); \ + } + +#define SELECT_SIGNATURE int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout +#define SELECT_ARGNAMES n, readfds, writefds, exceptfds, timeout + +/* forward declare opaque structures instead of bringing in real Darwin decls. */ +typedef struct fd_set fd_set; +struct timeval; + +int (*realselect)(SELECT_SIGNATURE); +int tsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE)); + +int select(SELECT_SIGNATURE) { + if (!realselect) { + dlerror(); + if ((realselect = dlsym(RTLD_NEXT, "select")) == NULL) + LOAD_ERROR("select", MSGERR); + } + return tsocks_select_guts(SELECT_ARGNAMES, realselect); +} + +#endif /* 10.6 */ +#endif /* darwin */ diff --git a/src/patch_table.h b/src/patch_table.h new file mode 100644 index 0000000..9ebde08 --- /dev/null +++ b/src/patch_table.h @@ -0,0 +1,114 @@ +#undef FUNC +#undef FUNCD +#undef FUND32 +#undef FUNCD64 + +#ifdef SUPPORT_RES_API + #define RES_FUNC FUNC + #define RES_FUNCD FUNCD + #define RES_FUNCD32 FUNCD32 + #define RES_FUNCD64 FUNCD64 +#else + #define RES_FUNC EMPTY_FUNC + #define RES_FUNCD EMPTY_FUNC + #define RES_FUNCD32 EMPTY_FUNC + #define RES_FUNCD64 EMPTY_FUNC +#endif + +#ifdef USE_TOR_DNS + #define DNS_FUNC FUNC + #define DNS_FUNCD FUNCD + #define DNS_FUNCD32 FUNCD32 + #define DNS_FUNCD64 FUNCD64 +#else + #define DNS_FUNC EMPTY_FUNC + #define DNS_FUNCD EMPTY_FUNC + #define DNS_FUNCD32 EMPTY_FUNC + #define DNS_FUNCD64 EMPTY_FUNC +#endif + +#define EMPTY_FUNC(e,r,s,n,b,m) + +#if defined(__APPLE__) || defined(__darwin__) + #ifndef DARWIN_EXPANSION + #define DARWIN_EXPANSION PATCH_TABLE_EXPANSION + #endif + + #define FUNCD(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m) + #if (__LP64__) + #define FUNCD32(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) + #define FUNCD64(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m) + + /* This tests if we're building with 10.6 or later headers, not + if we're running on 10.6. We'd rather do the latter. */ + #ifdef MAC_OS_X_VERSION_10_6 + #define FUNCD64_106(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m) + #else + #define FUNCD64_106(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) + #endif + #else + #define FUNCD32(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m) + #define FUNCD64(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) + #define FUNCD64_106(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) + #endif +#else + #define FUNCD(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) + #define FUNCD32(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) + #define FUNCD64(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) + #define FUNCD64_106(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m) +#endif +#define FUNC(e,r,s,n,b,m) PATCH_TABLE_EXPANSION(e,r,s,n,b,m) + +/* dlsym return type SIG/ARGS C name base name asm name */ +/*RES_FUNC (ERR, int, RES_INIT_, res_init, res_init, "res_init") */ +/* res_init takes void, so we do that one manually. */ +RES_FUNC (ERR, int, RES_QUERY_, res_query, res_query, "res_query") +RES_FUNC (ERR, int, RES_SEARCH_, res_search, res_search, "res_search") +RES_FUNC (ERR, int, RES_SEND_, res_send, res_send, "res_send") +RES_FUNC (ERR, int, RES_QUERYDOMAIN_, res_querydomain, res_querydomain, "res_querydomain") + +DNS_FUNC (ERR, struct hostent *, GETHOSTBYNAME_, gethostbyname, gethostbyname, "gethostbyname") +DNS_FUNC (ERR, struct hostent *, GETHOSTBYADDR_, gethostbyaddr, gethostbyaddr, "gethostbyaddr") +DNS_FUNC (ERR, int, GETADDRINFO_, getaddrinfo, getaddrinfo, "getaddrinfo") +/* getipnodebyname is deprecated so do not report an error if it is not + available.*/ +DNS_FUNC (WARN, struct hostent *, GETIPNODEBYNAME_, getipnodebyname, getipnodebyname, "getipnodebyname") + +DNS_FUNC (ERR, ssize_t, SENDTO_, sendto, sendto, "sendto") +DNS_FUNCD32 (ERR, ssize_t, SENDTO_, sendto_unix2003, sendto, "sendto$UNIX2003") +DNS_FUNCD32 (ERR, ssize_t, SENDTO_, sendto_nocancel_unix2003, sendto, "sendto$NOCANCEL$UNIX2003") +DNS_FUNCD64 (ERR, ssize_t, SENDTO_, sendto_nocancel, sendto, "sendto$NOCANCEL") + +DNS_FUNC (ERR, ssize_t, SENDMSG_, sendmsg, sendmsg, "sendmsg") +DNS_FUNCD32 (ERR, ssize_t, SENDMSG_, sendmsg_unix2003, sendmsg, "sendmsg$UNIX2003") +DNS_FUNCD32 (ERR, ssize_t, SENDMSG_, sendmsg_nocancel_unix2003, sendmsg, "sendmsg$NOCANCEL$UNIX2003") +DNS_FUNCD64 (ERR, ssize_t, SENDMSG_, sendmsg_nocancel, sendmsg, "sendmsg$NOCANCEL") + +FUNC (ERR, int, CONNECT_, connect, connect, "connect") +FUNCD32 (ERR, int, CONNECT_, connect_unix2003, connect, "connect$UNIX2003") +FUNCD32 (ERR, int, CONNECT_, connect_nocancel_unix2003, connect, "connect$NOCANCEL$UNIX2003") +FUNCD64 (ERR, int, CONNECT_, connect_nocancel, connect, "connect$NOCANCEL") + +#if !(defined(__APPLE__) || defined(__darwin__) && defined(MAX_OS_X_VERSION_10_6)) +/* see darwin_warts.c */ +FUNC (ERR, int, SELECT_, select, select, "select") +#endif +FUNCD (ERR, int, SELECT_, select_darwinextsn, select, "select$DARWIN_EXTSN") +FUNCD (ERR, int, SELECT_, select_darwinextsn_nocancel, select, "select$DARWIN_EXTSN$NOCANCEL") +FUNCD32 (ERR, int, SELECT_, select_unix2003, select, "select$UNIX2003") +FUNCD32 (ERR, int, SELECT_, select_nocancel_unix2003, select, "select$NOCANCEL$UNIX2003") +FUNCD64 (ERR, int, SELECT_, select_nocancel, select, "select$NOCANCEL") +FUNCD64_106 (ERR, int, SELECT_, select_1050, select, "select$1050") + +FUNC (ERR, int, POLL_, poll, poll, "poll") +FUNCD32 (ERR, int, POLL_, poll_unix2003, poll, "poll$UNIX2003") +FUNCD32 (ERR, int, POLL_, poll_nocancel_unix2003, poll, "poll$NOCANCEL$UNIX2003") +FUNCD64 (ERR, int, POLL_, poll_nocancel, poll, "poll$NOCANCEL") + +FUNC (ERR, int, CLOSE_, close, close, "close") +FUNCD32 (ERR, int, CLOSE_, close_unix2003, close, "close$UNIX2003") +FUNCD32 (ERR, int, CLOSE_, close_nocancel_unix2003, close, "close$NOCANCEL$UNIX2003") +FUNCD64 (ERR, int, CLOSE_, close_nocancel, close, "close$NOCANCEL") + +FUNC (ERR, int, GETPEERNAME_, getpeername, getpeername, "getpeername") +FUNCD32 (ERR, int, GETPEERNAME_, getpeername_unix2003, getpeername, "getpeername$UNIX2003") diff --git a/src/tsocks.c b/src/tsocks.c index 92bca5b..2545e42 100644 --- a/src/tsocks.c +++ b/src/tsocks.c @@ -90,6 +90,7 @@ const char *progname = "libtorsocks"; /* Name used in err msgs */ #include <errno.h> #include <fcntl.h> #include <common.h> +#include <pthread.h> #include <stdarg.h> #if !defined(__APPLE__) && !defined(__darwin__) #include <sys/socket.h> @@ -101,105 +102,51 @@ const char *progname = "libtorsocks"; /* Name used in err msgs */ #include <tsocks.h> #include "dead_pool.h"
+/* Some function names are macroized on Darwin. Allow those names + to expand accordingly. */ +#define EXPAND_GUTS(x) tsocks_##x##_guts +#define EXPAND_GUTS_NAME(x) EXPAND_GUTS(x) + /* Global Declarations */ -#ifdef SUPPORT_RES_API -static int (*realresinit)(void); -static int (*realresquery)(RES_QUERY_SIGNATURE); -static int (*realressearch)(RES_SEARCH_SIGNATURE); -static int (*realressend)(RES_SEND_SIGNATURE); -static int (*realresquerydomain)(RES_QUERYDOMAIN_SIGNATURE); -#endif /*SUPPORT_RES_API*/ #ifdef USE_TOR_DNS static dead_pool *pool = NULL; -static struct hostent *(*realgethostbyname)(GETHOSTBYNAME_SIGNATURE); -static struct hostent *(*realgethostbyaddr)(GETHOSTBYADDR_SIGNATURE); -int (*realgetaddrinfo)(GETADDRINFO_SIGNATURE); -static struct hostent *(*realgetipnodebyname)(GETIPNODEBYNAME_SIGNATURE); -static ssize_t (*realsendto)(SENDTO_SIGNATURE); -static ssize_t (*realsendmsg)(SENDMSG_SIGNATURE); -#if defined(__APPLE__) || defined(__darwin__) -static ssize_t (*realsendto_unix2003)(SENDTO_SIGNATURE); -static ssize_t (*realsendto_nocancel)(SENDTO_SIGNATURE); -static ssize_t (*realsendmsg_unix2003)(SENDMSG_SIGNATURE); -static ssize_t (*realsendmsg_nocancel)(SENDMSG_SIGNATURE); -#endif #endif /*USE_TOR_DNS*/ -int (*realconnect)(CONNECT_SIGNATURE); -static int (*realselect)(SELECT_SIGNATURE); -static int (*realpoll)(POLL_SIGNATURE); -int (*realclose)(CLOSE_SIGNATURE); -static int (*realgetpeername)(GETPEERNAME_SIGNATURE); -#if defined(__APPLE__) || defined(__darwin__) -static int (*realconnect_unix2003)(CONNECT_SIGNATURE); -static int (*realconnect_nocancel)(CONNECT_SIGNATURE); -static int (*realselect_darwinextsn)(SELECT_SIGNATURE); -static int (*realselect_darwinextsn_nocancel)(SELECT_SIGNATURE); -static int (*realselect_unix2003)(SELECT_SIGNATURE); -static int (*realselect_nocancel)(SELECT_SIGNATURE); -static int (*realpoll_unix2003)(POLL_SIGNATURE); -static int (*realpoll_nocancel)(POLL_SIGNATURE); -static int (*realclose_unix2003)(CLOSE_SIGNATURE); -static int (*realclose_nocancel)(CLOSE_SIGNATURE); -static int (*realgetpeername_unix2003)(GETPEERNAME_SIGNATURE); + +/* Function prototypes for original functions that we patch */ +#ifdef SUPPORT_RES_API +int (*realres_init)(void); #endif +#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r (*real##n)(s##SIGNATURE); +#include "patch_table.h" +#undef PATCH_TABLE_EXPANSION +#undef DARWIN_EXPANSION
-static struct parsedfile *config; +static struct parsedfile config; static struct connreq *requests = NULL; static int suid = 0; static char *conffile = NULL; -static int tsocks_init_complete = 0; +static volatile int tsocks_init_complete = 0;
/* Exported Function Prototypes */ void __attribute__ ((constructor)) tsocks_init(void); -int connect(CONNECT_SIGNATURE); -int select(SELECT_SIGNATURE); -int poll(POLL_SIGNATURE); -int close(CLOSE_SIGNATURE); -int getpeername(GETPEERNAME_SIGNATURE); -#if defined(__APPLE__) || defined(__darwin__) -int connect_unix2003(CONNECT_SIGNATURE) __asm("_connect$UNIX2003"); -int connect_nocancel(CONNECT_SIGNATURE) __asm("_connect$NOCANCEL$UNIX2003"); -int select_darwinextsn(SELECT_SIGNATURE) __asm("_select$DARWIN_EXTSN"); -int select_darwinextsn_nocancel(SELECT_SIGNATURE) __asm("_select$DARWIN_EXTSN$NOCANCEL"); -int select_unix2003(SELECT_SIGNATURE) __asm("_select$UNIX2003"); -int select_nocancel(SELECT_SIGNATURE) __asm("_select$NOCANCEL$UNIX2003"); -int poll_unix2003(POLL_SIGNATURE) __asm("_poll$UNIX2003"); -int poll_nocancel(POLL_SIGNATURE) __asm("_poll$NOCANCEL$UNIX2003"); -int close_unix2003(CLOSE_SIGNATURE) __asm("_close$UNIX2003"); -int close_nocancel(CLOSE_SIGNATURE) __asm("_close$NOCANCEL$UNIX2003"); -int getpeername_unxi2003(GETPEERNAME_SIGNATURE) __asm("_getpeername$UNIX2003"); -#endif
+/* Function prototypes for our patches */ #ifdef SUPPORT_RES_API int res_init(void); -int res_query(RES_QUERY_SIGNATURE); -int res_search(RES_SEARCH_SIGNATURE); -int res_querydomain(RES_QUERYDOMAIN_SIGNATURE); -int res_send(RES_SEND_SIGNATURE); -#endif -#ifdef USE_TOR_DNS -struct hostent *gethostbyname(GETHOSTBYNAME_SIGNATURE); -struct hostent *gethostbyaddr(GETHOSTBYADDR_SIGNATURE); -int getaddrinfo(GETADDRINFO_SIGNATURE); -struct hostent *getipnodebyname(GETIPNODEBYNAME_SIGNATURE); -ssize_t sendto(SENDTO_SIGNATURE); -ssize_t sendmsg(SENDMSG_SIGNATURE); -#if defined(__APPLE__) || defined(__darwin__) -ssize_t sendto_unix2003(SENDTO_SIGNATURE) __asm("_sendto$UNIX2003"); -ssize_t sendto_nocancel(SENDTO_SIGNATURE) __asm("_sendto$NOCANCEL$UNIX2003"); -ssize_t sendmsg_unix2003(SENDMSG_SIGNATURE) __asm("_sendmsg$UNIX2003"); -ssize_t sendmsg_nocancel(SENDMSG_SIGNATURE) __asm("_sendmsg$NOCANCEL$UNIX2003"); -#endif #endif /*USE_TOR_DNS*/
+#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r n(s##SIGNATURE); +#define DARWIN_EXPANSION(e,r,s,n,b,m) r n(s##SIGNATURE) __asm("_" m); +#include "patch_table.h" +#undef PATCH_TABLE_EXPANSION +#undef DARWIN_EXPANSION + /* Private Function Prototypes */ -static int tsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIGNATURE)); -static int tsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE)); -static int tsocks_poll_guts(POLL_SIGNATURE, int (*original_poll)(POLL_SIGNATURE)); -static int tsocks_close_guts(CLOSE_SIGNATURE, int (*original_close)(CLOSE_SIGNATURE)); -static int tsocks_getpeername_guts(GETPEERNAME_SIGNATURE, int (*original_getpeername)(GETPEERNAME_SIGNATURE)); -static ssize_t tsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO_SIGNATURE)); -static ssize_t tsocks_sendmsg_guts(SENDMSG_SIGNATURE, ssize_t (*original_sendmsg)(SENDMSG_SIGNATURE)); +/* no tsocks_res_init_guts */ +#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r tsocks_##b##_guts(s##SIGNATURE, r (*original_##b)(s##SIGNATURE)); +#include "patch_table.h" +#undef PATCH_TABLE_EXPANSION +
static int get_config(); static int get_environment(); @@ -227,6 +174,8 @@ static int deadpool_init(void); static int send_socksv4a_request(struct connreq *conn, const char *onion_host); #endif
+static pthread_mutex_t tsocks_init_mutex = PTHREAD_MUTEX_INITIALIZER; + void tsocks_init(void) {
#define LOAD_ERROR(s,l) { \ @@ -238,6 +187,8 @@ void tsocks_init(void) { dlerror(); \ }
+ pthread_mutex_lock(&tsocks_init_mutex); + /* We only need to be called once */ if (tsocks_init_complete) { return; @@ -249,10 +200,10 @@ void tsocks_init(void) {
show_msg(MSGWARN, "In tsocks_init \n");
-// get_environment(); -// get_config(); -// -// show_msg(MSGWARN, "In tsocks_init after env/config\n"); + get_environment(); + get_config(); + + show_msg(MSGWARN, "In tsocks_init after env/config\n");
#ifdef USE_OLD_DLSYM void *lib; @@ -267,95 +218,13 @@ void tsocks_init(void) {
dlerror(); #ifndef USE_OLD_DLSYM - if ((realconnect = dlsym(RTLD_NEXT, "connect")) == NULL) - LOAD_ERROR("connect", MSGERR); -#if defined(__APPLE__) || defined(__darwin__) - if ((realconnect_unix2003 = dlsym(RTLD_NEXT, "connect$UNIX2003")) == NULL) - LOAD_ERROR("connect$UNIX2003", MSGERR); - if ((realconnect_nocancel = dlsym(RTLD_NEXT, "connect$NOCANCEL$UNIX2003")) == NULL) - LOAD_ERROR("connect$NOCANCEL$UNIX2003", MSGERR); -#endif - - if ((realselect = dlsym(RTLD_NEXT, "select")) == NULL) - LOAD_ERROR("select", MSGERR); -#if defined(__APPLE__) || defined(__darwin__) - if ((realselect_darwinextsn = dlsym(RTLD_NEXT, "select$DARWIN_EXTSN")) == NULL) - LOAD_ERROR("select$DARWIN_EXTSN", MSGERR); - if ((realselect_darwinextsn_nocancel = dlsym(RTLD_NEXT, "select$DARWIN_EXTSN$NOCANCEL")) == NULL) - LOAD_ERROR("select$DARWIN_EXTSN$NOCANCEL", MSGERR); - if ((realselect_unix2003 = dlsym(RTLD_NEXT, "select$UNIX2003")) == NULL) - LOAD_ERROR("select$UNIX2003", MSGERR); - if ((realselect_nocancel = dlsym(RTLD_NEXT, "select$NOCANCEL$UNIX2003")) == NULL) - LOAD_ERROR("select$NOCANCEL$UNIX2003", MSGERR); -#endif - - if ((realpoll = dlsym(RTLD_NEXT, "poll")) == NULL) - LOAD_ERROR("poll", MSGERR); -#if defined(__APPLE__) || defined(__darwin__) - if ((realpoll_unix2003 = dlsym(RTLD_NEXT, "poll$UNIX2003")) == NULL) - LOAD_ERROR("poll$UNIX2003", MSGERR); - if ((realpoll_nocancel = dlsym(RTLD_NEXT, "poll$NOCANCEL$UNIX2003")) == NULL) - LOAD_ERROR("poll$NOCANCEL$UNIX2003", MSGERR); -#endif - - if ((realclose = dlsym(RTLD_NEXT, "close")) == NULL) - LOAD_ERROR("close", MSGERR); -#if defined(__APPLE__) || defined(__darwin__) - if ((realclose_unix2003 = dlsym(RTLD_NEXT, "close$UNIX2003")) == NULL) - LOAD_ERROR("close$UNIX2003", MSGERR); - if ((realclose_nocancel = dlsym(RTLD_NEXT, "close$NOCANCEL$UNIX2003")) == NULL) - LOAD_ERROR("close$NOCANCEL$UNIX2003", MSGERR); -#endif - - if ((realgetpeername = dlsym(RTLD_NEXT, "getpeername")) == NULL) - LOAD_ERROR("getpeername", MSGERR); -#if defined(__APPLE__) || defined(__darwin__) - if ((realgetpeername_unix2003 = dlsym(RTLD_NEXT, "getpeername$UNIX2003")) == NULL) - LOAD_ERROR("getpeername$UNIX2003", MSGERR); -#endif - - #ifdef SUPPORT_RES_API - if ((realresinit = dlsym(RTLD_NEXT, "res_init")) == NULL) - LOAD_ERROR("res_init", MSGERR); - if ((realresquery = dlsym(RTLD_NEXT, "res_query")) == NULL) - LOAD_ERROR("res_query", MSGERR); - if ((realressearch = dlsym(RTLD_NEXT, "res_search")) == NULL) - LOAD_ERROR("res_search", MSGERR); - if ((realresquerydomain = dlsym(RTLD_NEXT, "res_querydomain")) == NULL) - LOAD_ERROR("res_querydomain", MSGERR); - if ((realressend = dlsym(RTLD_NEXT, "res_send")) == NULL) - LOAD_ERROR("res_send", MSGERR); - #endif - #ifdef USE_TOR_DNS - if ((realgethostbyname = dlsym(RTLD_NEXT, "gethostbyname")) == NULL) - LOAD_ERROR("gethostbyname", MSGERR); - if ((realgethostbyaddr = dlsym(RTLD_NEXT, "gethostbyaddr")) == NULL) - LOAD_ERROR("gethostbyaddr", MSGERR); - if ((realgetaddrinfo = dlsym(RTLD_NEXT, "getaddrinfo")) == NULL) - LOAD_ERROR("getaddrinfo", MSGERR); - /* getipnodebyname is deprecated so do not report an error if it is not - available.*/ - if ((realgetipnodebyname = dlsym(RTLD_NEXT, "getipnodebyname")) == NULL) - LOAD_ERROR("getipnodebyname", MSGWARN); - - if ((realsendto = dlsym(RTLD_NEXT, "sendto")) == NULL) - LOAD_ERROR("sendto", MSGERR); -#if defined(__APPLE__) || defined(__darwin__) - if ((realsendto_unix2003 = dlsym(RTLD_NEXT, "sendto$UNIX2003")) == NULL) - LOAD_ERROR("sendto$UNIX2003", MSGERR); - if ((realsendto_nocancel = dlsym(RTLD_NEXT, "sendto$NOCANCEL$UNIX2003")) == NULL) - LOAD_ERROR("sendto$NOCANCEL$UNIX2003", MSGERR); -#endif - - if ((realsendmsg = dlsym(RTLD_NEXT, "sendmsg")) == NULL) - LOAD_ERROR("sendmsg", MSGERR); -#if defined(__APPLE__) || defined(__darwin__) - if ((realsendmsg_unix2003 = dlsym(RTLD_NEXT, "sendmsg$UNIX2003")) == NULL) - LOAD_ERROR("sendmsg$UNIX2003", MSGERR); - if ((realsendmsg_nocancel = dlsym(RTLD_NEXT, "sendmsg$NOCANCEL$UNIX2003")) == NULL) - LOAD_ERROR("sendmsg$NOCANCEL$UNIX2003", MSGERR); -#endif - #endif /*USE_TOR_DNS*/ + #ifdef SUPPORT_RES_API + if ((realres_init = dlsym(RTLD_NEXT, "res_init")) == NULL) + LOAD_ERROR("res_init", MSGERR); + #endif + #define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) if ((real##n = dlsym(RTLD_NEXT, m)) == NULL) LOAD_ERROR(m, MSG##e); + #include "patch_table.h" + #undef PATCH_TABLE_EXPANSION #else lib = dlopen(LIBCONNECT, RTLD_LAZY); realconnect = dlsym(lib, "connect"); @@ -375,7 +244,7 @@ void tsocks_init(void) { dlclose(lib); #ifdef SUPPORT_RES_API lib = dlopen(LIBRESOLV, RTLD_LAZY); - realresinit = dlsym(lib, "res_init"); + realres_init = dlsym(lib, "res_init"); realresquery = dlsym(lib, "res_query"); realressend = dlsym(lib, "res_send"); realresquerydomain = dlsym(lib, "res_querydomain"); @@ -388,7 +257,10 @@ void tsocks_init(void) { area won't be shared across fork()s. */ deadpool_init(); #endif + tsocks_init_complete=1; + pthread_mutex_unlock(&tsocks_init_mutex);
+ show_msg(MSGWARN, "Exit tsocks_init \n"); }
static int get_environment() { @@ -431,123 +303,31 @@ static int get_config () { #endif
/* Read in the config file */ - config = malloc(sizeof(*config)); +/* config = malloc(sizeof(*config)); if (!config) - return(0); - read_config(conffile, config); - if (config->paths) - show_msg(MSGDEBUG, "First lineno for first path is %d\n", config->paths->lineno); + return(0);*/ + read_config(conffile, &config); + if (config.paths) + show_msg(MSGDEBUG, "First lineno for first path is %d\n", config.paths->lineno);
done = 1;
return(0); }
-#define PATCH_CONNECT(funcname, symbolname) \ - int funcname(CONNECT_SIGNATURE) { \ - if (!real ## funcname) { \ - dlerror(); \ - if ((real ## funcname = dlsym(RTLD_NEXT, symbolname)) == NULL) \ - LOAD_ERROR(symbolname, MSGERR); \ - } \ - return tsocks_connect_guts(__fd, __addr, __len, real ## funcname); \ - } -PATCH_CONNECT(connect, "connect") -#if defined(__APPLE__) || defined(__darwin__) -PATCH_CONNECT(connect_unix2003, "conncect$UNIX2003") -PATCH_CONNECT(connect_nocancel, "conncect$NOCANCEL$UNIX2003") -#endif - -#define PATCH_CLOSE(funcname, symbolname) \ - int funcname(CLOSE_SIGNATURE) { \ - if (!real ## funcname) { \ - dlerror(); \ - if ((real ## funcname = dlsym(RTLD_NEXT, symbolname)) == NULL) \ - LOAD_ERROR(symbolname, MSGERR); \ - } \ - return tsocks_close_guts(fd, real ## funcname); \ - } -PATCH_CLOSE(close, "close") -#if defined(__APPLE__) || defined(__darwin__) -PATCH_CLOSE(close_unix2003, "close$UNIX2003") -PATCH_CLOSE(close_nocancel, "close$NOCANCEL$UNIX2003") -#endif - -#define PATCH_SELECT(funcname, symbolname) \ - int funcname(SELECT_SIGNATURE) { \ - if (!real ## funcname) { \ - dlerror(); \ - if ((real ## funcname = dlsym(RTLD_NEXT, symbolname)) == NULL) \ - LOAD_ERROR(symbolname, MSGERR); \ - } \ - return tsocks_select_guts(n, readfds, writefds, exceptfds, timeout, real ## funcname); \ - } -PATCH_SELECT(select, "select") -#if defined(__APPLE__) || defined(__darwin__) -PATCH_SELECT(select_darwinextsn, "select$DARWIN_EXTSN") -PATCH_SELECT(select_darwinextsn_nocancel, "select$DARWIN_EXTSN$NOCANCEL") -PATCH_SELECT(select_unix2003, "select$UNIX2003") -PATCH_SELECT(select_nocancel, "select$NOCANCEL$UNIX2003") -#endif - -#define PATCH_POLL(funcname, symbolname) \ - int funcname(POLL_SIGNATURE) { \ - if (!real ## funcname) { \ - dlerror(); \ - if ((real ## funcname = dlsym(RTLD_NEXT, symbolname)) == NULL) \ - LOAD_ERROR(symbolname, MSGERR); \ - } \ - return tsocks_poll_guts(ufds, nfds, timeout, real ## funcname); \ - } -PATCH_POLL(poll, "poll") -#if defined(__APPLE__) || defined(__darwin__) -PATCH_POLL(poll_unix2003, "poll$UNIX2003") -PATCH_POLL(poll_nocancel, "poll$NOCANCEL$UNIX2003") -#endif - -#define PATCH_GETPEERNAME(funcname, symbolname) \ - int funcname(GETPEERNAME_SIGNATURE) { \ - if (!real ## funcname) { \ - dlerror(); \ - if ((real ## funcname = dlsym(RTLD_NEXT, symbolname)) == NULL) \ - LOAD_ERROR(symbolname, MSGERR); \ - } \ - return tsocks_getpeername_guts(__fd, __name, __namelen, real ## funcname); \ - } -PATCH_GETPEERNAME(getpeername, "getpeername") -#if defined(__APPLE__) || defined(__darwin__) -PATCH_GETPEERNAME(getpeername_unix2003, "getpeername$UNIX2003") -#endif - -#define PATCH_SENDTO(funcname, symbolname) \ - ssize_t funcname(SENDTO_SIGNATURE) { \ - if (!real ## funcname) { \ - dlerror(); \ - if ((real ## funcname = dlsym(RTLD_NEXT, symbolname)) == NULL) \ - LOAD_ERROR(symbolname, MSGERR); \ - } \ - return tsocks_sendto_guts(s, buf, len, flags, to, tolen, real ## funcname); \ - } -PATCH_SENDTO(sendto, "sendto") -#if defined(__APPLE__) || defined(__darwin__) -PATCH_SENDTO(sendto_unix2003, "sendto$UNIX2003") -PATCH_SENDTO(sendto_nocancel, "sendto$NOCANCEL$UNIX2003") -#endif - -#define PATCH_SENDMSG(funcname, symbolname) \ - ssize_t funcname(SENDMSG_SIGNATURE) { \ - if (!real ## funcname) { \ - dlerror(); \ - if ((real ## funcname = dlsym(RTLD_NEXT, symbolname)) == NULL) \ - LOAD_ERROR(symbolname, MSGERR); \ - } \ - return tsocks_sendmsg_guts(s, msg, flags, real ## funcname); \ - } -PATCH_SENDMSG(sendmsg, "sendmsg") -#if defined(__APPLE__) || defined(__darwin__) -PATCH_SENDMSG(sendmsg_unix2003, "sendmsg$UNIX2003") -PATCH_SENDMSG(sendmsg_nocancel, "sendmsg$NOCANCEL$UNIX2003") -#endif +/* Patch trampoline functions */ +/* no tsocks_res_init_guts */ +#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) \ + r n(s##SIGNATURE) { \ + if (!real##n) { \ + dlerror(); \ + if ((real##n = dlsym(RTLD_NEXT, m)) == NULL) \ + LOAD_ERROR(m, MSG##e); \ + } \ + return tsocks_##b##_guts(s##ARGNAMES, real##n); \ + } +#include "patch_table.h" +#undef PATCH_TABLE_EXPANSION
int tsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIGNATURE)) { struct sockaddr_in *connaddr; @@ -662,22 +442,22 @@ int tsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIGNA
/* If the address is local call original_connect */ #ifdef USE_TOR_DNS - if (!(is_local(config, &(connaddr->sin_addr))) && + if (!(is_local(&config, &(connaddr->sin_addr))) && !is_dead_address(pool, connaddr->sin_addr.s_addr)) { #else - if (!(is_local(config, &(connaddr->sin_addr)))) { + if (!(is_local(&config, &(connaddr->sin_addr)))) { #endif show_msg(MSGDEBUG, "Connection for socket %d is local\n", __fd); return(original_connect(__fd, __addr, __len)); }
/* Ok, so its not local, we need a path to the net */ - pick_server(config, &path, &(connaddr->sin_addr), ntohs(connaddr->sin_port)); + pick_server(&config, &path, &(connaddr->sin_addr), ntohs(connaddr->sin_port));
show_msg(MSGDEBUG, "Picked server %s for connection\n", (path->address ? path->address : "(Not Provided)")); if (path->address == NULL) { - if (path == &(config->defaultserver)) + if (path == &(config.defaultserver)) show_msg(MSGERR, "Connection needs to be made " "via default server but " "the default server has not " @@ -701,7 +481,7 @@ int tsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIGNA bzero(&(server_address.sin_zero), 8);
/* Complain if this server isn't on a localnet */ - if (is_local(config, &server_address.sin_addr)) { + if (is_local(&config, &server_address.sin_addr)) { show_msg(MSGERR, "SOCKS server %s (%s) is not on a local subnet!\n", path->address, inet_ntoa(server_address.sin_addr)); } else @@ -1078,6 +858,13 @@ int tsocks_close_guts(CLOSE_SIGNATURE, int (*original_close)(CLOSE_SIGNATURE)) { int rc; struct connreq *conn;
+ /* If we're not currently managing any requests we can just + * leave here */ + if (!requests) { + show_msg(MSGDEBUG, "No requests waiting, calling real close\n"); + return(original_close(fd)); + } + /* If we are called before this symbol has been dlopened then try loading symbols now. This is a workaround for a problem I don't really understand and have only encountered when using torsocks @@ -1712,8 +1499,8 @@ static int read_socksv4_req(struct connreq *conn) { int res_init(void) { int rc;
- if (!realresinit) { - if ((realresinit = dlsym(RTLD_NEXT, "res_init")) == NULL) + if (!realres_init) { + if ((realres_init = dlsym(RTLD_NEXT, "res_init")) == NULL) LOAD_ERROR("res_init", MSGERR); }
@@ -1724,23 +1511,23 @@ int res_init(void) { tsocks_init(); }
- if (realresinit == NULL) { + if (realres_init == NULL) { show_msg(MSGERR, "Unresolved symbol: res_init\n"); return(-1); } /* Call normal res_init */ - rc = realresinit(); + rc = realres_init();
/* Force using TCP protocol for DNS queries */ _res.options |= RES_USEVC; return(rc); }
-int res_query(RES_QUERY_SIGNATURE) { +int EXPAND_GUTS_NAME(res_query)(RES_QUERY_SIGNATURE, int (*original_res_query)(RES_QUERY_SIGNATURE)) { int rc;
- if (!realresquery) { - if ((realresquery = dlsym(RTLD_NEXT, "res_query")) == NULL) + if (!original_res_query) { + if ((original_res_query = dlsym(RTLD_NEXT, "res_query")) == NULL) LOAD_ERROR("res_query", MSGERR); }
@@ -1751,7 +1538,7 @@ int res_query(RES_QUERY_SIGNATURE) { tsocks_init(); }
- if (realresquery == NULL) { + if (original_res_query == NULL) { show_msg(MSGERR, "Unresolved symbol: res_query\n"); return(-1); } @@ -1762,16 +1549,16 @@ int res_query(RES_QUERY_SIGNATURE) { res_init();
/* Call normal res_query */ - rc = realresquery(dname, class, type, answer, anslen); + rc = original_res_query(dname, class, type, answer, anslen);
return(rc); }
-int res_querydomain(RES_QUERYDOMAIN_SIGNATURE) { +int EXPAND_GUTS_NAME(res_querydomain)(RES_QUERYDOMAIN_SIGNATURE, int (*original_res_querydomain)(RES_QUERYDOMAIN_SIGNATURE)) { int rc;
- if (!realresquerydomain) { - if ((realresquerydomain = dlsym(RTLD_NEXT, "res_querydomain")) == NULL) + if (!original_res_querydomain) { + if ((original_res_querydomain = dlsym(RTLD_NEXT, "res_querydomain")) == NULL) LOAD_ERROR("res_querydoimain", MSGERR); }
@@ -1782,7 +1569,7 @@ int res_querydomain(RES_QUERYDOMAIN_SIGNATURE) { tsocks_init(); }
- if (realresquerydomain == NULL) { + if (original_res_querydomain == NULL) { show_msg(MSGERR, "Unresolved symbol: res_querydomain\n"); return(-1); } @@ -1793,16 +1580,16 @@ int res_querydomain(RES_QUERYDOMAIN_SIGNATURE) { res_init();
/* Call normal res_querydomain */ - rc = realresquerydomain(name, domain, class, type, answer, anslen); + rc = original_res_querydomain(name, domain, class, type, answer, anslen);
return(rc); }
-int res_search(RES_SEARCH_SIGNATURE) { +int EXPAND_GUTS_NAME(res_search)(RES_SEARCH_SIGNATURE, int (*original_res_search)(RES_SEARCH_SIGNATURE)) { int rc;
- if (!realressearch) { - if ((realressearch = dlsym(RTLD_NEXT, "res_search")) == NULL) + if (!original_res_search) { + if ((original_res_search = dlsym(RTLD_NEXT, "res_search")) == NULL) LOAD_ERROR("res_search", MSGERR); }
@@ -1813,7 +1600,7 @@ int res_search(RES_SEARCH_SIGNATURE) { tsocks_init(); }
- if (realressearch == NULL) { + if (original_res_search == NULL) { show_msg(MSGERR, "Unresolved symbol: res_search\n"); return(-1); } @@ -1824,16 +1611,16 @@ int res_search(RES_SEARCH_SIGNATURE) { res_init();
/* Call normal res_search */ - rc = realressearch(dname, class, type, answer, anslen); + rc = original_res_search(dname, class, type, answer, anslen);
return(rc); }
-int res_send(RES_SEND_SIGNATURE) { +int EXPAND_GUTS_NAME(res_send)(RES_SEND_SIGNATURE, int (*original_res_send)(RES_SEND_SIGNATURE)) { int rc;
- if (!realressend) { - if ((realressend = dlsym(RTLD_NEXT, "res_send")) == NULL) + if (!original_res_send) { + if ((original_res_send = dlsym(RTLD_NEXT, "res_send")) == NULL) LOAD_ERROR("res_send", MSGERR); }
@@ -1844,7 +1631,7 @@ int res_send(RES_SEND_SIGNATURE) { tsocks_init(); }
- if (realressend == NULL) { + if (original_res_send == NULL) { show_msg(MSGERR, "Unresolved symbol: res_send\n"); return(-1); } @@ -1855,7 +1642,7 @@ int res_send(RES_SEND_SIGNATURE) { res_init();
/* Call normal res_send */ - rc = realressend(msg, msglen, answer, anslen); + rc = original_res_send(msg, msglen, answer, anslen);
return(rc); } @@ -1866,13 +1653,13 @@ static int deadpool_init(void) if(!pool) { get_environment(); get_config(); - if(config->tordns_enabled) { + if(config.tordns_enabled) { pool = init_pool( - config->tordns_cache_size, - config->tordns_deadpool_range->localip, - config->tordns_deadpool_range->localnet, - config->defaultserver.address, - config->defaultserver.port + config.tordns_cache_size, + config.tordns_deadpool_range->localip, + config.tordns_deadpool_range->localnet, + config.defaultserver.address, + config.defaultserver.port ); if(!pool) { show_msg(MSGERR, "failed to initialize deadpool: tordns disabled\n"); @@ -1882,39 +1669,39 @@ static int deadpool_init(void) return 0; }
-struct hostent *gethostbyname(GETHOSTBYNAME_SIGNATURE) +struct hostent *tsocks_gethostbyname_guts(GETHOSTBYNAME_SIGNATURE, struct hostent *(*original_gethostbyname)(GETHOSTBYNAME_SIGNATURE)) { if(pool) { return our_gethostbyname(pool, name); } else { - return realgethostbyname(name); + return original_gethostbyname(name); } }
-struct hostent *gethostbyaddr(GETHOSTBYADDR_SIGNATURE) +struct hostent *tsocks_gethostbyaddr_guts(GETHOSTBYADDR_SIGNATURE, struct hostent *(*original_gethostbyaddr)(GETHOSTBYADDR_SIGNATURE)) { if(pool) { return our_gethostbyaddr(pool, addr, len, type); } else { - return realgethostbyaddr(addr, len, type); + return original_gethostbyaddr(addr, len, type); } }
-int getaddrinfo(GETADDRINFO_SIGNATURE) +int tsocks_getaddrinfo_guts(GETADDRINFO_SIGNATURE, int (*original_getaddrinfo)(GETADDRINFO_SIGNATURE)) { if(pool) { return our_getaddrinfo(pool, node, service, hints, res); } else { - return realgetaddrinfo(node, service, hints, res); + return original_getaddrinfo(node, service, hints, res); } }
-struct hostent *getipnodebyname(GETIPNODEBYNAME_SIGNATURE) +struct hostent *tsocks_getipnodebyname_guts(GETIPNODEBYNAME_SIGNATURE, struct hostent *(*original_getipnodebyname)(GETIPNODEBYNAME_SIGNATURE)) { if(pool) { return our_getipnodebyname(pool, name, af, flags, error_num); } else { - return realgetipnodebyname(name, af, flags, error_num); + return original_getipnodebyname(name, af, flags, error_num); } }