summaryrefslogtreecommitdiff
path: root/netcon
diff options
context:
space:
mode:
Diffstat (limited to 'netcon')
-rwxr-xr-xnetcon/Intercept.c53
-rw-r--r--netcon/NetconEthernetTap.cpp186
-rw-r--r--netcon/NetconEthernetTap.hpp2
-rw-r--r--netcon/NetconUtilities.cpp4
-rwxr-xr-xnetcon/libintercept.so.1.0bin56400 -> 0 bytes
5 files changed, 139 insertions, 106 deletions
diff --git a/netcon/Intercept.c b/netcon/Intercept.c
index 27e57c76..a124ccb6 100755
--- a/netcon/Intercept.c
+++ b/netcon/Intercept.c
@@ -331,6 +331,11 @@ int setsockopt(SETSOCKOPT_SIG)
{
dwr("setsockopt(%d)\n", socket);
//return(realsetsockopt(socket, level, option_name, option_value, option_len));
+ if(level == SOL_IPV6 && option_name == IPV6_V6ONLY)
+ return 0;
+
+ if(level == SOL_IP && option_name == IP_TTL)
+ return 0;
if(level == IPPROTO_TCP || (level == SOL_SOCKET && option_name == SO_KEEPALIVE)){
return 0;
@@ -353,7 +358,7 @@ int setsockopt(SETSOCKOPT_SIG)
/* int sockfd, int level, int optname, void *optval, socklen_t *optlen */
int getsockopt(GETSOCKOPT_SIG)
{
- dwr("setsockopt(%d)\n", sockfd);
+ dwr("getsockopt(%d)\n", sockfd);
int err = realgetsockopt(sockfd, level, optname, optval, optlen);
// FIXME: this condition will need a little more intelligence later on
// -- we will need to know if this fd is a local we are spoofing, or a true local
@@ -385,19 +390,19 @@ int socket(SOCKET_SIG)
int flags = socket_type & ~SOCK_TYPE_MASK;
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
errno = EINVAL;
- handle_error("socket", "", -1);
+ handle_error("socket1", "", -1);
return -1;
}
socket_type &= SOCK_TYPE_MASK;
/* Check protocol is in range */
if (socket_family < 0 || socket_family >= NPROTO){
errno = EAFNOSUPPORT;
- handle_error("socket", "", -1);
+ handle_error("socket2", "", -1);
return -1;
}
if (socket_type < 0 || socket_type >= SOCK_MAX) {
errno = EINVAL;
- handle_error("socket", "", -1);
+ handle_error("socket3", "", -1);
return -1;
}
/* Check that we haven't hit the soft-limit file descriptors allowed */
@@ -416,7 +421,7 @@ int socket(SOCKET_SIG)
fdret_sock = !is_initialized ? init_service_connection() : fdret_sock;
if(fdret_sock < 0) {
dwr("BAD service connection. exiting.\n");
- handle_error("socket", "", -1);
+ handle_error("socket4", "", -1);
exit(-1);
}
@@ -425,7 +430,7 @@ int socket(SOCKET_SIG)
|| socket_family == AF_UNIX) {
int err = realsocket(socket_family, socket_type, protocol);
dwr("realsocket, err = %d\n", err);
- handle_error("socket", "", err);
+ handle_error("socket5", "", err);
return err;
}
@@ -447,6 +452,7 @@ int socket(SOCKET_SIG)
/* get new fd */
char rbuf[16];
ssize_t sz = sock_fd_read(fdret_sock, rbuf, sizeof(rbuf), &newfd);
+ dwr("read %d bytes (%s)\n", sz, &rbuf);
if(sz > 0)
{
/* send our local-fd number back to service so
@@ -455,27 +461,27 @@ int socket(SOCKET_SIG)
cmd[0] = RPC_MAP;
memcpy(&cmd[1], &newfd, sizeof(newfd));
- //if(newfd > -1) {
+ if(newfd > -1) { // FIXME: check logic
send_command(fdret_sock, cmd);
pthread_mutex_unlock(&lock);
errno = ERR_OK; // OK
- handle_error("socket", "", newfd);
+ handle_error("socket6", "", newfd);
return newfd;
- //}
- /*
+ }
else { // Try to read retval+errno since we RXed a bad fd
dwr("Error, service sent bad fd.\n");
err = get_retval();
pthread_mutex_unlock(&lock);
+ handle_error("socket7", "", -1);
return err;
}
- */
+
}
else {
dwr("Error while receiving new FD.\n");
err = get_retval();
pthread_mutex_unlock(&lock);
- handle_error("socket", "", -1);
+ handle_error("socket8", "", -1);
return err;
}
}
@@ -764,9 +770,9 @@ int accept(ACCEPT_SIG)
return -1;
}
}
- errno = EAGAIN; /* necessary? */
- handle_error("accept", "EAGAIN - Error reading signal byte from service", -1);
- return -EAGAIN;
+ errno = EBADF; /* necessary? */
+ handle_error("accept", "EBADF - Error reading signal byte from service", -1);
+ return -1;
}
@@ -825,7 +831,7 @@ int listen(LISTEN_SIG)
memcpy(&cmd[1], &rpc_st, sizeof(struct listen_st));
pthread_mutex_lock(&lock);
send_command(fdret_sock, cmd);
- //err = get_retval();
+ int err = get_retval();
pthread_mutex_unlock(&lock);
handle_error("listen", "", ERR_OK);
return ERR_OK;
@@ -866,7 +872,8 @@ int poll(POLL_SIG)
long syscall(SYSCALL_SIG)
{
- //dwr("syscall(%u, ...):\n", number);
+ dwr("syscall(%u, ...):\n", number);
+
va_list ap;
uintptr_t a,b,c,d,e,f;
va_start(ap, number);
@@ -891,7 +898,17 @@ long syscall(SYSCALL_SIG)
struct sockaddr * addr = (struct sockaddr*)b;
socklen_t * addrlen = (socklen_t*)c;
int flags = d;
- return accept4(sockfd, addr, addrlen, flags);
+ int old_errno = errno;
+ int err = accept4(sockfd, addr, addrlen, flags);
+ errno = old_errno;
+
+ if(err == -EBADF) {
+ //errno = EAGAIN;
+ err = -EAGAIN;
+ //exit(0);
+ }
+
+ return err;
}
#endif
return realsyscall(number,a,b,c,d,e,f);
diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp
index dd49a186..70eb511a 100644
--- a/netcon/NetconEthernetTap.cpp
+++ b/netcon/NetconEthernetTap.cpp
@@ -82,7 +82,7 @@ NetconEthernetTap::NetconEthernetTap(
_dev = sockPath;
lwipstack = new LWIPStack("ext/bin/lwip/liblwip.so"); // ext/bin/liblwip.so.debug for debug symbols
- if(!lwipstack) // TODO double check this check
+ if(!lwipstack)
throw std::runtime_error("unable to load lwip lib.");
lwipstack->lwip_init();
@@ -261,14 +261,33 @@ TcpConnection *NetconEthernetTap::getConnectionByTheirFD(PhySocket *sock, int fd
void NetconEthernetTap::compact_dump()
{
/*
- //clearscreen();
+ //
refresh();
clear();
gotoxy(0,0);
+ */
+ clearscreen();
+ gotoxy(0,0);
+
fprintf(stderr, "ZeroTier - Network Containers Service [State Dump]\n\r");
fprintf(stderr, " RPC Sockets = %d\n\r", rpc_sockets.size());
fprintf(stderr, " TCP Connections = %d\n\r", tcp_connections.size());
- */
+
+ for(size_t i=0; i<rpc_sockets.size(); i++) {
+ int rpc_fd = _phy.getDescriptor(rpc_sockets[i]);
+ char buf[80];
+ int pid = pidmap[rpc_sockets[i]];
+ memset(&buf, '\0', 80);
+ get_path_from_pid(buf, pid);
+ fprintf(stderr, "\n Client(addr=0x%x, rpc=%d, pid=%d) %s\n", rpc_sockets[i], rpc_fd, pid, buf);
+ for(size_t j=0; j<tcp_connections.size(); j++) {
+ memset(&buf, '\0', 80);
+ get_path_from_pid(buf, tcp_connections[j]->pid);
+ if(tcp_connections[j]->rpcSock==rpc_sockets[i]) {
+ fprintf(stderr, "\t\tpath\t\t= %s\n", buf);
+ }
+ }
+ }
}
/*
@@ -331,7 +350,7 @@ void NetconEthernetTap::die(int exret) {
*/
void NetconEthernetTap::closeConnection(TcpConnection *conn)
{
- fprintf(stderr, " closeConnection(%x, %d)\n", conn->pcb, _phy.getDescriptor(conn->dataSock));
+ dwr(" closeConnection(%x, %d)\n", conn->pcb, _phy.getDescriptor(conn->dataSock));
//lwipstack->_tcp_sent(conn->pcb, NULL);
//lwipstack->_tcp_recv(conn->pcb, NULL);
@@ -524,7 +543,7 @@ void NetconEthernetTap::phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,
}
/*
- * Add a new PhySocket for the client connection
+ * Add a new PhySocket for the client connections
*/
void NetconEthernetTap::phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN) {
if(find(rpc_sockets.begin(), rpc_sockets.end(), sockN) != rpc_sockets.end()){
@@ -549,9 +568,10 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns
pid_t pid;
memcpy(&pid, &buf[1], sizeof(pid_t)); // PID for client RPC tracking (only for debug)
memcpy(&socket_rpc, &buf[64], sizeof(struct socket_st));
- if(handle_socket(sock, uptr, &socket_rpc) >= 0) {
- fprintf(stderr, "pidmap[...] = %d\n", pid);
+ TcpConnection * new_conn;
+ if(new_conn = handle_socket(sock, uptr, &socket_rpc)) {
pidmap[sock] = pid;
+ new_conn->pid = pid;
}
break;
case RPC_LISTEN:
@@ -621,12 +641,14 @@ int NetconEthernetTap::send_return_value(TcpConnection *conn, int retval, int _e
int NetconEthernetTap::send_return_value(int fd, int retval, int _errno = 0)
{
+ fprintf(stderr, "send_return_value(): fd = %d, retval = %d, errno = %d\n", fd, retval, _errno);
int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
char retmsg[sz];
memset(&retmsg, '\0', sizeof(retmsg));
retmsg[0]=RPC_RETVAL;
memcpy(&retmsg[1], &retval, sizeof(retval));
memcpy(&retmsg[1]+sizeof(retval), &_errno, sizeof(_errno));
+ fprintf(stderr, "send_return_value(): retmsg = %s, sizeof(retmsg) = %d\n", &retmsg, sizeof(retmsg));
return write(fd, &retmsg, sz);
}
@@ -804,76 +826,71 @@ void NetconEthernetTap::nc_err(void *arg, err_t err)
if(!l->conn)
dwr("nc_err(): Connection is NULL!\n");
- if(l->conn) {
- switch(err)
- {
- case ERR_MEM:
- dwr("nc_err(): ERR_MEM->ENOMEM\n");
- l->tap->send_return_value(l->conn, -1, ENOMEM);
- break;
- case ERR_BUF:
- dwr("nc_err(): ERR_BUF->ENOBUFS\n");
- l->tap->send_return_value(l->conn, -1, ENOBUFS);
- break;
- case ERR_TIMEOUT:
- dwr("nc_err(): ERR_TIMEOUT->ETIMEDOUT\n");
- l->tap->send_return_value(l->conn, -1, ETIMEDOUT);
- break;
- case ERR_RTE:
- dwr("nc_err(): ERR_RTE->ENETUNREACH\n");
- l->tap->send_return_value(l->conn, -1, ENETUNREACH);
- break;
- case ERR_INPROGRESS:
- dwr("nc_err(): ERR_INPROGRESS->EINPROGRESS\n");
- l->tap->send_return_value(l->conn, -1, EINPROGRESS);
- break;
- case ERR_VAL:
- dwr("nc_err(): ERR_VAL->EINVAL\n");
- l->tap->send_return_value(l->conn, -1, EINVAL);
- break;
- case ERR_WOULDBLOCK:
- dwr("nc_err(): ERR_WOULDBLOCK->EWOULDBLOCK\n");
- l->tap->send_return_value(l->conn, -1, EWOULDBLOCK);
- break;
- case ERR_USE:
- dwr("nc_err(): ERR_USE->EADDRINUSE\n");
- l->tap->send_return_value(l->conn, -1, EADDRINUSE);
- break;
- case ERR_ISCONN:
- dwr("nc_err(): ERR_ISCONN->EISCONN\n");
- l->tap->send_return_value(l->conn, -1, EISCONN);
- break;
- case ERR_ABRT:
- dwr("nc_err(): ERR_ABRT->ECONNREFUSED\n");
- l->tap->send_return_value(l->conn, -1, ECONNREFUSED);
- break;
-
- // FIXME: Below are errors which don't have a standard errno correlate
-
- case ERR_RST:
- l->tap->send_return_value(l->conn, -1, -1);
- break;
- case ERR_CLSD:
- l->tap->send_return_value(l->conn, -1, -1);
- break;
- case ERR_CONN:
- l->tap->send_return_value(l->conn, -1, -1);
- break;
- case ERR_ARG:
- l->tap->send_return_value(l->conn, -1, -1);
- break;
- case ERR_IF:
- l->tap->send_return_value(l->conn, -1, -1);
- break;
- default:
- break;
- }
- dwr("nc_err(): closing connection\n");
- l->tap->closeConnection(l->conn);
- }
- else {
- dwr("nc_err(): can't locate connection object for PCB\n");
- }
+ switch(err)
+ {
+ case ERR_MEM:
+ dwr("nc_err(): ERR_MEM->ENOMEM\n");
+ l->tap->send_return_value(l->conn, -1, ENOMEM);
+ break;
+ case ERR_BUF:
+ dwr("nc_err(): ERR_BUF->ENOBUFS\n");
+ l->tap->send_return_value(l->conn, -1, ENOBUFS);
+ break;
+ case ERR_TIMEOUT:
+ dwr("nc_err(): ERR_TIMEOUT->ETIMEDOUT\n");
+ l->tap->send_return_value(l->conn, -1, ETIMEDOUT);
+ break;
+ case ERR_RTE:
+ dwr("nc_err(): ERR_RTE->ENETUNREACH\n");
+ l->tap->send_return_value(l->conn, -1, ENETUNREACH);
+ break;
+ case ERR_INPROGRESS:
+ dwr("nc_err(): ERR_INPROGRESS->EINPROGRESS\n");
+ l->tap->send_return_value(l->conn, -1, EINPROGRESS);
+ break;
+ case ERR_VAL:
+ dwr("nc_err(): ERR_VAL->EINVAL\n");
+ l->tap->send_return_value(l->conn, -1, EINVAL);
+ break;
+ case ERR_WOULDBLOCK:
+ dwr("nc_err(): ERR_WOULDBLOCK->EWOULDBLOCK\n");
+ l->tap->send_return_value(l->conn, -1, EWOULDBLOCK);
+ break;
+ case ERR_USE:
+ dwr("nc_err(): ERR_USE->EADDRINUSE\n");
+ l->tap->send_return_value(l->conn, -1, EADDRINUSE);
+ break;
+ case ERR_ISCONN:
+ dwr("nc_err(): ERR_ISCONN->EISCONN\n");
+ l->tap->send_return_value(l->conn, -1, EISCONN);
+ break;
+ case ERR_ABRT:
+ dwr("nc_err(): ERR_ABRT->ECONNREFUSED\n");
+ l->tap->send_return_value(l->conn, -1, ECONNREFUSED);
+ break;
+
+ // FIXME: Below are errors which don't have a standard errno correlate
+
+ case ERR_RST:
+ l->tap->send_return_value(l->conn, -1, -1);
+ break;
+ case ERR_CLSD:
+ l->tap->send_return_value(l->conn, -1, -1);
+ break;
+ case ERR_CONN:
+ l->tap->send_return_value(l->conn, -1, -1);
+ break;
+ case ERR_ARG:
+ l->tap->send_return_value(l->conn, -1, -1);
+ break;
+ case ERR_IF:
+ l->tap->send_return_value(l->conn, -1, -1);
+ break;
+ default:
+ break;
+ }
+ dwr("nc_err(): closing connection\n");
+ l->tap->closeConnection(l->conn);
}
/*
@@ -912,10 +929,8 @@ err_t NetconEthernetTap::nc_poll(void* arg, struct tcp_pcb *tpcb)
*/
err_t NetconEthernetTap::nc_sent(void* arg, struct tcp_pcb *tpcb, u16_t len)
{
- //fprintf(stderr, " nc_sent()\n");
Larg *l = (Larg*)arg;
if(len) {
- //fprintf(stderr, " nc_sent(): ACKING len = %d, setting read-notify = true, (sndbuf = %d)\n", len, l->conn->pcb->snd_buf);
l->tap->_phy.setNotifyReadable(l->conn->dataSock, true);
l->tap->_phy.whack();
}
@@ -1146,7 +1161,7 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste
}
else {
/*
- fprintf(stderr, "handle_listen(): unable to allocate memory for new listening PCB\n");
+ dwr"handle_listen(): unable to allocate memory for new listening PCB\n");
// FIXME: This does not have an equivalent errno value
// lwip will reclaim space with a tcp_listen call since a PCB in a LISTEN
// state takes up less space. If something goes wrong during the creation of a
@@ -1186,7 +1201,7 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste
[?] EPROTONOSUPPORT - The protocol type or the specified protocol is not supported within this domain.
*/
-int NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc)
+TcpConnection * NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc)
{
int rpc_fd = _phy.getDescriptor(sock);
struct tcp_pcb *newpcb = lwipstack->tcp_new();
@@ -1198,7 +1213,7 @@ int NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socket
if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
if(errno < 0) {
send_return_value(rpc_fd, -1, errno);
- return -1;
+ return NULL;
}
}
dwr(" handle_socket(): socketpair = {%d, %d}\n", fds[0], fds[1]);
@@ -1209,17 +1224,18 @@ int NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socket
new_conn->pcb = newpcb;
new_conn->their_fd = fds[1];
tcp_connections.push_back(new_conn);
- sock_fd_write(_phy.getDescriptor(sock), fds[1]);
+ 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;
- return 0;
+ return new_conn;
}
else {
sock_fd_write(rpc_fd, -1); // Send a bad fd, to signal error
dwr(" handle_socket(): Memory not available for new PCB\n");
send_return_value(rpc_fd, -1, ENOMEM);
- return -1;
+ return NULL;
}
}
diff --git a/netcon/NetconEthernetTap.hpp b/netcon/NetconEthernetTap.hpp
index 930807a5..885f34a7 100644
--- a/netcon/NetconEthernetTap.hpp
+++ b/netcon/NetconEthernetTap.hpp
@@ -109,7 +109,7 @@ private:
void handle_map_request(PhySocket *sock, void **uptr, unsigned char* buf);
void handle_i_am(PhySocket *sock, void **uptr, unsigned char* buf);
void handle_retval(PhySocket *sock, void **uptr, unsigned char* buf);
- int handle_socket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc);
+ 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);
diff --git a/netcon/NetconUtilities.cpp b/netcon/NetconUtilities.cpp
index 45332512..83e3c1d2 100644
--- a/netcon/NetconUtilities.cpp
+++ b/netcon/NetconUtilities.cpp
@@ -44,13 +44,13 @@ namespace ZeroTier
{
void dwr(char *fmt, ... )
{
-//#ifdef ZT_DEBUG
+
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fflush(stderr);
va_end(ap);
-//#endif
+
}
void clearscreen()
diff --git a/netcon/libintercept.so.1.0 b/netcon/libintercept.so.1.0
deleted file mode 100755
index 46a1f024..00000000
--- a/netcon/libintercept.so.1.0
+++ /dev/null
Binary files differ