Added more safety checks to del_virtual_socket(), new zts_shutdown() implementation
This commit is contained in:
@@ -575,8 +575,26 @@ namespace ZeroTier {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shuts down some aspect of a connection (Read/Write)
|
||||||
|
int VirtualTap::Shutdown(VirtualSocket *vs, int how)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
#if defined(STACK_PICO)
|
||||||
|
if(picostack) {
|
||||||
|
err = picostack->pico_Shutdown(vs, how);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
#if defined(STACK_LWIP)
|
||||||
|
if(lwipstack) {
|
||||||
|
err = lwipstack->lwip_Shutdown(vs, how);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualTap::Housekeeping()
|
void VirtualTap::Housekeeping()
|
||||||
{/*
|
{
|
||||||
Mutex::Lock _l(_tcpconns_m);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
std::time_t current_ts = std::time(nullptr);
|
std::time_t current_ts = std::time(nullptr);
|
||||||
if(current_ts > last_housekeeping_ts + ZT_HOUSEKEEPING_INTERVAL) {
|
if(current_ts > last_housekeeping_ts + ZT_HOUSEKEEPING_INTERVAL) {
|
||||||
@@ -635,11 +653,8 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Clean up VirtualSocket objects
|
// TODO: Clean up VirtualSocket objects
|
||||||
|
|
||||||
last_housekeeping_ts = std::time(nullptr);
|
last_housekeeping_ts = std::time(nullptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|||||||
@@ -296,6 +296,11 @@ namespace ZeroTier {
|
|||||||
*/
|
*/
|
||||||
int Close(VirtualSocket *vs);
|
int Close(VirtualSocket *vs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts down some aspect of a VirtualSocket
|
||||||
|
*/
|
||||||
|
int Shutdown(VirtualSocket *vs, int how);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disposes of previously-closed VirtualSockets
|
* Disposes of previously-closed VirtualSockets
|
||||||
*/
|
*/
|
||||||
|
|||||||
185
src/libzt.cpp
185
src/libzt.cpp
@@ -905,13 +905,14 @@ EPERM Firewall rules forbid VirtualSocket.
|
|||||||
*/
|
*/
|
||||||
int zts_setsockopt(ZT_SETSOCKOPT_SIG)
|
int zts_setsockopt(ZT_SETSOCKOPT_SIG)
|
||||||
{
|
{
|
||||||
int err = errno = 0;
|
// TODO: Move stack-specific logic into stack driver section
|
||||||
#if defined(STACK_PICO)
|
|
||||||
//DEBUG_INFO("fd=%d", fd);
|
//DEBUG_INFO("fd=%d", fd);
|
||||||
|
int err = errno = 0;
|
||||||
if(fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
if(fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#if defined(STACK_PICO)
|
||||||
// Disable Nagle's algorithm
|
// Disable Nagle's algorithm
|
||||||
struct pico_socket *p = NULL;
|
struct pico_socket *p = NULL;
|
||||||
err = zts_get_pico_socket(fd, &p);
|
err = zts_get_pico_socket(fd, &p);
|
||||||
@@ -1074,12 +1075,12 @@ int zts_close(ZT_CLOSE_SIG)
|
|||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
del_virtual_socket(fd);
|
||||||
if(vs->tap) {
|
if(vs->tap) {
|
||||||
vs->tap->Close(vs);
|
vs->tap->Close(vs);
|
||||||
}
|
}
|
||||||
delete vs;
|
delete vs;
|
||||||
vs = NULL;
|
vs = NULL;
|
||||||
del_virtual_socket(fd);
|
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1216,7 +1217,7 @@ Linux:
|
|||||||
|
|
||||||
ssize_t zts_sendto(ZT_SENDTO_SIG)
|
ssize_t zts_sendto(ZT_SENDTO_SIG)
|
||||||
{
|
{
|
||||||
DEBUG_TRANS("fd=%d", fd);
|
//DEBUG_TRANS("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;
|
||||||
@@ -1293,7 +1294,6 @@ ssize_t zts_sendto(ZT_SENDTO_SIG)
|
|||||||
err = -1;
|
err = -1;
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
}
|
}
|
||||||
//err = sendto(fd, buf, len, flags, addr, addrlen);
|
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1473,6 +1473,10 @@ ssize_t zts_recv(ZT_RECV_SIG)
|
|||||||
{
|
{
|
||||||
DEBUG_TRANS("fd=%d", fd);
|
DEBUG_TRANS("fd=%d", fd);
|
||||||
int err = errno = 0;
|
int err = errno = 0;
|
||||||
|
if(fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
ZeroTier::VirtualSocket *vs = get_virtual_socket(fd);
|
ZeroTier::VirtualSocket *vs = get_virtual_socket(fd);
|
||||||
if(!vs) {
|
if(!vs) {
|
||||||
DEBUG_ERROR("invalid vs for fd=%d", fd);
|
DEBUG_ERROR("invalid vs for fd=%d", fd);
|
||||||
@@ -1544,18 +1548,18 @@ ssize_t zts_recv(ZT_RECV_SIG)
|
|||||||
allows either error to be returned for this case, and does
|
allows either error to be returned for this case, and does
|
||||||
not require these constants to have the same value, so a
|
not require these constants to have the same value, so a
|
||||||
portable application should check for both possibilities.
|
portable application should check for both possibilities.
|
||||||
[ ] [EBADF] The argument sockfd is an invalid descriptor.
|
[--] [EBADF] The argument sockfd is an invalid descriptor.
|
||||||
[ ] [ECONNREFUSED] A remote host refused to allow the network connection
|
[ ] [ECONNREFUSED] A remote host refused to allow the network connection
|
||||||
(typically because it is not running the requested service).
|
(typically because it is not running the requested service).
|
||||||
[ ] [EFAULT] The receive buffer pointer(s) point outside the process's
|
[ ] [EFAULT] The receive buffer pointer(s) point outside the process's
|
||||||
address space.
|
address space.
|
||||||
[ ] [EINTR] The receive was interrupted by delivery of a signal before any
|
[ ] [EINTR] The receive was interrupted by delivery of a signal before any
|
||||||
data were available; see signal(7).
|
data were available; see signal(7).
|
||||||
[ ] [EINVAL] Invalid argument passed.
|
[--] [EINVAL] Invalid argument passed.
|
||||||
[ ] [ENOMEM] Could not allocate memory for recvmsg().
|
[ ] [ENOMEM] Could not allocate memory for recvmsg().
|
||||||
[ ] [ENOTCONN] The socket is associated with a connection-oriented protocol
|
[ ] [ENOTCONN] The socket is associated with a connection-oriented protocol
|
||||||
and has not been connected (see connect(2) and accept(2)).
|
and has not been connected (see connect(2) and accept(2)).
|
||||||
[ ] [ENOTSOCK] The argument sockfd does not refer to a socket.
|
[NA] [ENOTSOCK] The argument sockfd does not refer to a socket.
|
||||||
|
|
||||||
ZT_RECVFROM_SIG int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen
|
ZT_RECVFROM_SIG int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen
|
||||||
*/
|
*/
|
||||||
@@ -1652,93 +1656,46 @@ int zts_write(ZT_WRITE_SIG) {
|
|||||||
return write(fd, buf, len);
|
return write(fd, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
[--] [EBADF] The socket argument is not a valid file descriptor.
|
||||||
|
[--] [EINVAL] The how argument is invalid.
|
||||||
|
[--] [ENOTCONN] The socket is not connected.
|
||||||
|
[NA] [ENOTSOCK] The socket argument does not refer to a socket.
|
||||||
|
[NA] [ENOBUFS] Insufficient resources were available in the system to perform the operation.
|
||||||
|
|
||||||
|
ZT_SHUTDOWN_SIG int fd, int how
|
||||||
|
*/
|
||||||
|
|
||||||
int zts_shutdown(ZT_SHUTDOWN_SIG)
|
int zts_shutdown(ZT_SHUTDOWN_SIG)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
int err = errno = 0;
|
int err = errno = 0;
|
||||||
#if defined(STACK_PICO)
|
if(fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
||||||
DEBUG_INFO("fd = %d", fd);
|
|
||||||
|
|
||||||
int mode = 0;
|
|
||||||
if(how == SHUT_RD) mode = PICO_SHUT_RD;
|
|
||||||
if(how == SHUT_WR) mode = PICO_SHUT_WR;
|
|
||||||
if(how == SHUT_RDWR) mode = PICO_SHUT_RDWR;
|
|
||||||
|
|
||||||
if(fd < 0) {
|
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
err = -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
if(how != SHUT_RD && how != SHUT_WR && how != SHUT_RDWR) {
|
||||||
{
|
errno = EINVAL;
|
||||||
if(!ZeroTier::zt1Service) {
|
return -1;
|
||||||
DEBUG_ERROR("cannot shutdown socket. service not started. call zts_start(path) first");
|
}
|
||||||
errno = EBADF;
|
ZeroTier::VirtualSocket *vs = get_virtual_socket(fd);
|
||||||
err = -1;
|
if(!vs) {
|
||||||
}
|
DEBUG_ERROR("invalid vs for fd=%d", fd);
|
||||||
else
|
errno = EBADF;
|
||||||
{
|
return -1;
|
||||||
ZeroTier::_multiplexer_lock.lock();
|
}
|
||||||
// First, look for for unassigned VirtualSockets
|
if(vs->state != ZT_SOCK_STATE_CONNECTED || vs->socket_type != SOCK_STREAM) {
|
||||||
ZeroTier::VirtualSocket *vs = ZeroTier::unmap[fd];
|
DEBUG_ERROR("the socket is either not in a connected state, or isn't connection-based, fd=%d", fd);
|
||||||
// Since we found an unassigned VirtualSocket, we don't need to consult the stack or tap
|
errno = ENOTCONN;
|
||||||
// during closure - it isn't yet stitched into the clockwork
|
return -1;
|
||||||
if(vs) // unassigned
|
}
|
||||||
{
|
if(vs->tap) {
|
||||||
DEBUG_ERROR("unassigned shutdown");
|
err = vs->tap->Shutdown(vs, how);
|
||||||
|
|
||||||
// PICO_SHUT_RD
|
|
||||||
// PICO_SHUT_WR
|
|
||||||
// PICO_SHUT_RDWR
|
|
||||||
|
|
||||||
if((err = pico_socket_shutdown(vs->picosock, mode)) < 0)
|
|
||||||
DEBUG_ERROR("error calling pico_socket_shutdown()");
|
|
||||||
DEBUG_ERROR("vs=%p", vs);
|
|
||||||
delete vs;
|
|
||||||
vs = NULL;
|
|
||||||
ZeroTier::unmap.erase(fd);
|
|
||||||
// FIXME: Is deleting this correct behaviour?
|
|
||||||
}
|
|
||||||
else // assigned
|
|
||||||
{
|
|
||||||
std::pair<ZeroTier::VirtualSocket*, ZeroTier::VirtualTap*> *p = ZeroTier::fdmap[fd];
|
|
||||||
if(!p)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("unable to locate VirtualSocket pair.");
|
|
||||||
errno = EBADF;
|
|
||||||
err = -1;
|
|
||||||
}
|
|
||||||
else // found everything, begin closure
|
|
||||||
{
|
|
||||||
vs = p->first;
|
|
||||||
int f_err, blocking = 1;
|
|
||||||
if ((f_err = fcntl(fd, F_GETFL, 0)) < 0) {
|
|
||||||
DEBUG_ERROR("fcntl error, err = %s, errno = %d", f_err, errno);
|
|
||||||
err = -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
blocking = !(f_err & O_NONBLOCK);
|
|
||||||
}
|
|
||||||
if(blocking) {
|
|
||||||
DEBUG_INFO("blocking, waiting for write operations before shutdown...");
|
|
||||||
for(int i=0; i<ZT_SDK_CLTIME; i++) {
|
|
||||||
if(vs->TXbuf->count() == 0)
|
|
||||||
break;
|
|
||||||
nanosleep((const struct timespec[]){{0, (ZT_API_CHECK_INTERVAL * 1000000)}}, NULL);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err = pico_socket_shutdown(vs->picosock, mode)) < 0)
|
|
||||||
DEBUG_ERROR("error calling pico_socket_shutdown()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_add_dns_nameserver(struct sockaddr *addr)
|
int zts_add_dns_nameserver(struct sockaddr *addr)
|
||||||
@@ -2081,7 +2038,7 @@ bool can_provision_new_socket()
|
|||||||
|
|
||||||
int zts_nsockets()
|
int zts_nsockets()
|
||||||
{
|
{
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.lock();
|
||||||
int num = ZeroTier::unmap.size() + ZeroTier::fdmap.size();
|
int num = ZeroTier::unmap.size() + ZeroTier::fdmap.size();
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
return num;
|
return num;
|
||||||
@@ -2228,52 +2185,62 @@ 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();
|
||||||
std::map<int, ZeroTier::VirtualSocket*>::iterator fd_iter = ZeroTier::unmap.find(fd);
|
std::map<int, ZeroTier::VirtualSocket*>::iterator un_iter = ZeroTier::unmap.find(fd);
|
||||||
if(fd_iter != ZeroTier::unmap.end()) {
|
if(un_iter != ZeroTier::unmap.end()) {
|
||||||
ZeroTier::unmap.erase(fd_iter);
|
ZeroTier::unmap.erase(un_iter);
|
||||||
}
|
}
|
||||||
//ZeroTier::unmap.erase(fd);
|
std::map<int, std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>*>::iterator fd_iter = ZeroTier::fdmap.find(fd);
|
||||||
std::map<int, std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>*>::iterator un_iter = ZeroTier::fdmap.find(fd);
|
if(fd_iter != ZeroTier::fdmap.end()) {
|
||||||
if(un_iter != ZeroTier::fdmap.end()) {
|
ZeroTier::fdmap.erase(fd_iter);
|
||||||
ZeroTier::fdmap.erase(un_iter);
|
|
||||||
}
|
}
|
||||||
//ZeroTier::fdmap.erase(fd);
|
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_unassigned_virtual_socket(int fd, ZeroTier::VirtualSocket *vs)
|
void add_unassigned_virtual_socket(int fd, ZeroTier::VirtualSocket *vs)
|
||||||
{
|
{
|
||||||
ZeroTier::_multiplexer_lock.lock();
|
ZeroTier::_multiplexer_lock.lock();
|
||||||
ZeroTier::unmap[fd] = vs;
|
std::map<int, ZeroTier::VirtualSocket*>::iterator un_iter = ZeroTier::unmap.find(fd);
|
||||||
|
if(un_iter == ZeroTier::unmap.end()) {
|
||||||
|
ZeroTier::unmap[fd] = vs;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG_ERROR("fd=%d already contained in <fd:vs> map", fd);
|
||||||
|
handle_general_failure();
|
||||||
|
}
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void del_unassigned_virtual_socket(int fd)
|
void del_unassigned_virtual_socket(int fd)
|
||||||
{
|
{
|
||||||
ZeroTier::_multiplexer_lock.lock();
|
ZeroTier::_multiplexer_lock.lock();
|
||||||
std::map<int, ZeroTier::VirtualSocket*>::iterator iter = ZeroTier::unmap.find(fd);
|
std::map<int, ZeroTier::VirtualSocket*>::iterator un_iter = ZeroTier::unmap.find(fd);
|
||||||
if(iter != ZeroTier::unmap.end()) {
|
if(un_iter != ZeroTier::unmap.end()) {
|
||||||
ZeroTier::unmap.erase(iter);
|
ZeroTier::unmap.erase(un_iter);
|
||||||
}
|
}
|
||||||
//ZeroTier::unmap.erase(fd);
|
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_assigned_virtual_socket(ZeroTier::VirtualTap *tap, ZeroTier::VirtualSocket *vs, int fd)
|
void add_assigned_virtual_socket(ZeroTier::VirtualTap *tap, ZeroTier::VirtualSocket *vs, int fd)
|
||||||
{
|
{
|
||||||
ZeroTier::_multiplexer_lock.lock();
|
ZeroTier::_multiplexer_lock.lock();
|
||||||
ZeroTier::fdmap[fd] = new std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>(vs, tap);
|
std::map<int, std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>*>::iterator fd_iter = ZeroTier::fdmap.find(fd);
|
||||||
|
if(fd_iter == ZeroTier::fdmap.end()) {
|
||||||
|
ZeroTier::fdmap[fd] = new std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>(vs, tap);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG_ERROR("fd=%d already contained in <fd,<vs,vt>> map", fd);
|
||||||
|
handle_general_failure();
|
||||||
|
}
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
std::map<int, std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>*>::iterator iter = ZeroTier::fdmap.find(fd);
|
std::map<int, std::pair<ZeroTier::VirtualSocket*,ZeroTier::VirtualTap*>*>::iterator fd_iter = ZeroTier::fdmap.find(fd);
|
||||||
if(iter != ZeroTier::fdmap.end()) {
|
if(fd_iter != ZeroTier::fdmap.end()) {
|
||||||
ZeroTier::fdmap.erase(iter);
|
ZeroTier::fdmap.erase(fd_iter);
|
||||||
}
|
}
|
||||||
//ZeroTier::fdmap.erase(fd);
|
|
||||||
ZeroTier::_multiplexer_lock.unlock();
|
ZeroTier::_multiplexer_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
src/lwIP.cpp
29
src/lwIP.cpp
@@ -638,6 +638,25 @@ namespace ZeroTier
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lwIP::lwip_Shutdown(VirtualSocket *vs, int how)
|
||||||
|
{
|
||||||
|
int err=0, shut_rx=0, shut_tx=0;
|
||||||
|
if(how == SHUT_RD) {
|
||||||
|
shut_rx = 1;
|
||||||
|
}
|
||||||
|
if(how == SHUT_WR) {
|
||||||
|
shut_tx = 1;
|
||||||
|
}
|
||||||
|
if(how == SHUT_RDWR) {
|
||||||
|
shut_rx = 1;
|
||||||
|
shut_tx = 1;
|
||||||
|
}
|
||||||
|
if((err = tcp_shutdown((tcp_pcb*)(vs->pcb), shut_rx, shut_tx) < 0)) {
|
||||||
|
DEBUG_ERROR("error while shutting down socket, fd=%d", vs->app_fd);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Callbacks from lwIP stack */
|
/* Callbacks from lwIP stack */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@@ -716,15 +735,7 @@ namespace ZeroTier
|
|||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// callback from stack to notify driver of the successful acceptance of a connection
|
||||||
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();
|
//DEBUG_INFO();
|
||||||
|
|||||||
14
src/lwIP.hpp
14
src/lwIP.hpp
@@ -68,7 +68,6 @@ struct netif;
|
|||||||
#define LWIP_PBUF_ALLOC_SIG pbuf_layer layer, u16_t length, pbuf_type type
|
#define LWIP_PBUF_ALLOC_SIG pbuf_layer layer, u16_t length, pbuf_type type
|
||||||
#define LWIP_HTONS_SIG u16_t x
|
#define LWIP_HTONS_SIG u16_t x
|
||||||
#define LWIP_NTOHS_SIG u16_t x
|
#define LWIP_NTOHS_SIG u16_t x
|
||||||
|
|
||||||
#define LWIP_UDP_NEW_SIG void
|
#define LWIP_UDP_NEW_SIG void
|
||||||
#define LWIP_UDP_CONNECT_SIG struct udp_pcb * pcb, const ip_addr_t * ipaddr, u16_t port
|
#define LWIP_UDP_CONNECT_SIG struct udp_pcb * pcb, const ip_addr_t * ipaddr, u16_t port
|
||||||
#define LWIP_UDP_SEND_SIG struct udp_pcb * pcb, struct pbuf * p
|
#define LWIP_UDP_SEND_SIG struct udp_pcb * pcb, struct pbuf * p
|
||||||
@@ -77,7 +76,6 @@ struct netif;
|
|||||||
#define LWIP_UDP_RECVED_SIG struct udp_pcb * pcb, u16_t len
|
#define LWIP_UDP_RECVED_SIG struct udp_pcb * pcb, u16_t len
|
||||||
#define LWIP_UDP_BIND_SIG struct udp_pcb * pcb, const ip_addr_t * ipaddr, u16_t port
|
#define LWIP_UDP_BIND_SIG struct udp_pcb * pcb, const ip_addr_t * ipaddr, u16_t port
|
||||||
#define LWIP_UDP_REMOVE_SIG struct udp_pcb *pcb
|
#define LWIP_UDP_REMOVE_SIG struct udp_pcb *pcb
|
||||||
|
|
||||||
#define LWIP_TCP_WRITE_SIG struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags
|
#define LWIP_TCP_WRITE_SIG struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags
|
||||||
#define LWIP_TCP_SENT_SIG struct tcp_pcb * pcb, err_t (* sent)(void * arg, struct tcp_pcb * tpcb, u16_t len)
|
#define LWIP_TCP_SENT_SIG struct tcp_pcb * pcb, err_t (* sent)(void * arg, struct tcp_pcb * tpcb, u16_t len)
|
||||||
#define LWIP_TCP_NEW_SIG void
|
#define LWIP_TCP_NEW_SIG void
|
||||||
@@ -96,15 +94,13 @@ struct netif;
|
|||||||
#define LWIP_TCP_LISTEN_WITH_BACKLOG_SIG struct tcp_pcb * pcb, u8_t backlog
|
#define LWIP_TCP_LISTEN_WITH_BACKLOG_SIG struct tcp_pcb * pcb, u8_t backlog
|
||||||
#define LWIP_TCP_BIND_SIG struct tcp_pcb * pcb, const ip_addr_t * ipaddr, u16_t port
|
#define LWIP_TCP_BIND_SIG struct tcp_pcb * pcb, const ip_addr_t * ipaddr, u16_t port
|
||||||
#define LWIP_TCP_INPUT_SIG struct pbuf *p, struct netif *inp
|
#define LWIP_TCP_INPUT_SIG struct pbuf *p, struct netif *inp
|
||||||
|
|
||||||
#define LWIP_ETHERNET_INPUT_SIG struct pbuf *p, struct netif *netif
|
#define LWIP_ETHERNET_INPUT_SIG struct pbuf *p, struct netif *netif
|
||||||
#define LWIP_IP_INPUT_SIG struct pbuf *p, struct netif *inp
|
#define LWIP_IP_INPUT_SIG struct pbuf *p, struct netif *inp
|
||||||
#define LWIP_NETIF_SET_DEFAULT_SIG struct netif *netif
|
#define LWIP_NETIF_SET_DEFAULT_SIG struct netif *netif
|
||||||
#define LWIP_NETIF_SET_UP_SIG struct netif *netif
|
#define LWIP_NETIF_SET_UP_SIG struct netif *netif
|
||||||
#define LWIP_NETIF_POLL_SIG struct netif *netif
|
#define LWIP_NETIF_POLL_SIG struct netif *netif
|
||||||
|
|
||||||
#define NETIF_SET_STATUS_CALLBACK struct netif *netif, netif_status_callback_fn status_callback
|
#define NETIF_SET_STATUS_CALLBACK struct netif *netif, netif_status_callback_fn status_callback
|
||||||
|
#define LWIP_TCP_SHUTDOWN_SIG struct tcp_pcb *pcb, int shut_rx, int shut_tx
|
||||||
|
|
||||||
#if defined(LIBZT_IPV4)
|
#if defined(LIBZT_IPV4)
|
||||||
extern "C" err_t etharp_output(LWIP_ETHARP_OUTPUT_SIG);
|
extern "C" err_t etharp_output(LWIP_ETHARP_OUTPUT_SIG);
|
||||||
@@ -160,11 +156,9 @@ extern "C" u16_t lwip_htons(LWIP_HTONS_SIG);
|
|||||||
extern "C" u16_t lwip_ntohs(LWIP_NTOHS_SIG);
|
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" err_t tcp_shutdown(LWIP_TCP_SHUTDOWN_SIG);
|
||||||
|
|
||||||
//extern "C" void netif_set_status_callback(NETIF_SET_STATUS_CALLBACK);
|
//extern "C" void netif_set_status_callback(NETIF_SET_STATUS_CALLBACK);
|
||||||
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
class VirtualTap;
|
class VirtualTap;
|
||||||
@@ -239,6 +233,10 @@ namespace ZeroTier {
|
|||||||
*/
|
*/
|
||||||
int lwip_Close(VirtualSocket *vs);
|
int lwip_Close(VirtualSocket *vs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts down some aspect of a VirtualSocket - Called from VirtualTap
|
||||||
|
*/
|
||||||
|
int lwip_Shutdown(VirtualSocket *vs, int how);
|
||||||
|
|
||||||
// --- Callbacks from network stack ---
|
// --- Callbacks from network stack ---
|
||||||
|
|
||||||
|
|||||||
@@ -1014,6 +1014,24 @@ namespace ZeroTier {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int picoTCP::pico_Shutdown(VirtualSocket *vs, int how)
|
||||||
|
{
|
||||||
|
int err = 0, mode = 0;
|
||||||
|
if(how == SHUT_RD) {
|
||||||
|
mode = PICO_SHUT_RD;
|
||||||
|
}
|
||||||
|
if(how == SHUT_WR) {
|
||||||
|
mode = PICO_SHUT_WR;
|
||||||
|
}
|
||||||
|
if(how == SHUT_RDWR) {
|
||||||
|
mode = PICO_SHUT_RDWR;
|
||||||
|
}
|
||||||
|
if((err = pico_socket_shutdown(vs->picosock, mode)) < 0) {
|
||||||
|
DEBUG_ERROR("error while shutting down socket, fd=%d, pico_err=%d, %s", vs->app_fd, pico_err, beautify_pico_error(pico_err));
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int picoTCP::map_pico_err_to_errno(int err)
|
int picoTCP::map_pico_err_to_errno(int err)
|
||||||
{
|
{
|
||||||
if(err == PICO_ERR_NOERR) { errno = 0; return 0; } //
|
if(err == PICO_ERR_NOERR) { errno = 0; return 0; } //
|
||||||
|
|||||||
@@ -192,6 +192,11 @@ namespace ZeroTier
|
|||||||
*/
|
*/
|
||||||
int pico_Close(VirtualSocket *vs);
|
int pico_Close(VirtualSocket *vs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts down some aspect of a VirtualSocket - Called from VirtualTap
|
||||||
|
*/
|
||||||
|
int pico_Shutdown(VirtualSocket *vs, int how);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts a pico_err to its most closely-related errno, and sets errno
|
* Converts a pico_err to its most closely-related errno, and sets errno
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1847,6 +1847,7 @@ int random_api_test()
|
|||||||
// PASSED implies we didn't segfault or hang anywhere
|
// PASSED implies we didn't segfault or hang anywhere
|
||||||
|
|
||||||
// variables which will be populated with random values
|
// variables which will be populated with random values
|
||||||
|
/*
|
||||||
int socket_family;
|
int socket_family;
|
||||||
int socket_type;
|
int socket_type;
|
||||||
int protocol;
|
int protocol;
|
||||||
@@ -1858,6 +1859,7 @@ int random_api_test()
|
|||||||
struct sockaddr_storage;
|
struct sockaddr_storage;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
struct sockaddr_in6 addr6;
|
struct sockaddr_in6 addr6;
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
int num_operations = 100;
|
int num_operations = 100;
|
||||||
|
|||||||
Reference in New Issue
Block a user