summaryrefslogtreecommitdiff
path: root/netcon
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2016-01-11 15:27:22 -0800
committerAdam Ierymenko <adam.ierymenko@gmail.com>2016-01-11 15:27:22 -0800
commitc6571073feb5eeb2cdd5fe102871fafba43b8c17 (patch)
tree41acc0ae6e242b1a47880811e1295d73128a990c /netcon
parentba9fcb31d06e31f4b31a114093aee93054eb931a (diff)
downloadinfinitytier-c6571073feb5eeb2cdd5fe102871fafba43b8c17.tar.gz
infinitytier-c6571073feb5eeb2cdd5fe102871fafba43b8c17.zip
Get rid of constructor/destructor in libzerotierintercept, and simplify a few things.
Diffstat (limited to 'netcon')
-rw-r--r--netcon/Intercept.c173
-rw-r--r--netcon/Intercept.h25
2 files changed, 77 insertions, 121 deletions
diff --git a/netcon/Intercept.c b/netcon/Intercept.c
index e89f6a9f..5b0b3480 100644
--- a/netcon/Intercept.c
+++ b/netcon/Intercept.c
@@ -58,15 +58,11 @@
#include "RPC.h"
#include "common.inc.c"
-static void load_symbols(void);
-static void set_up_intercept();
-
/*------------------------------------------------------------------------------
------------------- Intercept<--->Service Comm mechanisms ----------------------
------------------------------------------------------------------------------*/
-static int thispid = -1;
-char *network_pathname;
+static char *network_pathname = (char *)0;
/* Check whether the socket is mapped to the service or not. We
need to know if this is a regular AF_LOCAL socket or an end of a socketpair
@@ -87,59 +83,48 @@ static int connected_to_service(int sockfd)
dwr(MSG_DEBUG_EXTRA,"connected_to_service(): Yes, %s\n", addr_un->sun_path);
return 1;
}
- }
- dwr(MSG_DEBUG_EXTRA,"connected_to_service(): Not connected to service\n");
+ }
+ dwr(MSG_DEBUG_EXTRA,"connected_to_service(): Not connected to service\n");
return 0;
}
-
-/*------------------------------------------------------------------------------
------------------------- ctors and dtors (and friends) ------------------------
-------------------------------------------------------------------------------*/
-
-static void my_dest(void) __attribute__ ((destructor));
+/*static void my_dest(void) __attribute__ ((destructor));
static void my_dest(void) {
dwr(MSG_DEBUG,"closing connections to service...\n");
rpc_mutex_destroy();
-}
-
-static void load_symbols(void)
-{
- if(thispid == getpid()) {
- dwr(MSG_DEBUG,"detected duplicate call to global constructor (pid=%d).\n", thispid);
- }
- thispid = getpid();
- realconnect = dlsym(RTLD_NEXT, "connect");
- realbind = dlsym(RTLD_NEXT, "bind");
- realaccept = dlsym(RTLD_NEXT, "accept");
- reallisten = dlsym(RTLD_NEXT, "listen");
- realsocket = dlsym(RTLD_NEXT, "socket");
- realbind = dlsym(RTLD_NEXT, "bind");
- realsetsockopt = dlsym(RTLD_NEXT, "setsockopt");
- realgetsockopt = dlsym(RTLD_NEXT, "getsockopt");
- realaccept4 = dlsym(RTLD_NEXT, "accept4");
- realclone = dlsym(RTLD_NEXT, "clone");
- realclose = dlsym(RTLD_NEXT, "close");
- realsyscall = dlsym(RTLD_NEXT, "syscall");
- realdup2 = dlsym(RTLD_NEXT, "dup2");
- realdup3 = dlsym(RTLD_NEXT, "dup3");
- realgetsockname = dlsym(RTLD_NEXT, "getsockname");
-}
+}*/
/* Private Function Prototypes */
-static void _init(void) __attribute__ ((constructor));
-static void _init(void) { set_up_intercept(); }
+/*static void _init(void) __attribute__ ((constructor));
+static void _init(void) { set_up_intercept(); } */
/* get symbols and initialize mutexes */
-static void set_up_intercept()
+static int set_up_intercept()
{
- network_pathname = getenv("ZT_NC_NETWORK");
- dwr(MSG_DEBUG,"Connecting to service at: %s\n", network_pathname);
- if (!getenv("ZT_NC_NETWORK"))
- return;
- /* Hook/intercept Posix net API symbols */
- rpc_mutex_init();
- load_symbols();
+ if (!realconnect) {
+ realconnect = dlsym(RTLD_NEXT, "connect");
+ realbind = dlsym(RTLD_NEXT, "bind");
+ realaccept = dlsym(RTLD_NEXT, "accept");
+ reallisten = dlsym(RTLD_NEXT, "listen");
+ realsocket = dlsym(RTLD_NEXT, "socket");
+ realbind = dlsym(RTLD_NEXT, "bind");
+ realsetsockopt = dlsym(RTLD_NEXT, "setsockopt");
+ realgetsockopt = dlsym(RTLD_NEXT, "getsockopt");
+ realaccept4 = dlsym(RTLD_NEXT, "accept4");
+ realclose = dlsym(RTLD_NEXT, "close");
+ realsyscall = dlsym(RTLD_NEXT, "syscall");
+ realgetsockname = dlsym(RTLD_NEXT, "getsockname");
+ }
+
+ if (!network_pathname) {
+ network_pathname = getenv("ZT_NC_NETWORK");
+ if (!network_pathname)
+ return 0;
+ dwr(MSG_DEBUG,"Connecting to service at: %s\n", network_pathname);
+ /* Hook/intercept Posix net API symbols */
+ rpc_mutex_init();
+ }
+ return 1;
}
/*------------------------------------------------------------------------------
@@ -149,10 +134,9 @@ static void set_up_intercept()
/* int socket, int level, int option_name, const void *option_value, socklen_t option_len */
int setsockopt(SETSOCKOPT_SIG)
{
- if(realsetsockopt == NULL){
- dwr(MSG_ERROR,"setsockopt(): SYMBOL NOT FOUND.\n");
- return -1;
- }
+ if (!set_up_intercept())
+ return realsetsockopt(socket, level, option_name, option_value, option_len);
+
dwr(MSG_DEBUG,"setsockopt(%d)\n", socket);
/* return(realsetsockopt(socket, level, option_name, option_value, option_len)); */
if(level == SOL_IPV6 && option_name == IPV6_V6ONLY)
@@ -177,10 +161,9 @@ int setsockopt(SETSOCKOPT_SIG)
/* int sockfd, int level, int optname, void *optval, socklen_t *optlen */
int getsockopt(GETSOCKOPT_SIG)
{
- if(realgetsockopt == NULL){
- dwr(MSG_ERROR,"getsockopt(): SYMBOL NOT FOUND.\n");
- return -1;
- }
+ if (!set_up_intercept())
+ return realgetsockopt(sockfd, level, optname, optval, optlen);
+
dwr(MSG_DEBUG,"getsockopt(%d)\n", sockfd);
if(!connected_to_service(sockfd)) {
return realgetsockopt(sockfd, level, optname, optval, optlen);
@@ -200,9 +183,10 @@ int getsockopt(GETSOCKOPT_SIG)
/* int socket_family, int socket_type, int protocol
socket() intercept function */
int socket(SOCKET_SIG)
-{
- if(realsocket == NULL)
- set_up_intercept();
+{
+ if (!set_up_intercept())
+ return realsocket(socket_family, socket_type, protocol);
+
dwr(MSG_DEBUG,"socket():\n");
/* Check that type makes sense */
int flags = socket_type & ~SOCK_TYPE_MASK;
@@ -246,10 +230,9 @@ int socket(SOCKET_SIG)
connect() intercept function */
int connect(CONNECT_SIG)
{
- if(realconnect == NULL){
- dwr(MSG_ERROR,"connect(): SYMBOL NOT FOUND.\n");
- return -1;
- }
+ if (!set_up_intercept())
+ return realconnect(__fd, __addr, __len);
+
dwr(MSG_DEBUG,"connect(%d):\n", __fd);
struct sockaddr_in *connaddr;
connaddr = (struct sockaddr_in *) __addr;
@@ -298,10 +281,9 @@ int connect(CONNECT_SIG)
bind() intercept function */
int bind(BIND_SIG)
{
- if(realbind == NULL){
- dwr(MSG_ERROR,"bind(): SYMBOL NOT FOUND.\n");
- return -1;
- }
+ if (!set_up_intercept())
+ return realbind(sockfd, addr, addrlen);
+
dwr(MSG_DEBUG,"bind(%d):\n", sockfd);
/* Check that this is a valid fd */
if(fcntl(sockfd, F_GETFD) < 0) {
@@ -353,10 +335,6 @@ int bind(BIND_SIG)
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
int accept4(ACCEPT4_SIG)
{
- if(realaccept4 == NULL){
- dwr(MSG_ERROR,"accept4(): SYMBOL NOT FOUND.\n");
- return -1;
- }
dwr(MSG_DEBUG,"accept4(%d):\n", sockfd);
if ((flags & SOCK_CLOEXEC))
fcntl(sockfd, F_SETFL, FD_CLOEXEC);
@@ -373,10 +351,9 @@ int accept4(ACCEPT4_SIG)
accept() intercept function */
int accept(ACCEPT_SIG)
{
- if(realaccept == NULL){
- dwr(MSG_ERROR,"accept(): SYMBOL NOT FOUND.\n");
- return -1;
- }
+ if (!set_up_intercept())
+ return realaccept(sockfd, addr, addrlen);
+
dwr(MSG_DEBUG,"accept(%d):\n", sockfd);
/* Check that this is a valid fd */
if(fcntl(sockfd, F_GETFD) < 0) {
@@ -441,10 +418,9 @@ int accept(ACCEPT_SIG)
/* int sockfd, int backlog */
int listen(LISTEN_SIG)
{
- if(reallisten == NULL){
- dwr(MSG_ERROR,"listen(): SYMBOL NOT FOUND.\n");
- return -1;
- }
+ if (!set_up_intercept())
+ return(reallisten(sockfd, backlog));
+
dwr(MSG_DEBUG,"listen(%d):\n", sockfd);
int sock_type;
socklen_t sock_type_len = sizeof(sock_type);
@@ -480,23 +456,6 @@ int listen(LISTEN_SIG)
}
/*------------------------------------------------------------------------------
--------------------------------------- clone() ---------------------------------
-------------------------------------------------------------------------------*/
-
-/* int (*fn)(void *), void *child_stack, int flags, void *arg, ... */
-int clone(CLONE_SIG)
-{
- if(realclone == NULL){
- dwr(MSG_ERROR,"clone(): SYMBOL NOT FOUND.\n");
- return -1;
- }
- dwr(MSG_DEBUG,"clone()\n");
- int err = realclone(fn, child_stack, flags, arg);
- set_up_intercept();
- return err;
-}
-
-/*------------------------------------------------------------------------------
------------------------------------- close() ----------------------------------
------------------------------------------------------------------------------*/
@@ -504,8 +463,7 @@ int clone(CLONE_SIG)
int close(CLOSE_SIG)
{
dwr(MSG_DEBUG, "close(%d)\n", fd);
- if(realclose == NULL)
- set_up_intercept();
+ set_up_intercept();
return realclose(fd);
}
@@ -516,10 +474,9 @@ int close(CLOSE_SIG)
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen */
int getsockname(GETSOCKNAME_SIG)
{
- if (realgetsockname == NULL) {
- dwr(MSG_ERROR,"getsockname(): SYMBOL NOT FOUND. \n");
- return -1;
- }
+ if (!set_up_intercept())
+ return realgetsockname(sockfd, addr, addrlen);
+
dwr(MSG_DEBUG,"getsockname(%d)\n", sockfd);
if(connected_to_service(sockfd) == 0) {
dwr(MSG_DEBUG,"getsockname(): not used by service\n");
@@ -537,11 +494,11 @@ int getsockname(GETSOCKNAME_SIG)
/* read address info from service */
char addrbuf[sizeof(struct sockaddr_storage)];
memset(&addrbuf, 0, sizeof(struct sockaddr_storage));
-
+
if(rpcfd > -1)
if(read(rpcfd, &addrbuf, sizeof(struct sockaddr_storage)) > 0)
close(rpcfd);
-
+
struct sockaddr_storage sock_storage;
memcpy(&sock_storage, addrbuf, sizeof(struct sockaddr_storage));
*addrlen = sizeof(struct sockaddr_in);
@@ -554,8 +511,8 @@ int getsockname(GETSOCKNAME_SIG)
------------------------------------ syscall() ---------------------------------
------------------------------------------------------------------------------*/
-long syscall(SYSCALL_SIG){
- dwr(MSG_DEBUG_EXTRA,"syscall(%u, ...):\n", number);
+long syscall(SYSCALL_SIG)
+{
va_list ap;
uintptr_t a,b,c,d,e,f;
va_start(ap, number);
@@ -567,8 +524,10 @@ long syscall(SYSCALL_SIG){
f=va_arg(ap, uintptr_t);
va_end(ap);
- if(realsyscall == NULL)
- return -1;
+ if (!set_up_intercept())
+ return realsyscall(number,a,b,c,d,e,f);
+
+ dwr(MSG_DEBUG_EXTRA,"syscall(%u, ...):\n", number);
#if defined(__i386__)
/* TODO: Implement for 32-bit systems: syscall(__NR_socketcall, 18, args);
diff --git a/netcon/Intercept.h b/netcon/Intercept.h
index 3a362022..b399993b 100644
--- a/netcon/Intercept.h
+++ b/netcon/Intercept.h
@@ -69,19 +69,16 @@ int dup2(DUP2_SIG);
int dup3(DUP3_SIG);
int getsockname(GETSOCKNAME_SIG);
-static int (*realconnect)(CONNECT_SIG);
-static int (*realbind)(BIND_SIG);
-static int (*realaccept)(ACCEPT_SIG);
-static int (*reallisten)(LISTEN_SIG);
-static int (*realsocket)(SOCKET_SIG);
-static int (*realsetsockopt)(SETSOCKOPT_SIG);
-static int (*realgetsockopt)(GETSOCKOPT_SIG);
-static int (*realaccept4)(ACCEPT4_SIG);
-static long (*realsyscall)(SYSCALL_SIG);
-static int (*realclose)(CLOSE_SIG);
-static int (*realclone)(CLONE_SIG);
-static int (*realdup2)(DUP2_SIG);
-static int (*realdup3)(DUP3_SIG);
-static int (*realgetsockname)(GETSOCKNAME_SIG);
+static int (*realconnect)(CONNECT_SIG) = 0;
+static int (*realbind)(BIND_SIG) = 0;
+static int (*realaccept)(ACCEPT_SIG) = 0;
+static int (*reallisten)(LISTEN_SIG) = 0;
+static int (*realsocket)(SOCKET_SIG) = 0;
+static int (*realsetsockopt)(SETSOCKOPT_SIG) = 0;
+static int (*realgetsockopt)(GETSOCKOPT_SIG) = 0;
+static int (*realaccept4)(ACCEPT4_SIG) = 0;
+static long (*realsyscall)(SYSCALL_SIG) = 0;
+static int (*realclose)(CLOSE_SIG) = 0;
+static int (*realgetsockname)(GETSOCKNAME_SIG) = 0;
#endif