diff --git a/ext/picotcp/include/pico_protocol.h b/ext/picotcp/include/pico_protocol.h index 67c86ff..fd7c122 100644 --- a/ext/picotcp/include/pico_protocol.h +++ b/ext/picotcp/include/pico_protocol.h @@ -92,6 +92,4 @@ int pico_protocol_network_loop(int loop_score, int direction); int pico_protocol_transport_loop(int loop_score, int direction); int pico_protocol_socket_loop(int loop_score, int direction); -// static pico_err_t get_pico_err(); - #endif diff --git a/ext/picotcp/stack/pico_protocol.c b/ext/picotcp/stack/pico_protocol.c index 9bad18b..c1b4657 100644 --- a/ext/picotcp/stack/pico_protocol.c +++ b/ext/picotcp/stack/pico_protocol.c @@ -11,13 +11,6 @@ #include "pico_protocol.h" #include "pico_tree.h" -/* -static pico_err_t get_pico_err() -{ - return pico_err; -} -*/ - struct pico_proto_rr { struct pico_tree *t; diff --git a/make-linux.mk b/make-linux.mk index 6ce0928..20c1599 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -221,10 +221,10 @@ linux_service_and_intercept: linux_intercept linux_sdk_service # Builds a single shared library which contains everything ifeq ($(SDK_LWIP),1) linux_shared_lib: $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_SERVICE -shared -o $(SHARED_LIB) $(OBJS) $(LWIP_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(SDK_INTERCEPT_C_FILES) $(LDLIBS) -ldl + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_INTERCEPT -shared -o $(SHARED_LIB) $(OBJS) $(LWIP_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl else linux_shared_lib: $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_SERVICE -shared -o $(SHARED_LIB) $(OBJS) $(PICOTCP_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(SDK_INTERCEPT_C_FILES) $(LDLIBS) -ldl + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_INTERCEPT -shared -o $(SHARED_LIB) $(OBJS) $(PICO_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl endif diff --git a/make-mac.mk b/make-mac.mk index 862871e..1a21d6f 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -225,7 +225,7 @@ osx_shared_lib: lwip $(OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(INCLUDES) $(ZTFLAGS) -DSDK_INTERCEPT -shared -o $(SHARED_LIB) $(OBJS) $(LWIP_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl else osx_shared_lib: pico $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(INCLUDES) $(ZTFLAGS) -shared -o $(SHARED_LIB) $(OBJS) $(PICO_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) $(INCLUDES) $(ZTFLAGS) -DSDK_INTERCEPT -shared -o $(SHARED_LIB) $(OBJS) $(PICO_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl endif osx_intercept: diff --git a/src/defs.h b/src/defs.h index 29d88ff..47e15ae 100644 --- a/src/defs.h +++ b/src/defs.h @@ -1,3 +1,30 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + // --- lwIP #define APPLICATION_POLL_FREQ 2 #define ZT_LWIP_TCP_TIMER_INTERVAL 50 @@ -8,7 +35,6 @@ // --- jip - // --- General // TCP Buffer sizes diff --git a/src/intercept.c b/src/intercept.c index d7279db..c9c6ab1 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -167,7 +167,7 @@ pthread_key_t thr_id_key; ssize_t sendto(SENDTO_SIG) { DEBUG_INFO("fd=%d, len=%d", fd, (int)len); - //if (!check_intercept_enabled()) + if (!check_intercept_enabled()) return realsendto(fd, buf, len, flags, addr, addrlen); return zts_sendto(fd, buf, len, flags, addr, addrlen); } @@ -198,8 +198,8 @@ pthread_key_t thr_id_key; ssize_t recvfrom(RECVFROM_SIG) { DEBUG_INFO("fd=%d", fd); - if(!check_intercept_enabled()) - return realrecvfrom(fd, buf, len, flags, addr, addrlen); + //if(!check_intercept_enabled()) + // return realrecvfrom(fd, buf, len, flags, addr, addrlen); return zts_recvfrom(fd, buf, len, flags, addr, addrlen); } #endif diff --git a/src/sockets.c b/src/sockets.c index dd7ee94..ecb1459 100644 --- a/src/sockets.c +++ b/src/sockets.c @@ -279,12 +279,15 @@ int (*realclose)(CLOSE_SIG); ssize_t zts_recvfrom(RECVFROM_SIG) #endif { - int tmpsz = 0; // payload size - if(read(fd, buf, ZT_MAX_MTU) > 0) { + int payload_offset, tmpsz = 0; // payload size + char tmpbuf[ZT_MAX_MTU]; + if(read(fd, tmpbuf, ZT_MAX_MTU) > 0) { // TODO: case for address size mismatch? - memcpy(addr, buf, *addrlen); - DEBUG_ERROR("addrlen = %d", *addrlen); - memcpy(&tmpsz, buf + sizeof(struct sockaddr_storage), sizeof(tmpsz)); + memcpy(addr, tmpbuf, *addrlen); + memcpy(&tmpsz, tmpbuf + sizeof(struct sockaddr_storage), sizeof(tmpsz)); + char body[2800]; + payload_offset = sizeof(int) + sizeof(struct sockaddr_storage); + memcpy(buf, tmpbuf + payload_offset, ZT_MAX_MTU-payload_offset); } else { perror("read:\n"); diff --git a/src/stack_drivers/picotcp/picotcp.cpp b/src/stack_drivers/picotcp/picotcp.cpp index 57c9360..cc9fa82 100644 --- a/src/stack_drivers/picotcp/picotcp.cpp +++ b/src/stack_drivers/picotcp/picotcp.cpp @@ -37,22 +37,23 @@ #include "pico_protocol.h" #include "pico_socket.h" -/* -static inline uint32_t long_be2(uint32_t le) -{ - uint8_t *b = (uint8_t *)≤ - uint32_t be = 0; - uint32_t b0, b1, b2; - b0 = b[0]; - b1 = b[1]; - b2 = b[2]; - be = b[3] + (b2 << 8) + (b1 << 16) + (b0 << 24); - return be; -} -*/ - namespace ZeroTier { + // This may be removed in production + void check_buffer_states(Connection *conn) + { + #if defined(SDK_DEBUG) + if(conn->rxsz < 0) { + DEBUG_ERROR("conn->rxsz < 0"); + exit(0); + } + if(conn->txsz < 0) { + DEBUG_ERROR("conn->txsz < 0"); + exit(0); + } + #endif + } + // Reference to the tap interface // This is needed due to the fact that there's a lot going on in the tap interface // that needs to be updated on each of the network stack's callbacks and not every @@ -169,10 +170,80 @@ namespace ZeroTier { } while(r > 0); return; - } + } DEBUG_ERROR("invalid connection"); } + // RX packets from network onto internal buffer + // Also notifies the tap service that data can be read + // ----------------------------------------- + // | TAP <-> MEM BUFFER <-> STACK <-> APP | + // | | + // | APP <-> I/O BUFFER <-> STACK <-> TAP | + // | |<-----------------| | RX + // ----------------------------------------- + // After this step, buffer will be emptied periodically by pico_handleRead() + // Read payload is encapsulated as such: + // + // [addr|payload_len|payload] + // + void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s) + { + Connection *conn = tap->getConnection(s); + if(conn) { + + uint16_t port = 0; + union { + struct pico_ip4 ip4; + struct pico_ip6 ip6; + } peer; + + char tmpbuf[ZT_MAX_MTU]; + int tot = 0; + unsigned char *addr_pos, *sz_pos, *payload_pos; + struct sockaddr_in addr_in; + addr_in.sin_addr.s_addr = peer.ip4.addr; + addr_in.sin_port = port; + + // RX + int r = tap->picostack->__pico_socket_recvfrom(s, tmpbuf, ZT_MAX_MTU, (void *)&peer.ip4.addr, &port); + DEBUG_EXTRA("read=%d", r); + + // Mutex::Lock _l2(tap->_rx_buf_m); + // struct sockaddr_in6 addr_in6; + // addr_in6.sin6_addr.s6_addr; + // addr_in6.sin6_port = Utils::ntoh(s->remote_port); + // DEBUG_ATTN("remote_port=%d, local_port=%d", s->remote_port, Utils::ntoh(s->local_port)); + + if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full + DEBUG_INFO("UDP RX buffer full. Discarding oldest payload segment"); + memmove(conn->rxbuf, conn->rxbuf + ZT_MAX_MTU, DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU); + addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU); // TODO: + sz_pos = addr_pos + sizeof(struct sockaddr_storage); + conn->rxsz -= ZT_MAX_MTU; + } + else { + addr_pos = conn->rxbuf + conn->rxsz; // where we'll prepend the size of the address + sz_pos = addr_pos + sizeof(struct sockaddr_storage); + } + payload_pos = addr_pos + sizeof(struct sockaddr_storage) + sizeof(tot); + memcpy(addr_pos, &addr_in, sizeof(struct sockaddr_storage)); + + // Adjust buffer size + if(r) { + conn->rxsz += ZT_MAX_MTU; + memcpy(sz_pos, &r, sizeof(r)); + tap->phyOnUnixWritable(conn->sock, NULL, false); + tap->_phy.setNotifyWritable(conn->sock, false); + } + if (r < 0) { + DEBUG_ERROR("unable to read from picosock=%p", s); + } + memcpy(payload_pos, tmpbuf, r); // write payload to app's socket + return; + } + } + // TX packets from internal buffer to network void pico_cb_tcp_write(NetconEthernetTap *tap, struct pico_socket *s) { @@ -187,7 +258,7 @@ namespace ZeroTier { if(conn->txsz > 0) { int r = conn->txsz < ZT_MAX_MTU ? conn->txsz : ZT_MAX_MTU; if((r = tap->picostack->__pico_socket_write(s, &conn->txbuf, r)) < 0) { - DEBUG_ERROR("unable to write to pico_socket=%p", (void*)s); + DEBUG_ERROR("unable to write to picosock=%p", (void*)s); return; } int sz = (conn->txsz)-r; @@ -195,14 +266,14 @@ namespace ZeroTier { memmove(&conn->txbuf, (conn->txbuf+r), sz); conn->txsz -= r; int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ; - DEBUG_TRANS("[TCP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %d bytes", - (float)conn->txsz / (float)max, (float)conn->rxsz / max, (void*)&conn->sock, r); + DEBUG_TRANS("[TCP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes", + (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r); return; } } // Main callback for TCP connections - void pico_cb_tcp(uint16_t ev, struct pico_socket *s) + void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s) { int err; Mutex::Lock _l(picotap->_tcpconns_m); @@ -210,18 +281,14 @@ namespace ZeroTier { if(!conn) { DEBUG_ERROR("invalid connection"); } - if (ev & PICO_SOCK_EV_RD) { - pico_cb_tcp_read(picotap, s); - } - // Accept connection (analogous to lwip_nc_accept) if (ev & PICO_SOCK_EV_CONN) { - DEBUG_INFO("connection established with server, sock=%p", (void*)(conn->picosock)); + DEBUG_INFO("connection established with server, picosock=%p", (void*)(conn->picosock)); uint32_t peer; uint16_t port; struct pico_socket *client = picotap->picostack->__pico_socket_accept(s, &peer, &port); if(!client) { - DEBUG_EXTRA("unable to accept conn. (event might not be incoming, not necessarily an error), sock=%p", (void*)(conn->picosock)); + DEBUG_EXTRA("unable to accept conn. (event might not be incoming, not necessarily an error), picosock=%p", (void*)(conn->picosock)); } ZT_PHY_SOCKFD_TYPE fds[2]; if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) { @@ -248,7 +315,6 @@ namespace ZeroTier { } if (ev & PICO_SOCK_EV_ERR) { DEBUG_INFO("socket error received" /*, strerror(pico_err)*/); - //exit(1); } if (ev & PICO_SOCK_EV_CLOSE) { err = picotap->picostack->__pico_socket_close(s); @@ -256,6 +322,15 @@ namespace ZeroTier { picotap->closeConnection(conn); return; } + + // Read from picoTCP socket + if (ev & PICO_SOCK_EV_RD) { + if(conn->type==SOCK_STREAM) + pico_cb_tcp_read(picotap, s); + if(conn->type==SOCK_DGRAM) + pico_cb_udp_read(picotap, s); + } + // Write to picoTCP socket if (ev & PICO_SOCK_EV_WR) { pico_cb_tcp_write(picotap, s); } @@ -374,19 +449,30 @@ namespace ZeroTier { { DEBUG_INFO(); struct pico_socket * psock; + int protocol, protocol_version; + #if defined(SDK_IPV4) - psock = picotap->picostack->__pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &pico_cb_tcp); + protocol_version = PICO_PROTO_IPV4; #elif defined(SDK_IPV6) - psock = picotap->picostack->__pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_TCP, &pico_cb_tcp); + protocol_version = PICO_PROTO_IPV6; #endif + if(socket_rpc->socket_type == SOCK_DGRAM) { + protocol = PICO_PROTO_UDP; + psock = picotap->picostack->__pico_socket_open(protocol_version, protocol, &pico_cb_socket_activity); + } + if(socket_rpc->socket_type == SOCK_STREAM) { + protocol = PICO_PROTO_TCP; + psock = picotap->picostack->__pico_socket_open(protocol_version, protocol, &pico_cb_socket_activity); + } + if(psock) { - DEBUG_ATTN("psock = %p", (void*)psock); + DEBUG_ATTN("physock=%p, picosock=%p", sock, (void*)psock); Connection * newConn = new Connection(); *uptr = newConn; newConn->type = socket_rpc->socket_type; newConn->sock = sock; newConn->local_addr = NULL; - newConn->peer_addr = NULL; + // newConn->peer_addr = NULL; newConn->picosock = psock; picotap->_Connections.push_back(newConn); return newConn; @@ -412,12 +498,14 @@ namespace ZeroTier { return; } - int r, max_write_len = conn->txsz < ZT_MAX_MTU ? conn->txsz : ZT_MAX_MTU; + int max, r, max_write_len = conn->txsz < ZT_MAX_MTU ? conn->txsz : ZT_MAX_MTU; if((r = picotap->picostack->__pico_socket_write(conn->picosock, &conn->txbuf, max_write_len)) < 0) { - DEBUG_ERROR("unable to write to pico_socket(%p), r=%d", (void*)&(conn->picosock), r); + DEBUG_ERROR("unable to write to pico_socket(%p), r=%d", (conn->picosock), r); return; } + // TODO: Errors + /* if(pico_err == PICO_ERR_EINVAL) DEBUG_ERROR("PICO_ERR_EINVAL - invalid argument"); @@ -436,14 +524,23 @@ namespace ZeroTier { if(pico_err == PICO_ERR_EAGAIN) DEBUG_ERROR("PICO_ERR_EAGAIN - resource temporarily unavailable"); */ + // adjust buffer int sz = (conn->txsz)-r; if(sz) memmove(&conn->txbuf, (conn->txbuf+r), sz); conn->txsz -= r; - int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ; - DEBUG_TRANS("[TCP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %d bytes", - (float)conn->txsz / (float)max, (float)conn->rxsz / max, (void*)&conn->sock, r); + + if(conn->type == SOCK_STREAM) { + max = DEFAULT_TCP_TX_BUF_SZ; + DEBUG_TRANS("[TCP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes", + (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r); + } + if(conn->type == SOCK_DGRAM) { + max = DEFAULT_UDP_TX_BUF_SZ; + DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes", + (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r); + } } // Instructs the stack to connect to a remote host @@ -505,7 +602,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, Utils::ntoh(addr->sin_port)); + DEBUG_ATTN("addr=%s:%d, physock=%p, picosock=%p", ipv4_str, Utils::ntoh(addr->sin_port), sock, (conn->picosock)); ret = picotap->picostack->__pico_socket_bind(conn->picosock, &zaddr, (uint16_t*)&(addr->sin_port)); #elif defined(SDK_IPV6) struct pico_ip6 zaddr; @@ -513,7 +610,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, Utils::ntoh(addr->sin_port)); + DEBUG_ATTN("addr=%s:%d, physock=%p, picosock=%p", ipv6_str, Utils::ntoh(addr->sin_port), sock, (conn->picosock)); ret = picotap->picostack->__pico_socket_bind(conn->picosock, &zaddr, (uint16_t*)&(addr->sin_port)); #endif if(ret < 0) { @@ -567,13 +664,23 @@ namespace ZeroTier { // ----------------------------------------- void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked) { - // DEBUG_INFO(); + /* + if(!lwip_invoked) { + picotap->_tcpconns_m.lock(); + //picotap->_rx_buf_m.lock(); + } + */ + + DEBUG_ATTN(); Connection *conn = picotap->getConnection(sock); if(conn && conn->rxsz) { float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ; - long n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, /* ZT_MAX_MTU */ conn->rxsz); + long n = -1; // extract address and payload size info + if(conn->type==SOCK_DGRAM) { + n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, ZT_MAX_MTU); + DEBUG_EXTRA("SOCK_DGRAM, physock=%p", sock); int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage); memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int)); struct sockaddr_storage addr; @@ -583,29 +690,26 @@ namespace ZeroTier { memcpy(conn->rxbuf, conn->rxbuf+ZT_MAX_MTU, conn->rxsz - ZT_MAX_MTU); conn->rxsz -= ZT_MAX_MTU; } + if(conn->type==SOCK_STREAM) { - //int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage); - //memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int)); - //struct sockaddr_storage addr; - //memcpy(&addr, conn->rxbuf, addr_sz_offset); - // adjust buffer + n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, conn->rxsz); + DEBUG_EXTRA("SOCK_STREAM, physock=%p", sock); if(conn->rxsz-n > 0) // If more remains on buffer memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n); conn->rxsz -= n; - DEBUG_INFO("rxsz=%d", conn->rxsz); } if(n) { - //DEBUG_INFO("wrote %d bytes to client application", n); - if(conn->type==SOCK_STREAM) { // Only acknolwedge receipt of TCP packets - DEBUG_TRANS("[TCP RX] <--- :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %ld bytes", + if(conn->type==SOCK_STREAM) { + DEBUG_TRANS("[TCP RX] <--- :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %ld bytes", (float)conn->txsz / max, (float)conn->rxsz / max, (void*)conn->sock, n); } picotap->_phy.setNotifyWritable(conn->sock, true); } - if(!n || !(conn->rxsz)) { + if(conn->rxsz == 0) { picotap->_phy.setNotifyWritable(conn->sock, false); } } + check_buffer_states(conn); } // Closes a pico_socket diff --git a/src/stack_drivers/picotcp/picotcp.hpp b/src/stack_drivers/picotcp/picotcp.hpp index 9c7aad1..6f74518 100644 --- a/src/stack_drivers/picotcp/picotcp.hpp +++ b/src/stack_drivers/picotcp/picotcp.hpp @@ -92,6 +92,7 @@ namespace ZeroTier { void pico_init_interface(NetconEthernetTap *tap, const InetAddress &ip); void pico_loop(NetconEthernetTap *tap); void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s); + void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s); void pico_cb_tcp_write(NetconEthernetTap *tap, struct pico_socket *s); void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s); diff --git a/src/tap.cpp b/src/tap.cpp index 9981d44..4f7e348 100644 --- a/src/tap.cpp +++ b/src/tap.cpp @@ -296,7 +296,7 @@ Connection *NetconEthernetTap::getConnection(struct pico_socket *sock) void NetconEthernetTap::closeConnection(PhySocket *sock) { - DEBUG_EXTRA("sock=%p", (void*)sock); + DEBUG_EXTRA("physock=%p", (void*)sock); Mutex::Lock _l(_close_m); // Here we assume _tcpconns_m is already locked by caller if(!sock) { @@ -328,7 +328,7 @@ void NetconEthernetTap::closeConnection(PhySocket *sock) } void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) { - DEBUG_EXTRA("sock=%p", (void*)&sock); + DEBUG_EXTRA("physock=%p", (void*)&sock); Mutex::Lock _l(_tcpconns_m); //closeConnection(sock); } @@ -343,12 +343,10 @@ void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) { // ----------------------------------------- void NetconEthernetTap::handleRead(PhySocket *sock,void **uptr,bool lwip_invoked) { - // DEBUG_EXTRA("handleRead(sock=%p): lwip_invoked = %d\n", (void*)&sock, lwip_invoked); - // picoTCP + // DEBUG_EXTRA("handleRead(physock=%p): lwip_invoked = %d\n", (void*)&sock, lwip_invoked); #if defined(SDK_PICOTCP) pico_handleRead(sock, uptr, lwip_invoked); #endif - // lwIP #if defined(SDK_LWIP) lwip_handleRead(this, sock, uptr, lwip_invoked); #endif @@ -361,7 +359,7 @@ void NetconEthernetTap::phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len) { - DEBUG_EXTRA("sock=%p, len=%d", (void*)&sock, (int)len); + DEBUG_EXTRA("physock=%p, len=%d", (void*)&sock, (int)len); uint64_t CANARY_num; pid_t pid, tid; ssize_t wlen = len; @@ -383,10 +381,10 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, if(detected_rpc) { unloadRPC(data, pid, tid, timestamp, CANARY, cmd, payload); memcpy(&CANARY_num, CANARY, CANARY_SZ); - // DEBUG_EXTRA(" RPC: sock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", (void*)&sock, pid, tid, timestamp, cmd); + // DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", (void*)&sock, pid, tid, timestamp, cmd); if(cmd == RPC_SOCKET) { - DEBUG_INFO("RPC_SOCKET, sock=%p", (void*)&sock); + DEBUG_INFO("RPC_SOCKET, physock=%p", (void*)&sock); // Create new lwip socket and associate it with this sock struct socket_st socket_rpc; memcpy(&socket_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct socket_st)); @@ -475,34 +473,34 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, rpcSock = sockdata.first; buf = (unsigned char*)sockdata.second; unloadRPC(buf, pid, tid, timestamp, CANARY, cmd, payload); - // DEBUG_EXTRA(" RPC: sock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", (void*)&sock, pid, tid, timestamp, cmd); + // DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", (void*)&sock, pid, tid, timestamp, cmd); switch(cmd) { case RPC_BIND: - DEBUG_INFO("RPC_BIND, sock=%p", (void*)&sock); + DEBUG_INFO("RPC_BIND, physock=%p", (void*)&sock); struct bind_st bind_rpc; memcpy(&bind_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct bind_st)); handleBind(sock, rpcSock, uptr, &bind_rpc); break; case RPC_LISTEN: - DEBUG_INFO("RPC_LISTEN, sock=%p", (void*)&sock); + DEBUG_INFO("RPC_LISTEN, physock=%p", (void*)&sock); struct listen_st listen_rpc; memcpy(&listen_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct listen_st)); handleListen(sock, rpcSock, uptr, &listen_rpc); break; case RPC_GETSOCKNAME: - DEBUG_INFO("RPC_GETSOCKNAME, sock=%p", (void*)&sock); + DEBUG_INFO("RPC_GETSOCKNAME, physock=%p", (void*)&sock); struct getsockname_st getsockname_rpc; memcpy(&getsockname_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st)); handleGetsockname(sock, rpcSock, uptr, &getsockname_rpc); break; case RPC_GETPEERNAME: - DEBUG_INFO("RPC_GETPEERNAME, sock=%p", (void*)&sock); + DEBUG_INFO("RPC_GETPEERNAME, physock=%p", (void*)&sock); struct getsockname_st getpeername_rpc; memcpy(&getpeername_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st)); handleGetpeername(sock, rpcSock, uptr, &getpeername_rpc); break; case RPC_CONNECT: - DEBUG_INFO("RPC_CONNECT, sock=%p", (void*)&sock); + DEBUG_INFO("RPC_CONNECT, physock=%p", (void*)&sock); struct connect_st connect_rpc; memcpy(&connect_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct connect_st)); handleConnect(sock, rpcSock, conn, &connect_rpc); @@ -552,12 +550,10 @@ void NetconEthernetTap::handleGetpeername(PhySocket *sock, PhySocket *rpcSock, v Connection * NetconEthernetTap::handleSocket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc) { - DEBUG_ATTN("sock=%p, sock_type=%d", (void*)&sock, socket_rpc->socket_type); - // picoTCP + DEBUG_ATTN("physock=%p, sock_type=%d", sock, socket_rpc->socket_type); #if defined(SDK_PICOTCP) return pico_handleSocket(sock, uptr, socket_rpc); #endif - // lwIP #if defined(SDK_LWIP) return lwip_handleSocket(this, sock, uptr, socket_rpc); #endif @@ -576,13 +572,11 @@ int NetconEthernetTap::handleConnectProxy(PhySocket *sock, struct sockaddr_in *r // Connect a stack's PCB/socket/Connection object to a remote host void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc) { - DEBUG_ATTN("sock=%p", (void*)&sock); + DEBUG_ATTN("physock=%p", (void*)&sock); Mutex::Lock _l(_tcpconns_m); - // picoTCP #if defined(SDK_PICOTCP) pico_handleConnect(sock, rpcSock, conn, connect_rpc); #endif - // lwIP #if defined(SDK_LWIP) lwip_handleConnect(this, sock, rpcSock, conn, connect_rpc); #endif @@ -597,11 +591,9 @@ void NetconEthernetTap::handleBind(PhySocket *sock, PhySocket *rpcSock, void **u sendReturnValue(_phy.getDescriptor(rpcSock), -1, ENOMEM); return; } - // picoTCP #if defined(SDK_PICOTCP) pico_handleBind(sock,rpcSock,uptr,bind_rpc); #endif - // lwIP #if defined(SDK_LWIP) lwip_handleBind(this, sock, rpcSock, uptr, bind_rpc); #endif @@ -610,11 +602,9 @@ void NetconEthernetTap::handleBind(PhySocket *sock, PhySocket *rpcSock, void **u void NetconEthernetTap::handleListen(PhySocket *sock, PhySocket *rpcSock, void **uptr, struct listen_st *listen_rpc) { Mutex::Lock _l(_tcpconns_m); - // picoTCP #if defined(SDK_PICOTCP) pico_handleListen(sock, rpcSock, uptr, listen_rpc); #endif - // lwIP #if defined(SDK_LWIP) lwip_handleListen(this, sock, rpcSock, uptr, listen_rpc); #endif @@ -623,11 +613,9 @@ void NetconEthernetTap::handleListen(PhySocket *sock, PhySocket *rpcSock, void * // Write to the network stack (and thus out onto the network) void NetconEthernetTap::handleWrite(Connection *conn) { - // picoTCP #if defined(SDK_PICOTCP) pico_handleWrite(conn); #endif - // lwIP #if defined(SDK_LWIP) lwip_handleWrite(this, conn); #endif diff --git a/tests/api_test/tcpclient4.c b/tests/api_test/tcpclient4.c index d105d89..cf4b345 100644 --- a/tests/api_test/tcpclient4.c +++ b/tests/api_test/tcpclient4.c @@ -41,7 +41,6 @@ int main(int argc , char *argv[]) while(1) { - sleep(1); // TX if(send(sock, msg, strlen(msg), 0) < 0) { printf("send failed"); diff --git a/tests/api_test/udpclient4.c b/tests/api_test/udpclient4.c index c8cc4c1..663e69c 100755 --- a/tests/api_test/udpclient4.c +++ b/tests/api_test/udpclient4.c @@ -23,7 +23,7 @@ void error(char *msg) { } int main(int argc, char **argv) { - int sockfd, portno, n; + int sock, portno, n; int serverlen; struct sockaddr_in serveraddr; struct hostent *server; @@ -39,8 +39,8 @@ int main(int argc, char **argv) { portno = atoi(argv[2]); /* socket: create the socket */ - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) error("ERROR opening socket"); /* gethostbyname: get the server's DNS entry */ @@ -59,31 +59,27 @@ int main(int argc, char **argv) { /* get a message from the user */ char *msg = "A message to the server!\0"; - fcntl(sockfd, F_SETFL, O_NONBLOCK); + fcntl(sock, F_SETFL, O_NONBLOCK); long count = 0; while(1) { count++; - printf("\nTX(%lu)...\n", count); - usleep(10000); + printf("\n\n\nTX(%lu)...\n", count); + sleep(1); + //usleep(10000); //bzero(buf, BUFSIZE); //printf("\nPlease enter msg: "); //fgets(buf, BUFSIZE, stdin); /* send the message to the server */ serverlen = sizeof(serveraddr); - printf("A\n"); - n = sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&serveraddr, serverlen); - printf("B\n"); + n = sendto(sock, msg, strlen(msg), 0, (struct sockaddr *)&serveraddr, serverlen); //if (n < 0) // error("ERROR in sendto"); /* print the server's reply */ - printf("C\n"); memset(buf, 0, sizeof(buf)); - printf("D\n"); - n = recvfrom(sockfd, buf, BUFSIZE, 0, (struct sockaddr *)&serveraddr, (socklen_t *)&serverlen); - printf("E\n"); + n = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *)&serveraddr, (socklen_t *)&serverlen); //if (n < 0) // printf("ERROR in recvfrom: %d", n); printf("Echo from server: %s", buf); diff --git a/tests/api_test/udpclient6.c b/tests/api_test/udpclient6.c index f5b0fea..36607fa 100755 --- a/tests/api_test/udpclient6.c +++ b/tests/api_test/udpclient6.c @@ -12,63 +12,32 @@ int main(int argc, char* argv[]) { - int sock; int status; struct addrinfo sainfo, *psinfo; - struct sockaddr_in6 sin6; - socklen_t sin6len; + struct hostent *server; char buffer[MAXBUF]; - sin6len = sizeof(struct sockaddr_in6); + int sock, portno, n; + struct sockaddr_in6 serv_addr; if(argc < 2) printf("Specify a port number\n"), exit(1); sock = socket(PF_INET6, SOCK_DGRAM,0); - memset(&sin6, 0, sizeof(struct sockaddr_in6)); - sin6.sin6_port = htons(0); - sin6.sin6_family = AF_INET6; - sin6.sin6_addr = in6addr_any; + portno = atoi(argv[2]); + server = gethostbyname2(argv[1],AF_INET6); + memset((char *) &serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin6_flowinfo = 0; + serv_addr.sin6_family = AF_INET6; + memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length); + serv_addr.sin6_port = htons(portno); - status = bind(sock, (struct sockaddr *)&sin6, sin6len); - - if(-1 == status) - perror("bind"), exit(1); - - memset(&sainfo, 0, sizeof(struct addrinfo)); - memset(&sin6, 0, sin6len); - - sainfo.ai_flags = 0; - sainfo.ai_family = PF_INET6; - sainfo.ai_socktype = SOCK_DGRAM; - sainfo.ai_protocol = IPPROTO_UDP; - status = getaddrinfo("ip6-localhost", argv[1], &sainfo, &psinfo); - - switch (status) - { - case EAI_FAMILY: printf("family\n"); - break; - case EAI_SOCKTYPE: printf("stype\n"); - break; - case EAI_BADFLAGS: printf("flag\n"); - break; - case EAI_NONAME: printf("noname\n"); - break; - case EAI_SERVICE: printf("service\n"); - break; - } sprintf(buffer,"Ciao"); - status = sendto(sock, buffer, strlen(buffer), 0, - (struct sockaddr *)psinfo->ai_addr, sin6len); + status = sendto(sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)); printf("buffer : %s \t%d\n", buffer, status); - // free memory - freeaddrinfo(psinfo); - psinfo = NULL; - - shutdown(sock, 2); close(sock); return 0; } \ No newline at end of file diff --git a/tests/api_test/udpserver4.c b/tests/api_test/udpserver4.c index c6bd4b3..2280435 100755 --- a/tests/api_test/udpserver4.c +++ b/tests/api_test/udpserver4.c @@ -11,7 +11,7 @@ #define MAXBUF 1024*1024 -void echo( int sd ) { +void echo(int sock) { char bufin[MAXBUF]; struct sockaddr_in remote; int n; @@ -19,10 +19,11 @@ void echo( int sd ) { long count = 0; while (1) { - usleep(50); + sleep(1); + //usleep(50); count++; // read a datagram from the socket (put result in bufin) - n=recvfrom(sd,bufin,MAXBUF,0,(struct sockaddr *)&remote,&len); + n=recvfrom(sock,bufin,MAXBUF,0,(struct sockaddr *)&remote,&len); // print out the address of the sender printf("DGRAM from %s:%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); @@ -31,7 +32,8 @@ void echo( int sd ) { } else { printf("GOT %d BYTES (count = %ld)\n", n, count); // Got something, just send it back - // sendto(sd,bufin,n,0,(struct sockaddr *)&remote,len); + // sendto(sock,bufin,n,0,(struct sockaddr *)&remote,len); + printf("RX = %s\n", bufin); } } } @@ -42,13 +44,13 @@ int main(int argc, char *argv[]) { printf("usage: udp_server \n"); return 0; } - int ld, port = atoi(argv[1]); + int sock, port = atoi(argv[1]); socklen_t len; struct sockaddr_in skaddr; struct sockaddr_in skaddr2; // Create socket - if ((ld = socket( PF_INET, SOCK_DGRAM, 0)) < 0) { + if ((sock = socket( PF_INET, SOCK_DGRAM, 0)) < 0) { printf("error creating socket\n"); return 0; } @@ -57,17 +59,18 @@ int main(int argc, char *argv[]) { skaddr.sin_addr.s_addr = htonl(INADDR_ANY); skaddr.sin_port = htons(port); // Bind to address - if (bind(ld, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) { + if (bind(sock, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) { printf("error binding\n"); return 0; } // find out what port we were assigned len = sizeof( skaddr2 ); - if (getsockname(ld, (struct sockaddr *) &skaddr2, &len)<0) { - printf("error getsockname\n"); - return 0; - } + //if (getsockname(sock, (struct sockaddr *) &skaddr2, &len)<0) { + // printf("error getsockname\n"); + // return 0; + //} // Display address:port to verify it was sent over RPC correctly + /* port = ntohs(skaddr2.sin_port); int ip = skaddr2.sin_addr.s_addr; unsigned char d[4]; @@ -76,8 +79,8 @@ int main(int argc, char *argv[]) { d[2] = (ip >> 16) & 0xFF; d[3] = (ip >> 24) & 0xFF; printf("bound to address: %d.%d.%d.%d : %d\n", d[0],d[1],d[2],d[3], port); - + */ // RX - echo(ld); + echo(sock); return(0); } diff --git a/tests/api_test/udpserver6.c b/tests/api_test/udpserver6.c index d30320f..4ed977b 100755 --- a/tests/api_test/udpserver6.c +++ b/tests/api_test/udpserver6.c @@ -9,37 +9,34 @@ #define MAXBUF 65536 -int main() +int main(int argc, char *argv[]) { int sock; - int status; + int n; struct sockaddr_in6 sin6; socklen_t sin6len; char buffer[MAXBUF]; sock = socket(PF_INET6, SOCK_DGRAM,0); - sin6len = sizeof(struct sockaddr_in6); - memset(&sin6, 0, sin6len); - /* just use the first address returned in the structure */ - - sin6.sin6_port = htons(0); + sin6.sin6_port = htons(atoi(argv[1])); sin6.sin6_family = AF_INET6; sin6.sin6_addr = in6addr_any; - status = bind(sock, (struct sockaddr *)&sin6, sin6len); - if(-1 == status) + n = bind(sock, (struct sockaddr *)&sin6, sin6len); + if(-1 == n) perror("bind"), exit(1); - status = getsockname(sock, (struct sockaddr *)&sin6, &sin6len); + //n = getsockname(sock, (struct sockaddr *)&sin6, &sin6len); + //printf("%d\n", ntohs(sin6.sin6_port)); - printf("%d\n", ntohs(sin6.sin6_port)); - - status = recvfrom(sock, buffer, MAXBUF, 0, - (struct sockaddr *)&sin6, &sin6len); - printf("buffer : %s\n", buffer); + while (1) { + sleep(1); + n = recvfrom(sock, buffer, MAXBUF, 0, (struct sockaddr *)&sin6, &sin6len); + printf("n = %d, buffer : %s\n", n, buffer); + } shutdown(sock, 2); close(sock); diff --git a/zerotierone/service/OneService.cpp b/zerotierone/service/OneService.cpp index 0ee69cd..e945395 100644 --- a/zerotierone/service/OneService.cpp +++ b/zerotierone/service/OneService.cpp @@ -907,8 +907,8 @@ public: { Mutex::Lock _l(_nets_m); for(std::map::iterator n(_nets.begin());n!=_nets.end();++n) { - if (n->second.tap) - syncManagedStuff(n->second,false,true); + //if (n->second.tap) + // syncManagedStuff(n->second,false,true); } } } @@ -1093,8 +1093,8 @@ public: fclose(out); } - if (n->second.tap) - syncManagedStuff(n->second,true,true); + //if (n->second.tap) + // syncManagedStuff(n->second,true,true); return true; } @@ -1216,7 +1216,7 @@ public: for(std::list::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();++mr) { if ( (mr->target() == *target) && ( ((via->ss_family == target->ss_family)&&(mr->via() == *via)) || (tapdev == mr->device()) ) ) { haveRoute = true; - mr->sync(); + //mr->sync(); break; } } @@ -1515,7 +1515,7 @@ public: case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: memcpy(&(n.config),nwc,sizeof(ZT_VirtualNetworkConfig)); if (n.tap) { // sanity check - syncManagedStuff(n,true,true); + //syncManagedStuff(n,true,true); } else { _nets.erase(nwid); return -999; // tap init failed