diff --git a/README.md b/README.md index 6333c75..7f49979 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ We've designed a background tap service that pairs the ZeroTier protocol with sw - `SDK_DEBUG=1` - Enables SDK debugging - `SDK_PICOTCP=1` - Enable the use of `picoTCP` (recommended) -- `SDK_PICO_DEBUG=1` - Enables debug output for the `picoTCP` network stack +- `SDK_PICOTCP_DEBUG=1` - Enables debug output for the `picoTCP` network stack - `SDK_LWIP=1` - Enable the use of `lwIP` (deprecated) - `SDK_LWIP_DEBUG=1` - Enables debug output for the `lwIP` library. diff --git a/docs/zt_sdk_intro.md b/docs/zt_sdk_intro.md index 6333c75..7f49979 100644 --- a/docs/zt_sdk_intro.md +++ b/docs/zt_sdk_intro.md @@ -40,7 +40,7 @@ We've designed a background tap service that pairs the ZeroTier protocol with sw - `SDK_DEBUG=1` - Enables SDK debugging - `SDK_PICOTCP=1` - Enable the use of `picoTCP` (recommended) -- `SDK_PICO_DEBUG=1` - Enables debug output for the `picoTCP` network stack +- `SDK_PICOTCP_DEBUG=1` - Enables debug output for the `picoTCP` network stack - `SDK_LWIP=1` - Enable the use of `lwIP` (deprecated) - `SDK_LWIP_DEBUG=1` - Enables debug output for the `lwIP` library. diff --git a/make-linux.mk b/make-linux.mk index 261f54d..6ce0928 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -114,6 +114,13 @@ ifeq ($(SDK_LWIP_DEBUG),1) LWIP_FLAGS+=SDK_LWIP_DEBUG=1 endif +# picoTCP debug +ifeq ($(SDK_PICOTCP_DEBUG),1) + PICOTCP_FLAGS+=DEBUG=1 +else + PICOTCP_FLAGS+=DEBUG=0 +endif + # lwIP ifeq ($(SDK_LWIP),1) STACK_FLAGS+=-DSDK_LWIP @@ -170,7 +177,7 @@ lwip: pico: mkdir -p build - cd ext/picotcp; make lib PICO_SUPPORT_UDP=1 ARCH=shared IPV4=1 IPV6=1 + cd ext/picotcp; make lib $(SDK_PICOTCP_FLAGS) PICO_SUPPORT_UDP=1 ARCH=shared IPV4=1 IPV6=1 $(CC) -g -nostartfiles -shared -o ext/picotcp/build/lib/libpicotcp.so ext/picotcp/build/lib/*.o ext/picotcp/build/modules/*.o cp ext/picotcp/build/lib/libpicotcp.so build/libpicotcp.so diff --git a/src/intercept.c b/src/intercept.c index 1e6aead..d7279db 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -263,24 +263,24 @@ pthread_key_t thr_id_key; int socket(SOCKET_SIG) { DEBUG_ATTN(); + int err; if (!check_intercept_enabled() && socket_type) { - int err = realsocket(socket_family, socket_type, protocol); - if(err < 0) { + if((err = realsocket(socket_family, socket_type, protocol)) < 0) { perror("socket:\n"); } else { - DEBUG_INFO("err=%d", err); + DEBUG_BLANK("realsocket(): fd=%d", err); return err; } } - // Check if local + // If the socket type is LOCAL, we don't want to handle it, pass to system if(socket_family == AF_LOCAL #if defined(__linux__) || socket_family == AF_NETLINK #endif || socket_family == AF_UNIX) { - int err = realsocket(socket_family, socket_type, protocol); - DEBUG_BLANK("realsocket(): err=%d", err); + err = realsocket(socket_family, socket_type, protocol); + DEBUG_BLANK("realsocket(): fd=%d", err); return err; } return zts_socket(socket_family, socket_type, protocol); diff --git a/src/sockets.c b/src/sockets.c index 09c9aed..dd7ee94 100644 --- a/src/sockets.c +++ b/src/sockets.c @@ -88,7 +88,6 @@ int (*realclose)(CLOSE_SIG); // Assembles (and/or) sets the RPC path for communication with the ZeroTier service void zts_init_rpc(const char *path, const char *nwid) { - DEBUG_EXTRA(); #if !defined(__IOS__) // Since we don't use function interposition in iOS if(!realconnect) { @@ -110,13 +109,11 @@ int (*realclose)(CLOSE_SIG); } #else // Get path/nwid from environment variables - // This is used when you're dynamically-linking our library into your application at runtime if (!api_netpath) { api_netpath = getenv("ZT_NC_NETWORK"); - DEBUG_INFO("$ZT_NC_NETWORK(len=%ld)=%s", strlen(api_netpath), api_netpath); + DEBUG_INFO("$ZT_NC_NETWORK=%s", api_netpath); } #endif - //DEBUG_EXTRA("api_netpath=%s", api_netpath); } } @@ -283,7 +280,6 @@ int (*realclose)(CLOSE_SIG); #endif { int tmpsz = 0; // payload size - // DEBUG_EXTRA("zt_recvfrom(%d, ...)\n", fd); if(read(fd, buf, ZT_MAX_MTU) > 0) { // TODO: case for address size mismatch? memcpy(addr, buf, *addrlen); @@ -343,7 +339,7 @@ int (*realclose)(CLOSE_SIG); #endif // ------------------------------------------------------------------------------ - // ----------------------- Exposed RX/TX API for UNITY 3D ----------------------- + // --------------------- Exposed RX/TX API for .NET Wrapper --------------------- // ------------------------------------------------------------------------------ #if defined(__UNITY_3D__) @@ -455,14 +451,12 @@ int (*realclose)(CLOSE_SIG); get_api_netpath(); DEBUG_INFO(""); // Check that type makes sense -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) int flags = socket_type & ~SOCK_TYPE_MASK; - #if !defined(__ANDROID__) if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) { errno = EINVAL; return -1; } - #endif #endif socket_type &= SOCK_TYPE_MASK; // Check protocol is in range @@ -481,15 +475,7 @@ int (*realclose)(CLOSE_SIG); rpc_st.socket_family = socket_family; rpc_st.socket_type = socket_type; rpc_st.protocol = protocol; -#if defined(__linux__) - #if !defined(__ANDROID__) - rpc_st.tid = 5; //syscall(SYS_gettid); - #else - rpc_st.tid = gettid(); // dummy value - #endif -#endif // -1 is passed since we we're generating the new socket in this call - DEBUG_INFO("api_netpath=%s", api_netpath); int err = rpc_send_command(api_netpath, RPC_SOCKET, -1, &rpc_st, sizeof(struct socket_st)); DEBUG_INFO("err=%d", err); return err; @@ -522,13 +508,6 @@ int (*realclose)(CLOSE_SIG); get_api_netpath(); DEBUG_INFO("fd=%d", fd); struct connect_st rpc_st; -#if defined(__linux__) - #if !defined(__ANDROID__) - //rpc_st.tid = syscall(SYS_gettid); - #else - //rpc_st.tid = gettid(); // dummy value - #endif -#endif rpc_st.fd = fd; memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage)); memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t)); @@ -563,14 +542,6 @@ int (*realclose)(CLOSE_SIG); DEBUG_INFO("fd=%d", fd); struct bind_st rpc_st; rpc_st.fd = fd; -#if defined(__linux__) - #if !defined(__ANDROID__) - // TODO: Candidate for removal - rpc_st.tid = 5;//syscall(SYS_gettid); - #else - rpc_st.tid = gettid(); // dummy value - #endif -#endif memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage)); memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t)); return rpc_send_command(api_netpath, RPC_BIND, fd, &rpc_st, sizeof(struct bind_st)); @@ -676,13 +647,6 @@ int (*realclose)(CLOSE_SIG); struct listen_st rpc_st; rpc_st.fd = fd; rpc_st.backlog = backlog; -#if defined(__linux__) - #if !defined(__ANDROID__) - rpc_st.tid = syscall(SYS_gettid); - #else - rpc_st.tid = gettid(); // dummy value - #endif -#endif return rpc_send_command(api_netpath, RPC_LISTEN, fd, &rpc_st, sizeof(struct listen_st)); } diff --git a/src/stack_drivers/picotcp/picotcp.cpp b/src/stack_drivers/picotcp/picotcp.cpp index d471cf4..57c9360 100644 --- a/src/stack_drivers/picotcp/picotcp.cpp +++ b/src/stack_drivers/picotcp/picotcp.cpp @@ -125,8 +125,8 @@ namespace ZeroTier { DEBUG_INFO(); while(tap->_run) { - tap->_phy.poll((unsigned long)std::min(500,1000)); - usleep(1000); + tap->_phy.poll(25); // in ms + usleep(50); tap->picostack->__pico_stack_tick(); } } @@ -160,11 +160,9 @@ namespace ZeroTier { r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), ZT_MAX_MTU, (void *)&peer.ip4.addr, &port); // DEBUG_ATTN("received packet (%d byte) from %08X:%u", r, long_be2(peer.ip4.addr), short_be(port)); tap->_phy.setNotifyWritable(conn->sock, true); - DEBUG_INFO("read=%d", r); + DEBUG_EXTRA("read=%d", r); if (r > 0) conn->rxsz += r; - else - DEBUG_ERROR("error while reading from pico_socket(%p)", s); } else DEBUG_ERROR("not enough space left on I/O RX buffer for pico_socket(%p)", s); @@ -206,6 +204,7 @@ namespace ZeroTier { // Main callback for TCP connections void pico_cb_tcp(uint16_t ev, struct pico_socket *s) { + int err; Mutex::Lock _l(picotap->_tcpconns_m); Connection *conn = picotap->getConnection(s); if(!conn) { @@ -224,7 +223,6 @@ namespace ZeroTier { if(!client) { DEBUG_EXTRA("unable to accept conn. (event might not be incoming, not necessarily an error), sock=%p", (void*)(conn->picosock)); } - ZT_PHY_SOCKFD_TYPE fds[2]; if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) { if(errno < 0) { @@ -245,7 +243,7 @@ namespace ZeroTier { } } if (ev & PICO_SOCK_EV_FIN) { - DEBUG_INFO("socket closed. Exit normally."); + DEBUG_INFO("socket closed. exit normally."); //picotap->__pico_timer_add(2000, compare_results, NULL); } if (ev & PICO_SOCK_EV_ERR) { @@ -253,8 +251,8 @@ namespace ZeroTier { //exit(1); } if (ev & PICO_SOCK_EV_CLOSE) { - DEBUG_INFO("socket received close from peer - Wrong case if not all client data sent!"); - picotap->picostack->__pico_socket_close(s); + err = picotap->picostack->__pico_socket_close(s); + DEBUG_INFO("socket closure = %d", err); picotap->closeConnection(conn); return; } @@ -462,7 +460,7 @@ namespace ZeroTier { char ipv4_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(in4->sin_addr), ipv4_str, INET_ADDRSTRLEN); picotap->picostack->__pico_string_to_ipv4(ipv4_str, &(zaddr.addr)); - DEBUG_ATTN("addr=%s:%d", ipv4_str, addr->sin_port); + DEBUG_ATTN("addr=%s:%d", ipv4_str, Utils::ntoh(addr->sin_port)); ret = picotap->picostack->__pico_socket_connect(conn->picosock, &zaddr, addr->sin_port); #elif defined(SDK_IPV6) // "fd56:5799:d8f6:1238:8c99:9322:30ce:418a" struct pico_ip6 zaddr; @@ -470,7 +468,7 @@ namespace ZeroTier { char ipv6_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &(in6->sin6_addr), ipv6_str, INET6_ADDRSTRLEN); picotap->picostack->__pico_string_to_ipv6(ipv6_str, zaddr.addr); - DEBUG_ATTN("addr=%s:%d", ipv6_str, addr->sin_port); + DEBUG_ATTN("addr=%s:%d", ipv6_str, Utils::ntoh(addr->sin_port)); ret = picotap->picostack->__pico_socket_connect(conn->picosock, &zaddr, addr->sin_port); #endif @@ -507,7 +505,7 @@ namespace ZeroTier { char ipv4_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(in4->sin_addr), ipv4_str, INET_ADDRSTRLEN); picotap->picostack->__pico_string_to_ipv4(ipv4_str, &(zaddr.addr)); - DEBUG_ATTN("addr=%s", ipv4_str/*, ntohs((uint16_t*)&(addr->sin_port))*/); + DEBUG_ATTN("addr=%s:%d", ipv4_str, Utils::ntoh(addr->sin_port)); ret = picotap->picostack->__pico_socket_bind(conn->picosock, &zaddr, (uint16_t*)&(addr->sin_port)); #elif defined(SDK_IPV6) struct pico_ip6 zaddr; @@ -515,7 +513,7 @@ namespace ZeroTier { char ipv6_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &(in6->sin6_addr), ipv6_str, INET6_ADDRSTRLEN); picotap->picostack->__pico_string_to_ipv6(ipv6_str, zaddr.addr); - DEBUG_ATTN("addr=%s", ipv6_str/*, ntohs((uint16_t*)&(addr->sin_port))*/); + DEBUG_ATTN("addr=%s:%d", ipv6_str, Utils::ntoh(addr->sin_port)); ret = picotap->picostack->__pico_socket_bind(conn->picosock, &zaddr, (uint16_t*)&(addr->sin_port)); #endif if(ret < 0) { diff --git a/src/tap.cpp b/src/tap.cpp index e166f1c..9981d44 100644 --- a/src/tap.cpp +++ b/src/tap.cpp @@ -212,6 +212,13 @@ std::vector NetconEthernetTap::ips() const return _ips; } +// Receive data from ZT tap service (virtual wire) and present it to network stack +// ----------------------------------------- +// | TAP <-> MEM BUFFER <-> STACK <-> APP | +// | |--------------->| | RX +// | APP <-> I/O BUFFER <-> STACK <-> TAP | +// | | +// ----------------------------------------- void NetconEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) { // DEBUG_EXTRA("RX packet: len=%d, etherType=%d", len, etherType); @@ -326,6 +333,14 @@ void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) { //closeConnection(sock); } + +// Receive data from ZT tap service and present it to network stack +// ----------------------------------------- +// | TAP <-> MEM BUFFER <-> STACK <-> APP | +// | |--------------->| | RX +// | APP <-> I/O BUFFER <-> STACK <-> TAP | +// | | +// ----------------------------------------- void NetconEthernetTap::handleRead(PhySocket *sock,void **uptr,bool lwip_invoked) { // DEBUG_EXTRA("handleRead(sock=%p): lwip_invoked = %d\n", (void*)&sock, lwip_invoked); diff --git a/tests/api_test/pressureclient4.c b/tests/api_test/pressureclient4.c new file mode 100644 index 0000000..bf49f66 --- /dev/null +++ b/tests/api_test/pressureclient4.c @@ -0,0 +1,63 @@ +// TCP Client test program + +#include +#include +#include +#include +#include + +#define MSGSZ 1024 + +int atoi(const char *str); +int close(int filedes); + +int main(int argc , char *argv[]) +{ + if(argc < 3) { + printf("usage: client \n"); + return 1; + } + + int sock, port = atoi(argv[2]); + struct sockaddr_in server; + char message[MSGSZ] , server_reply[MSGSZ]; + + sock = socket(AF_INET , SOCK_STREAM , 0); + if (sock == -1) { + printf("could not create socket"); + } + server.sin_addr.s_addr = inet_addr(argv[1]); + server.sin_family = AF_INET; + server.sin_port = htons( port ); + + printf("connecting...\n"); + if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { + perror("connect failed. Error"); + return 1; + } + printf("connected\n"); + + memset(message, 1, MSGSZ); + + while(1) + { + //sleep(1); + // TX + if(send(sock, message, MSGSZ, 0) < 0) { + printf("send failed"); + return 1; + } + else { + printf("TX: %s\n", message); + printf("len = %ld\n", strlen(message)); + + int bytes_read = read(sock, server_reply, MSGSZ); + if(bytes_read < 0) + printf("\tRX: Nothing\n"); + else + printf("\tRX = (%d bytes): %s\n", bytes_read, server_reply); + } + } + close(sock); + return 0; +} diff --git a/tests/api_test/pressureserver4.c b/tests/api_test/pressureserver4.c new file mode 100644 index 0000000..827c6ea --- /dev/null +++ b/tests/api_test/pressureserver4.c @@ -0,0 +1,67 @@ +// TCP Server test program + +#include +#include +#include +#include +#include + + +#define MSGSZ 1024 + +int atoi(const char *str); + +int main(int argc , char *argv[]) +{ + if(argc < 2) { + printf("usage: tcp_server \n"); + return 0; + } + + int sock, client_sock, c, read_size, port = atoi(argv[1]); + char message[MSGSZ]; + + char str[MSGSZ]; + int comm_fd; + + struct sockaddr_in servaddr; + struct sockaddr_in client; + + sock = socket(AF_INET, SOCK_STREAM, 0); + bzero( &servaddr, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htons(INADDR_ANY); + servaddr.sin_port = htons(port); + bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)); + + printf("listening\n"); + listen(sock , 3); + printf("waiting to accept\n"); + c = sizeof(struct sockaddr_in); + + client_sock = accept(sock, (struct sockaddr *)&client, (socklen_t*)&c); + if (client_sock < 0) { + perror("accept failed"); + return 0; + } + printf("connection accepted\n reading...\n"); + + // RX + + unsigned long count = 0; + while(1) + { + count++; + int bytes_read = read(client_sock, message, MSGSZ); + printf("[%lu] RX = (%d): ", count, bytes_read); + //for(int i=0; i #include #include +#include #define MAXBUF 65536 @@ -15,7 +16,7 @@ int main(int argc, char* argv[]) int status; struct addrinfo sainfo, *psinfo; struct sockaddr_in6 sin6; - int sin6len; + socklen_t sin6len; char buffer[MAXBUF]; sin6len = sizeof(struct sockaddr_in6); diff --git a/tests/api_test/udpserver6.c b/tests/api_test/udpserver6.c index 0e78083..d30320f 100755 --- a/tests/api_test/udpserver6.c +++ b/tests/api_test/udpserver6.c @@ -5,6 +5,7 @@ #include #include #include +#include #define MAXBUF 65536 @@ -13,7 +14,7 @@ int main() int sock; int status; struct sockaddr_in6 sin6; - int sin6len; + socklen_t sin6len; char buffer[MAXBUF]; sock = socket(PF_INET6, SOCK_DGRAM,0);