improved performance, minor bugfix

This commit is contained in:
Joseph Henry
2017-03-15 13:01:22 -07:00
parent 695b8ecc55
commit ba923e96ed
9 changed files with 134 additions and 137 deletions

View File

@@ -2,7 +2,7 @@
BUILD=build BUILD=build
INT=integrations INT=integrations
ZT1=zerotierone ZT1=zto
OSTYPE=$(shell uname -s) OSTYPE=$(shell uname -s)

View File

@@ -1,36 +1,36 @@
OBJS=\ OBJS=\
zerotierone/controller/EmbeddedNetworkController.o \ zto/controller/EmbeddedNetworkController.o \
zerotierone/controller/JSONDB.o \ zto/controller/JSONDB.o \
zerotierone/node/C25519.o \ zto/node/C25519.o \
zerotierone/node/Capability.o \ zto/node/Capability.o \
zerotierone/node/CertificateOfMembership.o \ zto/node/CertificateOfMembership.o \
zerotierone/node/CertificateOfOwnership.o \ zto/node/CertificateOfOwnership.o \
zerotierone/node/Cluster.o \ zto/node/Cluster.o \
zerotierone/node/Identity.o \ zto/node/Identity.o \
zerotierone/node/IncomingPacket.o \ zto/node/IncomingPacket.o \
zerotierone/node/InetAddress.o \ zto/node/InetAddress.o \
zerotierone/node/Membership.o \ zto/node/Membership.o \
zerotierone/node/Multicaster.o \ zto/node/Multicaster.o \
zerotierone/node/Network.o \ zto/node/Network.o \
zerotierone/node/NetworkConfig.o \ zto/node/NetworkConfig.o \
zerotierone/node/Node.o \ zto/node/Node.o \
zerotierone/node/OutboundMulticast.o \ zto/node/OutboundMulticast.o \
zerotierone/node/Packet.o \ zto/node/Packet.o \
zerotierone/node/Path.o \ zto/node/Path.o \
zerotierone/node/Peer.o \ zto/node/Peer.o \
zerotierone/node/Poly1305.o \ zto/node/Poly1305.o \
zerotierone/node/Revocation.o \ zto/node/Revocation.o \
zerotierone/node/Salsa20.o \ zto/node/Salsa20.o \
zerotierone/node/SelfAwareness.o \ zto/node/SelfAwareness.o \
zerotierone/node/SHA512.o \ zto/node/SHA512.o \
zerotierone/node/Switch.o \ zto/node/Switch.o \
zerotierone/node/Tag.o \ zto/node/Tag.o \
zerotierone/node/Topology.o \ zto/node/Topology.o \
zerotierone/node/Utils.o \ zto/node/Utils.o \
zerotierone/osdep/ManagedRoute.o \ zto/osdep/ManagedRoute.o \
zerotierone/osdep/Http.o \ zto/osdep/Http.o \
zerotierone/osdep/OSUtils.o \ zto/osdep/OSUtils.o \
zerotierone/service/ClusterGeoIpService.o \ zto/service/ClusterGeoIpService.o \
zerotierone/service/ControlPlane.o \ zto/service/SoftwareUpdater.o \
zerotierone/service/SoftwareUpdater.o \ zto/ext/http-parser/http_parser.o
zerotierone/ext/http-parser/http_parser.o

View File

