diff --git a/netcon/Intercept.c b/netcon/Intercept.c index 27e57c76f..a124ccb6e 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 dd49a1862..70eb511a6 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; ipid); + 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; + 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 + // 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"); - } + 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 930807a50..885f34a7a 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 45332512f..83e3c1d29 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 46a1f0248..000000000 Binary files a/netcon/libintercept.so.1.0 and /dev/null differ