Browse Source

Merge branch 'edge' of http://10.6.6.2/zerotier/ZeroTierOne into edge

Adam Ierymenko 9 years ago
parent
commit
d03a63e055
6 changed files with 136 additions and 107 deletions
  1. 3 9
      make-linux.mk
  2. 55 20
      netcon/Intercept.c
  3. 25 32
      netcon/NetconEthernetTap.cpp
  4. 38 32
      netcon/RPC.c
  5. 14 13
      netcon/RPC.h
  6. 1 1
      netcon/common.inc.c

+ 3 - 9
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

+ 55 - 20
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));

+ 25 - 32
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; i<tcp_connections.size(); i++) {
 			if(tcp_connections[i]->sock == 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<PhySocket*, void*> 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<PhySocket*, void*>(sock, data);
+			jobmap[CANARY_num] = std::make_pair<PhySocket*, void*>(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));
 }
 
 /*

+ 38 - 32
netcon/RPC.c

@@ -6,16 +6,21 @@
 #include <sys/syscall.h>
 
 #include <fcntl.h>
+#include <dlfcn.h>
 #include <stdint.h>
 
 #include <sys/socket.h>
 #include <strings.h>
 #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],    &timestring,   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;
-}
+}

+ 14 - 13
netcon/RPC.h

@@ -3,29 +3,28 @@
 
 #include <stdint.h>
 
-#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);

+ 1 - 1
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