tcp_received() fix
This commit is contained in:
@@ -84,10 +84,26 @@ struct zts_ifreq {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Legend */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
NSLWIP network_stack_lwip
|
||||||
|
NSPICO network_stack_pico
|
||||||
|
NSRXBF network_stack_pico guarded frame buffer RX
|
||||||
|
ZTVIRT zt_virtual_wire
|
||||||
|
APPFDS app_fd
|
||||||
|
VSRXBF app_fd TX buf
|
||||||
|
VSTXBF app_fd RX buf
|
||||||
|
*/
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* lwIP */
|
/* lwIP */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
|
// For LWIP configuration see: include/lwipopts.h
|
||||||
|
|
||||||
#if defined(STACK_LWIP)
|
#if defined(STACK_LWIP)
|
||||||
#define LWIP_APPLICATION_POLL_FREQ 2
|
#define LWIP_APPLICATION_POLL_FREQ 2
|
||||||
#define LWIP_TCP_TIMER_INTERVAL 50
|
#define LWIP_TCP_TIMER_INTERVAL 50
|
||||||
|
|||||||
@@ -81,21 +81,27 @@
|
|||||||
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
|
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
|
||||||
|
|
||||||
#define ETHARP_DEBUG LWIP_DBG_OFF
|
#define ETHARP_DEBUG LWIP_DBG_OFF
|
||||||
|
|
||||||
|
// interfaces
|
||||||
|
#define SLIP_DEBUG LWIP_DBG_OFF
|
||||||
#define NETIF_DEBUG LWIP_DBG_OFF
|
#define NETIF_DEBUG LWIP_DBG_OFF
|
||||||
#define PBUF_DEBUG LWIP_DBG_OFF
|
// API (not used in libzt)
|
||||||
#define API_LIB_DEBUG LWIP_DBG_OFF
|
#define API_LIB_DEBUG LWIP_DBG_OFF
|
||||||
#define API_MSG_DEBUG LWIP_DBG_OFF
|
#define API_MSG_DEBUG LWIP_DBG_OFF
|
||||||
#define SOCKETS_DEBUG LWIP_DBG_OFF
|
#define SOCKETS_DEBUG LWIP_DBG_OFF
|
||||||
|
// other
|
||||||
#define ICMP_DEBUG LWIP_DBG_OFF
|
#define ICMP_DEBUG LWIP_DBG_OFF
|
||||||
#define IGMP_DEBUG LWIP_DBG_OFF
|
#define IGMP_DEBUG LWIP_DBG_OFF
|
||||||
#define INET_DEBUG LWIP_DBG_OFF
|
#define INET_DEBUG LWIP_DBG_OFF
|
||||||
#define IP_DEBUG LWIP_DBG_OFF
|
|
||||||
#define IP_REASS_DEBUG LWIP_DBG_OFF
|
|
||||||
#define RAW_DEBUG LWIP_DBG_OFF
|
#define RAW_DEBUG LWIP_DBG_OFF
|
||||||
|
// memory
|
||||||
|
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||||
#define MEM_DEBUG LWIP_DBG_OFF
|
#define MEM_DEBUG LWIP_DBG_OFF
|
||||||
#define MEMP_DEBUG LWIP_DBG_OFF
|
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||||
|
// system
|
||||||
#define SYS_DEBUG LWIP_DBG_OFF
|
#define SYS_DEBUG LWIP_DBG_OFF
|
||||||
#define TIMERS_DEBUG LWIP_DBG_OFF
|
#define TIMERS_DEBUG LWIP_DBG_OFF
|
||||||
|
// TCP
|
||||||
#define TCP_DEBUG LWIP_DBG_OFF
|
#define TCP_DEBUG LWIP_DBG_OFF
|
||||||
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
||||||
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
||||||
@@ -105,13 +111,19 @@
|
|||||||
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
||||||
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
||||||
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
||||||
#define UDP_DEBUG LWIP_DBG_OFF
|
// IP
|
||||||
#define TCPIP_DEBUG LWIP_DBG_OFF
|
|
||||||
#define SLIP_DEBUG LWIP_DBG_OFF
|
|
||||||
#define DHCP_DEBUG LWIP_DBG_OFF
|
|
||||||
#define AUTOIP_DEBUG LWIP_DBG_OFF
|
#define AUTOIP_DEBUG LWIP_DBG_OFF
|
||||||
#define DNS_DEBUG LWIP_DBG_OFF
|
#define IP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IP_REASS_DEBUG LWIP_DBG_OFF
|
||||||
#define IP6_DEBUG LWIP_DBG_OFF
|
#define IP6_DEBUG LWIP_DBG_OFF
|
||||||
|
// TCP/IP
|
||||||
|
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||||
|
// UDP
|
||||||
|
#define UDP_DEBUG LWIP_DBG_OFF
|
||||||
|
// services
|
||||||
|
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define DNS_DEBUG LWIP_DBG_OFF
|
||||||
|
|
||||||
|
|
||||||
#define LWIP_UDP 1
|
#define LWIP_UDP 1
|
||||||
#define LWIP_TCP 1
|
#define LWIP_TCP 1
|
||||||
@@ -134,7 +146,7 @@ reason for "twice" are both the nagle algorithm and delayed ACK from the
|
|||||||
remote peer.
|
remote peer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TCP_WND TCP_MSS*10 // max = 0xffff
|
#define TCP_WND 0xffff // max = 0xffff, min = TCP_MSS*2
|
||||||
|
|
||||||
//#define LWIP_NOASSERT 1
|
//#define LWIP_NOASSERT 1
|
||||||
#define TCP_LISTEN_BACKLOG 0
|
#define TCP_LISTEN_BACKLOG 0
|
||||||
@@ -330,7 +342,7 @@ happening sooner than they should.
|
|||||||
/**
|
/**
|
||||||
* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
|
* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
|
||||||
*/
|
*/
|
||||||
#define PBUF_POOL_SIZE 2048 /* was 32 */
|
#define PBUF_POOL_SIZE 8000 /* was 32 */
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
@@ -534,7 +546,7 @@ happening sooner than they should.
|
|||||||
/**
|
/**
|
||||||
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
|
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
|
||||||
*/
|
*/
|
||||||
#define LWIP_STATS 0
|
#define LWIP_STATS 1
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
--------------------------------- PPP Options ----------------------------------
|
--------------------------------- PPP Options ----------------------------------
|
||||||
|
|||||||
@@ -103,13 +103,13 @@ LWIPFILES=$(COREFILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES)
|
|||||||
|
|
||||||
ifeq ($(LIBZT_IPV4),1)
|
ifeq ($(LIBZT_IPV4),1)
|
||||||
LWIPFILES+=$(CORE4FILES)
|
LWIPFILES+=$(CORE4FILES)
|
||||||
CFLAGS+=-DLIBZT_IPV4=1 -DLWIP_IPV4 -DLWIP_IPV6=0 -DIPv4
|
CFLAGS+=-DLIBZT_IPV4=1 -DLWIP_IPV4 -DLWIP_IPV6=0 -DIPv4
|
||||||
#-DLWIP_DEBUG=1
|
#-DLWIP_DEBUG=1
|
||||||
endif
|
endif
|
||||||
ifeq ($(LIBZT_IPV6),1)
|
ifeq ($(LIBZT_IPV6),1)
|
||||||
LWIPFILES+=$(CORE6FILES)
|
LWIPFILES+=$(CORE6FILES)
|
||||||
CFLAGS+=-DLIBZT_IPV6=1 -DLWIP_IPV6 -DLWIP_IPV4=0 -DIPv6
|
CFLAGS+=-DLIBZT_IPV6=1 -DLWIP_IPV6 -DLWIP_IPV4=0 -DIPv6
|
||||||
# -DLWIP_DEBUG=1
|
#-DLWIP_DEBUG=1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LWIPFILESW=$(wildcard $(LWIPFILES))
|
LWIPFILESW=$(wildcard $(LWIPFILES))
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace ZeroTier {
|
|||||||
struct pico_socket *picosock = NULL;
|
struct pico_socket *picosock = NULL;
|
||||||
#endif
|
#endif
|
||||||
#if defined(STACK_LWIP)
|
#if defined(STACK_LWIP)
|
||||||
void *pcb = NULL;
|
void *pcb = NULL; // Protocol Control Block
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct sockaddr_storage local_addr; // address we've bound to locally
|
struct sockaddr_storage local_addr; // address we've bound to locally
|
||||||
@@ -82,19 +82,31 @@ namespace ZeroTier {
|
|||||||
std::time_t closure_ts = 0;
|
std::time_t closure_ts = 0;
|
||||||
|
|
||||||
VirtualSocket() {
|
VirtualSocket() {
|
||||||
|
|
||||||
|
memset(&local_addr, 0, sizeof(sockaddr_storage));
|
||||||
|
memset(&peer_addr, 0, sizeof(sockaddr_storage));
|
||||||
|
|
||||||
|
// ringbuffer used for incoming and outgoing traffic between app, stack, stack drivers, and ZT
|
||||||
TXbuf = new RingBuffer<unsigned char>(ZT_TCP_TX_BUF_SZ);
|
TXbuf = new RingBuffer<unsigned char>(ZT_TCP_TX_BUF_SZ);
|
||||||
RXbuf = new RingBuffer<unsigned char>(ZT_TCP_RX_BUF_SZ);
|
RXbuf = new RingBuffer<unsigned char>(ZT_TCP_RX_BUF_SZ);
|
||||||
|
|
||||||
|
// socketpair, I/O channel between app and stack drivers
|
||||||
closure_ts = -1;
|
closure_ts = -1;
|
||||||
ZT_PHY_SOCKFD_TYPE fdpair[2];
|
ZT_PHY_SOCKFD_TYPE fdpair[2];
|
||||||
if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fdpair) < 0) {
|
if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fdpair) < 0) {
|
||||||
if(errno < 0) {
|
if(errno < 0) {
|
||||||
DEBUG_ERROR("unable to create socketpair");
|
DEBUG_ERROR("unable to create socketpair, errno=%d", errno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdk_fd = fdpair[0];
|
sdk_fd = fdpair[0];
|
||||||
app_fd = fdpair[1];
|
app_fd = fdpair[1];
|
||||||
|
|
||||||
|
// set to non-blocking since these are used as the primary I/O channel
|
||||||
|
if (fcntl(sdk_fd, F_SETFL, O_NONBLOCK) < 0) {
|
||||||
|
DEBUG_ERROR("error while setting virtual socket to NONBLOCKING. exiting", errno);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~VirtualSocket() {
|
~VirtualSocket() {
|
||||||
close(app_fd);
|
close(app_fd);
|
||||||
|
|||||||
@@ -550,18 +550,24 @@ namespace ZeroTier {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove VritualSocket from VirtualTap, and instruct network stacks to dismantle their
|
||||||
|
// respective protocol control structures
|
||||||
int VirtualTap::Close(VirtualSocket *vs) {
|
int VirtualTap::Close(VirtualSocket *vs) {
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if(!vs) {
|
if(!vs) {
|
||||||
DEBUG_ERROR("invalid VirtualSocket");
|
DEBUG_ERROR("invalid VirtualSocket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
removeVirtualSocket(vs);
|
||||||
#if defined(STACK_PICO)
|
#if defined(STACK_PICO)
|
||||||
err = picostack->pico_Close(vs);
|
if(picostack) {
|
||||||
|
err = picostack->pico_Close(vs);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(STACK_LWIP)
|
#if defined(STACK_LWIP)
|
||||||
if(lwipstack)
|
if(lwipstack) {
|
||||||
lwipstack->lwip_Close(vs);
|
err = lwipstack->lwip_Close(vs);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if(vs->sock) {
|
if(vs->sock) {
|
||||||
_phy.close(vs->sock, false);
|
_phy.close(vs->sock, false);
|
||||||
|
|||||||
@@ -499,7 +499,7 @@ Linux:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int zts_connect(ZT_CONNECT_SIG) {
|
int zts_connect(ZT_CONNECT_SIG) {
|
||||||
DEBUG_INFO("fd=%d");
|
DEBUG_INFO("fd=%d",fd);
|
||||||
int err = errno = 0;
|
int err = errno = 0;
|
||||||
if(fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
if(fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
@@ -586,7 +586,7 @@ int zts_connect(ZT_CONNECT_SIG) {
|
|||||||
bool complete = false;
|
bool complete = false;
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
// FIXME: locking and unlocking so often might cause a performance bottleneck while outgoing VirtualSockets
|
// FIXME: locking and unlocking so often might cause significant performance overhead while outgoing VirtualSockets
|
||||||
// are being established (also applies to accept())
|
// are being established (also applies to accept())
|
||||||
nanosleep((const struct timespec[]){{0, (ZT_CONNECT_RECHECK_DELAY * 1000000)}}, NULL);
|
nanosleep((const struct timespec[]){{0, (ZT_CONNECT_RECHECK_DELAY * 1000000)}}, NULL);
|
||||||
tap->_tcpconns_m.lock();
|
tap->_tcpconns_m.lock();
|
||||||
@@ -607,8 +607,9 @@ int zts_connect(ZT_CONNECT_SIG) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tap->_tcpconns_m.unlock();
|
tap->_tcpconns_m.unlock();
|
||||||
if(complete)
|
if(complete) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@@ -771,7 +772,12 @@ int zts_accept(ZT_ACCEPT_SIG) {
|
|||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// +1 since we'll be creating a new pico_socket when we accept the VirtualSocket
|
if(addr && *addrlen <= 0) {
|
||||||
|
DEBUG_ERROR("invalid address length given");
|
||||||
|
errno = EINVAL; // TODO, not actually a valid error for this function
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// since we'll be creating a new stack socket or protocol control block when we accept the connection
|
||||||
if(!can_provision_new_socket()) {
|
if(!can_provision_new_socket()) {
|
||||||
DEBUG_ERROR("cannot provision additional socket due to limitation of network stack");
|
DEBUG_ERROR("cannot provision additional socket due to limitation of network stack");
|
||||||
errno = EMFILE;
|
errno = EMFILE;
|
||||||
@@ -797,9 +803,8 @@ int zts_accept(ZT_ACCEPT_SIG) {
|
|||||||
else {
|
else {
|
||||||
blocking = !(f_err & O_NONBLOCK);
|
blocking = !(f_err & O_NONBLOCK);
|
||||||
}
|
}
|
||||||
|
ZeroTier::VirtualSocket *accepted_vs;
|
||||||
if(!err) {
|
if(!err) {
|
||||||
ZeroTier::VirtualSocket *accepted_vs;
|
|
||||||
if(!blocking) { // non-blocking
|
if(!blocking) { // non-blocking
|
||||||
DEBUG_EXTRA("EWOULDBLOCK, not a real error, assuming non-blocking mode");
|
DEBUG_EXTRA("EWOULDBLOCK, not a real error, assuming non-blocking mode");
|
||||||
errno = EWOULDBLOCK;
|
errno = EWOULDBLOCK;
|
||||||
@@ -819,10 +824,12 @@ int zts_accept(ZT_ACCEPT_SIG) {
|
|||||||
err = accepted_vs->app_fd;
|
err = accepted_vs->app_fd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!err) {
|
if(err > 0) {
|
||||||
// copy address into provided address buffer and len buffer
|
if(addr && *addrlen) {
|
||||||
memcpy(addr, &(vs->peer_addr), sizeof(struct sockaddr));
|
*addrlen = *addrlen < sizeof(accepted_vs->peer_addr) ? *addrlen : sizeof(accepted_vs->peer_addr);
|
||||||
*addrlen = sizeof(vs->peer_addr);
|
// copy address into provided address buffer and len buffer
|
||||||
|
memcpy(addr, &(accepted_vs->peer_addr), *addrlen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
@@ -2221,8 +2228,16 @@ ZeroTier::VirtualSocket *get_virtual_socket(int fd)
|
|||||||
void del_virtual_socket(int fd)
|
void del_virtual_socket(int fd)
|
||||||
{
|
{
|
||||||
ZeroTier::_multiplexer_lock.lock();
|
ZeroTier::_multiplexer_lock.lock();
|
||||||
ZeroTier::unmap.erase(fd);
|
std::map<int, ZeroTier::VirtualSocket*>::iterator fd_iter = ZeroTier::unmap.find(fd);
|
||||||
ZeroTier::fdmap.erase(fd);
|
if(fd_iter != ZeroTier::unmap.end()) {
|
||||||
|
ZeroTier::unmap.erase(fd_iter);
|
||||||
|
}
|
||||||
|
//ZeroTier::unmap.erase(fd);
|
||||||
|
std::map<int, std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>*>::iterator un_iter = ZeroTier::fdmap.find(fd);
|
||||||
|
if(un_iter != ZeroTier::fdmap.end()) {
|
||||||
|
ZeroTier::fdmap.erase(un_iter);
|
||||||
|
}
|
||||||
|
//ZeroTier::fdmap.erase(fd);
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2236,7 +2251,11 @@ void add_unassigned_virtual_socket(int fd, ZeroTier::VirtualSocket *vs)
|
|||||||
void del_unassigned_virtual_socket(int fd)
|
void del_unassigned_virtual_socket(int fd)
|
||||||
{
|
{
|
||||||
ZeroTier::_multiplexer_lock.lock();
|
ZeroTier::_multiplexer_lock.lock();
|
||||||
ZeroTier::unmap.erase(fd);
|
std::map<int, ZeroTier::VirtualSocket*>::iterator iter = ZeroTier::unmap.find(fd);
|
||||||
|
if(iter != ZeroTier::unmap.end()) {
|
||||||
|
ZeroTier::unmap.erase(iter);
|
||||||
|
}
|
||||||
|
//ZeroTier::unmap.erase(fd);
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2250,7 +2269,11 @@ void add_assigned_virtual_socket(ZeroTier::VirtualTap *tap, ZeroTier::VirtualSoc
|
|||||||
void del_assigned_virtual_socket(ZeroTier::VirtualTap *tap, ZeroTier::VirtualSocket *vs, int fd)
|
void del_assigned_virtual_socket(ZeroTier::VirtualTap *tap, ZeroTier::VirtualSocket *vs, int fd)
|
||||||
{
|
{
|
||||||
ZeroTier::_multiplexer_lock.lock();
|
ZeroTier::_multiplexer_lock.lock();
|
||||||
ZeroTier::fdmap.erase(fd);
|
std::map<int, std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>*>::iterator iter = ZeroTier::fdmap.find(fd);
|
||||||
|
if(iter != ZeroTier::fdmap.end()) {
|
||||||
|
ZeroTier::fdmap.erase(iter);
|
||||||
|
}
|
||||||
|
//ZeroTier::fdmap.erase(fd);
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
177
src/lwIP.cpp
177
src/lwIP.cpp
@@ -57,13 +57,11 @@ err_t lwip_eth_tx(struct netif *netif, struct pbuf *p)
|
|||||||
|
|
||||||
ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap*)netif->state;
|
ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap*)netif->state;
|
||||||
bufptr = buf;
|
bufptr = buf;
|
||||||
// Copy data from each pbuf, one at a time
|
|
||||||
for(q = p; q != NULL; q = q->next) {
|
for(q = p; q != NULL; q = q->next) {
|
||||||
memcpy(bufptr, q->payload, q->len);
|
memcpy(bufptr, q->payload, q->len);
|
||||||
bufptr += q->len;
|
bufptr += q->len;
|
||||||
totalLength += q->len;
|
totalLength += q->len;
|
||||||
}
|
}
|
||||||
// Split ethernet header and feed into handler
|
|
||||||
struct eth_hdr *ethhdr;
|
struct eth_hdr *ethhdr;
|
||||||
ethhdr = (struct eth_hdr *)buf;
|
ethhdr = (struct eth_hdr *)buf;
|
||||||
|
|
||||||
@@ -290,6 +288,7 @@ namespace ZeroTier
|
|||||||
if(socket_type == SOCK_STREAM) {
|
if(socket_type == SOCK_STREAM) {
|
||||||
struct tcp_pcb *new_tcp_PCB = tcp_new();
|
struct tcp_pcb *new_tcp_PCB = tcp_new();
|
||||||
*pcb = new_tcp_PCB;
|
*pcb = new_tcp_PCB;
|
||||||
|
tcp_nagle_disable(new_tcp_PCB);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
if(socket_type == SOCK_DGRAM) {
|
if(socket_type == SOCK_DGRAM) {
|
||||||
@@ -455,7 +454,7 @@ namespace ZeroTier
|
|||||||
|
|
||||||
int lwIP::lwip_Listen(VirtualSocket *vs, int backlog)
|
int lwIP::lwip_Listen(VirtualSocket *vs, int backlog)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("vs=%p", vs);
|
//DEBUG_INFO("vs=%p", vs);
|
||||||
struct tcp_pcb* listeningPCB;
|
struct tcp_pcb* listeningPCB;
|
||||||
#ifdef TCP_LISTEN_BACKLOG
|
#ifdef TCP_LISTEN_BACKLOG
|
||||||
listeningPCB = tcp_listen_with_backlog((struct tcp_pcb*)vs->pcb, backlog);
|
listeningPCB = tcp_listen_with_backlog((struct tcp_pcb*)vs->pcb, backlog);
|
||||||
@@ -466,19 +465,20 @@ namespace ZeroTier
|
|||||||
vs->pcb = listeningPCB;
|
vs->pcb = listeningPCB;
|
||||||
tcp_accept(listeningPCB, lwip_cb_accept); // set callback
|
tcp_accept(listeningPCB, lwip_cb_accept); // set callback
|
||||||
tcp_arg(listeningPCB, vs);
|
tcp_arg(listeningPCB, vs);
|
||||||
//fcntl(tap->_phy.getDescriptor(vs->sock), F_SETFL, O_NONBLOCK);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualSocket* lwIP::lwip_Accept(VirtualSocket *vs)
|
VirtualSocket* lwIP::lwip_Accept(VirtualSocket *vs)
|
||||||
{
|
{
|
||||||
|
//DEBUG_INFO();
|
||||||
if(!vs) {
|
if(!vs) {
|
||||||
DEBUG_ERROR("invalid virtual socket");
|
DEBUG_ERROR("invalid virtual socket");
|
||||||
handle_general_failure();
|
handle_general_failure();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// Retreive first of queued VirtualSockets from parent VirtualSocket
|
// Retreive first of queued VirtualSockets from parent VirtualSocket
|
||||||
|
// TODO: check multithreaded behaviour
|
||||||
VirtualSocket *new_vs = NULL;
|
VirtualSocket *new_vs = NULL;
|
||||||
if(vs->_AcceptedConnections.size()) {
|
if(vs->_AcceptedConnections.size()) {
|
||||||
new_vs = vs->_AcceptedConnections.front();
|
new_vs = vs->_AcceptedConnections.front();
|
||||||
@@ -538,7 +538,6 @@ namespace ZeroTier
|
|||||||
}
|
}
|
||||||
if(vs->socket_type == SOCK_DGRAM)
|
if(vs->socket_type == SOCK_DGRAM)
|
||||||
{
|
{
|
||||||
//DEBUG_ERROR("socket_type==SOCK_DGRAM");
|
|
||||||
// TODO: Packet re-assembly hasn't yet been tested with lwIP so UDP packets are limited to MTU-sized chunks
|
// TODO: Packet re-assembly hasn't yet been tested with lwIP so UDP packets are limited to MTU-sized chunks
|
||||||
int udp_trans_len = std::min(len, (ssize_t)ZT_MAX_MTU);
|
int udp_trans_len = std::min(len, (ssize_t)ZT_MAX_MTU);
|
||||||
//DEBUG_EXTRA("allocating pbuf chain of size=%d for UDP packet", udp_trans_len);
|
//DEBUG_EXTRA("allocating pbuf chain of size=%d for UDP packet", udp_trans_len);
|
||||||
@@ -564,7 +563,6 @@ namespace ZeroTier
|
|||||||
}
|
}
|
||||||
if(vs->socket_type == SOCK_STREAM)
|
if(vs->socket_type == SOCK_STREAM)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("socket_type==SOCK_STREAM");
|
|
||||||
// How much we are currently allowed to write to the VirtualSocket
|
// How much we are currently allowed to write to the VirtualSocket
|
||||||
ssize_t sndbuf = ((struct tcp_pcb*)vs->pcb)->snd_buf;
|
ssize_t sndbuf = ((struct tcp_pcb*)vs->pcb)->snd_buf;
|
||||||
int err, r;
|
int err, r;
|
||||||
@@ -572,15 +570,16 @@ namespace ZeroTier
|
|||||||
// PCB send buffer is full, turn off readability notifications for the
|
// PCB send buffer is full, turn off readability notifications for the
|
||||||
// corresponding PhySocket until lwip_cb_sent() is called and confirms that there is
|
// corresponding PhySocket until lwip_cb_sent() is called and confirms that there is
|
||||||
// now space on the buffer
|
// now space on the buffer
|
||||||
DEBUG_ERROR("lwIP stack is full, sndbuf == 0");
|
DEBUG_ERROR("lwIP stack is full, sndbuf==0");
|
||||||
vs->tap->_phy.setNotifyReadable(vs->sock, false);
|
//vs->tap->_phy.setNotifyReadable(vs->sock, false);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int buf_w = vs->TXbuf->write((const unsigned char*)data, len);
|
int buf_w = vs->TXbuf->write((const unsigned char*)data, len);
|
||||||
if (buf_w != len) {
|
if (buf_w != len) {
|
||||||
// because we checked ZT_TCP_TX_BUF_SZ above, this should not happen
|
// because we checked ZT_TCP_TX_BUF_SZ above, this should not happen
|
||||||
DEBUG_ERROR("TX wrote only %d but expected to write %d", buf_w, len);
|
DEBUG_ERROR("TX wrote only %d but expected to write %d", buf_w, len);
|
||||||
exit(0);
|
handle_general_failure();
|
||||||
|
return ZT_ERR_GENERAL_FAILURE;
|
||||||
}
|
}
|
||||||
if(vs->TXbuf->count() <= 0) {
|
if(vs->TXbuf->count() <= 0) {
|
||||||
return -1; // nothing to write
|
return -1; // nothing to write
|
||||||
@@ -609,49 +608,61 @@ namespace ZeroTier
|
|||||||
|
|
||||||
int lwIP::lwip_Close(VirtualSocket *vs)
|
int lwIP::lwip_Close(VirtualSocket *vs)
|
||||||
{
|
{
|
||||||
//DEBUG_INFO();
|
int err = 0;
|
||||||
|
errno = 0;
|
||||||
if(vs->socket_type == SOCK_DGRAM) {
|
if(vs->socket_type == SOCK_DGRAM) {
|
||||||
udp_remove((struct udp_pcb*)vs->pcb);
|
udp_remove((struct udp_pcb*)vs->pcb);
|
||||||
}
|
}
|
||||||
// FIXME: check if already closed? vs->TCP_pcb->state != CLOSED
|
// FIXME: check if already closed? vs->TCP_pcb->state != CLOSED
|
||||||
if(vs->pcb) {
|
if(vs->pcb) {
|
||||||
//DEBUG_EXTRA("vs=%p, sock=%p, PCB->state = %d",
|
|
||||||
// conn, sock, vs->TCP_pcb->state);
|
|
||||||
if(((struct tcp_pcb*)vs->pcb)->state == SYN_SENT /*|| vs->TCP_pcb->state == CLOSE_WAIT*/) {
|
if(((struct tcp_pcb*)vs->pcb)->state == SYN_SENT /*|| vs->TCP_pcb->state == CLOSE_WAIT*/) {
|
||||||
DEBUG_EXTRA("ignoring close request. invalid PCB state for this operation. sock=%p", vs->sock);
|
DEBUG_EXTRA("ignoring close request. invalid PCB state for this operation. sock=%p", vs->sock);
|
||||||
|
// TODO: errno = ?;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct tcp_pcb* tpcb = (struct tcp_pcb*)vs->pcb;
|
struct tcp_pcb* tpcb = (struct tcp_pcb*)vs->pcb;
|
||||||
if(tcp_close(tpcb) == ERR_OK) {
|
if(tcp_close(tpcb) == ERR_OK) {
|
||||||
// Unregister callbacks for this PCB
|
// unregister callbacks for this PCB
|
||||||
tcp_arg(tpcb, NULL);
|
tcp_arg(tpcb, NULL);
|
||||||
tcp_recv(tpcb, NULL);
|
tcp_recv(tpcb, NULL);
|
||||||
tcp_err(tpcb, NULL);
|
tcp_err(tpcb, NULL);
|
||||||
tcp_sent(tpcb, NULL);
|
tcp_sent(tpcb, NULL);
|
||||||
tcp_poll(tpcb, NULL, 1);
|
tcp_poll(tpcb, NULL, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DEBUG_EXTRA("error while calling tcp_close() sock=%p", vs->sock);
|
DEBUG_EXTRA("error while calling tcp_close() sock=%p", vs->sock);
|
||||||
|
err = -1;
|
||||||
|
// TODO: set errno
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Callbacks from lwIP stack */
|
/* Callbacks from lwIP stack */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
|
// write data from processed packets from the stack to the client app
|
||||||
|
/*
|
||||||
|
With the raw API, tcp_recv() sets up to receive data via a callback function. Your callback
|
||||||
|
is delivered chains of pbufs as they become available. You have to manage extracting data
|
||||||
|
from the pbuf chain, and don't forget to watch out for multiple pbufs in a single callback:
|
||||||
|
the 'tot_len' field indicates the total length of data in the pbuf chain. You must call
|
||||||
|
tcp_recved() to tell LWIP when you have processed the received data. As with the netconn API,
|
||||||
|
you may receive more or less data than you want, and will have to either wait for further
|
||||||
|
callbacks, or hold onto excess data for later processing.
|
||||||
|
|
||||||
|
http://lwip.wikia.com/wiki/Receiving_data_with_LWIP
|
||||||
|
*/
|
||||||
err_t lwIP::lwip_cb_tcp_recved(void *arg, struct tcp_pcb *PCB, struct pbuf *p, err_t err)
|
err_t lwIP::lwip_cb_tcp_recved(void *arg, struct tcp_pcb *PCB, struct pbuf *p, err_t err)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
//DEBUG_INFO();
|
||||||
VirtualSocket *vs = (VirtualSocket *)arg;
|
VirtualSocket *vs = (VirtualSocket *)arg;
|
||||||
int tot = 0;
|
int tot = 0;
|
||||||
|
|
||||||
if(!vs) {
|
if(!vs) {
|
||||||
DEBUG_ERROR("no virtual socket");
|
DEBUG_ERROR("no virtual socket");
|
||||||
return ERR_OK; // FIXME: Determine if this is correct behaviour expected by the stack
|
return ERR_OK; // FIXME: Determine if this is correct behaviour expected by the stack
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pbuf* q = p;
|
struct pbuf* q = p;
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
/*
|
/*
|
||||||
@@ -659,13 +670,10 @@ namespace ZeroTier
|
|||||||
// FIXME: Implement?
|
// FIXME: Implement?
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
DEBUG_INFO("p == NULL");
|
return ERR_ABRT; // close connection
|
||||||
return ERR_ABRT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vs->tap->_tcpconns_m.lock();
|
vs->tap->_tcpconns_m.lock();
|
||||||
vs->_rx_m.lock();
|
vs->_rx_m.lock();
|
||||||
|
|
||||||
// cycle through pbufs and write them to the RX buffer
|
// cycle through pbufs and write them to the RX buffer
|
||||||
while(p != NULL) {
|
while(p != NULL) {
|
||||||
if(p->len <= 0)
|
if(p->len <= 0)
|
||||||
@@ -675,38 +683,51 @@ namespace ZeroTier
|
|||||||
if(avail < len) {
|
if(avail < len) {
|
||||||
DEBUG_ERROR("not enough room (%d bytes) on RX buffer", avail);
|
DEBUG_ERROR("not enough room (%d bytes) on RX buffer", avail);
|
||||||
}
|
}
|
||||||
// get it on the buffer, fast!
|
// place new incoming data on ringbuffer before we try to send it to the app
|
||||||
memcpy(vs->RXbuf->get_buf(), p->payload, len);
|
memcpy(vs->RXbuf->get_buf(), p->payload, len);
|
||||||
vs->RXbuf->produce(len);
|
vs->RXbuf->produce(len);
|
||||||
p = p->next;
|
p = p->next;
|
||||||
tot += len;
|
tot += len;
|
||||||
}
|
}
|
||||||
DEBUG_INFO("tot=%d", tot);
|
|
||||||
|
|
||||||
if(tot) {
|
if(tot) {
|
||||||
|
tcp_recved(PCB, tot);
|
||||||
|
DEBUG_TRANS("len=%5d buf_len=%13d [NSLWIP --> VSRXBF]", tot, vs->RXbuf->count());
|
||||||
int w, write_attempt_sz = vs->RXbuf->count() < ZT_MAX_MTU ? vs->RXbuf->count() : ZT_MAX_MTU;
|
int w, write_attempt_sz = vs->RXbuf->count() < ZT_MAX_MTU ? vs->RXbuf->count() : ZT_MAX_MTU;
|
||||||
if((w = write(vs->sdk_fd, vs->RXbuf->get_buf(), write_attempt_sz)) < 0) {
|
if((w = write(vs->sdk_fd, vs->RXbuf->get_buf(), write_attempt_sz)) < 0) {
|
||||||
perror("write");
|
|
||||||
DEBUG_ERROR("write(fd=%d)=%d, errno=%d", vs->sdk_fd, w, errno);
|
DEBUG_ERROR("write(fd=%d)=%d, errno=%d", vs->sdk_fd, w, errno);
|
||||||
}
|
}
|
||||||
if(w > 0) {
|
if(w > 0) {
|
||||||
DEBUG_INFO("write_attempt_sz=%d, w=%d", write_attempt_sz, w);
|
|
||||||
vs->RXbuf->consume(w);
|
vs->RXbuf->consume(w);
|
||||||
|
if(w < write_attempt_sz) {
|
||||||
|
DEBUG_TRANS("len=%5d buf_len=%13d [VSRXBF --> APPFDS]", w, vs->RXbuf->count());
|
||||||
|
DEBUG_ERROR("warning, intended to write %d bytes", write_attempt_sz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG_TRANS("len=%5d buf_len=%13d [VSRXBF --> APPFDS]", w, vs->RXbuf->count());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//vs->tap->_phy.setNotifyWritable(vs->sock, true);
|
|
||||||
//vs->tap->phyOnUnixWritable(vs->sock, NULL, true); // to app
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
DEBUG_EXTRA("warning, wrote 0 bytes");
|
||||||
|
}
|
||||||
vs->tap->_tcpconns_m.unlock();
|
vs->tap->_tcpconns_m.unlock();
|
||||||
vs->_rx_m.unlock();
|
vs->_rx_m.unlock();
|
||||||
|
|
||||||
pbuf_free(q);
|
pbuf_free(q);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NSLWIP network_stack_lwip
|
||||||
|
NSPICO network_stack_pico
|
||||||
|
NSRXBF network_stack_pico guarded frame buffer RX
|
||||||
|
ZTVIRT zt_virtual_wire
|
||||||
|
APPFDS app_fd
|
||||||
|
VSRXBF app_fd TX buf
|
||||||
|
VSTXBF app_fd RX buf
|
||||||
|
*/
|
||||||
err_t lwIP::lwip_cb_accept(void *arg, struct tcp_pcb *newPCB, err_t err)
|
err_t lwIP::lwip_cb_accept(void *arg, struct tcp_pcb *newPCB, err_t err)
|
||||||
{
|
{
|
||||||
|
//DEBUG_INFO();
|
||||||
VirtualSocket *vs = (VirtualSocket*)arg;
|
VirtualSocket *vs = (VirtualSocket*)arg;
|
||||||
struct sockaddr_storage ss;
|
struct sockaddr_storage ss;
|
||||||
#if defined(LIBZT_IPV4)
|
#if defined(LIBZT_IPV4)
|
||||||
@@ -742,7 +763,7 @@ namespace ZeroTier
|
|||||||
// copy processed datagram to app socket
|
// copy processed datagram to app socket
|
||||||
void lwIP::lwip_cb_udp_recved(void * arg, struct udp_pcb * upcb, struct pbuf * p, const ip_addr_t * addr, u16_t port)
|
void lwIP::lwip_cb_udp_recved(void * arg, struct udp_pcb * upcb, struct pbuf * p, const ip_addr_t * addr, u16_t port)
|
||||||
{
|
{
|
||||||
DEBUG_EXTRA("arg(vs)=%p, pcb=%p, port=%d)", arg, upcb, port);
|
//DEBUG_EXTRA("arg(vs)=%p, pcb=%p, port=%d)", arg, upcb, port);
|
||||||
VirtualSocket *vs = (VirtualSocket *)arg;
|
VirtualSocket *vs = (VirtualSocket *)arg;
|
||||||
if(!vs) {
|
if(!vs) {
|
||||||
DEBUG_ERROR("invalid virtual socket");
|
DEBUG_ERROR("invalid virtual socket");
|
||||||
@@ -799,9 +820,11 @@ namespace ZeroTier
|
|||||||
pbuf_free(q);
|
pbuf_free(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// callback from stack to notify driver that data was sent
|
||||||
err_t lwIP::lwip_cb_sent(void* arg, struct tcp_pcb *PCB, u16_t len)
|
err_t lwIP::lwip_cb_sent(void* arg, struct tcp_pcb *PCB, u16_t len)
|
||||||
{
|
{
|
||||||
DEBUG_EXTRA("pcb=%p", PCB);
|
//DEBUG_EXTRA("pcb=%p", PCB);
|
||||||
|
/*
|
||||||
VirtualSocket *vs = (VirtualSocket *)arg;
|
VirtualSocket *vs = (VirtualSocket *)arg;
|
||||||
Mutex::Lock _l(vs->tap->_tcpconns_m);
|
Mutex::Lock _l(vs->tap->_tcpconns_m);
|
||||||
if(vs && len) {
|
if(vs && len) {
|
||||||
@@ -811,6 +834,7 @@ namespace ZeroTier
|
|||||||
vs->tap->_phy.whack();
|
vs->tap->_phy.whack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,76 +861,79 @@ namespace ZeroTier
|
|||||||
|
|
||||||
void lwIP::lwip_cb_err(void *arg, err_t err)
|
void lwIP::lwip_cb_err(void *arg, err_t err)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("err=%d", err);
|
|
||||||
VirtualSocket *vs = (VirtualSocket *)arg;
|
VirtualSocket *vs = (VirtualSocket *)arg;
|
||||||
if(!vs){
|
if(!vs){
|
||||||
DEBUG_ERROR("vs==NULL");
|
DEBUG_ERROR("err=%d, invalid virtual socket", err);
|
||||||
errno = -1; // FIXME: Find more appropriate value
|
errno = -1; // FIXME: Find more appropriate value
|
||||||
}
|
}
|
||||||
Mutex::Lock _l(vs->tap->_tcpconns_m);
|
DEBUG_ERROR("vs=%p, pcb=%p, fd=%d, err=%d", vs, vs->pcb, vs->app_fd, err);
|
||||||
int fd = vs->tap->_phy.getDescriptor(vs->sock);
|
|
||||||
DEBUG_ERROR("vs=%p, pcb=%p, fd=%d, err=%d", vs, vs->pcb, fd, err);
|
|
||||||
DEBUG_ERROR("closing virtual socket");
|
|
||||||
vs->tap->Close(vs);
|
vs->tap->Close(vs);
|
||||||
|
|
||||||
switch(err)
|
switch(err)
|
||||||
{
|
{
|
||||||
case ERR_MEM:
|
case ERR_MEM: // -1
|
||||||
DEBUG_ERROR("ERR_MEM->ENOMEM");
|
DEBUG_ERROR("ERR_MEM->ENOMEM, Out of memory error.");
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
break;
|
break;
|
||||||
case ERR_BUF:
|
case ERR_BUF: // -2
|
||||||
DEBUG_ERROR("ERR_BUF->ENOBUFS");
|
DEBUG_ERROR("ERR_BUF->ENOBUFS, Buffer error.");
|
||||||
errno = ENOBUFS;
|
errno = ENOBUFS;
|
||||||
break;
|
break;
|
||||||
case ERR_TIMEOUT:
|
case ERR_TIMEOUT: // -3
|
||||||
DEBUG_ERROR("ERR_TIMEOUT->ETIMEDOUT");
|
DEBUG_ERROR("ERR_TIMEOUT->ETIMEDOUT, Timeout.");
|
||||||
errno = ETIMEDOUT;
|
errno = ETIMEDOUT;
|
||||||
break;
|
break;
|
||||||
case ERR_RTE:
|
case ERR_RTE: // -4
|
||||||
DEBUG_ERROR("ERR_RTE->ENETUNREACH");
|
DEBUG_ERROR("ERR_RTE->ENETUNREACH, Routing problem.");
|
||||||
errno = ENETUNREACH;
|
errno = ENETUNREACH;
|
||||||
break;
|
break;
|
||||||
case ERR_INPROGRESS:
|
case ERR_INPROGRESS: // -5
|
||||||
DEBUG_ERROR("ERR_INPROGRESS->EINPROGRESS");
|
DEBUG_ERROR("ERR_INPROGRESS->EINPROGRESS, Operation in progress.");
|
||||||
errno = EINPROGRESS;
|
errno = EINPROGRESS;
|
||||||
break;
|
break;
|
||||||
case ERR_VAL:
|
case ERR_VAL: // -6
|
||||||
DEBUG_ERROR("ERR_VAL->EINVAL");
|
DEBUG_ERROR("ERR_VAL->EINVAL, Illegal value.");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
break;
|
break;
|
||||||
case ERR_WOULDBLOCK:
|
case ERR_WOULDBLOCK: // -7
|
||||||
DEBUG_ERROR("ERR_WOULDBLOCK->EWOULDBLOCK");
|
DEBUG_ERROR("ERR_WOULDBLOCK->EWOULDBLOCK, Operation would block.");
|
||||||
errno = EWOULDBLOCK;
|
errno = EWOULDBLOCK;
|
||||||
break;
|
break;
|
||||||
case ERR_USE:
|
case ERR_USE: // -8
|
||||||
DEBUG_ERROR("ERR_USE->EADDRINUSE");
|
DEBUG_ERROR("ERR_USE->EADDRINUSE, Address in use.");
|
||||||
errno = EADDRINUSE;
|
errno = EADDRINUSE;
|
||||||
break;
|
break;
|
||||||
case ERR_ISCONN:
|
case ERR_ALREADY: // -9 ?
|
||||||
DEBUG_ERROR("ERR_ISvs->EISCONN");
|
DEBUG_ERROR("ERR_ALREADY->EISCONN, Already connecting.");
|
||||||
errno = EISCONN;
|
errno = EISCONN;
|
||||||
break;
|
break;
|
||||||
case ERR_ABRT:
|
case ERR_ISCONN: // -10
|
||||||
DEBUG_ERROR("ERR_ABRT->ECONNREFUSED");
|
DEBUG_ERROR("ERR_ISCONN->EISCONN, Already connected");
|
||||||
errno = ECONNREFUSED;
|
errno = EISCONN;
|
||||||
break;
|
break;
|
||||||
|
case ERR_CONN: // -11 ?
|
||||||
// TODO: Below are errors which don't have a standard errno correlate
|
DEBUG_ERROR("ERR_CONN->EISCONN, Not connected");
|
||||||
|
errno = EISCONN;
|
||||||
case ERR_RST:
|
|
||||||
// -1
|
|
||||||
break;
|
break;
|
||||||
case ERR_CLSD:
|
case ERR_IF: // -12
|
||||||
// -1
|
DEBUG_ERROR("ERR_IF, Low-level netif error.");
|
||||||
|
errno = -1;
|
||||||
break;
|
break;
|
||||||
case ERR_CONN:
|
case ERR_ABRT: // -13
|
||||||
// -1
|
DEBUG_ERROR("ERR_ABRT, Connection aborted.");
|
||||||
|
errno = -1;
|
||||||
|
break;
|
||||||
|
case ERR_RST: // -14
|
||||||
|
DEBUG_ERROR("ERR_RST, Connection reset.");
|
||||||
|
errno = -1;
|
||||||
break;
|
break;
|
||||||
case ERR_ARG:
|
case ERR_CLSD: // -15
|
||||||
// -1
|
DEBUG_ERROR("ERR_CLSD, Connection closed.");
|
||||||
|
errno = -1;
|
||||||
break;
|
break;
|
||||||
case ERR_IF:
|
case ERR_ARG: // -16
|
||||||
// -1
|
DEBUG_ERROR("ERR_ARG, Illegal argument.");
|
||||||
|
errno = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ extern "C" u16_t lwip_ntohs(LWIP_NTOHS_SIG);
|
|||||||
extern "C" void tcp_input(LWIP_TCP_INPUT_SIG);
|
extern "C" void tcp_input(LWIP_TCP_INPUT_SIG);
|
||||||
extern "C" err_t ip_input(LWIP_IP_INPUT_SIG);
|
extern "C" err_t ip_input(LWIP_IP_INPUT_SIG);
|
||||||
|
|
||||||
|
|
||||||
//extern "C" void netif_set_status_callback(NETIF_SET_STATUS_CALLBACK);
|
//extern "C" void netif_set_status_callback(NETIF_SET_STATUS_CALLBACK);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ namespace ZeroTier {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(vs->socket_type == SOCK_STREAM) {
|
if(vs->socket_type == SOCK_STREAM) {
|
||||||
DEBUG_TRANS("len=%5d, [app(buf) --> network_stack(vs=%p)] proto=0x%04x (TCP)", r, vs, PICO_PROTO_TCP);
|
DEBUG_TRANS("len=%5d buf_len=%13d [VSTXBF --> NSPICO] proto=0x%04x (TCP)", r, vs->TXbuf->count(), PICO_PROTO_TCP);
|
||||||
}
|
}
|
||||||
if(r == 0) {
|
if(r == 0) {
|
||||||
// DEBUG_ERROR("err=%d, pico_err=%d, %s", r, pico_err, beautify_pico_error(pico_err));
|
// DEBUG_ERROR("err=%d, pico_err=%d, %s", r, pico_err, beautify_pico_error(pico_err));
|
||||||
@@ -935,7 +935,7 @@ namespace ZeroTier {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(vs->picosock->state & PICO_SOCKET_STATE_CLOSED){
|
if(vs->picosock->state & PICO_SOCKET_STATE_CLOSED){
|
||||||
DEBUG_ERROR("socket is CLOSED, this write() will fail");
|
DEBUG_ERROR("socket is CLOSED, this wrpico_cb_tcp_writeite() will fail");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!vs) {
|
if(!vs) {
|
||||||
@@ -983,10 +983,10 @@ namespace ZeroTier {
|
|||||||
vs->TXbuf->consume(r);
|
vs->TXbuf->consume(r);
|
||||||
}
|
}
|
||||||
if(vs->socket_type == SOCK_STREAM) {
|
if(vs->socket_type == SOCK_STREAM) {
|
||||||
DEBUG_TRANS("len=%5d [app(buf) --> network_stack(vs=%p)] proto=0x%04x (TCP)", r, vs, PICO_PROTO_TCP);
|
DEBUG_TRANS("len=%5d buf_len=%13d [VSTXBF --> NSPICO] proto=0x%04x (TCP)", r, vs->TXbuf->count(), PICO_PROTO_TCP);
|
||||||
}
|
}
|
||||||
if(vs->socket_type == SOCK_DGRAM) {
|
if(vs->socket_type == SOCK_DGRAM) {
|
||||||
DEBUG_TRANS("len=%5d [app(buf) --> network_stack(vs=%p)] proto=0x%04x (TCP)", r, vs, PICO_PROTO_UDP);
|
DEBUG_TRANS("len=%5d buf_len= [APPFDS --> NSPICO] proto=0x%04x (UDP)", r, PICO_PROTO_TCP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ void wait_until_tplus_s(long int original_time, int tplus_s) {
|
|||||||
fprintf(stderr, "\n\n--- WAITING FOR T+%d --- (current: T+%d)\n\n", tplus_s, current_time_offset);
|
fprintf(stderr, "\n\n--- WAITING FOR T+%d --- (current: T+%d)\n\n", tplus_s, current_time_offset);
|
||||||
if(current_time_offset > tplus_s) {
|
if(current_time_offset > tplus_s) {
|
||||||
DEBUG_ERROR("--- ABORTING TEST: Tests are out of sync and might not yield valid results. ---");
|
DEBUG_ERROR("--- ABORTING TEST: Tests are out of sync and might not yield valid results. ---");
|
||||||
exit(0);
|
//exit(0);
|
||||||
}
|
}
|
||||||
if(current_time_offset == tplus_s) {
|
if(current_time_offset == tplus_s) {
|
||||||
DEBUG_ERROR("--- WARNING: Tests might be out of sync and might not yield valid results. ---");
|
DEBUG_ERROR("--- WARNING: Tests might be out of sync and might not yield valid results. ---");
|
||||||
@@ -824,10 +824,11 @@ void tcp_client_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
w += n;
|
w += n;
|
||||||
wrem -= n;
|
wrem -= n;
|
||||||
err = n;
|
err = n;
|
||||||
|
DEBUG_TEST("wrote=%d, w=%d, wrem=%d", n, w, wrem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long int tx_tf = get_now_ts();
|
long int tx_tf = get_now_ts();
|
||||||
DEBUG_TEST("wrote=%d", w);
|
DEBUG_TEST("wrote=%d, reading next...", w);
|
||||||
// RX
|
// RX
|
||||||
long int rx_ti = 0;
|
long int rx_ti = 0;
|
||||||
while(rrem) {
|
while(rrem) {
|
||||||
@@ -981,13 +982,14 @@ void tcp_server_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
*passed = false;
|
*passed = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct sockaddr_in client;
|
struct sockaddr_storage client;
|
||||||
socklen_t client_addrlen = sizeof(sockaddr_in);
|
struct sockaddr_in *in4 = (struct sockaddr_in*)&client;
|
||||||
if((client_fd = ACCEPT(fd, (struct sockaddr *)&client, &client_addrlen)) < 0) {
|
socklen_t client_addrlen = sizeof(sockaddr_storage);
|
||||||
|
if((client_fd = ACCEPT(fd, (struct sockaddr *)in4, &client_addrlen)) < 0) {
|
||||||
fprintf(stderr,"error accepting connection (%d)\n", err);
|
fprintf(stderr,"error accepting connection (%d)\n", err);
|
||||||
perror("accept");
|
perror("accept");
|
||||||
}
|
}
|
||||||
DEBUG_TEST("accepted connection from %s, on port %d", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
|
DEBUG_TEST("accepted connection from %s, on port %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port));
|
||||||
if(op == TEST_OP_N_BYTES) {
|
if(op == TEST_OP_N_BYTES) {
|
||||||
int wrem = cnt, rrem = cnt;
|
int wrem = cnt, rrem = cnt;
|
||||||
long int rx_ti = 0;
|
long int rx_ti = 0;
|
||||||
@@ -1001,11 +1003,11 @@ void tcp_server_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
r += n;
|
r += n;
|
||||||
rrem -= n;
|
rrem -= n;
|
||||||
err = n;
|
err = n;
|
||||||
|
DEBUG_TEST("read=%d, r=%d, rrem=%d", n, r, rrem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long int rx_tf = get_now_ts();
|
long int rx_tf = get_now_ts();
|
||||||
DEBUG_TEST("read=%d", r);
|
DEBUG_TEST("read=%d, writing next...", r);
|
||||||
|
|
||||||
long int tx_ti = get_now_ts();
|
long int tx_ti = get_now_ts();
|
||||||
while(wrem) {
|
while(wrem) {
|
||||||
int next_write = std::min(1024, wrem);
|
int next_write = std::min(1024, wrem);
|
||||||
@@ -2254,7 +2256,7 @@ int main(int argc , char *argv[])
|
|||||||
#if defined(__SELFTEST__)
|
#if defined(__SELFTEST__)
|
||||||
// set start time here since we need to wait for both libzt instances to be online
|
// set start time here since we need to wait for both libzt instances to be online
|
||||||
long int selftest_start_time = get_now_ts();
|
long int selftest_start_time = get_now_ts();
|
||||||
subtest_expected_duration = 30;
|
subtest_expected_duration = 5;
|
||||||
|
|
||||||
DEBUG_TEST("Waiting for libzt to come online...\n");
|
DEBUG_TEST("Waiting for libzt to come online...\n");
|
||||||
zts_simple_start(path.c_str(), nwid.c_str());
|
zts_simple_start(path.c_str(), nwid.c_str());
|
||||||
@@ -2319,7 +2321,7 @@ int main(int argc , char *argv[])
|
|||||||
#endif // __SELFTEST__
|
#endif // __SELFTEST__
|
||||||
|
|
||||||
port = start_port;
|
port = start_port;
|
||||||
cnt = 1024*128;
|
cnt = 1024*16;
|
||||||
op = TEST_OP_N_BYTES;
|
op = TEST_OP_N_BYTES;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2341,7 +2343,7 @@ udp-ip6-server | | OK | | OK
|
|||||||
|
|
||||||
#if defined(LIBZT_IPV4)
|
#if defined(LIBZT_IPV4)
|
||||||
// UDP 4 client/server
|
// UDP 4 client/server
|
||||||
/*
|
|
||||||
ipv = 4;
|
ipv = 4;
|
||||||
subtest_start_time_offset += subtest_expected_duration;
|
subtest_start_time_offset += subtest_expected_duration;
|
||||||
subtest_expected_duration = 30;
|
subtest_expected_duration = 30;
|
||||||
@@ -2413,7 +2415,7 @@ udp-ip6-server | | OK | | OK
|
|||||||
}
|
}
|
||||||
RECORD_RESULTS(passed, details, &results);
|
RECORD_RESULTS(passed, details, &results);
|
||||||
port++;
|
port++;
|
||||||
*/
|
|
||||||
// TCP 4 client/server
|
// TCP 4 client/server
|
||||||
|
|
||||||
ipv = 4;
|
ipv = 4;
|
||||||
|
|||||||
Reference in New Issue
Block a user