standardization pass: trim_right (trailing whitespaces)

This commit is contained in:
Joseph Henry
2017-09-13 22:41:30 -07:00
parent 3bec79314e
commit 48a07c32a1
10 changed files with 254 additions and 254 deletions

View File

@@ -46,7 +46,7 @@ namespace ZeroTier {
* create a RingBuffer with space for up to size elements. * create a RingBuffer with space for up to size elements.
*/ */
explicit RingBuffer(size_t size) explicit RingBuffer(size_t size)
: size(size), : size(size),
begin(0), begin(0),
end(0), end(0),
wrap(false) wrap(false)
@@ -156,10 +156,10 @@ namespace ZeroTier {
size_t count() { size_t count() {
if (end == begin) { if (end == begin) {
return wrap ? size : 0; return wrap ? size : 0;
} }
else if (end > begin) { else if (end > begin) {
return end - begin; return end - begin;
} }
else { else {
return size + end - begin; return size + end - begin;
} }

View File

@@ -119,13 +119,13 @@ bool ipv6_in_subnet(ZeroTier::InetAddress *subnet, ZeroTier::InetAddress *addr)
nm[0] &= ZeroTier::Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits)))); nm[0] &= ZeroTier::Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
nm[1] &= ZeroTier::Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits)))); nm[1] &= ZeroTier::Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
nm2[0] &= ZeroTier::Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits)))); nm2[0] &= ZeroTier::Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
nm2[1] &= ZeroTier::Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits)))); nm2[1] &= ZeroTier::Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm,16); memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm,16);
memcpy(reinterpret_cast<struct sockaddr_in6 *>(&b)->sin6_addr.s6_addr,nm2,16); memcpy(reinterpret_cast<struct sockaddr_in6 *>(&b)->sin6_addr.s6_addr,nm2,16);
} }
break; break;
} }
char b0[64], b1[64]; char b0[64], b1[64];
@@ -140,12 +140,12 @@ void sockaddr2inet(int socket_family, const struct sockaddr *addr, ZeroTier::Ine
char ipstr[INET6_ADDRSTRLEN]; char ipstr[INET6_ADDRSTRLEN];
memset(ipstr, 0, INET6_ADDRSTRLEN); memset(ipstr, 0, INET6_ADDRSTRLEN);
if(socket_family == AF_INET) { if(socket_family == AF_INET) {
inet_ntop(AF_INET, inet_ntop(AF_INET,
(const void *)&((struct sockaddr_in *)addr)->sin_addr.s_addr, ipstr, INET_ADDRSTRLEN); (const void *)&((struct sockaddr_in *)addr)->sin_addr.s_addr, ipstr, INET_ADDRSTRLEN);
inet->fromString(ipstr); inet->fromString(ipstr);
} }
if(socket_family == AF_INET6) { if(socket_family == AF_INET6) {
inet_ntop(AF_INET6, inet_ntop(AF_INET6,
(const void *)&((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, ipstr, INET6_ADDRSTRLEN); (const void *)&((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, ipstr, INET6_ADDRSTRLEN);
char addrstr[64]; char addrstr[64];
sprintf(addrstr, "%s", ipstr); sprintf(addrstr, "%s", ipstr);
@@ -157,4 +157,4 @@ void mac2str(char *macbuf, int len, unsigned char* addr)
{ {
snprintf(macbuf, len, "%02x:%02x:%02x:%02x:%02x:%02x", snprintf(macbuf, len, "%02x:%02x:%02x:%02x:%02x:%02x",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
} }

View File

@@ -55,7 +55,7 @@ void mac2str(char *macbuf, int len, unsigned char* addr);
(ipaddr)->addr[3] = ZeroTier::Utils::hton(((g & 0xffff) << 16) | (h & 0xffff)); } while(0) (ipaddr)->addr[3] = ZeroTier::Utils::hton(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
/* /*
* Convert from standard IPV6 address structure to an lwIP native structure * Convert from standard IPV6 address structure to an lwIP native structure
*/ */
inline void in6_to_ip6(ip6_addr_t *ba, struct sockaddr_in6 *in6) inline void in6_to_ip6(ip6_addr_t *ba, struct sockaddr_in6 *in6)
{ {
@@ -97,4 +97,4 @@ inline ip_addr_t convert_ip(struct sockaddr_in * addr)
#endif // STACK_LWIP && LIBZT_IPV4 #endif // STACK_LWIP && LIBZT_IPV4
#endif // UTILITIES_HPP #endif // UTILITIES_HPP

View File

@@ -46,14 +46,14 @@
#include "RingBuffer.hpp" #include "RingBuffer.hpp"
namespace ZeroTier { namespace ZeroTier {
class VirtualTap; class VirtualTap;
/* /*
* Something analogous to a socket. This is a common object used by the * Something analogous to a socket. This is a common object used by the
* libzt API, VirtualTap, and the userspace network stack driver implementations. * libzt API, VirtualTap, and the userspace network stack driver implementations.
* In some situations the word 'Connection' would capture the meaning and * In some situations the word 'Connection' would capture the meaning and
* function of this object, however I'd like to discourage this since this * function of this object, however I'd like to discourage this since this
* object also handles non-connection-based traffic as well. * object also handles non-connection-based traffic as well.
*/ */
struct VirtualSocket struct VirtualSocket
@@ -61,9 +61,9 @@ namespace ZeroTier {
RingBuffer<unsigned char> *TXbuf; RingBuffer<unsigned char> *TXbuf;
RingBuffer<unsigned char> *RXbuf; RingBuffer<unsigned char> *RXbuf;
Mutex _tx_m, _rx_m; Mutex _tx_m, _rx_m;
PhySocket *sock = NULL; PhySocket *sock = NULL;
#if defined(STACK_PICO) #if defined(STACK_PICO)
struct pico_socket *picosock = NULL; struct pico_socket *picosock = NULL;
#endif #endif
#if defined(STACK_LWIP) #if defined(STACK_LWIP)
@@ -121,9 +121,9 @@ namespace ZeroTier {
if (fcntl(sdk_fd, F_SETFL, O_NONBLOCK) < 0) { if (fcntl(sdk_fd, F_SETFL, O_NONBLOCK) < 0) {
DEBUG_ERROR("error while setting virtual socket to NONBLOCKING. exiting", errno); DEBUG_ERROR("error while setting virtual socket to NONBLOCKING. exiting", errno);
exit(0); exit(0);
} }
} }
~VirtualSocket() { ~VirtualSocket() {
close(app_fd); close(app_fd);
close(sdk_fd); close(sdk_fd);
delete TXbuf; delete TXbuf;
@@ -142,4 +142,4 @@ namespace ZeroTier {
VirtualBindingPair(VirtualTap *_tap, VirtualSocket *_vs) : tap(_tap), vs(_vs) {} VirtualBindingPair(VirtualTap *_tap, VirtualSocket *_vs) : tap(_tap), vs(_vs) {}
}; };
} }
#endif #endif

View File

@@ -107,7 +107,7 @@ namespace ZeroTier {
// set virtual tap interface name (abbreviated) // set virtual tap interface name (abbreviated)
memset(vtap_abbr_name, 0, sizeof(vtap_abbr_name)); memset(vtap_abbr_name, 0, sizeof(vtap_abbr_name));
snprintf(vtap_abbr_name, sizeof(vtap_abbr_name), "libzt%d", devno); snprintf(vtap_abbr_name, sizeof(vtap_abbr_name), "libzt%d", devno);
// start vtap thread and stack I/O loops // start vtap thread and stack I/O loops
_thread = Thread::start(this); _thread = Thread::start(this);
} }
@@ -202,7 +202,7 @@ namespace ZeroTier {
#if defined(STACK_LWIP) #if defined(STACK_LWIP)
if(lwipstack) if(lwipstack)
lwipstack->lwip_eth_rx(this,from,to,etherType,data,len); lwipstack->lwip_eth_rx(this,from,to,etherType,data,len);
#endif #endif
} }
std::string VirtualTap::deviceName() const std::string VirtualTap::deviceName() const
@@ -220,11 +220,11 @@ namespace ZeroTier {
return std::string(id); return std::string(id);
} }
else { else {
return std::string("----------"); return std::string("----------");
} }
} }
void VirtualTap::setFriendlyName(const char *friendlyName) void VirtualTap::setFriendlyName(const char *friendlyName)
{ {
DEBUG_INFO("%s", friendlyName); DEBUG_INFO("%s", friendlyName);
// Someday // Someday
@@ -242,7 +242,7 @@ namespace ZeroTier {
std::sort(newGroups.begin(),newGroups.end()); std::sort(newGroups.begin(),newGroups.end());
std::unique(newGroups.begin(),newGroups.end()); std::unique(newGroups.begin(),newGroups.end());
for(std::vector<MulticastGroup>::iterator m(newGroups.begin());m!=newGroups.end();++m) { for(std::vector<MulticastGroup>::iterator m(newGroups.begin());m!=newGroups.end();++m) {
if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m))
added.push_back(*m); added.push_back(*m);
@@ -282,7 +282,7 @@ namespace ZeroTier {
#endif #endif
} }
void VirtualTap::phyOnUnixClose(PhySocket *sock,void **uptr) void VirtualTap::phyOnUnixClose(PhySocket *sock,void **uptr)
{ {
if(sock) { if(sock) {
VirtualSocket *vs = (VirtualSocket*)uptr; VirtualSocket *vs = (VirtualSocket*)uptr;
@@ -290,7 +290,7 @@ namespace ZeroTier {
Close(vs); Close(vs);
} }
} }
void VirtualTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len) void VirtualTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len)
{ {
//DEBUG_ATTN("sock->fd=%d", _phy.getDescriptor(sock)); //DEBUG_ATTN("sock->fd=%d", _phy.getDescriptor(sock));
@@ -347,16 +347,16 @@ namespace ZeroTier {
return false; return false;
} }
void VirtualTap::addVirtualSocket(VirtualSocket *vs) void VirtualTap::addVirtualSocket(VirtualSocket *vs)
{ {
Mutex::Lock _l(_tcpconns_m); Mutex::Lock _l(_tcpconns_m);
_VirtualSockets.push_back(vs); _VirtualSockets.push_back(vs);
} }
void VirtualTap::removeVirtualSocket(VirtualSocket *vs) void VirtualTap::removeVirtualSocket(VirtualSocket *vs)
{ {
Mutex::Lock _l(_tcpconns_m); Mutex::Lock _l(_tcpconns_m);
for(int i=0; i<_VirtualSockets.size(); i++) { for(int i=0; i<_VirtualSockets.size(); i++) {
if(vs == _VirtualSockets[i]) { if(vs == _VirtualSockets[i]) {
_VirtualSockets.erase(_VirtualSockets.begin() + i); _VirtualSockets.erase(_VirtualSockets.begin() + i);
//DEBUG_EXTRA("Removed vs=%p from vt=%p", vs, this); //DEBUG_EXTRA("Removed vs=%p from vt=%p", vs, this);
@@ -429,7 +429,7 @@ namespace ZeroTier {
Mutex::Lock _l(_tcpconns_m); Mutex::Lock _l(_tcpconns_m);
return lwipstack->lwip_Bind(this, vs, addr, addrlen); return lwipstack->lwip_Bind(this, vs, addr, addrlen);
} }
#endif #endif
return -1; return -1;
} }
@@ -458,7 +458,7 @@ namespace ZeroTier {
#endif #endif
} }
// Accept a VirtualSocket // Accept a VirtualSocket
VirtualSocket* VirtualTap::Accept(VirtualSocket *vs) { VirtualSocket* VirtualTap::Accept(VirtualSocket *vs) {
#if defined(NO_STACK) #if defined(NO_STACK)
return NULL; return NULL;
@@ -527,7 +527,7 @@ namespace ZeroTier {
// Send data to a specified host // Send data to a specified host
int VirtualTap::SendTo(VirtualSocket *vs, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen) int VirtualTap::SendTo(VirtualSocket *vs, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen)
{ {
/* FIXME: There is a call to *_Connect for each send, we should probably figure out a better way to do this, /* FIXME: There is a call to *_Connect for each send, we should probably figure out a better way to do this,
possibly consult the stack for "connection" state */ possibly consult the stack for "connection" state */
// TODO: flags // TODO: flags
@@ -586,7 +586,7 @@ namespace ZeroTier {
int VirtualTap::Shutdown(VirtualSocket *vs, int how) int VirtualTap::Shutdown(VirtualSocket *vs, int how)
{ {
int err = 0; int err = 0;
#if defined(STACK_PICO) #if defined(STACK_PICO)
if(picostack) { if(picostack) {
err = picostack->pico_Shutdown(vs, how); err = picostack->pico_Shutdown(vs, how);
} }
@@ -604,8 +604,8 @@ namespace ZeroTier {
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) {
// update managed routes (add/del from network stacks) // update managed routes (add/del from network stacks)
ZeroTier::OneService *service = ((ZeroTier::OneService *)zt1ServiceRef); ZeroTier::OneService *service = ((ZeroTier::OneService *)zt1ServiceRef);
if(service) { if(service) {
std::vector<ZT_VirtualNetworkRoute> *managed_routes = service->getRoutes(this->_nwid); std::vector<ZT_VirtualNetworkRoute> *managed_routes = service->getRoutes(this->_nwid);
ZeroTier::InetAddress target_addr; ZeroTier::InetAddress target_addr;
@@ -634,8 +634,8 @@ namespace ZeroTier {
if(!found) { if(!found) {
if(!via_addr.ipsEqual(null_addr)) { if(!via_addr.ipsEqual(null_addr)) {
DEBUG_INFO("adding route <target=%s, nm=%s, via=%s>", target_addr.toString(ipbuf), nm.toString(ipbuf2), via_addr.toString(ipbuf3)); DEBUG_INFO("adding route <target=%s, nm=%s, via=%s>", target_addr.toString(ipbuf), nm.toString(ipbuf2), via_addr.toString(ipbuf3));
routes.push_back(std::pair<ZeroTier::InetAddress,ZeroTier::InetAddress>(target_addr, nm)); routes.push_back(std::pair<ZeroTier::InetAddress,ZeroTier::InetAddress>(target_addr, nm));
routeAdd(target_addr, nm, via_addr); routeAdd(target_addr, nm, via_addr);
} }
} }
} }
@@ -667,7 +667,7 @@ namespace ZeroTier {
/* Not used in this implementation */ /* Not used in this implementation */
/****************************************************************************/ /****************************************************************************/
void VirtualTap::phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *local_address, void VirtualTap::phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *local_address,
const struct sockaddr *from,void *data,unsigned long len) {} const struct sockaddr *from,void *data,unsigned long len) {}
void VirtualTap::phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) {} void VirtualTap::phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) {}
void VirtualTap::phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN, void VirtualTap::phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,

View File

@@ -62,7 +62,7 @@
#endif #endif
namespace ZeroTier { namespace ZeroTier {
/* /*
* Socket Tap -- emulates an Ethernet tap device * Socket Tap -- emulates an Ethernet tap device
*/ */
@@ -86,60 +86,60 @@ namespace ZeroTier {
void setEnabled(bool en); void setEnabled(bool en);
bool enabled() const; bool enabled() const;
/* /*
* Registers a device with the given address * Registers a device with the given address
*/ */
bool registerIpWithStack(const InetAddress &ip); bool registerIpWithStack(const InetAddress &ip);
/* /*
* Adds an address to the userspace stack interface associated with this VirtualTap * Adds an address to the userspace stack interface associated with this VirtualTap
* - Starts VirtualTap main thread ONLY if successful * - Starts VirtualTap main thread ONLY if successful
*/ */
bool addIp(const InetAddress &ip); bool addIp(const InetAddress &ip);
/* /*
* Removes an address from the userspace stack interface associated with this VirtualTap * Removes an address from the userspace stack interface associated with this VirtualTap
*/ */
bool removeIp(const InetAddress &ip); bool removeIp(const InetAddress &ip);
/* /*
* Presents data to the userspace stack * Presents data to the userspace stack
*/ */
void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data, void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,
unsigned int len); unsigned int len);
/* /*
* Get VirtualTap device name (e.g. 'libzt4-17d72843bc2c5760') * Get VirtualTap device name (e.g. 'libzt4-17d72843bc2c5760')
*/ */
std::string deviceName() const; std::string deviceName() const;
/* /*
* Get Node ID (ZT address) * Get Node ID (ZT address)
*/ */
std::string nodeId() const; std::string nodeId() const;
/* /*
* Set friendly name * Set friendly name
*/ */
void setFriendlyName(const char *friendlyName); void setFriendlyName(const char *friendlyName);
/* /*
* Scan multicast groups * Scan multicast groups
*/ */
void scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed); void scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed);
/* /*
* Set MTU * Set MTU
*/ */
void setMtu(unsigned int mtu); void setMtu(unsigned int mtu);
/* /*
* Calls main network stack loops * Calls main network stack loops
*/ */
void threadMain() void threadMain()
throw(); throw();
/* /*
* For moving data onto the ZeroTier virtual wire * For moving data onto the ZeroTier virtual wire
*/ */
void (*_handler)(void *, void *, uint64_t, const MAC &, const MAC &, unsigned int, unsigned int, void (*_handler)(void *, void *, uint64_t, const MAC &, const MAC &, unsigned int, unsigned int,
@@ -149,13 +149,13 @@ namespace ZeroTier {
* Signals us to close the TcpVirtualSocket associated with this PhySocket * Signals us to close the TcpVirtualSocket associated with this PhySocket
*/ */
void phyOnUnixClose(PhySocket *sock, void **uptr); void phyOnUnixClose(PhySocket *sock, void **uptr);
/* /*
* Notifies us that there is data to be read from an application's socket * Notifies us that there is data to be read from an application's socket
*/ */
void phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len); void phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len);
/* /*
* Notifies us that we can write to an application's socket * Notifies us that we can write to an application's socket
*/ */
void phyOnUnixWritable(PhySocket *sock, void **uptr, bool stack_invoked); void phyOnUnixWritable(PhySocket *sock, void **uptr, bool stack_invoked);
@@ -164,7 +164,7 @@ namespace ZeroTier {
* Adds a route to the virtual tap * Adds a route to the virtual tap
*/ */
bool routeAdd(const InetAddress &addr, const InetAddress &nm, const InetAddress &gw); bool routeAdd(const InetAddress &addr, const InetAddress &nm, const InetAddress &gw);
/* /*
* Deletes a route from the virtual tap * Deletes a route from the virtual tap
*/ */
@@ -173,7 +173,7 @@ namespace ZeroTier {
/* /*
* Assign a VirtualSocket to the VirtualTap * Assign a VirtualSocket to the VirtualTap
*/ */
void addVirtualSocket(VirtualSocket *vs); void addVirtualSocket(VirtualSocket *vs);
/* /*
* Remove a VirtualSocket from the VirtualTap * Remove a VirtualSocket from the VirtualTap
@@ -229,7 +229,7 @@ namespace ZeroTier {
std::string _homePath; std::string _homePath;
void *_arg; void *_arg;
volatile bool _enabled; volatile bool _enabled;
volatile bool _run; volatile bool _run;
MAC _mac; MAC _mac;
unsigned int _mtu; unsigned int _mtu;
uint64_t _nwid; uint64_t _nwid;
@@ -246,7 +246,7 @@ namespace ZeroTier {
Mutex _ips_m, _tcpconns_m, _rx_buf_m, _close_m; Mutex _ips_m, _tcpconns_m, _rx_buf_m, _close_m;
/* /*
* Timestamp of last run of housekeeping * Timestamp of last run of housekeeping
* SEE: ZT_HOUSEKEEPING_INTERVAL in libzt.h * SEE: ZT_HOUSEKEEPING_INTERVAL in libzt.h
*/ */
std::time_t last_housekeeping_ts; std::time_t last_housekeeping_ts;
@@ -256,37 +256,37 @@ namespace ZeroTier {
/* where one would put logic to select between different stacks */ /* where one would put logic to select between different stacks */
/****************************************************************************/ /****************************************************************************/
/* /*
* Connect to a remote host via the userspace stack interface associated with this VirtualTap * Connect to a remote host via the userspace stack interface associated with this VirtualTap
*/ */
int Connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen); int Connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen);
/* /*
* Bind to the userspace stack interface associated with this VirtualTap * Bind to the userspace stack interface associated with this VirtualTap
*/ */
int Bind(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen); int Bind(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen);
/* /*
* Listen for a VirtualSocket * Listen for a VirtualSocket
*/ */
int Listen(VirtualSocket *vs, int backlog); int Listen(VirtualSocket *vs, int backlog);
/* /*
* Accepts an incoming VirtualSocket * Accepts an incoming VirtualSocket
*/ */
VirtualSocket* Accept(VirtualSocket *vs); VirtualSocket* Accept(VirtualSocket *vs);
/* /*
* Move data from RX buffer to application's "socket" * Move data from RX buffer to application's "socket"
*/ */
int Read(PhySocket *sock,void **uptr,bool stack_invoked); int Read(PhySocket *sock,void **uptr,bool stack_invoked);
/* /*
* Move data from application's "socket" into network stack * Move data from application's "socket" into network stack
*/ */
int Write(VirtualSocket *vs, void *data, ssize_t len); int Write(VirtualSocket *vs, void *data, ssize_t len);
/* /*
* Send data to specified host * Send data to specified host
*/ */
int SendTo(VirtualSocket *vs, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen); int SendTo(VirtualSocket *vs, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen);
@@ -306,21 +306,21 @@ namespace ZeroTier {
*/ */
void Housekeeping(); void Housekeeping();
/* /*
* Return the address that the socket is bound to * Return the address that the socket is bound to
*/ */
void handleGetsockname(PhySocket *sock, PhySocket *rpcsock, void **uptr, struct getsockname_st *getsockname_rpc); void handleGetsockname(PhySocket *sock, PhySocket *rpcsock, void **uptr, struct getsockname_st *getsockname_rpc);
/* /*
* Return the address of the peer connected to this socket * Return the address of the peer connected to this socket
*/ */
void handleGetpeername(PhySocket *sock, PhySocket *rpcsock, void **uptr, struct getsockname_st *getsockname_rpc); void handleGetpeername(PhySocket *sock, PhySocket *rpcsock, void **uptr, struct getsockname_st *getsockname_rpc);
/****************************************************************************/ /****************************************************************************/
/* Not used in this implementation */ /* Not used in this implementation */
/****************************************************************************/ /****************************************************************************/
void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *local_address, void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *local_address,
const struct sockaddr *from,void *data,unsigned long len); const struct sockaddr *from,void *data,unsigned long len);
void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success); void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success);
void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN, void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,

View File

@@ -156,7 +156,7 @@ void zts_simple_start(const char *path, const char *nwid)
} }
void zts_stop() { void zts_stop() {
if(ZeroTier::zt1Service) { if(ZeroTier::zt1Service) {
ZeroTier::zt1Service->terminate(); ZeroTier::zt1Service->terminate();
dismantleTaps(); dismantleTaps();
} }
@@ -183,7 +183,7 @@ void zts_join(const char * nwid) {
} }
} }
void zts_join_soft(const char * filepath, const char * nwid) { void zts_join_soft(const char * filepath, const char * nwid) {
std::string net_dir = std::string(filepath) + "/networks.d/"; std::string net_dir = std::string(filepath) + "/networks.d/";
std::string confFile = net_dir + std::string(nwid) + ".conf"; std::string confFile = net_dir + std::string(nwid) + ".conf";
if(!ZeroTier::OSUtils::mkdir(net_dir)) { if(!ZeroTier::OSUtils::mkdir(net_dir)) {
@@ -198,17 +198,17 @@ void zts_join_soft(const char * filepath, const char * nwid) {
} }
} }
void zts_leave(const char * nwid) { void zts_leave(const char * nwid) {
if(ZeroTier::zt1Service) if(ZeroTier::zt1Service)
ZeroTier::zt1Service->leave(nwid); ZeroTier::zt1Service->leave(nwid);
} }
void zts_leave_soft(const char * filepath, const char * nwid) { void zts_leave_soft(const char * filepath, const char * nwid) {
std::string net_dir = std::string(filepath) + "/networks.d/"; std::string net_dir = std::string(filepath) + "/networks.d/";
ZeroTier::OSUtils::rm((net_dir + nwid + ".conf").c_str()); ZeroTier::OSUtils::rm((net_dir + nwid + ".conf").c_str());
} }
void zts_get_homepath(char *homePath, int len) { void zts_get_homepath(char *homePath, int len) {
if(ZeroTier::homeDir.length()) { if(ZeroTier::homeDir.length()) {
memset(homePath, 0, len); memset(homePath, 0, len);
memcpy(homePath, ZeroTier::homeDir.c_str(), len < ZeroTier::homeDir.length() ? len : ZeroTier::homeDir.length()); memcpy(homePath, ZeroTier::homeDir.c_str(), len < ZeroTier::homeDir.length() ? len : ZeroTier::homeDir.length());
@@ -225,7 +225,7 @@ void zts_lib_version(char *ver) {
sprintf(ver, "%d.%d.%d", ZT_LIB_VERSION_MAJOR, ZT_LIB_VERSION_MINOR, ZT_LIB_VERSION_REVISION); sprintf(ver, "%d.%d.%d", ZT_LIB_VERSION_MAJOR, ZT_LIB_VERSION_MINOR, ZT_LIB_VERSION_REVISION);
} }
int zts_get_device_id(char *devID) { int zts_get_device_id(char *devID) {
if(ZeroTier::zt1Service) { if(ZeroTier::zt1Service) {
char id[ZT_ID_LEN]; char id[ZT_ID_LEN];
sprintf(id, "%lx",ZeroTier::zt1Service->getNode()->address()); sprintf(id, "%lx",ZeroTier::zt1Service->getNode()->address());
@@ -247,8 +247,8 @@ int zts_get_device_id(char *devID) {
return -1; return -1;
} }
int zts_running() { int zts_running() {
return !ZeroTier::zt1Service ? false : ZeroTier::zt1Service->isRunning(); return !ZeroTier::zt1Service ? false : ZeroTier::zt1Service->isRunning();
} }
int zts_has_ipv4_address(const char *nwid) int zts_has_ipv4_address(const char *nwid)
@@ -277,14 +277,14 @@ void zts_get_ipv4_address(const char *nwid, char *addrstr, const int addrlen)
if(ZeroTier::zt1Service) { if(ZeroTier::zt1Service) {
uint64_t nwid_int = strtoull(nwid, NULL, 16); uint64_t nwid_int = strtoull(nwid, NULL, 16);
ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int); ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int);
if(tap && tap->_ips.size()){ if(tap && tap->_ips.size()){
for(int i=0; i<tap->_ips.size(); i++) { for(int i=0; i<tap->_ips.size(); i++) {
if(tap->_ips[i].isV4()) { if(tap->_ips[i].isV4()) {
char ipbuf[INET_ADDRSTRLEN]; char ipbuf[INET_ADDRSTRLEN];
std::string addr = tap->_ips[i].toString(ipbuf); std::string addr = tap->_ips[i].toString(ipbuf);
int len = addrlen < addr.length() ? addrlen : addr.length(); int len = addrlen < addr.length() ? addrlen : addr.length();
memset(addrstr, 0, len); memset(addrstr, 0, len);
memcpy(addrstr, addr.c_str(), len); memcpy(addrstr, addr.c_str(), len);
return; return;
} }
} }
@@ -299,14 +299,14 @@ void zts_get_ipv6_address(const char *nwid, char *addrstr, const int addrlen)
if(ZeroTier::zt1Service) { if(ZeroTier::zt1Service) {
uint64_t nwid_int = strtoull(nwid, NULL, 16); uint64_t nwid_int = strtoull(nwid, NULL, 16);
ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int); ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int);
if(tap && tap->_ips.size()){ if(tap && tap->_ips.size()){
for(int i=0; i<tap->_ips.size(); i++) { for(int i=0; i<tap->_ips.size(); i++) {
if(tap->_ips[i].isV6()) { if(tap->_ips[i].isV6()) {
char ipbuf[INET6_ADDRSTRLEN]; char ipbuf[INET6_ADDRSTRLEN];
std::string addr = tap->_ips[i].toString(ipbuf); std::string addr = tap->_ips[i].toString(ipbuf);
int len = addrlen < addr.length() ? addrlen : addr.length(); int len = addrlen < addr.length() ? addrlen : addr.length();
memset(addrstr, 0, len); memset(addrstr, 0, len);
memcpy(addrstr, addr.c_str(), len); memcpy(addrstr, addr.c_str(), len);
return; return;
} }
} }
@@ -368,7 +368,7 @@ void zts_disable_http_control_plane()
/* - This section of the API is used to implement the general socket */ /* - This section of the API is used to implement the general socket */
/* controls. Basically this is designed to handle socket provisioning */ /* controls. Basically this is designed to handle socket provisioning */
/* requests when no VirtualTap is yet initialized, and as a way to */ /* requests when no VirtualTap is yet initialized, and as a way to */
/* determine which VirtualTap is to be used for a particular connect() or */ /* determine which VirtualTap is to be used for a particular connect() or */
/* bind() call. This enables multi-network support */ /* bind() call. This enables multi-network support */
/****************************************************************************/ /****************************************************************************/
@@ -440,7 +440,7 @@ int zts_socket(ZT_SOCKET_SIG) {
vs->pcb = pcb; vs->pcb = pcb;
add_unassigned_virtual_socket(vs->app_fd, vs); add_unassigned_virtual_socket(vs->app_fd, vs);
// return one end of the socketpair for the app to use // return one end of the socketpair for the app to use
err = vs->app_fd; err = vs->app_fd;
} }
else { else {
DEBUG_ERROR("failed to create lwip pcb"); DEBUG_ERROR("failed to create lwip pcb");
@@ -465,7 +465,7 @@ Darwin:
[ ] [ECONNREFUSED] The attempt to connect was ignored (because the target is not listening for VirtualSockets) or explicitly rejected. [ ] [ECONNREFUSED] The attempt to connect was ignored (because the target is not listening for VirtualSockets) or explicitly rejected.
[ ] [EFAULT] The address parameter specifies an area outside the process address space. [ ] [EFAULT] The address parameter specifies an area outside the process address space.
[ ] [EHOSTUNREACH] The target host cannot be reached (e.g., down, disconnected). [ ] [EHOSTUNREACH] The target host cannot be reached (e.g., down, disconnected).
[--] [EINPROGRESS] The socket is non-blocking and the VirtualSocket cannot be completed immediately. [--] [EINPROGRESS] The socket is non-blocking and the VirtualSocket cannot be completed immediately.
It is possible to select(2) for completion by selecting the socket for writing. It is possible to select(2) for completion by selecting the socket for writing.
[NA] [EINTR] Its execution was interrupted by a signal. [NA] [EINTR] Its execution was interrupted by a signal.
[ ] [EINVAL] An invalid argument was detected (e.g., address_len is not valid for the address family, the specified address family is invalid). [ ] [EINVAL] An invalid argument was detected (e.g., address_len is not valid for the address family, the specified address family is invalid).
@@ -481,27 +481,27 @@ Darwin:
Linux: Linux:
[ ] [EACCES] For UNIX domain sockets, which are identified by pathname: Write permission is denied on the socket file, [ ] [EACCES] For UNIX domain sockets, which are identified by pathname: Write permission is denied on the socket file,
or search permission is denied for one of the directories in the path prefix. (See also path_resolution(7).) or search permission is denied for one of the directories in the path prefix. (See also path_resolution(7).)
[ ] [EACCES, EPERM] The user tried to connect to a broadcast address without having the socket broadcast flag enabled or the [ ] [EACCES, EPERM] The user tried to connect to a broadcast address without having the socket broadcast flag enabled or the
VirtualSocket request failed because of a local firewall rule. VirtualSocket request failed because of a local firewall rule.
[ ] [EADDRINUSE] Local address is already in use. [ ] [EADDRINUSE] Local address is already in use.
[ ] [EAFNOSUPPORT] The passed address didn't have the correct address family in its sa_family field. [ ] [EAFNOSUPPORT] The passed address didn't have the correct address family in its sa_family field.
[ ] [EAGAIN] No more free local ports or insufficient entries in the routing cache. For AF_INET see the description [ ] [EAGAIN] No more free local ports or insufficient entries in the routing cache. For AF_INET see the description
of /proc/sys/net/ipv4/ip_local_port_range ip(7) for information on how to increase the number of local ports. of /proc/sys/net/ipv4/ip_local_port_range ip(7) for information on how to increase the number of local ports.
[ ] [EALREADY] The socket is nonblocking and a previous VirtualSocket attempt has not yet been completed. [ ] [EALREADY] The socket is nonblocking and a previous VirtualSocket attempt has not yet been completed.
[ ] [EBADF] The file descriptor is not a valid index in the descriptor table. [ ] [EBADF] The file descriptor is not a valid index in the descriptor table.
[ ] [ECONNREFUSED] No-one listening on the remote address. [ ] [ECONNREFUSED] No-one listening on the remote address.
[ ] [EFAULT] The socket structure address is outside the user's address space. [ ] [EFAULT] The socket structure address is outside the user's address space.
[ ] [EINPROGRESS] The socket is nonblocking and the VirtualSocket cannot be completed immediately. It is possible to select(2) or [ ] [EINPROGRESS] The socket is nonblocking and the VirtualSocket cannot be completed immediately. It is possible to select(2) or
poll(2) for completion by selecting the socket for writing. After select(2) indicates writability, use getsockopt(2) poll(2) for completion by selecting the socket for writing. After select(2) indicates writability, use getsockopt(2)
to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed successfully (SO_ERROR is zero) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed successfully (SO_ERROR is zero)
or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure). or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure).
[ ] [EINTR] The system call was interrupted by a signal that was caught; see signal(7). [ ] [EINTR] The system call was interrupted by a signal that was caught; see signal(7).
[ ] [EISCONN] The socket is already connected. [ ] [EISCONN] The socket is already connected.
[ ] [ENETUNREACH] Network is unreachable. [ ] [ENETUNREACH] Network is unreachable.
[ ] [ENOTSOCK] The file descriptor is not associated with a socket. [ ] [ENOTSOCK] The file descriptor is not associated with a socket.
[ ] [ETIMEDOUT] Timeout while attempting VirtualSocket. The server may be too busy to accept new VirtualSockets. Note that for [ ] [ETIMEDOUT] Timeout while attempting VirtualSocket. The server may be too busy to accept new VirtualSockets. Note that for
IP sockets the timeout may be very long when syncookies are enabled on the server. IP sockets the timeout may be very long when syncookies are enabled on the server.
*/ */
@@ -534,8 +534,8 @@ int zts_connect(ZT_CONNECT_SIG) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
// TODO: Handle bad address lengths, right now this call will still // TODO: Handle bad address lengths, right now this call will still
// succeed with a complete connect despite a bad address length. // succeed with a complete connect despite a bad address length.
// DEBUG_EXTRA("fd = %d, %s : %d", fd, ipstr, ntohs(port)); // DEBUG_EXTRA("fd = %d, %s : %d", fd, ipstr, ntohs(port));
ZeroTier::InetAddress inet; ZeroTier::InetAddress inet;
@@ -549,7 +549,7 @@ int zts_connect(ZT_CONNECT_SIG) {
#if defined(STACK_PICO) #if defined(STACK_PICO)
// pointer to virtual tap we use in callbacks from the stack // pointer to virtual tap we use in callbacks from the stack
vs->picosock->priv = new ZeroTier::VirtualBindingPair(tap, vs); vs->picosock->priv = new ZeroTier::VirtualBindingPair(tap, vs);
#endif #endif
#if defined(STACK_LWIP) #if defined(STACK_LWIP)
#endif #endif
@@ -560,9 +560,9 @@ int zts_connect(ZT_CONNECT_SIG) {
return -1; return -1;
} }
// assign this VirtualSocket to the tap we decided on // assign this VirtualSocket to the tap we decided on
tap->_VirtualSockets.push_back(vs); tap->_VirtualSockets.push_back(vs);
vs->tap = tap; vs->tap = tap;
vs->sock = tap->_phy.wrapSocket(vs->sdk_fd, vs); vs->sock = tap->_phy.wrapSocket(vs->sdk_fd, vs);
// TODO: Consolidate these calls // TODO: Consolidate these calls
del_unassigned_virtual_socket(fd); del_unassigned_virtual_socket(fd);
@@ -575,7 +575,7 @@ int zts_connect(ZT_CONNECT_SIG) {
// NOTE: pico_socket_connect() will return 0 if no error happens immediately, but that doesn't indicate // NOTE: pico_socket_connect() will return 0 if no error happens immediately, but that doesn't indicate
// the connection was completed, for that we must wait for a callback from the stack. During that // the connection was completed, for that we must wait for a callback from the stack. During that
// callback we will place the VirtualSocket in a ZT_SOCK_STATE_UNHANDLED_CONNECTED state to signal // callback we will place the VirtualSocket in a ZT_SOCK_STATE_UNHANDLED_CONNECTED state to signal
// to the multiplexer logic that this connection is complete and a success value can be sent to the // to the multiplexer logic that this connection is complete and a success value can be sent to the
// user application // user application
@@ -584,7 +584,7 @@ int zts_connect(ZT_CONNECT_SIG) {
DEBUG_ERROR("fcntl error, err=%s, errno=%d", f_err, errno); DEBUG_ERROR("fcntl error, err=%s, errno=%d", f_err, errno);
// errno will be set by fcntl // errno will be set by fcntl
return -1; return -1;
} }
blocking = !(f_err & O_NONBLOCK); blocking = !(f_err & O_NONBLOCK);
if(!blocking) { if(!blocking) {
errno = EINPROGRESS; // can't connect immediately errno = EINPROGRESS; // can't connect immediately
@@ -601,7 +601,7 @@ int zts_connect(ZT_CONNECT_SIG) {
for(int i=0; i<tap->_VirtualSockets.size(); i++) for(int i=0; i<tap->_VirtualSockets.size(); i++)
{ {
#if defined(STACK_PICO) #if defined(STACK_PICO)
if(tap->_VirtualSockets[i]->state == PICO_ERR_ECONNRESET) { if(tap->_VirtualSockets[i]->state == PICO_ERR_ECONNRESET) {
errno = ECONNRESET; errno = ECONNRESET;
DEBUG_ERROR("ECONNRESET"); DEBUG_ERROR("ECONNRESET");
err = -1; err = -1;
@@ -645,7 +645,7 @@ int zts_bind(ZT_BIND_SIG) {
return -1; return -1;
} }
if(!ZeroTier::zt1Service) { if(!ZeroTier::zt1Service) {
DEBUG_ERROR("service not started. call zts_start(path) first"); DEBUG_ERROR("service not started. call zts_start(path) first");
errno = EBADF; errno = EBADF;
return -1; return -1;
} }
@@ -655,10 +655,10 @@ int zts_bind(ZT_BIND_SIG) {
errno = ENOTSOCK; errno = ENOTSOCK;
return -1; return -1;
} }
// detect local interface binds // detect local interface binds
ZeroTier::VirtualTap *tap = NULL; ZeroTier::VirtualTap *tap = NULL;
if(vs->socket_family == AF_INET) { if(vs->socket_family == AF_INET) {
struct sockaddr_in *in4 = (struct sockaddr_in *)addr; struct sockaddr_in *in4 = (struct sockaddr_in *)addr;
if(in4->sin_addr.s_addr == INADDR_ANY) { if(in4->sin_addr.s_addr == INADDR_ANY) {
@@ -695,7 +695,7 @@ int zts_bind(ZT_BIND_SIG) {
errno = ENETUNREACH; errno = ENETUNREACH;
return -1; return -1;
} }
#if defined(STACK_PICO) #if defined(STACK_PICO)
// used in callbacks from network stack // used in callbacks from network stack
vs->picosock->priv = new ZeroTier::VirtualBindingPair(tap, vs); vs->picosock->priv = new ZeroTier::VirtualBindingPair(tap, vs);
#endif #endif
@@ -791,7 +791,7 @@ int zts_accept(ZT_ACCEPT_SIG) {
errno = EMFILE; errno = EMFILE;
return -1; return -1;
} }
std::pair<ZeroTier::VirtualSocket*, ZeroTier::VirtualTap*> *p = get_assigned_virtual_pair(fd); std::pair<ZeroTier::VirtualSocket*, ZeroTier::VirtualTap*> *p = get_assigned_virtual_pair(fd);
if(!p) { if(!p) {
DEBUG_ERROR("unable to locate VirtualSocket pair (did you zts_bind())?"); DEBUG_ERROR("unable to locate VirtualSocket pair (did you zts_bind())?");
errno = EBADF; errno = EBADF;
@@ -806,7 +806,7 @@ int zts_accept(ZT_ACCEPT_SIG) {
if ((f_err = fcntl(fd, F_GETFL, 0)) < 0) { if ((f_err = fcntl(fd, F_GETFL, 0)) < 0) {
DEBUG_ERROR("fcntl error, err = %s, errno = %d", f_err, errno); DEBUG_ERROR("fcntl error, err = %s, errno = %d", f_err, errno);
err = -1; err = -1;
} }
else { else {
blocking = !(f_err & O_NONBLOCK); blocking = !(f_err & O_NONBLOCK);
} }
@@ -1104,7 +1104,7 @@ int zts_close(ZT_CLOSE_SIG)
if ((f_err = fcntl(fd, F_GETFL, 0)) < 0) { if ((f_err = fcntl(fd, F_GETFL, 0)) < 0) {
DEBUG_ERROR("fcntl error, err = %s, errno = %d", f_err, errno); DEBUG_ERROR("fcntl error, err = %s, errno = %d", f_err, errno);
err = -1; err = -1;
} }
else { else {
blocking = !(f_err & O_NONBLOCK); blocking = !(f_err & O_NONBLOCK);
} }
@@ -1201,9 +1201,9 @@ int zts_ioctl(ZT_IOCTL_SIG)
Linux: Linux:
[ ] [EAGAIN or EWOULDBLOCK] The socket is marked nonblocking and the requested operation would block. [ ] [EAGAIN or EWOULDBLOCK] The socket is marked nonblocking and the requested operation would block.
POSIX.1-2001 allows either error to be returned for this case, and does not POSIX.1-2001 allows either error to be returned for this case, and does not
require these constants to have the same value, so a portable application require these constants to have the same value, so a portable application
should check for both possibilities. should check for both possibilities.
[--] [EBADF] An invalid descriptor was specified. [--] [EBADF] An invalid descriptor was specified.
[ ] [ECONNRESET] VirtualSocket reset by peer. [ ] [ECONNRESET] VirtualSocket reset by peer.
@@ -1211,20 +1211,20 @@ Linux:
[ ] [EFAULT] An invalid user space address was specified for an argument. [ ] [EFAULT] An invalid user space address was specified for an argument.
[ ] [EINTR] A signal occurred before any data was transmitted; see signal(7). [ ] [EINTR] A signal occurred before any data was transmitted; see signal(7).
[ ] [EINVAL] Invalid argument passed. [ ] [EINVAL] Invalid argument passed.
[ ] [EISCONN] The VirtualSocket-mode socket was connected already but a recipient was [ ] [EISCONN] The VirtualSocket-mode socket was connected already but a recipient was
specified. (Now either this error is returned, or the recipient specified. (Now either this error is returned, or the recipient
specification is ignored.) specification is ignored.)
[ ] [EMSGSIZE] The socket type requires that message be sent atomically, and the size [ ] [EMSGSIZE] The socket type requires that message be sent atomically, and the size
of the message to be sent made this impossible. of the message to be sent made this impossible.
[ ] [ENOBUFS] The output queue for a network interface was full. This generally indicates [ ] [ENOBUFS] The output queue for a network interface was full. This generally indicates
that the interface has stopped sending, but may be caused by transient congestion. that the interface has stopped sending, but may be caused by transient congestion.
(Normally, this does not occur in Linux. Packets are just silently (Normally, this does not occur in Linux. Packets are just silently
dropped when a device queue overflows.) dropped when a device queue overflows.)
[ ] [ENOMEM] No memory available. [ ] [ENOMEM] No memory available.
[ ] [ENOTCONN] The socket is not connected, and no target has been given. [ ] [ENOTCONN] The socket is not connected, and no target has been given.
[ ] [ENOTSOCK] The argument sockfd is not a socket. [ ] [ENOTSOCK] The argument sockfd is not a socket.
[ ] [EOPNOTSUPP] Some bit in the flags argument is inappropriate for the socket type. [ ] [EOPNOTSUPP] Some bit in the flags argument is inappropriate for the socket type.
[ ] [EPIPE] The local end has been shut down on a VirtualSocket oriented socket. [ ] [EPIPE] The local end has been shut down on a VirtualSocket oriented socket.
In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.
ZT_SENDTO_SIG int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen ZT_SENDTO_SIG int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen
@@ -1262,21 +1262,21 @@ ssize_t zts_sendto(ZT_SENDTO_SIG)
ZeroTier::InetAddress iaddr; ZeroTier::InetAddress iaddr;
ZeroTier::VirtualTap *tap; ZeroTier::VirtualTap *tap;
if(vs->socket_type == SOCK_DGRAM) if(vs->socket_type == SOCK_DGRAM)
{ {
if(vs->socket_family == AF_INET) if(vs->socket_family == AF_INET)
{ {
char ipstr[INET_ADDRSTRLEN]; char ipstr[INET_ADDRSTRLEN];
memset(ipstr, 0, INET_ADDRSTRLEN); memset(ipstr, 0, INET_ADDRSTRLEN);
inet_ntop(AF_INET, inet_ntop(AF_INET,
(const void *)&((struct sockaddr_in *)addr)->sin_addr.s_addr, ipstr, INET_ADDRSTRLEN); (const void *)&((struct sockaddr_in *)addr)->sin_addr.s_addr, ipstr, INET_ADDRSTRLEN);
iaddr.fromString(ipstr); iaddr.fromString(ipstr);
} }
if(vs->socket_family == AF_INET6) if(vs->socket_family == AF_INET6)
{ {
char ipstr[INET6_ADDRSTRLEN]; char ipstr[INET6_ADDRSTRLEN];
memset(ipstr, 0, INET6_ADDRSTRLEN); memset(ipstr, 0, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, inet_ntop(AF_INET6,
(const void *)&((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, ipstr, INET6_ADDRSTRLEN); (const void *)&((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, ipstr, INET6_ADDRSTRLEN);
// TODO: This is a hack, determine a proper way to do this // TODO: This is a hack, determine a proper way to do this
char addrstr[INET6_ADDRSTRLEN]; char addrstr[INET6_ADDRSTRLEN];
@@ -1296,7 +1296,7 @@ ssize_t zts_sendto(ZT_SENDTO_SIG)
errno = EINVAL; // TODO: Not correct, but what else could we use? errno = EINVAL; // TODO: Not correct, but what else could we use?
} }
} }
if(vs->socket_type == SOCK_RAW) if(vs->socket_type == SOCK_RAW)
{ {
struct sockaddr_ll *socket_address = (struct sockaddr_ll *)addr; struct sockaddr_ll *socket_address = (struct sockaddr_ll *)addr;
ZeroTier::VirtualTap *tap = getTapByIndex(socket_address->sll_ifindex); ZeroTier::VirtualTap *tap = getTapByIndex(socket_address->sll_ifindex);
@@ -1396,7 +1396,7 @@ ssize_t zts_send(ZT_SEND_SIG)
return -1; return -1;
} }
if(flags & MSG_DONTWAIT) { if(flags & MSG_DONTWAIT) {
// The stack drivers and stack are inherently non-blocking by design, but we // The stack drivers and stack are inherently non-blocking by design, but we
// still need to modify the unix pipe connecting them to the application: // still need to modify the unix pipe connecting them to the application:
fcntl(fd, F_SETFL, O_NONBLOCK); fcntl(fd, F_SETFL, O_NONBLOCK);
} }
@@ -1445,7 +1445,7 @@ ssize_t zts_send(ZT_SEND_SIG)
// TODO // TODO
ssize_t zts_sendmsg(ZT_SENDMSG_SIG) ssize_t zts_sendmsg(ZT_SENDMSG_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;
@@ -1467,7 +1467,7 @@ ssize_t zts_sendmsg(ZT_SENDMSG_SIG)
[ ] EAGAIN or EWOULDBLOCK The socket is marked nonblocking and the receive operation [ ] EAGAIN or EWOULDBLOCK The socket is marked nonblocking and the receive operation
would block, or a receive timeout had been set and the timeout would block, or a receive timeout had been set and the timeout
expired before data was received. expired before data was received.
[--] EBADF The argument sockfd is an invalid file descriptor. [--] EBADF The argument sockfd is an invalid file descriptor.
[ ] ECONNREFUSED [ ] ECONNREFUSED
A remote host refused to allow the network connection A remote host refused to allow the network connection
@@ -1509,7 +1509,7 @@ ssize_t zts_recv(ZT_RECV_SIG)
return -1; return -1;
} }
if(flags & MSG_DONTWAIT) { if(flags & MSG_DONTWAIT) {
// The stack drivers and stack are inherently non-blocking by design, but we // The stack drivers and stack are inherently non-blocking by design, but we
// still need to modify the unix pipe connecting them to the application: // still need to modify the unix pipe connecting them to the application:
fcntl(fd, F_SETFL, O_NONBLOCK); fcntl(fd, F_SETFL, O_NONBLOCK);
} }
@@ -1557,22 +1557,22 @@ ssize_t zts_recv(ZT_RECV_SIG)
/* /*
Linux: Linux:
[ ] [EAGAIN or EWOULDBLOCK] The socket is marked nonblocking and the receive operation [ ] [EAGAIN or EWOULDBLOCK] The socket is marked nonblocking and the receive operation
would block, or a receive timeout had been set and the would block, or a receive timeout had been set and the
timeout expired before data was received. POSIX.1-2001 timeout expired before data was received. POSIX.1-2001
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)).
[NA] [ENOTSOCK] The argument sockfd does not refer to a socket. [NA] [ENOTSOCK] The argument sockfd does not refer to a socket.
@@ -1601,7 +1601,7 @@ ssize_t zts_recvfrom(ZT_RECVFROM_SIG)
memset(msg_ptr, 0, sizeof(int32_t)); // zero only len portion memset(msg_ptr, 0, sizeof(int32_t)); // zero only len portion
int32_t udp_msg_len = 0; int32_t udp_msg_len = 0;
// PEEK at the buffer and see if we can read a length, if not, err out // PEEK at the buffer and see if we can read a length, if not, err out
r = recv(fd, msg_ptr, sizeof(int32_t), MSG_PEEK); r = recv(fd, msg_ptr, sizeof(int32_t), MSG_PEEK);
if(r != sizeof(int32_t)){ if(r != sizeof(int32_t)){
@@ -1758,13 +1758,13 @@ namespace ZeroTier {
// Returns whether the ZeroTier service is running // Returns whether the ZeroTier service is running
JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_ztjni_1running( JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_ztjni_1running(
JNIEnv *env, jobject thisObj) JNIEnv *env, jobject thisObj)
{ {
return zts_running(); return zts_running();
} }
// Returns path for ZT config/data files // Returns path for ZT config/data files
JNIEXPORT jstring JNICALL Java_zerotier_ZeroTier_ztjni_1homepath( JNIEXPORT jstring JNICALL Java_zerotier_ZeroTier_ztjni_1homepath(
JNIEnv *env, jobject thisObj) JNIEnv *env, jobject thisObj)
{ {
// TODO: fix, should copy into given arg // TODO: fix, should copy into given arg
// return (*env).NewStringUTF(zts_get_homepath()); // return (*env).NewStringUTF(zts_get_homepath());
@@ -1772,7 +1772,7 @@ namespace ZeroTier {
} }
// Join a network // Join a network
JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1join( JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1join(
JNIEnv *env, jobject thisObj, jstring nwid) JNIEnv *env, jobject thisObj, jstring nwid)
{ {
const char *nwidstr; const char *nwidstr;
if(nwid) { if(nwid) {
@@ -1782,7 +1782,7 @@ namespace ZeroTier {
} }
// Leave a network // Leave a network
JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1leave( JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1leave(
JNIEnv *env, jobject thisObj, jstring nwid) JNIEnv *env, jobject thisObj, jstring nwid)
{ {
const char *nwidstr; const char *nwidstr;
if(nwid) { if(nwid) {
@@ -1793,35 +1793,35 @@ namespace ZeroTier {
// FIXME: Re-implemented to make it play nicer with the C-linkage required for Xcode integrations // FIXME: Re-implemented to make it play nicer with the C-linkage required for Xcode integrations
// Now only returns first assigned address per network. Shouldn't normally be a problem // Now only returns first assigned address per network. Shouldn't normally be a problem
JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_ztjni_1get_1ipv4_1address( JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_ztjni_1get_1ipv4_1address(
JNIEnv *env, jobject thisObj, jstring nwid) JNIEnv *env, jobject thisObj, jstring nwid)
{ {
const char *nwid_str = env->GetStringUTFChars(nwid, NULL); const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
char address_string[INET_ADDRSTRLEN]; char address_string[INET_ADDRSTRLEN];
memset(address_string, 0, INET_ADDRSTRLEN); memset(address_string, 0, INET_ADDRSTRLEN);
zts_get_ipv4_address(nwid_str, address_string, INET_ADDRSTRLEN); zts_get_ipv4_address(nwid_str, address_string, INET_ADDRSTRLEN);
jclass clazz = (*env).FindClass("java/util/ArrayList"); jclass clazz = (*env).FindClass("java/util/ArrayList");
jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V")); jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V"));
jstring _str = (*env).NewStringUTF(address_string); jstring _str = (*env).NewStringUTF(address_string);
env->CallBooleanMethod(addresses, env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"), _str); env->CallBooleanMethod(addresses, env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"), _str);
return addresses; return addresses;
} }
JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_ztjni_1get_1ipv6_1address( JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_ztjni_1get_1ipv6_1address(
JNIEnv *env, jobject thisObj, jstring nwid) JNIEnv *env, jobject thisObj, jstring nwid)
{ {
const char *nwid_str = env->GetStringUTFChars(nwid, NULL); const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
char address_string[INET6_ADDRSTRLEN]; char address_string[INET6_ADDRSTRLEN];
memset(address_string, 0, INET6_ADDRSTRLEN); memset(address_string, 0, INET6_ADDRSTRLEN);
zts_get_ipv6_address(nwid_str, address_string, INET6_ADDRSTRLEN); zts_get_ipv6_address(nwid_str, address_string, INET6_ADDRSTRLEN);
jclass clazz = (*env).FindClass("java/util/ArrayList"); jclass clazz = (*env).FindClass("java/util/ArrayList");
jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V")); jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V"));
jstring _str = (*env).NewStringUTF(address_string); jstring _str = (*env).NewStringUTF(address_string);
env->CallBooleanMethod(addresses, env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"), _str); env->CallBooleanMethod(addresses, env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"), _str);
return addresses; return addresses;
} }
// Returns the device is in integer form // Returns the device is in integer form
JNIEXPORT jint Java_zerotier_ZeroTier_ztjni_1get_1device_1id() JNIEXPORT jint Java_zerotier_ZeroTier_ztjni_1get_1device_1id()
{ {
return zts_get_device_id(NULL); // TODO return zts_get_device_id(NULL); // TODO
} }
@@ -1874,7 +1874,7 @@ namespace ZeroTier {
fid = (*env).GetFieldID( cls, "port", "I"); fid = (*env).GetFieldID( cls, "port", "I");
(*env).SetIntField( ztaddr, fid, addr.sin_port); (*env).SetIntField( ztaddr, fid, addr.sin_port);
fid = (*env).GetFieldID( cls,"_rawAddr", "J"); fid = (*env).GetFieldID( cls,"_rawAddr", "J");
(*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr); (*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr);
return rxbytes; return rxbytes;
} }
@@ -1894,7 +1894,7 @@ namespace ZeroTier {
int read_bytes = read(fd, body, len); int read_bytes = read(fd, body, len);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0); (*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
return read_bytes; return read_bytes;
} }
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1setsockopt( JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1setsockopt(
JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jint optval, jint optlen) { JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jint optval, jint optlen) {
@@ -1908,7 +1908,7 @@ namespace ZeroTier {
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1socket(JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol) { JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1socket(JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol) {
return zts_socket(family, type, protocol); return zts_socket(family, type, protocol);
} }
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1connect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) { JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1connect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
struct sockaddr_in addr; struct sockaddr_in addr;
const char *str = (*env).GetStringUTFChars( addrstr, 0); const char *str = (*env).GetStringUTFChars( addrstr, 0);
@@ -1949,7 +1949,7 @@ namespace ZeroTier {
addr.sin_addr.s_addr = inet_addr(""); addr.sin_addr.s_addr = inet_addr("");
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = htons( port ); addr.sin_port = htons( port );
return zts_accept(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr)); return zts_accept(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr));
} }
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1listen(JNIEnv *env, jobject thisObj, jint fd, int backlog) { JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1listen(JNIEnv *env, jobject thisObj, jint fd, int backlog) {
@@ -1968,8 +1968,8 @@ namespace ZeroTier {
fid = (*env).GetFieldID( cls, "port", "I"); fid = (*env).GetFieldID( cls, "port", "I");
(*env).SetIntField( ztaddr, fid, addr.sin_port); (*env).SetIntField( ztaddr, fid, addr.sin_port);
fid = (*env).GetFieldID( cls,"_rawAddr", "J"); fid = (*env).GetFieldID( cls,"_rawAddr", "J");
(*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr); (*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr);
return err; return err;
} }
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1getpeername(JNIEnv *env, jobject thisObj, jint fd, jobject ztaddr) { JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1getpeername(JNIEnv *env, jobject thisObj, jint fd, jobject ztaddr) {
@@ -1980,7 +1980,7 @@ namespace ZeroTier {
fid = (*env).GetFieldID( cls, "port", "I"); fid = (*env).GetFieldID( cls, "port", "I");
(*env).SetIntField( ztaddr, fid, addr.sin_port); (*env).SetIntField( ztaddr, fid, addr.sin_port);
fid = (*env).GetFieldID( cls,"_rawAddr", "J"); fid = (*env).GetFieldID( cls,"_rawAddr", "J");
(*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr); (*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr);
return err; return err;
} }
@@ -2013,7 +2013,7 @@ bool can_provision_new_socket(int socket_type)
#endif #endif
#if defined(NO_STACK) #if defined(NO_STACK)
// always true since there's no network stack timer/memory limitation // always true since there's no network stack timer/memory limitation
return true; return true;
#endif #endif
} }
@@ -2021,7 +2021,7 @@ int zts_nsockets()
{ {
ZeroTier::_multiplexer_lock.lock(); 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;
} }
@@ -2052,7 +2052,7 @@ std::vector<ZT_VirtualNetworkRoute> *zts_get_network_routes(char *nwid)
ZeroTier::VirtualTap *getTapByNWID(uint64_t nwid) ZeroTier::VirtualTap *getTapByNWID(uint64_t nwid)
{ {
ZeroTier::_vtaps_lock.lock(); ZeroTier::_vtaps_lock.lock();
ZeroTier::VirtualTap *s, *tap = nullptr; ZeroTier::VirtualTap *s, *tap = nullptr;
for(int i=0; i<ZeroTier::vtaps.size(); i++) { for(int i=0; i<ZeroTier::vtaps.size(); i++) {
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i]; s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
if(s->_nwid == nwid) { tap = s; } if(s->_nwid == nwid) { tap = s; }
@@ -2064,7 +2064,7 @@ ZeroTier::VirtualTap *getTapByNWID(uint64_t nwid)
ZeroTier::VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr) ZeroTier::VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr)
{ {
ZeroTier::_vtaps_lock.lock(); ZeroTier::_vtaps_lock.lock();
ZeroTier::VirtualTap *s, *tap = nullptr; ZeroTier::VirtualTap *s, *tap = nullptr;
//char ipbuf[64], ipbuf2[64], ipbuf3[64]; //char ipbuf[64], ipbuf2[64], ipbuf3[64];
for(int i=0; i<ZeroTier::vtaps.size(); i++) { for(int i=0; i<ZeroTier::vtaps.size(); i++) {
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i]; s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
@@ -2072,11 +2072,11 @@ ZeroTier::VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr)
for(int j=0; j<s->_ips.size(); j++) { for(int j=0; j<s->_ips.size(); j++) {
if((s->_ips[j].isV4() && addr->isV4()) || (s->_ips[j].isV6() && addr->isV6())) { if((s->_ips[j].isV4() && addr->isV4()) || (s->_ips[j].isV6() && addr->isV6())) {
//DEBUG_INFO("looking at tap %s, <addr=%s> --- for <%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf), addr->toIpString(ipbuf2)); //DEBUG_INFO("looking at tap %s, <addr=%s> --- for <%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf), addr->toIpString(ipbuf2));
if(s->_ips[j].isEqualPrefix(addr) if(s->_ips[j].isEqualPrefix(addr)
|| s->_ips[j].ipsEqual(addr) || s->_ips[j].ipsEqual(addr)
|| s->_ips[j].containsAddress(addr) || s->_ips[j].containsAddress(addr)
|| (addr->isV6() && ipv6_in_subnet(&s->_ips[j], addr)) || (addr->isV6() && ipv6_in_subnet(&s->_ips[j], addr))
) )
{ {
//DEBUG_INFO("selected tap %s, <addr=%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf)); //DEBUG_INFO("selected tap %s, <addr=%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf));
ZeroTier::_vtaps_lock.unlock(); ZeroTier::_vtaps_lock.unlock();
@@ -2107,7 +2107,7 @@ ZeroTier::VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr)
ZeroTier::VirtualTap *getTapByName(char *ifname) ZeroTier::VirtualTap *getTapByName(char *ifname)
{ {
ZeroTier::_vtaps_lock.lock(); ZeroTier::_vtaps_lock.lock();
ZeroTier::VirtualTap *s, *tap = nullptr; ZeroTier::VirtualTap *s, *tap = nullptr;
for(int i=0; i<ZeroTier::vtaps.size(); i++) { for(int i=0; i<ZeroTier::vtaps.size(); i++) {
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i]; s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
if(!strcmp(s->_dev.c_str(), ifname)) { if(!strcmp(s->_dev.c_str(), ifname)) {
@@ -2121,7 +2121,7 @@ ZeroTier::VirtualTap *getTapByName(char *ifname)
ZeroTier::VirtualTap *getTapByIndex(int index) ZeroTier::VirtualTap *getTapByIndex(int index)
{ {
ZeroTier::_vtaps_lock.lock(); ZeroTier::_vtaps_lock.lock();
ZeroTier::VirtualTap *s, *tap = nullptr; ZeroTier::VirtualTap *s, *tap = nullptr;
for(int i=0; i<ZeroTier::vtaps.size(); i++) { for(int i=0; i<ZeroTier::vtaps.size(); i++) {
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i]; s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
if(s->ifindex == index) { if(s->ifindex == index) {
@@ -2284,9 +2284,9 @@ std::pair<ZeroTier::VirtualSocket*, ZeroTier::VirtualTap*> *get_assigned_virtual
void dismantleTaps() void dismantleTaps()
{ {
ZeroTier::_vtaps_lock.lock(); ZeroTier::_vtaps_lock.lock();
for(int i=0; i<ZeroTier::vtaps.size(); i++) { for(int i=0; i<ZeroTier::vtaps.size(); i++) {
DEBUG_ERROR("ZeroTier::vtapsf[i]=%p", ZeroTier::vtaps[i]); DEBUG_ERROR("ZeroTier::vtapsf[i]=%p", ZeroTier::vtaps[i]);
delete (ZeroTier::VirtualTap*)ZeroTier::vtaps[i]; delete (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
ZeroTier::vtaps[i] = NULL; ZeroTier::vtaps[i] = NULL;
} }
ZeroTier::vtaps.clear(); ZeroTier::vtaps.clear();
@@ -2313,7 +2313,7 @@ void *zts_start_service(void *thread_id) {
// Where network .conf files will be stored // Where network .conf files will be stored
ZeroTier::netDir = ZeroTier::homeDir + "/networks.d"; ZeroTier::netDir = ZeroTier::homeDir + "/networks.d";
ZeroTier::zt1Service = (ZeroTier::OneService *)0; ZeroTier::zt1Service = (ZeroTier::OneService *)0;
// Construct path for network config and supporting service files // Construct path for network config and supporting service files
if (ZeroTier::homeDir.length()) { if (ZeroTier::homeDir.length()) {
std::vector<std::string> hpsp(ZeroTier::OSUtils::split(ZeroTier::homeDir.c_str(), std::vector<std::string> hpsp(ZeroTier::OSUtils::split(ZeroTier::homeDir.c_str(),
@@ -2348,7 +2348,7 @@ void *zts_start_service(void *thread_id) {
for(;;) { for(;;) {
ZeroTier::zt1Service = ZeroTier::OneService::newInstance(ZeroTier::homeDir.c_str(),servicePort); ZeroTier::zt1Service = ZeroTier::OneService::newInstance(ZeroTier::homeDir.c_str(),servicePort);
switch(ZeroTier::zt1Service->run()) { switch(ZeroTier::zt1Service->run()) {
case ZeroTier::OneService::ONE_STILL_RUNNING: case ZeroTier::OneService::ONE_STILL_RUNNING:
case ZeroTier::OneService::ONE_NORMAL_TERMINATION: case ZeroTier::OneService::ONE_NORMAL_TERMINATION:
break; break;
case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR:
@@ -2359,17 +2359,17 @@ void *zts_start_service(void *thread_id) {
delete ZeroTier::zt1Service; delete ZeroTier::zt1Service;
ZeroTier::zt1Service = (ZeroTier::OneService *)0; ZeroTier::zt1Service = (ZeroTier::OneService *)0;
std::string oldid; std::string oldid;
ZeroTier::OSUtils::readFile((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S ZeroTier::OSUtils::readFile((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S
+ "identity.secret").c_str(),oldid); + "identity.secret").c_str(),oldid);
if (oldid.length()) { if (oldid.length()) {
ZeroTier::OSUtils::writeFile((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S ZeroTier::OSUtils::writeFile((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S
+ "identity.secret.saved_after_collision").c_str(),oldid); + "identity.secret.saved_after_collision").c_str(),oldid);
ZeroTier::OSUtils::rm((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S ZeroTier::OSUtils::rm((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S
+ "identity.secret").c_str()); + "identity.secret").c_str());
ZeroTier::OSUtils::rm((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S ZeroTier::OSUtils::rm((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S
+ "identity.public").c_str()); + "identity.public").c_str());
} }
} }
continue; // restart! continue; // restart!
} }
break; // terminate loop -- normally we don't keep restarting break; // terminate loop -- normally we don't keep restarting

View File

@@ -24,7 +24,7 @@
* of your own application. * of your own application.
*/ */
// lwIP network stack driver // lwIP network stack driver
#ifndef ZT_LWIP_HPP #ifndef ZT_LWIP_HPP
#define ZT_LWIP_HPP #define ZT_LWIP_HPP
@@ -132,7 +132,7 @@ static const int lwip_err_to_errno_table[] = {
#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);
#endif #endif
#if defined(LIBZT_IPV6) #if defined(LIBZT_IPV6)
extern "C" void nd6_tmr(void); extern "C" void nd6_tmr(void);
//extern "C" void netif_ip6_addr_set_state(LWIP_NETIF_IP6_ADDR_SET_STATE_SIG); //extern "C" void netif_ip6_addr_set_state(LWIP_NETIF_IP6_ADDR_SET_STATE_SIG);
@@ -188,7 +188,7 @@ 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;
struct VirtualSocket; struct VirtualSocket;
@@ -240,7 +240,7 @@ namespace ZeroTier {
* Packets from the ZeroTier virtual wire enter the stack here * Packets from the ZeroTier virtual wire enter the stack here
*/ */
void lwip_eth_rx(VirtualTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); void lwip_eth_rx(VirtualTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
/* /*
* Creates a stack-specific "socket" or "VirtualSocket object" * Creates a stack-specific "socket" or "VirtualSocket object"
*/ */
@@ -325,6 +325,6 @@ namespace ZeroTier {
*/ */
static err_t lwip_cb_connected(void *arg, struct tcp_pcb *PCB, err_t err); static err_t lwip_cb_connected(void *arg, struct tcp_pcb *PCB, err_t err);
}; };
} }
#endif #endif

View File

@@ -100,7 +100,7 @@ namespace ZeroTier {
bool err = false; bool err = false;
_picostack_driver_lock.lock(); _picostack_driver_lock.lock();
// give right to vtap to start the stack // give right to vtap to start the stack
// only one stack loop is permitted // only one stack loop is permitted
if(!picodev_initialized) { if(!picodev_initialized) {
tap->should_start_stack = true; tap->should_start_stack = true;
picodev.send = pico_eth_tx; // tx picodev.send = pico_eth_tx; // tx
@@ -126,7 +126,7 @@ namespace ZeroTier {
_picostack_driver_lock.lock(); _picostack_driver_lock.lock();
bool err = false; bool err = false;
char ipbuf[INET6_ADDRSTRLEN]; char ipbuf[INET6_ADDRSTRLEN];
uint8_t hwaddr[6]; uint8_t hwaddr[6];
// register addresses // register addresses
if(ip.isV4()) { if(ip.isV4()) {
struct pico_ip4 ipaddr, netmask; struct pico_ip4 ipaddr, netmask;
@@ -153,7 +153,7 @@ namespace ZeroTier {
char macbuf[ZT_MAC_ADDRSTRLEN]; char macbuf[ZT_MAC_ADDRSTRLEN];
mac2str(macbuf, ZT_MAC_ADDRSTRLEN, hwaddr); mac2str(macbuf, ZT_MAC_ADDRSTRLEN, hwaddr);
DEBUG_INFO("mac=%s", macbuf); DEBUG_INFO("mac=%s", macbuf);
err = true; err = true;
} }
_picostack_driver_lock.unlock(); _picostack_driver_lock.unlock();
return err; return err;
@@ -178,7 +178,7 @@ namespace ZeroTier {
} }
return err; return err;
} }
bool picoTCP::pico_route_del(VirtualTap *tap, const InetAddress &addr, const InetAddress &nm, int metric) bool picoTCP::pico_route_del(VirtualTap *tap, const InetAddress &addr, const InetAddress &nm, int metric)
{ {
struct pico_ip4 address; struct pico_ip4 address;
@@ -194,7 +194,7 @@ namespace ZeroTier {
int picoTCP::pico_add_dns_nameserver(struct sockaddr *addr) int picoTCP::pico_add_dns_nameserver(struct sockaddr *addr)
{ {
int err = errno = 0; int err = errno = 0;
// TODO: De-complexify this // TODO: De-complexify this
struct pico_ip4 ns; struct pico_ip4 ns;
memset(&ns, 0, sizeof (struct pico_ip4)); memset(&ns, 0, sizeof (struct pico_ip4));
@@ -205,16 +205,16 @@ namespace ZeroTier {
pico_string_to_ipv4(ipv4_str, &ipval); pico_string_to_ipv4(ipv4_str, &ipval);
ns.addr = ipval; ns.addr = ipval;
if((err = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD)) < 0) { if((err = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD)) < 0) {
DEBUG_ERROR("error while adding DNS nameserver, err=%d, pico_err=%d, %s", DEBUG_ERROR("error while adding DNS nameserver, err=%d, pico_err=%d, %s",
err, pico_err, beautify_pico_error(pico_err)); err, pico_err, beautify_pico_error(pico_err));
map_pico_err_to_errno(pico_err); map_pico_err_to_errno(pico_err);
} }
return err; return err;
} }
int picoTCP::pico_del_dns_nameserver(struct sockaddr *addr) int picoTCP::pico_del_dns_nameserver(struct sockaddr *addr)
{ {
int err = errno = 0; int err = errno = 0;
// TODO: De-complexify this // TODO: De-complexify this
struct pico_ip4 ns; struct pico_ip4 ns;
memset(&ns, 0, sizeof (struct pico_ip4)); memset(&ns, 0, sizeof (struct pico_ip4));
@@ -225,7 +225,7 @@ namespace ZeroTier {
pico_string_to_ipv4(ipv4_str, &ipval); pico_string_to_ipv4(ipv4_str, &ipval);
ns.addr = ipval; ns.addr = ipval;
if((err = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL)) < 0) { if((err = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL)) < 0) {
DEBUG_ERROR("error while removing DNS nameserver, err=%d, pico_err=%d, %s", DEBUG_ERROR("error while removing DNS nameserver, err=%d, pico_err=%d, %s",
err, pico_err, beautify_pico_error(pico_err)); err, pico_err, beautify_pico_error(pico_err));
} }
return err; return err;
@@ -253,7 +253,7 @@ namespace ZeroTier {
return; return;
} }
Mutex::Lock _l(vs->_rx_m); Mutex::Lock _l(vs->_rx_m);
if(!tap) { if(!tap) {
DEBUG_ERROR("invalid tap"); DEBUG_ERROR("invalid tap");
handle_general_failure(); handle_general_failure();
@@ -264,18 +264,18 @@ namespace ZeroTier {
handle_general_failure(); handle_general_failure();
return; return;
} }
int r; int r;
uint16_t port = 0; uint16_t port = 0;
union { union {
struct pico_ip4 ip4; struct pico_ip4 ip4;
struct pico_ip6 ip6; struct pico_ip6 ip6;
} peer; } peer;
do { do {
int n = 0; int n = 0;
int avail = ZT_TCP_RX_BUF_SZ - vs->RXbuf->count(); int avail = ZT_TCP_RX_BUF_SZ - vs->RXbuf->count();
if(avail) { if(avail) {
r = pico_socket_recvfrom(s, vs->RXbuf->get_buf(), ZT_STACK_SOCKET_RD_MAX, r = pico_socket_recvfrom(s, vs->RXbuf->get_buf(), ZT_STACK_SOCKET_RD_MAX,
(void *)&peer.ip4.addr, &port); (void *)&peer.ip4.addr, &port);
if (r > 0) if (r > 0)
{ {
@@ -289,8 +289,8 @@ namespace ZeroTier {
tap->_phy.setNotifyWritable(vs->sock, false); tap->_phy.setNotifyWritable(vs->sock, false);
} }
else { else {
tap->_phy.setNotifyWritable(vs->sock, true); tap->_phy.setNotifyWritable(vs->sock, true);
} }
} }
else { else {
//tap->_phy.setNotifyWritable(vs->sock, false); //tap->_phy.setNotifyWritable(vs->sock, false);
@@ -394,7 +394,7 @@ namespace ZeroTier {
int r, max_write_len = std::min(std::min(txsz, ZT_SDK_MTU),ZT_STACK_SOCKET_WR_MAX); int r, max_write_len = std::min(std::min(txsz, ZT_SDK_MTU),ZT_STACK_SOCKET_WR_MAX);
if((r = pico_socket_write(vs->picosock, vs->TXbuf->get_buf(), max_write_len)) < 0) { if((r = pico_socket_write(vs->picosock, vs->TXbuf->get_buf(), max_write_len)) < 0) {
DEBUG_ERROR("unable to write to pico_socket=%p, err=%d, pico_err=%d, %s", DEBUG_ERROR("unable to write to pico_socket=%p, err=%d, pico_err=%d, %s",
vs->picosock, r, pico_err, beautify_pico_error(pico_err)); vs->picosock, r, pico_err, beautify_pico_error(pico_err));
handle_general_failure(); handle_general_failure();
return; return;
@@ -404,10 +404,10 @@ namespace ZeroTier {
} }
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));
// This is a peciliarity of the picoTCP network stack, if we receive no error code, and the size of // This is a peciliarity of the picoTCP network stack, if we receive no error code, and the size of
// the byte stream written is 0, this is an indication that the buffer for this pico_socket is too small // the byte stream written is 0, this is an indication that the buffer for this pico_socket is too small
// DEBUG_ERROR("pico_socket buffer is too small (adjust ZT_STACK_SOCKET_TX_SZ, ZT_STACK_SOCKET_RX_SZ)"); // DEBUG_ERROR("pico_socket buffer is too small (adjust ZT_STACK_SOCKET_TX_SZ, ZT_STACK_SOCKET_RX_SZ)");
// handle_general_failure(); // handle_general_failure();
} }
if(r>0) if(r>0)
vs->TXbuf->consume(r); vs->TXbuf->consume(r);
@@ -425,7 +425,7 @@ namespace ZeroTier {
if (ev & PICO_SOCK_EV_FIN) { if (ev & PICO_SOCK_EV_FIN) {
DEBUG_EXTRA("PICO_SOCK_EV_FIN (socket closed), picosock=%p", s); DEBUG_EXTRA("PICO_SOCK_EV_FIN (socket closed), picosock=%p", s);
//DEBUG_EXTRA("PICO_SOCK_EV_FIN (socket closed), picosock=%p, vs=%p, app_fd=%d, sdk_fd=%d", s, vs, vs->app_fd, vs->sdk_fd); //DEBUG_EXTRA("PICO_SOCK_EV_FIN (socket closed), picosock=%p, vs=%p, app_fd=%d, sdk_fd=%d", s, vs, vs->app_fd, vs->sdk_fd);
//vs->closure_ts = std::time(nullptr); //vs->closure_ts = std::time(nullptr);
} }
// PICO_SOCK_EV_ERR - triggered when an error occurs. // PICO_SOCK_EV_ERR - triggered when an error occurs.
@@ -433,8 +433,8 @@ namespace ZeroTier {
if(pico_err == PICO_ERR_ECONNRESET) { if(pico_err == PICO_ERR_ECONNRESET) {
DEBUG_ERROR("PICO_ERR_ECONNRESET"); DEBUG_ERROR("PICO_ERR_ECONNRESET");
} }
//DEBUG_ERROR("PICO_SOCK_EV_ERR, err=%s, picosock=%p, app_fd=%d, sdk_fd=%d", //DEBUG_ERROR("PICO_SOCK_EV_ERR, err=%s, picosock=%p, app_fd=%d, sdk_fd=%d",
// beautify_pico_error(pico_err), s, vs->app_fd, vs->sdk_fd); // beautify_pico_error(pico_err), s, vs->app_fd, vs->sdk_fd);
} }
// PICO_SOCK_EV_CLOSE - triggered when a FIN segment is received (TCP only). This event // PICO_SOCK_EV_CLOSE - triggered when a FIN segment is received (TCP only). This event
// indicates that the oher endpont has closed the VirtualSocket, so the local TCP layer is only // indicates that the oher endpont has closed the VirtualSocket, so the local TCP layer is only
@@ -446,8 +446,8 @@ namespace ZeroTier {
DEBUG_ERROR("pico_socket_close()=%d, pico_err=%d, %s", err, pico_err, beautify_pico_error(pico_err)); DEBUG_ERROR("pico_socket_close()=%d, pico_err=%d, %s", err, pico_err, beautify_pico_error(pico_err));
} }
DEBUG_EXTRA("PICO_SOCK_EV_CLOSE (socket closure) err=%d (%s), picosock=%p", pico_err, beautify_pico_error(pico_err), s); DEBUG_EXTRA("PICO_SOCK_EV_CLOSE (socket closure) err=%d (%s), picosock=%p", pico_err, beautify_pico_error(pico_err), s);
//DEBUG_EXTRA("PICO_SOCK_EV_CLOSE (socket closure) err=%d, picosock=%p, vs=%p, app_fd=%d, sdk_fd=%d", err, s, vs, vs->app_fd, vs->sdk_fd); //DEBUG_EXTRA("PICO_SOCK_EV_CLOSE (socket closure) err=%d, picosock=%p, vs=%p, app_fd=%d, sdk_fd=%d", err, s, vs, vs->app_fd, vs->sdk_fd);
//vs->closure_ts = std::time(nullptr); //vs->closure_ts = std::time(nullptr);
return; return;
} }
@@ -488,16 +488,16 @@ namespace ZeroTier {
if(!client_psock) { if(!client_psock) {
DEBUG_ERROR("pico_socket_accept(): pico_socket=%p, pico_err=%d, %s", s, pico_err, beautify_pico_error(pico_err)); DEBUG_ERROR("pico_socket_accept(): pico_socket=%p, pico_err=%d, %s", s, pico_err, beautify_pico_error(pico_err));
return; return;
} }
// Create a new VirtualSocket and add it to the queue, // Create a new VirtualSocket and add it to the queue,
// some time in the future a call to zts_multiplex_accept() will pick up // some time in the future a call to zts_multiplex_accept() will pick up
// this new VirtualSocket, add it to the VirtualSocket list and return its // this new VirtualSocket, add it to the VirtualSocket list and return its
// VirtualSocket->sock to the application // VirtualSocket->sock to the application
VirtualSocket *new_vs = new VirtualSocket(); VirtualSocket *new_vs = new VirtualSocket();
new_vs->socket_type = SOCK_STREAM; new_vs->socket_type = SOCK_STREAM;
new_vs->picosock = client_psock; new_vs->picosock = client_psock;
// TODO: Condense this // TODO: Condense this
if(vs->socket_family == AF_INET) { if(vs->socket_family == AF_INET) {
char addrstr[INET_ADDRSTRLEN]; char addrstr[INET_ADDRSTRLEN];
@@ -554,7 +554,7 @@ namespace ZeroTier {
pico_cb_tcp_write(tap, s); pico_cb_tcp_write(tap, s);
} }
} }
int pico_eth_tx(struct pico_device *dev, void *buf, int len) int pico_eth_tx(struct pico_device *dev, void *buf, int len)
{ {
//_picostack_driver_lock.lock(); //_picostack_driver_lock.lock();
@@ -581,7 +581,7 @@ namespace ZeroTier {
memset(&flagbuf, 0, 32); memset(&flagbuf, 0, 32);
struct pico_tcp_hdr *hdr; struct pico_tcp_hdr *hdr;
void * tcp_hdr_ptr; void * tcp_hdr_ptr;
if(Utils::ntoh(ethhdr->proto) == 0x86dd) { // tcp, ipv6 if(Utils::ntoh(ethhdr->proto) == 0x86dd) { // tcp, ipv6
tcp_hdr_ptr = &ethhdr + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR; tcp_hdr_ptr = &ethhdr + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR;
} }
@@ -590,7 +590,7 @@ namespace ZeroTier {
{ {
tcp_hdr_ptr = &buf + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR; tcp_hdr_ptr = &buf + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR;
hdr = (struct pico_tcp_hdr *)tcp_hdr_ptr; hdr = (struct pico_tcp_hdr *)tcp_hdr_ptr;
if(hdr) { if(hdr) {
char *flag_ptr = flagbuf; char *flag_ptr = flagbuf;
@@ -604,7 +604,7 @@ namespace ZeroTier {
} }
if (hdr->flags & PICO_TCP_ACK) { if (hdr->flags & PICO_TCP_ACK) {
sprintf(flag_ptr, "ACK "); sprintf(flag_ptr, "ACK ");
flag_ptr+=4; flag_ptr+=4;
} }
if (hdr->flags & PICO_TCP_FIN) { if (hdr->flags & PICO_TCP_FIN) {
sprintf(flag_ptr, "FIN "); sprintf(flag_ptr, "FIN ");
@@ -617,11 +617,11 @@ namespace ZeroTier {
} }
} }
DEBUG_TRANS("len=%5d dst=%s [%s TX <-- %s] proto=0x%04x %s %s", len, macBuf, nodeBuf, tap->nodeId().c_str(), DEBUG_TRANS("len=%5d dst=%s [%s TX <-- %s] proto=0x%04x %s %s", len, macBuf, nodeBuf, tap->nodeId().c_str(),
Utils::ntoh(ethhdr->proto), beautify_eth_proto_nums(Utils::ntoh(ethhdr->proto)), flagbuf); Utils::ntoh(ethhdr->proto), beautify_eth_proto_nums(Utils::ntoh(ethhdr->proto)), flagbuf);
} }
tap->_handler(tap->_arg,NULL,tap->_nwid,src_mac,dest_mac, tap->_handler(tap->_arg,NULL,tap->_nwid,src_mac,dest_mac,
Utils::ntoh((uint16_t)ethhdr->proto), 0, ((char*)buf) Utils::ntoh((uint16_t)ethhdr->proto), 0, ((char*)buf)
+ sizeof(struct pico_eth_hdr),len - sizeof(struct pico_eth_hdr)); + sizeof(struct pico_eth_hdr),len - sizeof(struct pico_eth_hdr));
//_picostack_driver_lock.unlock(); //_picostack_driver_lock.unlock();
return len; return len;
@@ -646,7 +646,7 @@ namespace ZeroTier {
to.copyTo(ethhdr.daddr, 6); to.copyTo(ethhdr.daddr, 6);
ethhdr.proto = Utils::hton((uint16_t)etherType); ethhdr.proto = Utils::hton((uint16_t)etherType);
int32_t msg_len = len + sizeof(int32_t) + sizeof(struct pico_eth_hdr); int32_t msg_len = len + sizeof(int32_t) + sizeof(struct pico_eth_hdr);
if(ZT_DEBUG_LEVEL >= ZT_MSG_TRANSFER) { if(ZT_DEBUG_LEVEL >= ZT_MSG_TRANSFER) {
char macBuf[ZT_MAC_ADDRSTRLEN], nodeBuf[ZT_ID_LEN]; char macBuf[ZT_MAC_ADDRSTRLEN], nodeBuf[ZT_ID_LEN];
mac2str(macBuf, sizeof(macBuf), ethhdr.saddr); mac2str(macBuf, sizeof(macBuf), ethhdr.saddr);
@@ -658,18 +658,18 @@ namespace ZeroTier {
memset(&flagbuf, 0, 32); memset(&flagbuf, 0, 32);
struct pico_tcp_hdr *hdr; struct pico_tcp_hdr *hdr;
void * tcp_hdr_ptr; void * tcp_hdr_ptr;
if(etherType == 0x86dd) { // tcp, ipv6 if(etherType == 0x86dd) { // tcp, ipv6
tcp_hdr_ptr = &ethhdr + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR; tcp_hdr_ptr = &ethhdr + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR;
} }
if(etherType == 0x0800) // tcp, ipv4 if(etherType == 0x0800) // tcp, ipv4
{ {
tcp_hdr_ptr = &ethhdr + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR; tcp_hdr_ptr = &ethhdr + PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR;
hdr = (struct pico_tcp_hdr *)tcp_hdr_ptr; hdr = (struct pico_tcp_hdr *)tcp_hdr_ptr;
if(hdr) { if(hdr) {
char *flag_ptr = flagbuf; char *flag_ptr = flagbuf;
if (hdr->flags & PICO_TCP_PSH) { if (hdr->flags & PICO_TCP_PSH) {
sprintf(flag_ptr, "PSH "); sprintf(flag_ptr, "PSH ");
flag_ptr+=4; flag_ptr+=4;
@@ -680,7 +680,7 @@ namespace ZeroTier {
} }
if (hdr->flags & PICO_TCP_ACK) { if (hdr->flags & PICO_TCP_ACK) {
sprintf(flag_ptr, "ACK "); sprintf(flag_ptr, "ACK ");
flag_ptr+=4; flag_ptr+=4;
} }
if (hdr->flags & PICO_TCP_FIN) { if (hdr->flags & PICO_TCP_FIN) {
sprintf(flag_ptr, "FIN "); sprintf(flag_ptr, "FIN ");
@@ -692,11 +692,11 @@ namespace ZeroTier {
} }
} }
} }
DEBUG_TRANS("len=%5d src=%s [%s RX --> %s] proto=0x%04x %s %s", len, macBuf, nodeBuf, tap->nodeId().c_str(), DEBUG_TRANS("len=%5d src=%s [%s RX --> %s] proto=0x%04x %s %s", len, macBuf, nodeBuf, tap->nodeId().c_str(),
etherType, beautify_eth_proto_nums(etherType), flagbuf); etherType, beautify_eth_proto_nums(etherType), flagbuf);
} }
// write virtual ethernet frame to guarded buffer (emptied by pico_eth_poll()) // write virtual ethernet frame to guarded buffer (emptied by pico_eth_poll())
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot, &msg_len, sizeof(int32_t)); // size of frame + meta memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot, &msg_len, sizeof(int32_t)); // size of frame + meta
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(int32_t), &ethhdr, sizeof(ethhdr)); // new eth header memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(int32_t), &ethhdr, sizeof(ethhdr)); // new eth header
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(int32_t) + sizeof(ethhdr), data, len); // frame data memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(int32_t) + sizeof(ethhdr), data, len); // frame data
tap->pico_frame_rxbuf_tot += msg_len; tap->pico_frame_rxbuf_tot += msg_len;
@@ -739,7 +739,7 @@ namespace ZeroTier {
} }
return loop_score; return loop_score;
} }
int picoTCP::pico_Socket(struct pico_socket **p, int socket_family, int socket_type, int protocol) int picoTCP::pico_Socket(struct pico_socket **p, int socket_family, int socket_type, int protocol)
{ {
int err = 0; int err = 0;
@@ -756,19 +756,19 @@ namespace ZeroTier {
protocol_version = PICO_PROTO_IPV4; protocol_version = PICO_PROTO_IPV4;
if(socket_family == AF_INET6) if(socket_family == AF_INET6)
protocol_version = PICO_PROTO_IPV6; protocol_version = PICO_PROTO_IPV6;
if(socket_type == SOCK_DGRAM) { if(socket_type == SOCK_DGRAM) {
psock = pico_socket_open( psock = pico_socket_open(
protocol_version, PICO_PROTO_UDP, &ZeroTier::picoTCP::pico_cb_socket_ev); protocol_version, PICO_PROTO_UDP, &ZeroTier::picoTCP::pico_cb_socket_ev);
if(psock) { if(psock) {
// configure size of UDP SND/RCV buffers // configure size of UDP SND/RCV buffers
// TODO // TODO
} }
} }
if(socket_type == SOCK_STREAM) { if(socket_type == SOCK_STREAM) {
psock = pico_socket_open( psock = pico_socket_open(
protocol_version, PICO_PROTO_TCP, &ZeroTier::picoTCP::pico_cb_socket_ev); protocol_version, PICO_PROTO_TCP, &ZeroTier::picoTCP::pico_cb_socket_ev);
if(psock) { if(psock) {
// configure size of TCP SND/RCV buffers // configure size of TCP SND/RCV buffers
int tx_buf_sz = ZT_STACK_TCP_SOCKET_TX_SZ; int tx_buf_sz = ZT_STACK_TCP_SOCKET_TX_SZ;
int rx_buf_sz = ZT_STACK_TCP_SOCKET_RX_SZ; int rx_buf_sz = ZT_STACK_TCP_SOCKET_RX_SZ;
@@ -778,16 +778,16 @@ namespace ZeroTier {
// pico_socket_setoption(psock, PICO_TCP_NODELAY, &value); // pico_socket_setoption(psock, PICO_TCP_NODELAY, &value);
if((t_err = pico_socket_setoption(psock, PICO_SOCKET_OPT_SNDBUF, &tx_buf_sz)) < 0) if((t_err = pico_socket_setoption(psock, PICO_SOCKET_OPT_SNDBUF, &tx_buf_sz)) < 0)
DEBUG_ERROR("unable to set SNDBUF size, err=%d, pico_err=%d, %s", DEBUG_ERROR("unable to set SNDBUF size, err=%d, pico_err=%d, %s",
t_err, pico_err, beautify_pico_error(pico_err)); t_err, pico_err, beautify_pico_error(pico_err));
if((t_err = pico_socket_setoption(psock, PICO_SOCKET_OPT_RCVBUF, &rx_buf_sz)) < 0) if((t_err = pico_socket_setoption(psock, PICO_SOCKET_OPT_RCVBUF, &rx_buf_sz)) < 0)
DEBUG_ERROR("unable to set RCVBUF size, err=%d, pico_err=%d, %s", DEBUG_ERROR("unable to set RCVBUF size, err=%d, pico_err=%d, %s",
t_err, pico_err, beautify_pico_error(pico_err)); t_err, pico_err, beautify_pico_error(pico_err));
if(ZT_SOCK_BEHAVIOR_LINGER) { if(ZT_SOCK_BEHAVIOR_LINGER) {
int linger_time_ms = ZT_SOCK_BEHAVIOR_LINGER_TIME; int linger_time_ms = ZT_SOCK_BEHAVIOR_LINGER_TIME;
if((t_err = pico_socket_setoption(psock, PICO_SOCKET_OPT_LINGER, &linger_time_ms)) < 0) if((t_err = pico_socket_setoption(psock, PICO_SOCKET_OPT_LINGER, &linger_time_ms)) < 0)
DEBUG_ERROR("unable to set LINGER, err=%d, pico_err=%d, %s", DEBUG_ERROR("unable to set LINGER, err=%d, pico_err=%d, %s",
t_err, pico_err, beautify_pico_error(pico_err)); t_err, pico_err, beautify_pico_error(pico_err));
} }
} }
@@ -798,7 +798,7 @@ namespace ZeroTier {
} }
int picoTCP::pico_Connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen) int picoTCP::pico_Connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen)
{ {
if(!vs || !vs->picosock) { if(!vs || !vs->picosock) {
DEBUG_ERROR("invalid vs or vs->picosock"); DEBUG_ERROR("invalid vs or vs->picosock");
handle_general_failure(); handle_general_failure();
@@ -831,7 +831,7 @@ namespace ZeroTier {
err = pico_socket_connect(vs->picosock, &zaddr, in6->sin6_port); err = pico_socket_connect(vs->picosock, &zaddr, in6->sin6_port);
} }
if(err) { if(err) {
DEBUG_ERROR("error connecting pico_socket=%p, err=%d, pico_err=%d, %s", DEBUG_ERROR("error connecting pico_socket=%p, err=%d, pico_err=%d, %s",
vs->picosock, err, pico_err, beautify_pico_error(pico_err)); vs->picosock, err, pico_err, beautify_pico_error(pico_err));
return map_pico_err_to_errno(pico_err); return map_pico_err_to_errno(pico_err);
} }
@@ -847,7 +847,7 @@ namespace ZeroTier {
return ZT_ERR_GENERAL_FAILURE; return ZT_ERR_GENERAL_FAILURE;
} }
int err = 0; int err = 0;
if(vs->socket_family == AF_INET) { if(vs->socket_family == AF_INET) {
struct pico_ip4 zaddr; struct pico_ip4 zaddr;
uint32_t tempaddr; uint32_t tempaddr;
memset(&zaddr, 0, sizeof (struct pico_ip4)); memset(&zaddr, 0, sizeof (struct pico_ip4));
@@ -859,7 +859,7 @@ namespace ZeroTier {
DEBUG_EXTRA("binding to addr=%s port=%d", ipv4_str, Utils::ntoh(in4->sin_port)); DEBUG_EXTRA("binding to addr=%s port=%d", ipv4_str, Utils::ntoh(in4->sin_port));
err = pico_socket_bind(vs->picosock, &zaddr, (uint16_t *)&(in4->sin_port)); err = pico_socket_bind(vs->picosock, &zaddr, (uint16_t *)&(in4->sin_port));
} }
if(vs->socket_family == AF_INET6) { if(vs->socket_family == AF_INET6) {
struct pico_ip6 pip6; struct pico_ip6 pip6;
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
char ipv6_str[INET6_ADDRSTRLEN]; char ipv6_str[INET6_ADDRSTRLEN];
@@ -870,7 +870,7 @@ namespace ZeroTier {
err = pico_socket_bind(vs->picosock, &pip6, (uint16_t *)&(in6->sin6_port)); err = pico_socket_bind(vs->picosock, &pip6, (uint16_t *)&(in6->sin6_port));
} }
if(err < 0) { if(err < 0) {
DEBUG_ERROR("unable to bind pico_socket=%p, err=%d, pico_err=%d, %s", DEBUG_ERROR("unable to bind pico_socket=%p, err=%d, pico_err=%d, %s",
(vs->picosock), err, pico_err, beautify_pico_error(pico_err)); (vs->picosock), err, pico_err, beautify_pico_error(pico_err));
return map_pico_err_to_errno(pico_err); return map_pico_err_to_errno(pico_err);
} }
@@ -886,7 +886,7 @@ namespace ZeroTier {
} }
int err = 0; int err = 0;
if((err = pico_socket_listen(vs->picosock, backlog)) < 0) { if((err = pico_socket_listen(vs->picosock, backlog)) < 0) {
DEBUG_ERROR("error putting pico_socket=%p into listening state. err=%d, pico_err=%d, %s", DEBUG_ERROR("error putting pico_socket=%p into listening state. err=%d, pico_err=%d, %s",
vs->picosock, err, pico_err, beautify_pico_error(pico_err)); vs->picosock, err, pico_err, beautify_pico_error(pico_err));
return map_pico_err_to_errno(pico_err); return map_pico_err_to_errno(pico_err);
} }
@@ -945,7 +945,7 @@ namespace ZeroTier {
if(vs->socket_type == SOCK_DGRAM) { if(vs->socket_type == SOCK_DGRAM) {
int r; int r;
if((r = pico_socket_write(vs->picosock, data, len)) < 0) { if((r = pico_socket_write(vs->picosock, data, len)) < 0) {
DEBUG_ERROR("unable to write to picosock=%p, err=%d, pico_err=%d, %s", DEBUG_ERROR("unable to write to picosock=%p, err=%d, pico_err=%d, %s",
vs->picosock, r, pico_err, beautify_pico_error(pico_err)); vs->picosock, r, pico_err, beautify_pico_error(pico_err));
err = -1; err = -1;
} }
@@ -969,9 +969,9 @@ namespace ZeroTier {
return ZT_ERR_GENERAL_FAILURE; return ZT_ERR_GENERAL_FAILURE;
} }
int txsz = vs->TXbuf->count(); int txsz = vs->TXbuf->count();
int r, max_write_len = std::min(std::min(txsz, ZT_SDK_MTU),ZT_STACK_SOCKET_WR_MAX); int r, max_write_len = std::min(std::min(txsz, ZT_SDK_MTU),ZT_STACK_SOCKET_WR_MAX);
if((r = pico_socket_write(vs->picosock, vs->TXbuf->get_buf(), max_write_len)) < 0) { if((r = pico_socket_write(vs->picosock, vs->TXbuf->get_buf(), max_write_len)) < 0) {
DEBUG_ERROR("unable to write to picosock=%p, err=%d, pico_err=%d, %s", DEBUG_ERROR("unable to write to picosock=%p, err=%d, pico_err=%d, %s",
vs->picosock, r, pico_err, beautify_pico_error(pico_err)); vs->picosock, r, pico_err, beautify_pico_error(pico_err));
err = -1; err = -1;
} }
@@ -996,18 +996,18 @@ namespace ZeroTier {
if(!vs) { if(!vs) {
DEBUG_ERROR("invalid vs"); DEBUG_ERROR("invalid vs");
handle_general_failure(); handle_general_failure();
return ZT_ERR_GENERAL_FAILURE; return ZT_ERR_GENERAL_FAILURE;
} }
DEBUG_EXTRA("vs=%p, picosock=%p, fd=%d", vs, vs->picosock, vs->app_fd); DEBUG_EXTRA("vs=%p, picosock=%p, fd=%d", vs, vs->picosock, vs->app_fd);
if(!vs || !vs->picosock) if(!vs || !vs->picosock)
return ZT_ERR_GENERAL_FAILURE; return ZT_ERR_GENERAL_FAILURE;
int err = 0; int err = 0;
Mutex::Lock _l(vs->tap->_tcpconns_m); Mutex::Lock _l(vs->tap->_tcpconns_m);
if(vs->closure_ts != -1) // it was closed at some point in the past, it'll work itself out if(vs->closure_ts != -1) // it was closed at some point in the past, it'll work itself out
return ZT_ERR_OK; return ZT_ERR_OK;
if((err = pico_socket_close(vs->picosock)) < 0) { if((err = pico_socket_close(vs->picosock)) < 0) {
errno = pico_err; errno = pico_err;
DEBUG_ERROR("error closing pico_socket, err=%d, pico_err=%s, %s", DEBUG_ERROR("error closing pico_socket, err=%d, pico_err=%s, %s",
err, pico_err, beautify_pico_error(pico_err)); err, pico_err, beautify_pico_error(pico_err));
} }
return err; return err;
@@ -1022,7 +1022,7 @@ namespace ZeroTier {
if(how == SHUT_WR) { if(how == SHUT_WR) {
mode = PICO_SHUT_WR; mode = PICO_SHUT_WR;
} }
if(how == SHUT_RDWR) { if(how == SHUT_RDWR) {
mode = PICO_SHUT_RDWR; mode = PICO_SHUT_RDWR;
} }
if((err = pico_socket_shutdown(vs->picosock, mode)) < 0) { if((err = pico_socket_shutdown(vs->picosock, mode)) < 0) {

View File

@@ -81,7 +81,7 @@ namespace ZeroTier
int pico_eth_tx(struct pico_device *dev, void *buf, int len); int pico_eth_tx(struct pico_device *dev, void *buf, int len);
/* /*
* Read raw frames from RX frame buffer into the stack * Read raw frames from RX frame buffer into the stack
*/ */
int pico_eth_poll(struct pico_device *dev, int loop_score); int pico_eth_poll(struct pico_device *dev, int loop_score);
@@ -89,7 +89,7 @@ namespace ZeroTier
struct VirtualSocket; struct VirtualSocket;
class picoTCP class picoTCP
{ {
public: public:
/* /*
@@ -111,7 +111,7 @@ namespace ZeroTier
* Deletes a route from the picoTCP device * Deletes a route from the picoTCP device
*/ */
bool pico_route_del(VirtualTap *tap, const InetAddress &addr, const InetAddress &nm, int metric); bool pico_route_del(VirtualTap *tap, const InetAddress &addr, const InetAddress &nm, int metric);
/* /*
* Registers a DNS nameserver with the network stack * Registers a DNS nameserver with the network stack
*/ */
@@ -151,7 +151,7 @@ namespace ZeroTier
* Packets from the ZeroTier virtual wire enter the stack here * Packets from the ZeroTier virtual wire enter the stack here
*/ */
void pico_eth_rx(VirtualTap *tap, const ZeroTier::MAC &from,const ZeroTier::MAC &to,unsigned int etherType,const void *data,unsigned int len); void pico_eth_rx(VirtualTap *tap, const ZeroTier::MAC &from,const ZeroTier::MAC &to,unsigned int etherType,const void *data,unsigned int len);
/* /*
* Creates a stack-specific "socket" or "VirtualSocket object" * Creates a stack-specific "socket" or "VirtualSocket object"
*/ */
@@ -161,12 +161,12 @@ namespace ZeroTier
* Connect to remote host via userspace network stack interface - Called from VirtualTap * Connect to remote host via userspace network stack interface - Called from VirtualTap
*/ */
int pico_Connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen); int pico_Connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen);
/* /*
* Bind to a userspace network stack interface - Called from VirtualTap * Bind to a userspace network stack interface - Called from VirtualTap
*/ */
int pico_Bind(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen); int pico_Bind(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen);
/* /*
* Listen for incoming VirtualSockets - Called from VirtualTap * Listen for incoming VirtualSockets - Called from VirtualTap
*/ */
@@ -214,4 +214,4 @@ namespace ZeroTier
}; };
} }
#endif #endif