From e2ae9165c6fea5c1099428da7147a42068c0ce1a Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Tue, 12 Jan 2016 09:46:49 -0800 Subject: [PATCH] RPC update --- make-linux.mk | 12 ++---- netcon/Intercept.c | 75 ++++++++++++++++++++++++++---------- netcon/NetconEthernetTap.cpp | 57 ++++++++++++--------------- netcon/RPC.c | 70 ++++++++++++++++++--------------- netcon/RPC.h | 27 ++++++------- netcon/common.inc.c | 2 +- 6 files changed, 136 insertions(+), 107 deletions(-) diff --git a/make-linux.mk b/make-linux.mk index 5fd21afe4..502cd0e4b 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -95,24 +95,18 @@ one: $(OBJS) service/OneService.o one.o osdep/LinuxEthernetTap.o ln -sf zerotier-one zerotier-idtool ln -sf zerotier-one zerotier-cli -netcon: rpc_lib $(OBJS) +netcon: $(OBJS) rm -f *.o # Need to selectively rebuild one.cpp and OneService.cpp with ZT_SERVICE_NETCON and ZT_ONE_NO_ROOT_CHECK defined, and also NetconEthernetTap - $(CXX) $(CXXFLAGS) $(LDFLAGS) -DZT_SERVICE_NETCON -DZT_ONE_NO_ROOT_CHECK -Iext/lwip/src/include -Iext/lwip/src/include/ipv4 -Iext/lwip/src/include/ipv6 -o zerotier-netcon-service $(OBJS) service/OneService.cpp netcon/NetconEthernetTap.cpp one.cpp $(LDLIBS) -ldl -Lnetcon/ -lrpc + $(CXX) $(CXXFLAGS) $(LDFLAGS) -DZT_SERVICE_NETCON -DZT_ONE_NO_ROOT_CHECK -Iext/lwip/src/include -Iext/lwip/src/include/ipv4 -Iext/lwip/src/include/ipv6 -o zerotier-netcon-service $(OBJS) service/OneService.cpp netcon/NetconEthernetTap.cpp one.cpp -x c netcon/RPC.c $(LDLIBS) -ldl # Build netcon/liblwip.so which must be placed in ZT home for zerotier-netcon-service to work cd netcon ; make -f make-liblwip.mk # Use gcc not clang to build standalone intercept library since gcc is typically used for libc and we want to ensure maximal ABI compatibility - cd netcon ; gcc -Wl,--whole-archive -g -O2 -Wall -std=c99 -fPIC -DVERBOSE -D_GNU_SOURCE -DNETCON_INTERCEPT -I. -nostdlib -shared librpc.a -o libzerotierintercept.so Intercept.c -ldl + cd netcon ; gcc -g -O2 -Wall -std=c99 -fPIC -DVERBOSE -D_GNU_SOURCE -DNETCON_INTERCEPT -I. -nostdlib -shared -o libzerotierintercept.so Intercept.c RPC.c -ldl cp netcon/libzerotierintercept.so libzerotierintercept.so ln -sf zerotier-netcon-service zerotier-cli ln -sf zerotier-netcon-service zerotier-idtool - -rpc_lib: - g++ -c -fPIC -lpthread netcon/RPC.c -DVERBOSE -o netcon/RPC.o - ar -rv netcon/librpc.a netcon/RPC.o - - selftest: $(OBJS) selftest.o $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LDLIBS) $(STRIP) zerotier-selftest diff --git a/netcon/Intercept.c b/netcon/Intercept.c index 5b0b34808..ed7e3cb81 100644 --- a/netcon/Intercept.c +++ b/netcon/Intercept.c @@ -62,7 +62,7 @@ ------------------- Intercept<--->Service Comm mechanisms ---------------------- ------------------------------------------------------------------------------*/ -static char *network_pathname = (char *)0; +static char *netpath = (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 @@ -79,7 +79,7 @@ static int connected_to_service(int sockfd) getpeername(sockfd, (struct sockaddr*)&addr, &len); if (addr.ss_family == AF_LOCAL || addr.ss_family == AF_LOCAL) { addr_un = (struct sockaddr_un*)&addr; - if(strcmp(addr_un->sun_path, network_pathname) == 0) { + if(strcmp(addr_un->sun_path, netpath) == 0) { dwr(MSG_DEBUG_EXTRA,"connected_to_service(): Yes, %s\n", addr_un->sun_path); return 1; } @@ -115,12 +115,11 @@ static int set_up_intercept() realsyscall = dlsym(RTLD_NEXT, "syscall"); realgetsockname = dlsym(RTLD_NEXT, "getsockname"); } - - if (!network_pathname) { - network_pathname = getenv("ZT_NC_NETWORK"); - if (!network_pathname) + if (!netpath) { + netpath = getenv("ZT_NC_NETWORK"); + if (!netpath) return 0; - dwr(MSG_DEBUG,"Connecting to service at: %s\n", network_pathname); + dwr(MSG_DEBUG,"Connecting to service at: %s\n", netpath); /* Hook/intercept Posix net API symbols */ rpc_mutex_init(); } @@ -194,6 +193,14 @@ int socket(SOCKET_SIG) errno = EINVAL; return -1; } + +/* + if(flags & SOCK_DGRAM) { + fprintf(stderr, "socket(): DGRAM, passing through\n"); + return realsocket(socket_family, socket_type, protocol); + } +*/ + socket_type &= SOCK_TYPE_MASK; /* Check protocol is in range */ if (socket_family < 0 || socket_family >= NPROTO){ @@ -219,7 +226,7 @@ int socket(SOCKET_SIG) rpc_st.protocol = protocol; rpc_st.__tid = syscall(SYS_gettid); /* -1 is passed since we we're generating the new socket in this call */ - return rpc_send_command(RPC_SOCKET, -1, &rpc_st, sizeof(struct socket_st)); + return rpc_send_command(netpath, RPC_SOCKET, -1, &rpc_st, sizeof(struct socket_st)); } /*------------------------------------------------------------------------------ @@ -233,9 +240,42 @@ int connect(CONNECT_SIG) if (!set_up_intercept()) return realconnect(__fd, __addr, __len); - dwr(MSG_DEBUG,"connect(%d):\n", __fd); +/* + int opt; + socklen_t opt_len; + realgetsockopt(__fd, SOL_SOCKET, SO_TYPE, (void *) &opt, &opt_len); + + if(opt & SOCK_DGRAM) + { + fprintf(stderr, "connect(): DGRAM, passing through.\n"); + return realconnect(__fd, __addr, __len); + } +*/ + struct sockaddr_in *connaddr; - connaddr = (struct sockaddr_in *) __addr; + connaddr = (struct sockaddr_in *)__addr; + + if(__addr->sa_family == AF_LOCAL || __addr->sa_family == AF_UNIX) { + struct sockaddr_storage storage; + memcpy(&storage, __addr, __len); + struct sockaddr_un *s_un = (struct sockaddr_un*)&storage; + fprintf(stderr, "connect(): address = %s\n", s_un->sun_path); + } + + int port = connaddr->sin_port; + int ip = connaddr->sin_addr.s_addr; + unsigned char d[4]; + d[0] = ip & 0xFF; + d[1] = (ip >> 8) & 0xFF; + d[2] = (ip >> 16) & 0xFF; + d[3] = (ip >> 24) & 0xFF; + dwr(MSG_DEBUG,"connect(): %d.%d.%d.%d: %d\n", d[0],d[1],d[2],d[3], ntohs(port)); + + + if (!set_up_intercept()) + return realconnect(__fd, __addr, __len); + + dwr(MSG_DEBUG,"connect(%d):\n", __fd); /* Check that this is a valid fd */ if(fcntl(__fd, F_GETFD) < 0) { errno = EBADF; @@ -261,8 +301,7 @@ int connect(CONNECT_SIG) || connaddr->sin_family == PF_NETLINK || connaddr->sin_family == AF_NETLINK || connaddr->sin_family == AF_UNIX)) { - int err = realconnect(__fd, __addr, __len); - return err; + return realconnect(__fd, __addr, __len); } /* Assemble and send RPC */ struct connect_st rpc_st; @@ -270,7 +309,7 @@ int connect(CONNECT_SIG) rpc_st.__fd = __fd; memcpy(&rpc_st.__addr, __addr, sizeof(struct sockaddr_storage)); memcpy(&rpc_st.__len, &__len, sizeof(socklen_t)); - return rpc_send_command(RPC_CONNECT, __fd, &rpc_st, sizeof(struct connect_st)); + return rpc_send_command(netpath, RPC_CONNECT, __fd, &rpc_st, sizeof(struct connect_st)); } /*------------------------------------------------------------------------------ @@ -325,7 +364,7 @@ int bind(BIND_SIG) rpc_st.__tid = syscall(SYS_gettid); memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage)); memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t)); - return rpc_send_command(RPC_BIND, sockfd, &rpc_st, sizeof(struct bind_st)); + return rpc_send_command(netpath, RPC_BIND, sockfd, &rpc_st, sizeof(struct bind_st)); } /*------------------------------------------------------------------------------ @@ -398,10 +437,6 @@ int accept(ACCEPT_SIG) if(addr) addr->sa_family = AF_INET; - /* The following line is required for libuv/nodejs to accept connections properly, - however, this has the side effect of causing certain webservers to max out the CPU - in an accept loop */ - //fcntl(sockfd, F_SETFL, SOCK_NONBLOCK); int new_fd = get_new_fd(sockfd); if(new_fd > 0) { errno = ERR_OK; @@ -452,7 +487,7 @@ int listen(LISTEN_SIG) rpc_st.sockfd = sockfd; rpc_st.backlog = backlog; rpc_st.__tid = syscall(SYS_gettid); - return rpc_send_command(RPC_LISTEN, sockfd, &rpc_st, sizeof(struct listen_st)); + return rpc_send_command(netpath, RPC_LISTEN, sockfd, &rpc_st, sizeof(struct listen_st)); } /*------------------------------------------------------------------------------ @@ -490,7 +525,7 @@ int getsockname(GETSOCKNAME_SIG) rpc_st.sockfd = sockfd; memcpy(&rpc_st.addr, addr, *addrlen); memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t)); - int rpcfd = rpc_send_command(RPC_GETSOCKNAME, sockfd, &rpc_st, sizeof(struct getsockname_st)); + int rpcfd = rpc_send_command(netpath, RPC_GETSOCKNAME, sockfd, &rpc_st, sizeof(struct getsockname_st)); /* read address info from service */ char addrbuf[sizeof(struct sockaddr_storage)]; memset(&addrbuf, 0, sizeof(struct sockaddr_storage)); diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp index 942da6cad..9a9be273f 100644 --- a/netcon/NetconEthernetTap.cpp +++ b/netcon/NetconEthernetTap.cpp @@ -63,15 +63,6 @@ namespace ZeroTier { // --------------------------------------------------------------------------- -// Gets the process/path name associated with a pid -static void get_path_from_pid(char* dest, int pid) -{ - char ppath[80]; - sprintf(ppath, "/proc/%d/exe", pid); - if (readlink (ppath, dest, 80) != -1){ - } -} - static err_t tapif_init(struct netif *netif) { // Actual init functionality is in addIp() of tap @@ -438,10 +429,12 @@ void NetconEthernetTap::closeConnection(PhySocket *sock) if(conn) { if(!conn->pcb) return; + // TODO: Removed to address double-free segfault when killing a python simple server + // tell LWIP to close the associated PCB - if(conn->pcb->state != CLOSED && lwipstack->_tcp_close(conn->pcb) != ERR_OK) { - dwr(MSG_ERROR," closeConnection(): Error while calling tcp_close()\n"); - } + //if(conn->pcb->state != CLOSED && lwipstack->_tcp_close(conn->pcb) != ERR_OK) { + // dwr(MSG_ERROR," closeConnection(): Error while calling tcp_close()\n"); + //} // remove from connection list for(size_t i=0; isock == sock){ @@ -478,7 +471,7 @@ void NetconEthernetTap::phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void * /* Unpacks the buffer from an RPC command */ void NetconEthernetTap::unload_rpc(void *data, pid_t &pid, pid_t &tid, - int &rpc_count, char (timestamp[20]), char (magic[sizeof(uint64_t)]), char &cmd, void* &payload) + int &rpc_count, char (timestamp[20]), char (CANARY[sizeof(uint64_t)]), char &cmd, void* &payload) { unsigned char *buf = (unsigned char*)data; memcpy(&pid, &buf[IDX_PID], sizeof(pid_t)); @@ -486,7 +479,7 @@ void NetconEthernetTap::unload_rpc(void *data, pid_t &pid, pid_t &tid, memcpy(&rpc_count, &buf[IDX_COUNT], sizeof(int)); memcpy(timestamp, &buf[IDX_TIME], 20); memcpy(&cmd, &buf[IDX_PAYLOAD], sizeof(char)); - memcpy(magic, &buf[IDX_PAYLOAD+1], MAGIC_SIZE); + memcpy(CANARY, &buf[IDX_PAYLOAD+1], CANARY_SIZE); } /* @@ -494,14 +487,14 @@ void NetconEthernetTap::unload_rpc(void *data, pid_t &pid, pid_t &tid, */ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len) { - uint64_t magic_num; + uint64_t CANARY_num; pid_t pid, tid; int rpc_count; - char cmd, timestamp[20], magic[MAGIC_SIZE]; + char cmd, timestamp[20], CANARY[CANARY_SIZE]; void *payload; unsigned char *buf = (unsigned char*)data; std::pair sockdata; - PhySocket *streamsock, *rpcsock; + PhySocket *rpcsock; bool found_job = false, detected_rpc = false; TcpConnection *conn; int wlen = len; @@ -515,8 +508,8 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns detected_rpc = true; } if(detected_rpc) { - unload_rpc(data, pid, tid, rpc_count, timestamp, magic, cmd, payload); - memcpy(&magic_num, magic, MAGIC_SIZE); + unload_rpc(data, pid, tid, rpc_count, timestamp, CANARY, cmd, payload); + memcpy(&CANARY_num, CANARY, CANARY_SIZE); dwr(MSG_DEBUG," <%x> RPC: (pid=%d, tid=%d, rpc_count=%d, timestamp=%s, cmd=%d)\n", sock, pid, tid, rpc_count, timestamp, cmd); if(cmd == RPC_SOCKET) { dwr(MSG_DEBUG," <%x> RPC_SOCKET\n", sock); @@ -530,7 +523,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns } } else { // All RPCs other than RPC_SOCKET - jobmap[magic_num] = std::make_pair(sock, data); + jobmap[CANARY_num] = std::make_pair(sock, data); } write(_phy.getDescriptor(sock), "z", 1); // RPC ACK byte to maintain RPC->Stream order } @@ -541,19 +534,19 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns char padding[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89}; dwr(MSG_DEBUG," <%x> stream data, len = %d\n", sock, len); // Look for padding - std::string padding_pattern(padding, padding+MAGIC_PADDING_SIZE); + std::string padding_pattern(padding, padding+CANARY_PADDING_SIZE); std::string buffer(buf, buf + len); padding_pos = buffer.find(padding_pattern); - token_pos = padding_pos-MAGIC_SIZE; + token_pos = padding_pos-CANARY_SIZE; dwr(MSG_DEBUG, " <%x> padding_pos = %d\n", sock, padding_pos); // Grab token, next we'll use it to look up an RPC job if(token_pos > -1) { - memcpy(&magic_num, buf+token_pos, MAGIC_SIZE); - if(magic_num != 0) { // TODO: Added to address magic_num==0 bug, last seeen 20160108 + memcpy(&CANARY_num, buf+token_pos, CANARY_SIZE); + if(CANARY_num != 0) { // TODO: Added to address CANARY_num==0 bug, last seeen 20160108 // Find job - sockdata = jobmap[magic_num]; + sockdata = jobmap[CANARY_num]; if(!sockdata.first) { // Stream before RPC - dwr(MSG_DEBUG," <%x> unable to locate job entry for %llu\n", sock, magic_num); + dwr(MSG_DEBUG," <%x> unable to locate job entry for %llu\n", sock, CANARY_num); return; } else @@ -577,7 +570,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns // [TOKEN] + [DATA] if(len > TOKEN_SIZE && token_pos == 0) { wlen = len - TOKEN_SIZE; - data_start = padding_pos+MAGIC_PADDING_SIZE; + data_start = padding_pos+CANARY_PADDING_SIZE; memcpy((&conn->buf)+conn->idx, buf+data_start, wlen); } // [DATA] + [TOKEN] @@ -590,9 +583,9 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns if(len > TOKEN_SIZE && token_pos > 0 && len > (token_pos + TOKEN_SIZE)) { wlen = len - TOKEN_SIZE; data_start = 0; - data_end = padding_pos-MAGIC_SIZE; + data_end = padding_pos-CANARY_SIZE; memcpy((&conn->buf)+conn->idx, buf+data_start, (data_end-data_start)+1); - memcpy((&conn->buf)+conn->idx, buf+(padding_pos+MAGIC_PADDING_SIZE), len-(token_pos+TOKEN_SIZE)); + memcpy((&conn->buf)+conn->idx, buf+(padding_pos+CANARY_PADDING_SIZE), len-(token_pos+TOKEN_SIZE)); } } } @@ -614,7 +607,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns // Process RPC if we have a corresponding jobmap entry if(found_job) { conn = getConnection(sock); - unload_rpc(buf, pid, tid, rpc_count, timestamp, magic, cmd, payload); + unload_rpc(buf, pid, tid, rpc_count, timestamp, CANARY, cmd, payload); switch(cmd) { case RPC_BIND: dwr(MSG_DEBUG," <%x> RPC_BIND\n", sock); @@ -644,7 +637,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns break; } closeConnection(sockdata.first); // close RPC after sending retval, no longer needed - jobmap.erase(magic_num); + jobmap.erase(CANARY_num); return; } } @@ -973,7 +966,7 @@ void NetconEthernetTap::handle_getsockname(PhySocket *sock, PhySocket *rpcsock, memset(&retmsg, 0, sizeof(retmsg)); if ((conn)&&(conn->addr)) memcpy(&retmsg, conn->addr, sizeof(struct sockaddr_storage)); - int n = write(_phy.getDescriptor(rpcsock), &retmsg, sizeof(struct sockaddr_storage)); + write(_phy.getDescriptor(rpcsock), &retmsg, sizeof(struct sockaddr_storage)); } /* diff --git a/netcon/RPC.c b/netcon/RPC.c index 46f09401a..ab51e28b0 100644 --- a/netcon/RPC.c +++ b/netcon/RPC.c @@ -6,16 +6,21 @@ #include #include +#include #include #include #include #include "RPC.h" -#define RPC_FD 1023 #define SERVICE_CONNECT_ATTEMPTS 30 -static int instance_count; +#define CONNECT_SIG int __fd, const struct sockaddr * __addr, socklen_t __len +#define SOCKET_SIG int socket_family, int socket_type, int protocol + +static int (*realconnect)(CONNECT_SIG) = 0; +static int (*realsocket)(SOCKET_SIG) = 0; + static int rpc_count; static pthread_mutex_t lock; @@ -63,30 +68,40 @@ int get_retval(int rpc_sock) return -1; } +int load_symbols_rpc() +{ + #ifdef NETCON_INTERCEPT + realsocket = dlsym(RTLD_NEXT, "socket"); + realconnect = dlsym(RTLD_NEXT, "connect"); + if(!realconnect || !realsocket) + return -1; + #endif + return 1; +} + int rpc_join(const char * sockname) { + if(!load_symbols_rpc()) + return -1; + struct sockaddr_un addr; int conn_err = -1, attempts = 0; - memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)-1); int sock; - if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){ + if((sock = realsocket(AF_UNIX, SOCK_STREAM, 0)) < 0){ fprintf(stderr, "Error while creating RPC socket\n"); return -1; } while((conn_err != 0) && (attempts < SERVICE_CONNECT_ATTEMPTS)){ - if((conn_err = connect(sock, (struct sockaddr*)&addr, sizeof(addr))) != 0) { + if((conn_err = realconnect(sock, (struct sockaddr*)&addr, sizeof(addr))) != 0) { fprintf(stderr, "Error while connecting to RPC socket. Re-attempting...\n"); sleep(1); } - else { - //int newfd = dup2(sock, RPC_FD-instance_count); - //close(sock); + else return sock; - } attempts++; } return -1; @@ -95,36 +110,24 @@ int rpc_join(const char * sockname) /* * Send a command to the service */ -int rpc_send_command(int cmd, int forfd, void *data, int len) +int rpc_send_command(char *path, int cmd, int forfd, void *data, int len) { pthread_mutex_lock(&lock); char c, padding[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89}; - char cmdbuf[BUF_SZ], magic[TOKEN_SIZE], metabuf[BUF_SZ]; - memcpy(magic+MAGIC_SIZE, padding, TOKEN_SIZE); - uint64_t magic_num; - + char cmdbuf[BUF_SZ], CANARY[TOKEN_SIZE], metabuf[BUF_SZ]; + memcpy(CANARY+CANARY_SIZE, padding, TOKEN_SIZE); + uint64_t canary_num; // ephemeral RPC socket used only for this command - int rpc_sock = rpc_join("/root/dev/ztest/nc_e5cd7a9e1c3511dd"); + int rpc_sock = rpc_join(path); // Generate token int fdrand = open("/dev/urandom", O_RDONLY); - read(fdrand, &magic, MAGIC_SIZE); - memcpy(&magic_num, magic, MAGIC_SIZE); + read(fdrand, &CANARY, CANARY_SIZE); + memcpy(&canary_num, CANARY, CANARY_SIZE); cmdbuf[CMD_ID_IDX] = cmd; - memcpy(&cmdbuf[MAGIC_IDX], &magic_num, MAGIC_SIZE); + memcpy(&cmdbuf[CANARY_IDX], &canary_num, CANARY_SIZE); memcpy(&cmdbuf[STRUCT_IDX], data, len); - // Format: [sig_byte] + [cmd_id] + [magic] + [meta] + [payload] - #ifdef VERBOSE - /* - #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] [...] */ memset(metabuf, 0, BUF_SZ); pid_t pid = syscall(SYS_getpid); pid_t tid = syscall(SYS_gettid); @@ -141,7 +144,7 @@ int rpc_send_command(int cmd, int forfd, void *data, int len) memcpy(&metabuf[IDX_TIME], ×tring, 20 ); /* timestamp */ #endif /* Combine command flag+payload with RPC metadata */ - memcpy(&metabuf[IDX_PAYLOAD], cmdbuf, len + 1 + MAGIC_SIZE); + memcpy(&metabuf[IDX_PAYLOAD], cmdbuf, len + 1 + CANARY_SIZE); // Write RPC int n_write = write(rpc_sock, &metabuf, BUF_SZ); @@ -152,7 +155,10 @@ int rpc_send_command(int cmd, int forfd, void *data, int len) // Write token to corresponding data stream read(rpc_sock, &c, 1); if(c == 'z' && n_write > 0 && forfd > -1){ - int w = send(forfd, &magic, TOKEN_SIZE, 0); + if(send(forfd, &CANARY, TOKEN_SIZE, 0) < 0) { + fprintf(stderr,"unable to write canary to stream\n"); + return -1; + } } // Process response from service int ret = ERR_OK; @@ -263,4 +269,4 @@ ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd) } } return size; -} +} \ No newline at end of file diff --git a/netcon/RPC.h b/netcon/RPC.h index 5affc0d4a..35387a8f5 100644 --- a/netcon/RPC.h +++ b/netcon/RPC.h @@ -3,29 +3,28 @@ #include -#define MAGIC_SIZE sizeof(uint64_t) -#define MAGIC_PADDING_SIZE 12 -#define TOKEN_SIZE MAGIC_SIZE+MAGIC_PADDING_SIZE +#define CANARY_SIZE sizeof(uint64_t) +#define CANARY_PADDING_SIZE 12 +#define TOKEN_SIZE CANARY_SIZE+CANARY_PADDING_SIZE #define RPC_PHRASE "zerotier\0" #define RPC_PHRASE_SIZE 9 -// 1st section +// 1st RPC section (metdata) #define IDX_SIGNAL_PHRASE 0 #define IDX_PID IDX_SIGNAL_PHRASE + RPC_PHRASE_SIZE #define IDX_TID sizeof(pid_t) + IDX_PID #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 */ +// 2nd RPC section (payload and canary) +#define CMD_ID_IDX 0 +#define CANARY_IDX 1 +#define STRUCT_IDX CANARY_IDX+CANARY_SIZE -// 2nd section -#define CMD_ID_IDX 0 -#define MAGIC_IDX 1 -#define STRUCT_IDX MAGIC_IDX+MAGIC_SIZE +#define BUF_SZ 256 +#define PAYLOAD_SZ 223 /* BUF_SZ-IDX_PAYLOAD */ -#define BUF_SZ 256 -#define PAYLOAD_SZ 223 /* BUF_SZ-IDX_PAYLOAD */ - -#define ERR_OK 0 +#define ERR_OK 0 /* RPC codes */ #define RPC_UNDEFINED 0 @@ -54,8 +53,10 @@ extern "C" { int get_retval(int); +//#ifdef NETCON_INTERCEPT int rpc_join(const char * sockname); -int rpc_send_command(int cmd, int forfd, void *data, int len); +int rpc_send_command(char *path, int cmd, int forfd, void *data, int len); +//#endif int get_new_fd(int sock); ssize_t sock_fd_write(int sock, int fd); diff --git a/netcon/common.inc.c b/netcon/common.inc.c index 858a2195f..60d2ab3b3 100644 --- a/netcon/common.inc.c +++ b/netcon/common.inc.c @@ -42,7 +42,7 @@ #ifndef _COMMON_H #define _COMMON_H 1 -#define DEBUG_LEVEL 0 +#define DEBUG_LEVEL 3 #define MSG_WARNING 4 #define MSG_ERROR 1 // Errors