@@ -26,11 +26,14 @@
* LLC. Start here: http://www.zerotier.com/ * LLC. Start here: http://www.zerotier.com/
*/ */
#include <pthread.h>
#include <sys/syscall.h>
#include <sys/types.h>
#ifndef _SDK_DEBUG_H_ #ifndef _SDK_DEBUG_H_
#define _SDK_DEBUG_H_ #define _SDK_DEBUG_H_
#define DEBUG_LEVEL 5 // Set this to adjust what you'd like to see in the debug traces #define DEBUG_LEVEL 1 // Set this to adjust what you'd like to see in the debug traces
#define MSG_ERROR 1 // Errors #define MSG_ERROR 1 // Errors
#define MSG_TRANSFER 2 // RX/TX specific statements #define MSG_TRANSFER 2 // RX/TX specific statements
@@ -80,6 +83,12 @@
extern "C" { extern "C" {
#endif #endif
#ifdef __linux__
#define THREAD_ID (long)getpid()
#elif __APPLE__
#define THREAD_ID (long)syscall(SYS_thread_selfid)
#endif
#if defined(__ANDROID__) #if defined(__ANDROID__)
#include <jni.h> #include <jni.h>
#include <android/log.h> #include <android/log.h>
@@ -88,7 +97,7 @@ extern "C" {
//#if defined(SDK_DEBUG) //#if defined(SDK_DEBUG)
#if DEBUG_LEVEL >= MSG_ERROR #if DEBUG_LEVEL >= MSG_ERROR
#define DEBUG_ERROR(fmt, args...) fprintf(stderr, RED "ZT_ERROR: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR(fmt, args...) fprintf(stderr, RED "ZT_ERROR[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#else #else
#define DEBUG_ERROR(fmt, args...) #define DEBUG_ERROR(fmt, args...)
#endif #endif
@@ -100,10 +109,10 @@ extern "C" {
#define DEBUG_ATTN(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)) #define DEBUG_ATTN(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#define DEBUG_STACK(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_STACK: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)) #define DEBUG_STACK(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_STACK: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else #else
#define DEBUG_INFO(fmt, args...) fprintf(stderr, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args) #define DEBUG_INFO(fmt, args...) fprintf(stderr, "ZT_INFO [%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_ATTN(fmt, args...) fprintf(stderr, CYN "ZT_INFO : %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ATTN(fmt, args...) fprintf(stderr, CYN "ZT_ATTN [%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_STACK(fmt, args...) fprintf(stderr, YEL "ZT_STACK: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args) #define DEBUG_STACK(fmt, args...) fprintf(stderr, YEL "ZT_STACK[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_BLANK(fmt, args...) fprintf(stderr, "ZT_INFO : %14s:%4d:" fmt "\n", __FILENAME__, __LINE__, ##args) #define DEBUG_BLANK(fmt, args...) fprintf(stderr, "ZT_INFO [%ld] : %14s:%4d:" fmt "\n", THREAD_ID, __FILENAME__, __LINE__, ##args)
#endif #endif
#else #else
#define DEBUG_INFO(fmt, args...) #define DEBUG_INFO(fmt, args...)
@@ -116,7 +125,7 @@ extern "C" {
#if defined(__ANDROID__) #if defined(__ANDROID__)
#define DEBUG_TRANS(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_TRANS : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)) #define DEBUG_TRANS(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_TRANS : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else #else
#define DEBUG_TRANS(fmt, args...) fprintf(stderr, GRN "ZT_TRANS: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args) #define DEBUG_TRANS(fmt, args...) fprintf(stderr, GRN "ZT_TRANS[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#endif #endif
#else #else
#define DEBUG_TRANS(fmt, args...) #define DEBUG_TRANS(fmt, args...)
@@ -126,7 +135,7 @@ extern "C" {
#if defined(__ANDROID__) #if defined(__ANDROID__)
#define DEBUG_EXTRA(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_EXTRA : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)) #define DEBUG_EXTRA(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_EXTRA : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else #else
#define DEBUG_EXTRA(fmt, args...) fprintf(stderr, "ZT_EXTRA: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args) #define DEBUG_EXTRA(fmt, args...) fprintf(stderr, "ZT_EXTRA[%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#endif #endif
#else #else
#define DEBUG_EXTRA(fmt, args...) #define DEBUG_EXTRA(fmt, args...)
@@ -136,7 +145,7 @@ extern "C" {
#if defined(__ANDROID__) #if defined(__ANDROID__)
#define DEBUG_FLOW(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_FLOW : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)) #define DEBUG_FLOW(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_FLOW : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else #else
#define DEBUG_FLOW(fmt, args...) fprintf(stderr, "ZT_FLOW : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args) #define DEBUG_FLOW(fmt, args...) fprintf(stderr, "ZT_FLOW [%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#endif #endif
#else #else
#define DEBUG_FLOW(fmt, args...) #define DEBUG_FLOW(fmt, args...)

View File

@@ -25,22 +25,15 @@
* LLC. Start here: http://www.zerotier.com/ * LLC. Start here: http://www.zerotier.com/
*/ */
#define SDK_MTU ZT_MAX_MTU // 2800, usually #define SDK_MTU 1200//ZT_MAX_MTU // 2800, usually
#define UNIX_SOCK_BUF_SIZE 1024*1024 #define UNIX_SOCK_BUF_SIZE 1024*1024
#define ZT_PHY_POLL_INTERVAL 50 // in ms
// --- lwIP // picoTCP
#define APPLICATION_POLL_FREQ 2
#define ZT_LWIP_TCP_TIMER_INTERVAL 50
#define STATUS_TMR_INTERVAL 500 // How often we check connection statuses (in ms)
// --- picoTCP
#define MAX_PICO_FRAME_RX_BUF_SZ ZT_MAX_MTU * 128 #define MAX_PICO_FRAME_RX_BUF_SZ ZT_MAX_MTU * 128
// --- jip // General
// --- General
// TCP Buffer sizes // TCP Buffer sizes
#define DEFAULT_TCP_TX_BUF_SZ 1024 * 1024 #define DEFAULT_TCP_TX_BUF_SZ 1024 * 1024
#define DEFAULT_TCP_RX_BUF_SZ 1024 * 1024 #define DEFAULT_TCP_RX_BUF_SZ 1024 * 1024
@@ -53,4 +46,9 @@
// UDP Buffer sizes (should be about the size of your MTU) // UDP Buffer sizes (should be about the size of your MTU)
#define DEFAULT_UDP_TX_BUF_SZ ZT_MAX_MTU #define DEFAULT_UDP_TX_BUF_SZ ZT_MAX_MTU
#define DEFAULT_UDP_RX_BUF_SZ ZT_MAX_MTU * 10 #define DEFAULT_UDP_RX_BUF_SZ ZT_MAX_MTU * 10
// lwIP
#define APPLICATION_POLL_FREQ 2
#define ZT_LWIP_TCP_TIMER_INTERVAL 50
#define STATUS_TMR_INTERVAL 500 // How often we check connection statuses (in ms)

View File

@@ -146,8 +146,10 @@ void zts_join_network_soft(const char * filepath, const char * nwid) {
if(!ZeroTier::OSUtils::mkdir(net_dir)) { if(!ZeroTier::OSUtils::mkdir(net_dir)) {
DEBUG_ERROR("unable to create: %s", net_dir.c_str()); DEBUG_ERROR("unable to create: %s", net_dir.c_str());
} }
if(!ZeroTier::OSUtils::writeFile(confFile.c_str(), "")) { if(!ZeroTier::OSUtils::fileExists(confFile.c_str(),false)) {
DEBUG_ERROR("unable to write network conf file: %s", confFile.c_str()); if(!ZeroTier::OSUtils::writeFile(confFile.c_str(), "")) {
DEBUG_ERROR("unable to write network conf file: %s", confFile.c_str());
}
} }
} }
// //

View File

@@ -308,23 +308,27 @@ int (*realclose)(CLOSE_SIG);
ssize_t zts_recvfrom(RECVFROM_SIG) ssize_t zts_recvfrom(RECVFROM_SIG)
#endif #endif
{ {
int payload_offset, tmpsz=0, pnum=0; // payload size int read_chunk_sz = 0, payload_offset, tmpsz=0, pnum=0; // payload size
char tmpbuf[SDK_MTU]; char tmpbuf[SDK_MTU];
memset(tmpbuf, 0, SDK_MTU); memset(tmpbuf, 0, SDK_MTU);
// Attempt to read SDK_MTU sized chunk // Attempt to read SDK_MTU sized chunk
int total_read = 0, n=0; int total_read = 0, n=0;
//fcntl(fd, F_SETFL, O_NONBLOCK);
// Read the entire SDK_MTU-sized chunk from the service socket
while(total_read < SDK_MTU) { while(total_read < SDK_MTU) {
//DEBUG_ERROR(" READING...");
n = read(fd, tmpbuf+total_read, SDK_MTU); n = read(fd, tmpbuf+total_read, SDK_MTU);
if(n>0) if(n>0)
total_read += n; total_read += n;
//DEBUG_ERROR(" R... (read=%d, total_read=%d, errno=%d)", n, total_read, errno); else
if(n<0) return n;
return -1;
} }
if(n > 0) { if(n > 0) {
// No matter how much we read from the service, only copy 'read_chunk_sz'
// into the app's buffer
read_chunk_sz = len < SDK_MTU ? len : SDK_MTU;
// TODO: case for address size mismatch? // TODO: case for address size mismatch?
memcpy(addr, tmpbuf, *addrlen); memcpy(addr, tmpbuf, *addrlen);
memcpy(&tmpsz, tmpbuf + sizeof(struct sockaddr_storage), sizeof(tmpsz)); memcpy(&tmpsz, tmpbuf + sizeof(struct sockaddr_storage), sizeof(tmpsz));
@@ -334,13 +338,12 @@ int (*realclose)(CLOSE_SIG);
return -1; return -1;
} }
payload_offset = sizeof(int) + sizeof(struct sockaddr_storage); payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
memcpy(buf, tmpbuf + payload_offset, tmpsz); memcpy(buf, tmpbuf + payload_offset, read_chunk_sz);
} }
else { else {
perror("read:\n"); return -1;
} }
//DEBUG_ERROR("recvfrom=%d", tmpsz); return read_chunk_sz;
return tmpsz;
} }
//#endif //#endif

View File

@@ -39,20 +39,6 @@
#include "pico_eth.h" #include "pico_eth.h"
namespace ZeroTier { 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 // Reference to the tap interface
// This is needed due to the fact that there's a lot going on in the tap interface // This is needed due to the fact that there's a lot going on in the tap interface
@@ -120,19 +106,19 @@ namespace ZeroTier {
} }
} }
// I/O thread loop // Main stack loop
void pico_loop(NetconEthernetTap *tap) void pico_loop(NetconEthernetTap *tap)
{ {
while(tap->_run) while(tap->_run)
{ {
tap->_phy.poll(50); // in ms tap->_phy.poll(ZT_PHY_POLL_INTERVAL); // in ms
//usleep(50);
tap->picostack->__pico_stack_tick(); tap->picostack->__pico_stack_tick();
} }
} }
// RX packets from network onto internal buffer // RX packets from [ZT->STACK] onto RXBUF
// Also notifies the tap service that data can be read // Also notify the tap service that data can be read:
// [RXBUF -> (ZTSOCK->APP)]
// ----------------------------------------- // -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP | // | TAP <-> MEM BUFFER <-> STACK <-> APP |
// | | // | |
@@ -142,8 +128,7 @@ namespace ZeroTier {
// After this step, buffer will be emptied periodically by pico_handleRead() // After this step, buffer will be emptied periodically by pico_handleRead()
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s) void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
{ {
// TODO: Verify DEBUG_INFO();
// DEBUG_INFO("picosock=%p", s);
Connection *conn = tap->getConnection(s); Connection *conn = tap->getConnection(s);
if(conn) { if(conn) {
int r; int r;
@@ -156,11 +141,9 @@ namespace ZeroTier {
do { do {
int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz; int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz;
if(avail) { if(avail) {
// r = tap->picostack->__pico_socket_read(s, conn->rxbuf + (conn->rxsz), SDK_MTU);
r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), SDK_MTU, (void *)&peer.ip4.addr, &port); r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), SDK_MTU, (void *)&peer.ip4.addr, &port);
// DEBUG_ATTN("received packet (%d byte) from %08X:%u", r, long_be2(peer.ip4.addr), short_be(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); tap->_phy.setNotifyWritable(conn->sock, true);
//DEBUG_EXTRA("read=%d", r);
if (r > 0) if (r > 0)
conn->rxsz += r; conn->rxsz += r;
} }
@@ -173,7 +156,7 @@ namespace ZeroTier {
DEBUG_ERROR("invalid connection"); DEBUG_ERROR("invalid connection");
} }
// RX packets from network onto internal buffer // RX packets from the stack onto internal buffer
// Also notifies the tap service that data can be read // Also notifies the tap service that data can be read
// ----------------------------------------- // -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP | // | TAP <-> MEM BUFFER <-> STACK <-> APP |
@@ -188,6 +171,8 @@ namespace ZeroTier {
// //
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s) void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
{ {
DEBUG_INFO();
Connection *conn = tap->getConnection(s); Connection *conn = tap->getConnection(s);
if(conn) { if(conn) {
@@ -212,11 +197,11 @@ namespace ZeroTier {
// addr_in6.sin6_addr.s6_addr; // addr_in6.sin6_addr.s6_addr;
// addr_in6.sin6_port = Utils::ntoh(s->remote_port); // 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)); // DEBUG_ATTN("remote_port=%d, local_port=%d", s->remote_port, Utils::ntoh(s->local_port));
picotap->_rx_buf_m.lock(); picotap->_rx_buf_m.lock();
if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment"); //DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment");
memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU); memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU);
addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - SDK_MTU); // TODO: addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - SDK_MTU); // TODO:
sz_pos = addr_pos + sizeof(struct sockaddr_storage); sz_pos = addr_pos + sizeof(struct sockaddr_storage);
@@ -241,9 +226,7 @@ namespace ZeroTier {
} }
memcpy(payload_pos, tmpbuf, r); // write payload to app's socket memcpy(payload_pos, tmpbuf, r); // write payload to app's socket
//DEBUG_EXTRA(" Copied onto rxbuf (%d) from stack socket", r); //DEBUG_EXTRA(" Copied onto rxbuf (%d) from stack socket", r);
picotap->_rx_buf_m.unlock(); picotap->_rx_buf_m.unlock();
return; return;
} }
} }
@@ -279,6 +262,7 @@ namespace ZeroTier {
// Main callback for TCP connections // Main callback for TCP connections
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s) void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
{ {
DEBUG_INFO();
int err; int err;
Mutex::Lock _l(picotap->_tcpconns_m); Mutex::Lock _l(picotap->_tcpconns_m);
Connection *conn = picotap->getConnection(s); Connection *conn = picotap->getConnection(s);
@@ -392,14 +376,10 @@ namespace ZeroTier {
// It will then periodically be transfered into the network stack via pico_eth_poll() // It will then periodically be transfered into the network stack via pico_eth_poll()
void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
{ {
//DEBUG_INFO("len=%d", len); DEBUG_INFO();
// Since picoTCP only allows the reception of frames from within the polling function, we // Since picoTCP only allows the reception of frames from within the polling function, we
// must enqueue each frame into a memory structure shared by both threads. This structure will // must enqueue each frame into a memory structure shared by both threads. This structure will
Mutex::Lock _l(tap->_pico_frame_rxbuf_m); Mutex::Lock _l(tap->_pico_frame_rxbuf_m);
//if(len != memcpy(pico_frame_rxbuf, data, len)) {
// DEBUG_ERROR("dropping packet (len = %d) - unable to copy contents of frame to RX frame buffer", len);
// return;
//}
// assemble new eth header // assemble new eth header
struct pico_eth_hdr ethhdr; struct pico_eth_hdr ethhdr;
@@ -425,8 +405,13 @@ namespace ZeroTier {
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), &ethhdr, sizeof(ethhdr)); // new eth header memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), &ethhdr, sizeof(ethhdr)); // new eth header
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
tap->pico_frame_rxbuf_tot += newlen; tap->pico_frame_rxbuf_tot += newlen;
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Moved FRAME(sz=%d) into FBUF(sz=%d), data_len=%d, ethhdr.proto=%d", newlen, picotap->pico_frame_rxbuf_tot, len, ethhdr.proto); DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Move FRAME(sz=%d) into FBUF(sz=%d), data_len=%d", newlen, picotap->pico_frame_rxbuf_tot, len);
/*
char graph[GRAPH_BUF_SZ];
gengraph(&graph, GRAPH_BUF_SZ, '|', 0.6);
DEBUG_FLOW(graph);
*/
//} //}
//else //else
//{ //{
@@ -445,7 +430,7 @@ namespace ZeroTier {
//} //}
} }
// Called periodically by the stack, this removes data from the locked memory buffer and feeds it into the stack. // Called periodically by the stack, this removes data from the locked memory buffer (FBUF) and feeds it into the stack.
// A maximum of 'loop_score' frames can be processed in each call // A maximum of 'loop_score' frames can be processed in each call
// ----------------------------------------- // -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP | // | TAP <-> MEM BUFFER <-> STACK <-> APP |
@@ -455,12 +440,13 @@ namespace ZeroTier {
// ----------------------------------------- // -----------------------------------------
int pico_eth_poll(struct pico_device *dev, int loop_score) int pico_eth_poll(struct pico_device *dev, int loop_score)
{ {
//DEBUG_ERROR();
// OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA // OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state; // NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m); Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
unsigned char frame[SDK_MTU]; unsigned char frame[SDK_MTU];
int len; int len;
while (picotap->pico_frame_rxbuf_tot > 0) { while (picotap->pico_frame_rxbuf_tot > 0 && loop_score > 0) {
DEBUG_INFO(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot); DEBUG_INFO(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot);
memset(frame, 0, sizeof(frame)); memset(frame, 0, sizeof(frame));
len = 0; len = 0;
@@ -476,7 +462,6 @@ namespace ZeroTier {
DEBUG_ERROR("Skipping frame of size (%d)",len); DEBUG_ERROR("Skipping frame of size (%d)",len);
exit(0); exit(0);
} }
loop_score--; loop_score--;
} }
return loop_score; return loop_score;
@@ -509,7 +494,7 @@ namespace ZeroTier {
*uptr = newConn; *uptr = newConn;
newConn->type = socket_rpc->socket_type; newConn->type = socket_rpc->socket_type;
newConn->sock = sock; newConn->sock = sock;
/*
int res = 0; int res = 0;
int sendbuff = UNIX_SOCK_BUF_SIZE; int sendbuff = UNIX_SOCK_BUF_SIZE;
socklen_t optlen = sizeof(sendbuff); socklen_t optlen = sizeof(sendbuff);
@@ -524,8 +509,8 @@ namespace ZeroTier {
// Get buffer size // Get buffer size
// optlen = sizeof(sendbuff); // optlen = sizeof(sendbuff);
// res = getsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen); // res = getsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
// DEBUG_ERROR("buflen=%d", sendbuff); // DEBUG_INFO("buflen=%d", sendbuff);
*/
newConn->local_addr = NULL; newConn->local_addr = NULL;
// newConn->peer_addr = NULL; // newConn->peer_addr = NULL;
newConn->picosock = psock; newConn->picosock = psock;
@@ -597,7 +582,6 @@ namespace ZeroTier {
//DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes", //DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
// (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r); // (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
} }
check_buffer_states(conn);
} }
// Instructs the stack to connect to a remote host // Instructs the stack to connect to a remote host
@@ -713,6 +697,7 @@ namespace ZeroTier {
} }
// Feeds data into the local app socket from the I/O buffer associated with the "connection" // Feeds data into the local app socket from the I/O buffer associated with the "connection"
// [ (APP<-ZTSOCK) <- RXBUF ]
// ----------------------------------------- // -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP | // | TAP <-> MEM BUFFER <-> STACK <-> APP |
// | | // | |
@@ -721,33 +706,28 @@ namespace ZeroTier {
// ----------------------------------------- // -----------------------------------------
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked) void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
{ {
DEBUG_ERROR(); DEBUG_INFO();
if(!lwip_invoked) { if(!lwip_invoked) {
// The stack thread writes to RXBUF as well
picotap->_tcpconns_m.lock(); picotap->_tcpconns_m.lock();
picotap->_rx_buf_m.lock(); picotap->_rx_buf_m.lock();
} }
int tot = 0, n = -1;
Connection *conn = picotap->getConnection(sock); Connection *conn = picotap->getConnection(sock);
if(conn && conn->rxsz) { if(conn && conn->rxsz) {
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ; float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ;
int n = -1;
if(conn->type==SOCK_DGRAM) { if(conn->type==SOCK_DGRAM) {
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] attempting write, RXBUF(%d)", conn->rxsz);
// DEBUG_ERROR("about to enter write loop, conn->sock=%p conn->rxsz=%d", conn->sock, conn->rxsz);
int pending = 0;
//ioctl(picotap->_phy.getDescriptor(conn->sock), SIOCOUTQ, &pending);
// Try to write SDK_MTU-sized chunk to app socket // Try to write SDK_MTU-sized chunk to app socket
int total_written = 0; while(tot < SDK_MTU) {
while(total_written < SDK_MTU) { n = picotap->_phy.streamSend(conn->sock, (conn->rxbuf)+tot, SDK_MTU);
//DEBUG_ERROR(" [ ZTSOCK <- RXBUF] WRITING.... (pending=%d)", pending); tot += n;
n = picotap->_phy.streamSend(conn->sock, (conn->rxbuf)+total_written, SDK_MTU); DEBUG_FLOW(" [ ZTSOCK <- RXBUF] wrote = %d, total = %d", n, tot);
total_written += n;
//DEBUG_ERROR(" [ ZTSOCK <- RXBUF] W... %d, written=%d, errno=%d", n, total_written, errno);
} }
//DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock); // DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage); int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int)); memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int));
struct sockaddr_storage addr; struct sockaddr_storage addr;
@@ -761,12 +741,10 @@ namespace ZeroTier {
////conn->rxsz=SDK_MTU; ////conn->rxsz=SDK_MTU;
} }
conn->rxsz -= SDK_MTU; conn->rxsz -= SDK_MTU;
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] conn->rxsz=%d", conn->rxsz);
} }
if(conn->type==SOCK_STREAM) { if(conn->type==SOCK_STREAM) {
n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, conn->rxsz); n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, conn->rxsz);
//DEBUG_EXTRA("SOCK_STREAM, conn=%p, physock=%p, n=%d", conn, sock, n);
if(conn->rxsz-n > 0) // If more remains on buffer if(conn->rxsz-n > 0) // If more remains on buffer
memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n); memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n);
conn->rxsz -= n; conn->rxsz -= n;
@@ -787,13 +765,12 @@ namespace ZeroTier {
picotap->_phy.setNotifyWritable(sock, false); picotap->_phy.setNotifyWritable(sock, false);
} }
} }
picotap->_phy.whack(); //picotap->_phy.whack();
check_buffer_states(conn);
if(!lwip_invoked) { if(!lwip_invoked) {
picotap->_tcpconns_m.unlock(); picotap->_tcpconns_m.unlock();
picotap->_rx_buf_m.unlock(); picotap->_rx_buf_m.unlock();
} }
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Emitted (%d) from RXBUF(%d) to socket", tot, conn->rxsz);
} }
// Closes a pico_socket // Closes a pico_socket

