mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-18 21:16:54 +02:00
Updated RPC handling
This commit is contained in:
parent
82a60b1e28
commit
e5fad005a9
22 changed files with 345 additions and 41 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
40
docker-test/throughput_httpd_2.4.17/Dockerfile
Normal file
40
docker-test/throughput_httpd_2.4.17/Dockerfile
Normal file
|
@ -0,0 +1,40 @@
|
|||
# ZT Netcon Throughput test
|
||||
FROM fedora:23
|
||||
MAINTAINER https://www.zerotier.com/
|
||||
|
||||
# Install apps
|
||||
RUN yum -y update
|
||||
RUN yum -y install httpd-2.4.17-3.fc23
|
||||
RUN yum -y install nano
|
||||
RUN yum -y install strace
|
||||
RUN yum clean all
|
||||
|
||||
EXPOSE 9993/udp 9992/udp 9991/udp 9990/udp
|
||||
|
||||
# Install sys-call intercept library
|
||||
ADD intercept /
|
||||
ADD libintercept.so.1.0 /
|
||||
RUN cp libintercept.so.1.0 lib/libintercept.so.1.0
|
||||
RUN cp libintercept.so.1.0 /lib/libintercept.so.1.0
|
||||
RUN ln -sf /lib/libintercept.so.1.0 /lib/libintercept
|
||||
RUN /usr/bin/install -c intercept /usr/bin
|
||||
|
||||
# Add ZT files
|
||||
RUN mkdir -p /var/lib/zerotier-one/networks.d
|
||||
RUN touch /var/lib/zerotier-one/networks.d/e5cd7a9e1c5311ab.conf
|
||||
ADD zerotier-one /
|
||||
ADD zerotier-cli /
|
||||
|
||||
# Install test-setup scripts
|
||||
ADD generate_file.sh /generate_file.sh
|
||||
RUN chmod -v +x /generate_file.sh
|
||||
ADD entrypoint.sh /entrypoint.sh
|
||||
RUN chmod -v +x /entrypoint.sh
|
||||
|
||||
# Install LWIP library used by service
|
||||
ADD liblwip.so /
|
||||
RUN mkdir -p ext/bin/lwip
|
||||
RUN cp liblwip.so ext/bin/lwip/liblwip.so
|
||||
|
||||
# Start ZeroTier-One
|
||||
CMD ["./entrypoint.sh"]
|
17
docker-test/throughput_httpd_2.4.17/build.sh
Executable file
17
docker-test/throughput_httpd_2.4.17/build.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
cd ../../
|
||||
make clean
|
||||
make
|
||||
cd netcon
|
||||
make -f make-intercept.mk lib
|
||||
rm *.o
|
||||
rm liblwip.so
|
||||
make -f make-liblwip.mk
|
||||
|
||||
cd ../docker-test/throughput_httpd_2.4.17
|
||||
|
||||
cp ../../zerotier-one zerotier-one
|
||||
cp ../../zerotier-cli zerotier-cli
|
||||
|
||||
cp ../../netcon/liblwip.so liblwip.so
|
||||
cp ../../netcon/libintercept.so.1.0 libintercept.so.1.0
|
||||
|
14
docker-test/throughput_httpd_2.4.17/entrypoint.sh
Normal file
14
docker-test/throughput_httpd_2.4.17/entrypoint.sh
Normal file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/
|
||||
|
||||
echo '***'
|
||||
echo '*** ZeroTier Network Containers Test Image'
|
||||
echo '*** https://www.zerotier.com/'
|
||||
echo '***'
|
||||
|
||||
./zerotier-one &
|
||||
./zerotier-cli join e5cd7a9e1c5311ab
|
||||
./zerotier-cli listnetworks
|
||||
|
||||
|
1
docker-test/throughput_httpd_2.4.17/generate_file.sh
Normal file
1
docker-test/throughput_httpd_2.4.17/generate_file.sh
Normal file
|
@ -0,0 +1 @@
|
|||
dd if=/dev/urandom of=/var/www/html/big bs=100M count=1
|
54
docker-test/throughput_httpd_2.4.17/intercept
Executable file
54
docker-test/throughput_httpd_2.4.17/intercept
Executable file
|
@ -0,0 +1,54 @@
|
|||
#!/bin/sh
|
||||
# usage:
|
||||
# /usr/bin/intercept program <args>
|
||||
|
||||
if [ $# = 0 ] ; then
|
||||
echo "$0: insufficient arguments"
|
||||
exit
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
on)
|
||||
if [ -z "$LD_PRELOAD" ]
|
||||
then
|
||||
export LD_PRELOAD="/lib/libintercept.so.1.0"
|
||||
else
|
||||
echo $LD_PRELOAD | grep -q "/lib/libintercept\.so.1.0" || \
|
||||
export LD_PRELOAD="/lib/libintercept.so $LD_PRELOAD"
|
||||
fi
|
||||
;;
|
||||
off)
|
||||
export LD_PRELOAD=`echo -n $LD_PRELOAD | sed 's/\/lib\/libintercept.so.1.0 \?//'`
|
||||
if [ -z "$LD_PRELOAD" ]
|
||||
then
|
||||
unset LD_PRELOAD
|
||||
fi
|
||||
;;
|
||||
show|sh)
|
||||
echo "LD_PRELOAD=\"$LD_PRELOAD\""
|
||||
;;
|
||||
-h|-?)
|
||||
echo ""
|
||||
;;
|
||||
*)
|
||||
if [ -z "$LD_PRELOAD" ]
|
||||
then
|
||||
export LD_PRELOAD="/lib/libintercept.so.1.0"
|
||||
else
|
||||
echo $LD_PRELOAD | grep -q "/lib/libintercept\.so.1.0" || \
|
||||
export LD_PRELOAD="/lib/libintercept.so.1.0 $LD_PRELOAD"
|
||||
fi
|
||||
|
||||
if [ $# = 0 ]
|
||||
then
|
||||
${SHELL:-/bin/sh}
|
||||
fi
|
||||
|
||||
if [ $# -gt 0 ]
|
||||
then
|
||||
exec "$@"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
#EOF
|
|
@ -112,6 +112,10 @@ installer: one FORCE
|
|||
|
||||
clean:
|
||||
rm -rf *.o
|
||||
find docker-test/ -name "*.1.0" -type f -delete
|
||||
find docker-test/ -name "*.so" -type f -delete
|
||||
find docker-test/ -name "zerotier-one" -type f -delete
|
||||
find docker-test/ -name "zerotier-cli" -type f -delete
|
||||
rm -rf netcon/*.o netcon/*.so netcon/*.1.0
|
||||
rm -rf node/*.o controller/*.o osdep/*.o service/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o zerotier-one zerotier-idtool zerotier-cli zerotier-selftest build-* ZeroTierOneInstaller-* *.deb *.rpm
|
||||
|
||||
|
|
|
@ -79,14 +79,16 @@ 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 (*realpoll)(POLL_SIG);
|
||||
static int (*realdup2)(DUP2_SIG);
|
||||
static int (*realdup3)(DUP3_SIG);
|
||||
|
||||
/* Exported Function Prototypes */
|
||||
void my_init(void);
|
||||
int connect(CONNECT_SIG);
|
||||
int select(SELECT_SIG);
|
||||
int close(CLOSE_SIG);
|
||||
int bind(BIND_SIG);
|
||||
int accept(ACCEPT_SIG);
|
||||
int listen(LISTEN_SIG);
|
||||
|
@ -95,8 +97,12 @@ int setsockopt(SETSOCKOPT_SIG);
|
|||
int getsockopt(GETSOCKOPT_SIG);
|
||||
int accept4(ACCEPT4_SIG);
|
||||
long syscall(SYSCALL_SIG);
|
||||
int close(CLOSE_SIG);
|
||||
//int clone(CLONE_SIG);
|
||||
//int poll(POLL_SIG);
|
||||
int dup2(DUP2_SIG);
|
||||
int dup3(DUP3_SIG);
|
||||
|
||||
|
||||
#ifdef USE_SOCKS_DNS
|
||||
int res_init(void);
|
||||
|
@ -110,6 +116,7 @@ void set_up_intercept();
|
|||
int checkpid();
|
||||
|
||||
#define SERVICE_CONNECT_ATTEMPTS 30
|
||||
#define RPC_FD 1023
|
||||
|
||||
ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd);
|
||||
|
||||
|
@ -126,10 +133,12 @@ void handle_error(char *name, char *info, int err)
|
|||
}
|
||||
#endif
|
||||
#ifdef VERBOSE
|
||||
//dwr("%s()=%d\n", name, err);
|
||||
dwr("%s()=%d\n", name, err);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned long rpc_count = 0;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
------------------- Intercept<--->Service Comm mechanisms-----------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
|
@ -158,7 +167,45 @@ int checkpid() {
|
|||
*/
|
||||
int send_command(int rpc_fd, char *cmd)
|
||||
{
|
||||
int n_write = write(rpc_fd, cmd, BUF_SZ);
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
dwr(" - IDX_PID = %d\n", IDX_PID);
|
||||
dwr(" - IDX_TID = %d\n", IDX_TID);
|
||||
dwr(" - IDX_COUNT = %d\n", IDX_COUNT);
|
||||
dwr(" - IDX_TIME = %d\n", IDX_TIME);
|
||||
dwr(" - IDX_PAYLOAD = %d\n", IDX_PAYLOAD);
|
||||
*/
|
||||
/*
|
||||
#define IDX_PID 0
|
||||
#define IDX_TID sizeof(pid_t)
|
||||
#define IDX_COUNT IDX_TID + sizeof(pid_t)
|
||||
#define IDX_TIME IDX_COUNT + sizeof(int)
|
||||
#define IDX_CMD IDX_TIME + 20 // 20 being the length of the timestamp string
|
||||
#define IDX_PAYLOAD IDX_TIME + sizeof(char)
|
||||
*/
|
||||
|
||||
// [pid_t] [pid_t] [rpc_count] [int] [...]
|
||||
char metabuf[BUF_SZ]; // portion of buffer which contains RPC meta-data for debugging
|
||||
memset(metabuf, '\0', BUF_SZ);
|
||||
pid_t pid = syscall(SYS_getpid);
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
int payload_idx = sizeof(pid_t)*2 + sizeof(rpc_count);
|
||||
rpc_count++;
|
||||
char timestring[20];
|
||||
time_t timestamp;
|
||||
timestamp = time(NULL);
|
||||
strftime(timestring, sizeof(timestring), "%H:%M:%S", localtime(×tamp));
|
||||
|
||||
memcpy(&metabuf[IDX_PID], &pid, sizeof(pid_t) ); // pid
|
||||
memcpy(&metabuf[IDX_TID], &tid, sizeof(pid_t) ); // tid
|
||||
memcpy(&metabuf[IDX_COUNT], &rpc_count, sizeof(rpc_count) ); // rpc_count
|
||||
memcpy(&metabuf[IDX_TIME], ×tring, 20 ); // timestamp
|
||||
#endif
|
||||
// copy payload into final command buffer
|
||||
int copied = BUF_SZ-IDX_PAYLOAD;
|
||||
memcpy(&metabuf[IDX_PAYLOAD], cmd, 200);
|
||||
//dwr(" RX: (pid=%d, tid=%d, rpc_count=%d, timestamp=%s, cmd=%d\n", pid, tid, rpc_count, timestring, cmd[0]);
|
||||
int n_write = write(rpc_fd, &metabuf, BUF_SZ);
|
||||
if(n_write < 0){
|
||||
dwr("Error writing command to service (CMD = %d)\n", cmd[0]);
|
||||
errno = 0;
|
||||
|
@ -200,9 +247,12 @@ int is_mapped_to_service(int sockfd)
|
|||
memset(cmd, '\0', BUF_SZ);
|
||||
cmd[0] = RPC_MAP_REQ;
|
||||
memcpy(&cmd[1], &sockfd, sizeof(sockfd));
|
||||
pthread_mutex_lock(&lock);
|
||||
if(send_command(fdret_sock, cmd) < 0)
|
||||
return -1;
|
||||
return get_retval();
|
||||
int err = get_retval();
|
||||
pthread_mutex_unlock(&lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
@ -233,7 +283,10 @@ int init_service_connection()
|
|||
else {
|
||||
dwr("AF_UNIX connection established: %d\n", tfd);
|
||||
is_initialized = 1;
|
||||
return tfd;
|
||||
int newtfd = realdup2(tfd, 1023);
|
||||
dwr("dup'd to rpc_fd = %d\n", newtfd);
|
||||
close(tfd);
|
||||
return newtfd;
|
||||
}
|
||||
attempts++;
|
||||
}
|
||||
|
@ -277,8 +330,11 @@ void load_symbols(void)
|
|||
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");
|
||||
//realsyscall = dlsym(RTLD_NEXT, "poll");
|
||||
realdup2 = dlsym(RTLD_NEXT, "dup2");
|
||||
realdup3 = dlsym(RTLD_NEXT, "dup3");
|
||||
#ifdef USE_SOCKS_DNS
|
||||
realresinit = dlsym(RTLD_NEXT, "res_init");
|
||||
#endif
|
||||
|
@ -295,8 +351,11 @@ void load_symbols(void)
|
|||
realgetsockopt = dlsym(lib, "getsockopt");
|
||||
realaccept4 = dlsym(lib), "accept4");
|
||||
//realclone = dlsym(lib, "clone");
|
||||
realclose = dlsym(lib, "close");
|
||||
realsyscall = dlsym(lib, "syscall");
|
||||
//realsyscall = dlsym(lib, "poll");
|
||||
realdup2 = dlsym(RTLD_NEXT, "dup2");
|
||||
realdup3 = dlsym(RTLD_NEXT, "dup3");
|
||||
#ifdef USE_SOCKS_DNS
|
||||
realresinit = dlsym(lib, "res_init");
|
||||
#endif
|
||||
|
@ -332,7 +391,7 @@ void set_up_intercept()
|
|||
/* int socket, int level, int option_name, const void *option_value, socklen_t option_len */
|
||||
int setsockopt(SETSOCKOPT_SIG)
|
||||
{
|
||||
dwr("setsockopt(%d)\n", socket);
|
||||
dwr("\n\nsetsockopt(%d)\n", socket);
|
||||
/*
|
||||
if(is_mapped_to_service(socket) < 0) { // First, check if the service manages this
|
||||
return realsetsockopt(socket, level, option_name, option_value, option_len);
|
||||
|
@ -363,7 +422,7 @@ int setsockopt(SETSOCKOPT_SIG)
|
|||
/* int sockfd, int level, int optname, void *optval, socklen_t *optlen */
|
||||
int getsockopt(GETSOCKOPT_SIG)
|
||||
{
|
||||
dwr("getsockopt(%d)\n", sockfd);
|
||||
dwr("\n\ngetsockopt(%d)\n", sockfd);
|
||||
/*
|
||||
if(is_mapped_to_service(sockfd) < 0) { // First, check if the service manages this
|
||||
return realgetsockopt(sockfd, level, optname, optval, optlen);
|
||||
|
@ -393,7 +452,7 @@ int getsockopt(GETSOCKOPT_SIG)
|
|||
socket() intercept function */
|
||||
int socket(SOCKET_SIG)
|
||||
{
|
||||
dwr("socket()*:\n");
|
||||
dwr("\n\nsocket()*:\n");
|
||||
int err;
|
||||
#ifdef CHECKS
|
||||
/* Check that type makes sense */
|
||||
|
@ -426,7 +485,6 @@ int socket(SOCKET_SIG)
|
|||
*/
|
||||
/* FIXME: detect ENFILE condition */
|
||||
#endif
|
||||
|
||||
char cmd[BUF_SZ];
|
||||
fdret_sock = !is_initialized ? init_service_connection() : fdret_sock;
|
||||
if(fdret_sock < 0) {
|
||||
|
@ -434,7 +492,6 @@ int socket(SOCKET_SIG)
|
|||
handle_error("socket4", "", -1);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if(socket_family == AF_LOCAL
|
||||
|| socket_family == AF_NETLINK
|
||||
|| socket_family == AF_UNIX) {
|
||||
|
@ -443,18 +500,15 @@ int socket(SOCKET_SIG)
|
|||
handle_error("socket5", "", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Assemble and send RPC */
|
||||
struct socket_st rpc_st;
|
||||
rpc_st.socket_family = socket_family;
|
||||
rpc_st.socket_type = socket_type;
|
||||
rpc_st.protocol = protocol;
|
||||
rpc_st.__tid = syscall(SYS_gettid);
|
||||
|
||||
memset(cmd, '\0', BUF_SZ);
|
||||
cmd[0] = RPC_SOCKET;
|
||||
dwr("pid = %d\n", thispid);
|
||||
memcpy(&cmd[1], &thispid, sizeof(pid_t));
|
||||
memcpy(&cmd[1]+sizeof(pid_t), &rpc_st, sizeof(struct socket_st));
|
||||
pthread_mutex_lock(&lock);
|
||||
send_command(fdret_sock, cmd);
|
||||
|
@ -462,9 +516,11 @@ int socket(SOCKET_SIG)
|
|||
/* get new fd */
|
||||
char rbuf[16];
|
||||
ssize_t sz = sock_fd_read(fdret_sock, rbuf, sizeof(rbuf), &newfd);
|
||||
int tmp = newfd;
|
||||
dwr("read %d bytes (%s)\n", sz, &rbuf);
|
||||
if(sz > 0)
|
||||
{
|
||||
dwr("sending fd = %d to Service over (%d)\n", newfd, fdret_sock);
|
||||
/* send our local-fd number back to service so
|
||||
it can complete its mapping table entry */
|
||||
memset(cmd, '\0', BUF_SZ);
|
||||
|
@ -504,7 +560,7 @@ int socket(SOCKET_SIG)
|
|||
connect() intercept function */
|
||||
int connect(CONNECT_SIG)
|
||||
{
|
||||
dwr("connect(%d):\n", __fd);
|
||||
dwr("\n\nconnect(%d):\n", __fd);
|
||||
print_addr(__addr);
|
||||
struct sockaddr_in *connaddr;
|
||||
connaddr = (struct sockaddr_in *) __addr;
|
||||
|
@ -597,7 +653,7 @@ int select(SELECT_SIG)
|
|||
bind() intercept function */
|
||||
int bind(BIND_SIG)
|
||||
{
|
||||
dwr("bind(%d):\n", sockfd);
|
||||
dwr("\n\nbind(%d):\n", sockfd);
|
||||
print_addr(addr);
|
||||
#ifdef CHECKS
|
||||
/* Check that this is a valid fd */
|
||||
|
@ -660,7 +716,7 @@ int bind(BIND_SIG)
|
|||
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
|
||||
int accept4(ACCEPT4_SIG)
|
||||
{
|
||||
dwr("accept4(%d):\n", sockfd);
|
||||
dwr("\n\naccept4(%d):\n", sockfd);
|
||||
#ifdef CHECKS
|
||||
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
|
||||
errno = EINVAL;
|
||||
|
@ -687,7 +743,7 @@ int accept4(ACCEPT4_SIG)
|
|||
accept() intercept function */
|
||||
int accept(ACCEPT_SIG)
|
||||
{
|
||||
dwr("accept(%d):\n", sockfd);
|
||||
dwr("\n\naccept(%d):\n", sockfd);
|
||||
#ifdef CHECKS
|
||||
/* Check that this is a valid fd */
|
||||
if(fcntl(sockfd, F_GETFD) < 0) {
|
||||
|
@ -794,7 +850,7 @@ int accept(ACCEPT_SIG)
|
|||
listen() intercept function */
|
||||
int listen(LISTEN_SIG)
|
||||
{
|
||||
dwr("listen(%d):\n", sockfd);
|
||||
dwr("\n\nlisten(%d):\n", sockfd);
|
||||
int sock_type;
|
||||
socklen_t sock_type_len = sizeof(sock_type);
|
||||
|
||||
|
@ -861,7 +917,6 @@ int clone(CLONE_SIG)
|
|||
*/
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
-------------------------------------- poll()-----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
|
@ -876,6 +931,59 @@ int poll(POLL_SIG)
|
|||
}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
-------------------------------------- close()-----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
// int fd
|
||||
int close(CLOSE_SIG)
|
||||
{
|
||||
dwr("close(%d)\n", fd);
|
||||
if(fd == fdret_sock)
|
||||
return 0; // FIXME: Ignore request to shut down our rpc fd, this is *almost always* safe
|
||||
if(fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO){
|
||||
return realclose(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
-------------------------------------- dup2()-----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
// int oldfd, int newfd
|
||||
int dup2(DUP2_SIG)
|
||||
{
|
||||
dwr("dup2(%d, %d)\n", oldfd, newfd);
|
||||
if(oldfd == fdret_sock) {
|
||||
dwr("client application attempted to dup2 RPC socket (%d). This is not allowed.\n", oldfd);
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if(oldfd != STDIN_FILENO && oldfd != STDOUT_FILENO && oldfd != STDERR_FILENO) {
|
||||
return realdup2(oldfd, newfd);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
-------------------------------------- dup3()-----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
// int oldfd, int newfd, int flags
|
||||
int dup3(DUP3_SIG)
|
||||
{
|
||||
dwr("dup3(%d, %d, %d)\n", oldfd, newfd, flags);
|
||||
#ifdef DEBUG
|
||||
// Only do this check if we want to debug the intercept, otherwise, dont mess with
|
||||
// the client application's logging methods
|
||||
if(newfd == STDIN_FILENO || newfd == STDOUT_FILENO || newfd == STDERR_FILENO)
|
||||
return newfd; // FIXME: This is to prevent httpd from dup'ing over our stderr
|
||||
//and preventing us from debugging
|
||||
else
|
||||
#endif
|
||||
return realdup3(oldfd, newfd, flags);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
------------------------------------ syscall()----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -31,7 +31,13 @@
|
|||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define BUF_SZ 128
|
||||
#define IDX_PID 0
|
||||
#define IDX_TID sizeof(pid_t)
|
||||
#define IDX_COUNT IDX_TID + sizeof(pid_t)
|
||||
#define IDX_TIME IDX_COUNT + sizeof(int)
|
||||
#define IDX_PAYLOAD IDX_TIME + 20 // 20 being the length of the timestamp string
|
||||
|
||||
#define BUF_SZ 256
|
||||
#define ERR_OK 0
|
||||
|
||||
/* Userland RPC codes */
|
||||
|
@ -177,4 +183,7 @@ struct shutdown_st
|
|||
#define CLONE_SIG int (*fn)(void *), void *child_stack, int flags, void *arg, ...
|
||||
#define POLL_SIG struct pollfd *fds, nfds_t nfds, int timeout
|
||||
|
||||
#define DUP2_SIG int oldfd, int newfd
|
||||
#define DUP3_SIG int oldfd, int newfd, int flags
|
||||
|
||||
#endif
|
||||
|
|
|
@ -567,22 +567,39 @@ void NetconEthernetTap::phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void *
|
|||
rpc_sockets.push_back(sockN);
|
||||
}
|
||||
|
||||
void unload_rpc(void *data, pid_t &pid, pid_t &tid, int &rpc_count, char (timestamp[20]), char &cmd, void* &payload);
|
||||
|
||||
/*
|
||||
* Processes incoming data on a client-specific RPC connection
|
||||
*/
|
||||
void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len)
|
||||
{
|
||||
pid_t pid, tid;
|
||||
int rpc_count;
|
||||
char timestamp[20];
|
||||
char cmd;
|
||||
void *payload;
|
||||
unload_rpc(data, pid, tid, rpc_count, timestamp, cmd, payload);
|
||||
dwr("\n\nRX: (pid=%d, tid=%d, rpc_count=%d, timestamp=%s, cmd=%d\n", pid, tid, rpc_count, timestamp, cmd);
|
||||
unsigned char *buf = (unsigned char*)data;
|
||||
switch(buf[0])
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case RPC_SOCKET:
|
||||
dwr(2, "RPC_SOCKET\n");
|
||||
struct socket_st socket_rpc;
|
||||
pid_t pid;
|
||||
memcpy(&pid, &buf[1], sizeof(pid_t)); // PID for client RPC tracking (only for debug)
|
||||
memcpy(&socket_rpc, &buf[sizeof(pid_t)], sizeof(struct socket_st));
|
||||
struct socket_st socket_rpc;
|
||||
memcpy(&socket_rpc, &buf[IDX_PAYLOAD+1], sizeof(struct socket_st));
|
||||
|
||||
if(rpc_count==rpc_counter) {
|
||||
dwr("Detected repeat RPC.\n");
|
||||
//return;
|
||||
}
|
||||
else {
|
||||
rpc_counter = rpc_count;
|
||||
}
|
||||
|
||||
TcpConnection * new_conn;
|
||||
if(new_conn = handle_socket(sock, uptr, &socket_rpc)) {
|
||||
if((new_conn = handle_socket(sock, uptr, &socket_rpc))) {
|
||||
pidmap[sock] = pid;
|
||||
new_conn->pid = pid;
|
||||
}
|
||||
|
@ -590,24 +607,30 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns
|
|||
case RPC_LISTEN:
|
||||
dwr(2, "RPC_LISTEN\n");
|
||||
struct listen_st listen_rpc;
|
||||
memcpy(&listen_rpc, &buf[1], sizeof(struct listen_st));
|
||||
memcpy(&listen_rpc, &buf[IDX_PAYLOAD+1], sizeof(struct listen_st));
|
||||
handle_listen(sock, uptr, &listen_rpc);
|
||||
break;
|
||||
case RPC_BIND:
|
||||
dwr(2, "RPC_BIND\n");
|
||||
struct bind_st bind_rpc;
|
||||
memcpy(&bind_rpc, &buf[1], sizeof(struct bind_st));
|
||||
memcpy(&bind_rpc, &buf[IDX_PAYLOAD+1], sizeof(struct bind_st));
|
||||
handle_bind(sock, uptr, &bind_rpc);
|
||||
break;
|
||||
case RPC_CONNECT:
|
||||
dwr(2, "RPC_CONNECT\n");
|
||||
struct connect_st connect_rpc;
|
||||
memcpy(&connect_rpc, &buf[1], sizeof(struct connect_st));
|
||||
memcpy(&connect_rpc, &buf[IDX_PAYLOAD+1], sizeof(struct connect_st));
|
||||
handle_connect(sock, uptr, &connect_rpc);
|
||||
break;
|
||||
case RPC_MAP:
|
||||
dwr(2, "RPC_MAP\n");
|
||||
handle_retval(sock, uptr, buf);
|
||||
dwr(2, "RPC_MAP (len = %d)\n", len);
|
||||
|
||||
int newfd;
|
||||
//memcpy(&pid, &buf[IDX_PAYLOAD+1], sizeof(pid_t)); // PID for client RPC tracking (only for debug)
|
||||
memcpy(&newfd, &buf[IDX_PAYLOAD+1], sizeof(int));
|
||||
//dwr("newfd = %d\n", newfd);
|
||||
|
||||
handle_retval(sock, uptr, rpc_count, newfd);
|
||||
break;
|
||||
case RPC_MAP_REQ:
|
||||
dwr(2, "RPC_MAP_REQ\n");
|
||||
|
@ -616,6 +639,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns
|
|||
default:
|
||||
break;
|
||||
}
|
||||
//memset(data, '\0', 256);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -973,7 +997,7 @@ void NetconEthernetTap::handle_map_request(PhySocket *sock, void **uptr, unsigne
|
|||
dwr(4, " handle_map_request()\n");
|
||||
TcpConnection *conn = (TcpConnection*)*uptr;
|
||||
int req_fd;
|
||||
memcpy(&req_fd, &buf[1], sizeof(req_fd));
|
||||
memcpy(&req_fd, &buf[IDX_PAYLOAD+1], sizeof(req_fd));
|
||||
for(size_t i=0; i<tcp_connections.size(); i++) {
|
||||
if(tcp_connections[i]->rpcSock == conn->rpcSock && tcp_connections[i]->perceived_fd == req_fd){
|
||||
send_return_value(conn, 1, ERR_OK); // True
|
||||
|
@ -994,16 +1018,26 @@ void NetconEthernetTap::handle_map_request(PhySocket *sock, void **uptr, unsigne
|
|||
* @param structure containing the data and parameters for this client's RPC
|
||||
*
|
||||
*/
|
||||
void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, unsigned char* buf)
|
||||
void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, int rpc_count, int newfd)
|
||||
{
|
||||
dwr(4, " handle_retval()\n");
|
||||
TcpConnection *conn = (TcpConnection*)*uptr;
|
||||
if(!conn->pending)
|
||||
return;
|
||||
|
||||
// Copy data from buffer to TcpConnection object, update status
|
||||
memcpy(&(conn->perceived_fd), &buf[1], sizeof(int));
|
||||
conn->pending = false;
|
||||
conn->perceived_fd = newfd;
|
||||
|
||||
if(rpc_count==rpc_counter) {
|
||||
dwr("Detected repeat RPC.\n");
|
||||
//return;
|
||||
}
|
||||
else {
|
||||
rpc_counter = rpc_count;
|
||||
//dwr("pid = %d\n", rpc_count);
|
||||
//dwr("rpc_counter = %d\n", rpc_counter);
|
||||
|
||||
}
|
||||
|
||||
dwr(4, " handle_retval(): CONN:%x - Mapping [our=%d -> their=%d]\n",conn,
|
||||
_phy.getDescriptor(conn->dataSock), conn->perceived_fd);
|
||||
|
@ -1027,7 +1061,7 @@ void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, unsigned cha
|
|||
}
|
||||
else {
|
||||
dwr(" handle_retval(): CONN:%x - This socket is mapped to two different pipes (?). Exiting.\n", conn);
|
||||
die(0); // FIXME: Print service mapping state and exit
|
||||
//die(0); // FIXME: Print service mapping state and exit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1104,7 @@ void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, unsigned cha
|
|||
*/
|
||||
void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st *bind_rpc)
|
||||
{
|
||||
dwr(3, " handle_bind()\n");
|
||||
|
||||
struct sockaddr_in *connaddr;
|
||||
connaddr = (struct sockaddr_in *) &bind_rpc->addr;
|
||||
int conn_port = lwipstack->ntohs(connaddr->sin_port);
|
||||
|
@ -1078,6 +1112,8 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st
|
|||
conn_addr.addr = *((u32_t *)_ips[0].rawIpData());
|
||||
TcpConnection *conn = getConnectionByTheirFD(sock, bind_rpc->sockfd);
|
||||
|
||||
dwr(3, " handle_bind(%d)\n", bind_rpc->sockfd);
|
||||
|
||||
if(conn) {
|
||||
if(conn->pcb->state == CLOSED){
|
||||
int err = lwipstack->tcp_bind(conn->pcb, &conn_addr, conn_port);
|
||||
|
@ -1229,7 +1265,6 @@ TcpConnection * NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, s
|
|||
new_conn->their_fd = fds[1];
|
||||
tcp_connections.push_back(new_conn);
|
||||
int n = sock_fd_write(_phy.getDescriptor(sock), fds[1]);
|
||||
dwr("wrote %d bytes\n", n);
|
||||
close(fds[1]); // close other end of socketpair
|
||||
// Once the client tells us what its fd is on the other end, we can then complete the mapping
|
||||
new_conn->pending = true;
|
||||
|
|
|
@ -107,7 +107,7 @@ private:
|
|||
void handle_bind(PhySocket *sock, void **uptr, struct bind_st *bind_rpc);
|
||||
void handle_listen(PhySocket *sock, void **uptr, struct listen_st *listen_rpc);
|
||||
void handle_map_request(PhySocket *sock, void **uptr, unsigned char* buf);
|
||||
void handle_retval(PhySocket *sock, void **uptr, unsigned char* buf);
|
||||
void handle_retval(PhySocket *sock, void **uptr, int rpc_count, int newfd);
|
||||
TcpConnection * handle_socket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc);
|
||||
void handle_connect(PhySocket *sock, void **uptr, struct connect_st* connect_rpc);
|
||||
void handle_write(TcpConnection *conn);
|
||||
|
@ -154,6 +154,7 @@ private:
|
|||
std::vector<TcpConnection*> tcp_connections;
|
||||
std::vector<PhySocket*> rpc_sockets;
|
||||
std::map<PhySocket*, pid_t> pidmap;
|
||||
pid_t rpc_counter = -1;
|
||||
|
||||
netif interface;
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/ip_frag.h"
|
||||
|
||||
#include "Intercept.h"
|
||||
|
||||
#ifndef _NETCON_UTILITIES_CPP
|
||||
#define _NETCON_UTILITIES_CPP
|
||||
|
||||
|
@ -64,8 +66,27 @@ namespace ZeroTier
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
void clearscreen()
|
||||
void unload_rpc(void *data, pid_t &pid, pid_t &tid, int &rpc_count, char (timestamp[20]), char &cmd, void* &payload)
|
||||
{
|
||||
unsigned char *buf = (unsigned char*)data;
|
||||
|
||||
/*
|
||||
dwr(" - IDX_PID = %d\n", IDX_PID);
|
||||
dwr(" - IDX_TID = %d\n", IDX_TID);
|
||||
dwr(" - IDX_COUNT = %d\n", IDX_COUNT);
|
||||
dwr(" - IDX_TIME = %d\n", IDX_TIME);
|
||||
dwr(" - IDX_PAYLOAD = %d\n", IDX_PAYLOAD);
|
||||
*/
|
||||
memcpy(&pid, &buf[IDX_PID], sizeof(pid_t));
|
||||
memcpy(&tid, &buf[IDX_TID], sizeof(pid_t));
|
||||
memcpy(&rpc_count, &buf[IDX_COUNT], sizeof(int));
|
||||
memcpy(timestamp, &buf[IDX_TIME], 20);
|
||||
memcpy(&cmd, &buf[IDX_PAYLOAD], sizeof(char));
|
||||
payload = buf+IDX_PAYLOAD+1;
|
||||
//dwr("RX: (pid=%d, tid=%d, rpc_count=%d, timestamp=%s, cmd=%d\n", pid, tid, rpc_count, timestamp, cmd);
|
||||
}
|
||||
|
||||
void clearscreen(){
|
||||
fprintf(stderr, "\033[2J");
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
SHCC=gcc
|
||||
|
||||
intercept_CFLAGS = -c -fPIC -g -O2 -Wall -std=c99 -DERRORS_ARE_FATAL -DVERBOSE -DCHECKS -D_GNU_SOURCE -DNETCON_INTERCEPT
|
||||
intercept_CFLAGS = -c -fPIC -g -O2 -Wall -std=c99 -DERRORS_ARE_FATAL -DDEBUG -DVERBOSE -DCHECKS -D_GNU_SOURCE -DNETCON_INTERCEPT
|
||||
LIB_NAME = intercept
|
||||
SHLIB_EXT=dylib
|
||||
SHLIB_MAJOR = 1
|
||||
|
|
Loading…
Add table
Reference in a new issue