View File

@@ -16,6 +16,8 @@
#define MAXBUF 65536 #define MAXBUF 65536
#define TESTBUF 1024
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int status, sock, portno, n; int status, sock, portno, n;
@@ -45,16 +47,19 @@ int main(int argc, char* argv[])
memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length); memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
serv_addr.sin6_port = htons(portno); serv_addr.sin6_port = htons(portno);
sprintf(buffer,"Ciao"); sprintf(buffer,"Welcome to the machine");
//memset(buffer, 1, TESTBUF);
fcntl(sock, F_SETFL, O_NONBLOCK); fcntl(sock, F_SETFL, O_NONBLOCK);
while(1) while(1)
{ {
sleep(1); //usleep(50000);
status = zts_sendto(sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)); status = zts_sendto(sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
printf("Sent : %s \t%d\n", buffer, status); if(status > 0)
printf("sendto() : %s \t%d\n", buffer, status);
} }
close(sock); close(sock);
zts_stop(); /* Shut down ZT */
return 0; return 0;
} }

View File

@@ -52,14 +52,17 @@ int main(int argc, char *argv[])
//n = 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));
fcntl(sock, F_SETFL, O_NONBLOCK); //fcntl(sock, F_SETFL, O_NONBLOCK);
while (1) { while (1) {
sleep(1); //usleep(50000);
n = zts_recvfrom(sock, buffer, MAXBUF, 0, (struct sockaddr *)&sin6, &sin6len); n = zts_recvfrom(sock, buffer, MAXBUF, 0, (struct sockaddr *)&sin6, &sin6len);
printf("n = %d, buffer : %s\n", n, buffer); //if(n > 0)
printf("recvfrom(): n = %d, buffer : %s\n", n, buffer);
} }
shutdown(sock, 2); shutdown(sock, 2);
close(sock); close(sock);
zts_stop(); /* Shut down ZT */
return 0; return 0;
} }