Removed files from attic/

This commit is contained in:
Joseph Henry
2019-01-25 10:38:39 -08:00
parent 270fc76b25
commit 2ac133b435
14 changed files with 0 additions and 5954 deletions

View File

@@ -1,45 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* Platform-specific implementations of common functions
*/
/*
#if defined(__linux__) || defined(__APPLE__)
#include <sys/socket.h>
#include <pthread.h>
#endif
#include <stdint.h>
#ifdef __linux__
#include <sys/syscall.h>
#include <unistd.h>
#endif
*/

View File

@@ -1,72 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* Platform-specific implementations of common functions
*/
#ifndef LIBZT_SYSUTILS_H
#define LIBZT_SYSUTILS_H
#include <stdint.h>
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#endif
/**
* @brief Current time in milliseconds since epoch, platform-aware convenience function.
*
* @usage For internal use only.
* @return Current time in integer form
*/
inline uint64_t time_now()
{
#ifdef _WIN32
FILETIME ft;
SYSTEMTIME st;
ULARGE_INTEGER tmp;
GetSystemTime(&st);
SystemTimeToFileTime(&st,&ft);
tmp.LowPart = ft.dwLowDateTime;
tmp.HighPart = ft.dwHighDateTime;
return (uint64_t)( ((tmp.QuadPart - 116444736000000000LL) / 10000L) + st.wMilliseconds );
#else
struct timeval tv;
#ifdef __LINUX__
syscall(SYS_gettimeofday,&tv,0); /* fix for musl libc broken gettimeofday bug */
#else
gettimeofday(&tv,(struct timezone *)0);
#endif
return ( (1000LL * (uint64_t)tv.tv_sec) + (uint64_t)(tv.tv_usec / 1000) );
#endif
}
#endif // _H

View File

@@ -1,266 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* Misc utilities
*/
/*
#include "Utilities.h"
#if defined(_WIN32_FALSE)
#include <WinSock2.h>
#include <stdint.h>
#include <string.h>
int inet_pton4(const char *src, void *dst)
{
uint8_t tmp[NS_INADDRSZ], *tp;
int saw_digit = 0;
int octets = 0;
*(tp = tmp) = 0;
int ch;
while ((ch = *src++) != '\0')
{
if (ch >= '0' && ch <= '9')
{
uint32_t n = *tp * 10 + (ch - '0');
if (saw_digit && *tp == 0)
return 0;
if (n > 255)
return 0;
*tp = n;
if (!saw_digit)
{
if (++octets > 4)
return 0;
saw_digit = 1;
}
}
else if (ch == '.' && saw_digit)
{
if (octets == 4)
return 0;
*++tp = 0;
saw_digit = 0;
}
else
return 0;
}
if (octets < 4)
return 0;
memcpy(dst, tmp, NS_INADDRSZ);
return 1;
}
*/
/*
int inet_pton6(const char *src, void *dst)
{
static const char xdigits[] = "0123456789abcdef";
uint8_t tmp[NS_IN6ADDRSZ];
uint8_t *tp = (uint8_t*) memset(tmp, '\0', NS_IN6ADDRSZ);
uint8_t *endp = tp + NS_IN6ADDRSZ;
uint8_t *colonp = NULL;
// Leading :: requires some special handling.
if (*src == ':')
{
if (*++src != ':')
return 0;
}
const char *curtok = src;
int saw_xdigit = 0;
uint32_t val = 0;
int ch;
while ((ch = tolower(*src++)) != '\0')
{
const char *pch = strchr(xdigits, ch);
if (pch != NULL)
{
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return 0;
saw_xdigit = 1;
continue;
}
if (ch == ':')
{
curtok = src;
if (!saw_xdigit)
{
if (colonp)
return 0;
colonp = tp;
continue;
}
else if (*src == '\0')
{
return 0;
}
if (tp + NS_INT16SZ > endp)
return 0;
*tp++ = (uint8_t) (val >> 8) & 0xff;
*tp++ = (uint8_t) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4(curtok, (char*) tp) > 0)
{
tp += NS_INADDRSZ;
saw_xdigit = 0;
break; // '\0' was seen by inet_pton4().
}
return 0;
}
if (saw_xdigit)
{
if (tp + NS_INT16SZ > endp)
return 0;
*tp++ = (uint8_t) (val >> 8) & 0xff;
*tp++ = (uint8_t) val & 0xff;
}
if (colonp != NULL)
{
//
// Since some memmove()'s erroneously fail to handle
// overlapping regions, we'll do the shift by hand.
//
const int n = tp - colonp;
if (tp == endp)
return 0;
for (int i = 1; i <= n; i++)
{
endp[-i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return 0;
memcpy(dst, tmp, NS_IN6ADDRSZ);
return 1;
}
*/
/*
int inet_pton(int af, const char *src, void *dst)
{
switch (af)
{
case AF_INET:
return inet_pton4(src, dst);
case AF_INET6:
return inet_pton6(src, dst);
default:
return -1;
}
}
#endif
char *beautify_eth_proto_nums(int proto)
{
if (proto == 0x0800) return (char*)"IPv4";
if (proto == 0x0806) return (char*)"ARP";
if (proto == 0x0842) return (char*)"Wake-on-LAN";
if (proto == 0x22F3) return (char*)"IETF TRILL Protocol";
if (proto == 0x22EA) return (char*)"Stream Reservation Protocol";
if (proto == 0x6003) return (char*)"DECnet Phase IV";
if (proto == 0x8035) return (char*)"Reverse Address Resolution Protocol";
if (proto == 0x809B) return (char*)"AppleTalk (Ethertalk)";
if (proto == 0x80F3) return (char*)"AppleTalk Address Resolution Protocol (AARP)";
if (proto == 0x8100) return (char*)"VLAN-tagged frame (IEEE 802.1Q) and Shortest Path Bridging IEEE 802.1aq with NNI compatibility";
if (proto == 0x8137) return (char*)"IPX";
if (proto == 0x8204) return (char*)"QNX Qnet";
if (proto == 0x86DD) return (char*)"IPv6";
if (proto == 0x8808) return (char*)"Ethernet flow control";
if (proto == 0x8809) return (char*)"Ethernet Slow Protocols";
if (proto == 0x8819) return (char*)"CobraNet";
if (proto == 0x8847) return (char*)"MPLS unicast";
if (proto == 0x8848) return (char*)"MPLS multicast";
if (proto == 0x8863) return (char*)"PPPoE Discovery Stage";
if (proto == 0x8864) return (char*)"PPPoE Session Stage";
if (proto == 0x886D) return (char*)"Intel Advanced Networking Services";
if (proto == 0x8870) return (char*)"Jumbo Frames (Obsoleted draft-ietf-isis-ext-eth-01)";
if (proto == 0x887B) return (char*)"HomePlug 1.0 MME";
if (proto == 0x888E) return (char*)"EAP over LAN (IEEE 802.1X)";
if (proto == 0x8892) return (char*)"PROFINET Protocol";
if (proto == 0x889A) return (char*)"HyperSCSI (SCSI over Ethernet)";
if (proto == 0x88A2) return (char*)"ATA over Ethernet";
if (proto == 0x88A4) return (char*)"EtherCAT Protocol";
if (proto == 0x88A8) return (char*)"Provider Bridging (IEEE 802.1ad) & Shortest Path Bridging IEEE 802.1aq";
if (proto == 0x88AB) return (char*)"Ethernet Powerlink[citation needed]";
if (proto == 0x88B8) return (char*)"GOOSE (Generic Object Oriented Substation event)";
if (proto == 0x88B9) return (char*)"GSE (Generic Substation Events) Management Services";
if (proto == 0x88BA) return (char*)"SV (Sampled Value Transmission)";
if (proto == 0x88CC) return (char*)"Link Layer Discovery Protocol (LLDP)";
if (proto == 0x88CD) return (char*)"SERCOS III";
if (proto == 0x88DC) return (char*)"WSMP, WAVE Short Message Protocol";
if (proto == 0x88E1) return (char*)"HomePlug AV MME[citation needed]";
if (proto == 0x88E3) return (char*)"Media Redundancy Protocol (IEC62439-2)";
if (proto == 0x88E5) return (char*)"MAC security (IEEE 802.1AE)";
if (proto == 0x88E7) return (char*)"Provider Backbone Bridges (PBB) (IEEE 802.1ah)";
if (proto == 0x88F7) return (char*)"Precision Time Protocol (PTP) over Ethernet (IEEE 1588)";
if (proto == 0x88FB) return (char*)"Parallel Redundancy Protocol (PRP)";
if (proto == 0x8902) return (char*)"IEEE 802.1ag Connectivity Fault Management (CFM) Protocol / ITU-T Recommendation Y.1731 (OAM)";
if (proto == 0x8906) return (char*)"Fibre Channel over Ethernet (FCoE)";
if (proto == 0x8914) return (char*)"FCoE Initialization Protocol";
if (proto == 0x8915) return (char*)"RDMA over Converged Ethernet (RoCE)";
if (proto == 0x891D) return (char*)"TTEthernet Protocol Control Frame (TTE)";
if (proto == 0x892F) return (char*)"High-availability Seamless Redundancy (HSR)";
if (proto == 0x9000) return (char*)"Ethernet Configuration Testing Protocol";
if (proto == 0x9100) return (char*)"VLAN-tagged (IEEE 802.1Q) frame with double tagging";
return (char*)"UNKNOWN";
}
*/
/*
void mac2str(char *macbuf, int len, unsigned char* addr)
{
snprintf(macbuf, len, "%02x:%02x:%02x:%02x:%02x:%02x",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
}
*/

View File

@@ -1,73 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* Misc utilities
*/
#ifndef LIBZT_UTILITIES_H
#define LIBZT_UTILITIES_H
#include <stdio.h>
namespace ZeroTier {
struct InetAddress;
}
#if defined(_WIN32_FALSE)
#define NS_INADDRSZ 4
#define NS_IN6ADDRSZ 16
#define NS_INT16SZ 2
int inet_pton4(const char *src, void *dst);
int inet_pton6(const char *src, void *dst);
int inet_pton(int af, const char *src, void *dst);
#endif
/**
* @brief Convert protocol numbers to human-readable strings
*
* @usage For internal use only.
* @param proto
* @return
*/
char *beautify_eth_proto_nums(int proto);
/**
* @brief Convert a raw MAC address byte array into a human-readable string
*
* @usage For internal use only.
* @param macbuf
* @param len
* @param addr
* @return
*/
void mac2str(char *macbuf, int len, unsigned char* addr);
#endif // _H

View File

@@ -1,54 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
*
*/
#ifndef LIBZT_VIRTUALBINDINGPAIR_H
#define LIBZT_VIRTUALBINDINGPAIR_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* A helper object for passing VirtualTap(s) and VirtualSocket(s) through the stack
*/
struct VirtualBindingPair
{
VirtualTap *tap;
VirtualSocket *vs;
VirtualBindingPair(VirtualTap *_tap, VirtualSocket *_vs) : tap(_tap), vs(_vs) {}
};
#ifdef __cplusplus
}
#endif
#endif // _H

View File

@@ -1,105 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* Platform- and stack-agnostic implementation of a socket-like object
*/
#include "libztDefs.h"
#ifdef ZT_VIRTUAL_SOCKET
#include <ctime>
#include <sys/socket.h>
#include "Phy.hpp"
#include "libzt.h"
#include "libztDebug.h"
#include "VirtualSocket.h"
#include "VirtualTap.h"
#include "RingBuffer.h"
class VirtualTap;
void VirtualSocket::apply_state(int state) {
// states may be set by application or by stack callbacks, thus this must be guarded
_op_m.lock();
_state &= state;
_op_m.unlock();
}
void VirtualSocket::set_state(int state) {
_op_m.lock();
_state = state;
_op_m.unlock();
}
int VirtualSocket::get_state() {
return _state;
}
VirtualSocket::VirtualSocket() {
DEBUG_EXTRA("this=%p",this);
memset(&local_addr, 0, sizeof(sockaddr_storage));
memset(&peer_addr, 0, sizeof(sockaddr_storage));
// ringbuffer used for incoming and outgoing traffic between app, stack, stack drivers, and ZT
TXbuf = new RingBuffer(ZT_TCP_TX_BUF_SZ);
RXbuf = new RingBuffer(ZT_TCP_RX_BUF_SZ);
// socketpair, I/O channel between app and stack drivers
ZT_PHY_SOCKFD_TYPE fdpair[2];
if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fdpair) < 0) {
if (errno < 0) {
DEBUG_ERROR("unable to create socketpair, errno=%d", errno);
return;
}
}
sdk_fd = fdpair[0];
app_fd = fdpair[1];
// set to non-blocking since these are used as the primary I/O channel
if (fcntl(sdk_fd, F_SETFL, O_NONBLOCK) < 0) {
DEBUG_ERROR("error while setting virtual socket to NONBLOCKING. exiting", errno);
exit(0);
}
}
VirtualSocket::~VirtualSocket() {
DEBUG_EXTRA("this=%p",this);
close(app_fd);
close(sdk_fd);
delete TXbuf;
delete RXbuf;
TXbuf = RXbuf = NULL;
//picosock->priv = NULL;
pcb = NULL;
}
#endif // ZT_VIRTUAL_SOCKET

View File

@@ -1,159 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* Platform- and stack-agnostic implementation of a socket-like object
*/
#ifndef LIBZT_VIRTUALSOCKET_H
#define LIBZT_VIRTUALSOCKET_H
#include <queue>
#include "RingBuffer.h"
#include "libztDefs.h"
#include "VirtualTap.h"
#include "Mutex.hpp"
#define VS_STATE_INACTIVE 0x000000u // Default value for newly created VirtualSocket
#define VS_STATE_ACTIVE 0x000001u // VirtualSocket is RX'ing or TX'ing without issue
#define VS_STATE_SHOULD_SHUTDOWN 0x000002u // Application, stack driver, or stack marked this VirtualSocket for death
#define VS_STATE_SHUTDOWN 0x000004u // VirtualSocket and underlying protocol control structures will not RX/TX
#define VS_STATE_CLOSED 0x000008u // VirtualSocket and underlying protocol control structures are closed
#define VS_STATE_UNHANDLED_CONNECTED 0x000010u // stack callback has received a connection but we haven't dealt with it
#define VS_STATE_CONNECTED 0x000020u // stack driver has akwnowledged new connection
#define VS_STATE_LISTENING 0x000040u // virtual socket is listening for incoming connections
#define VS_OPT_TCP_NODELAY 0x000000u // Nagle's algorithm
#define VS_OPT_SO_LINGER 0x000001u // VirtualSocket waits for data transmission before closure
/*
#define VS_RESERVED 0x000002u //
#define VS_RESERVED 0x000004u //
#define VS_RESERVED 0x000008u //
#define VS_RESERVED 0x000010u //
#define VS_RESERVED 0x000020u //
#define VS_RESERVED 0x000040u //
*/
#define VS_OPT_FD_NONBLOCKING 0x000080u // Whether the VirtualSocket exhibits non-blocking behaviour
/*
#define VS_RESERVED 0x000100u //
#define VS_RESERVED 0x000200u //
#define VS_RESERVED 0x000400u //
#define VS_RESERVED 0x000800u //
#define VS_RESERVED 0x001000u //
#define VS_RESERVED 0x002000u //
#define VS_RESERVED 0x004000u //
#define VS_RESERVED 0x008000u //
#define VS_RESERVED 0x010000u //
#define VS_RESERVED 0x020000u //
#define VS_RESERVED 0x040000u //
#define VS_RESERVED 0x080000u //
#define VS_RESERVED 0x100000u //
#define VS_RESERVED 0x200000u //
#define VS_RESERVED 0x400000u //
#define VS_RESERVED 0x800000u //
*/
#define vs_is_nonblocking(vs) (((vs)->optflags & VS_OPT_FD_NONBLOCKING) != 0)
#ifdef __cplusplus
extern "C" {
#endif
/**
* An abstraction of a socket that operates between the application-exposed platform-sockets
* and the network stack's representation of a protocol control structure. This object is used by
* the POSIX socket emulation layer and stack drivers.
*/
class VirtualSocket
{
private:
int _state = VS_STATE_INACTIVE;
public:
RingBuffer *TXbuf, *RXbuf;
ZeroTier::Mutex _tx_m, _rx_m, _op_m;
ZeroTier::PhySocket *sock = NULL;
void *pcb = NULL; // Protocol Control Block
#if defined(STACK_LWIP)
int32_t optflags = 0;
int linger;
/*
- TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated
for the data to be copied into. If this flag is not given, no new memory
should be allocated and the data should only be referenced by pointer. This
also means that the memory behind dataptr must not change until the data is
ACKed by the remote host
- TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted,
the PSH flag is set in the last segment created by this call to tcp_write.
If this flag is given, the PSH flag is not set.
*/
// copy as default, processed via pointer reference if set to 0. See notes in lwip_cb_sent() and lwip_Write()
int8_t copymode = 1; // TCP_WRITE_FLAG_COPY;
#endif
struct sockaddr_storage local_addr; // address we've bound to locally
struct sockaddr_storage peer_addr; // address of connection call to remote host
int socket_family = 0;
int socket_type = 0;
int protocol = 0;
int app_fd = 0; // used by app for I/O
int sdk_fd = 0; // used by lib for I/O
std::queue<VirtualSocket*> _AcceptedConnections;
VirtualTap *tap = NULL;
/**
* Sets the VirtualSocket's state value
*/
void apply_state(int state);
/**
* Sets the VirtualSocket's state value
*/
void set_state(int state);
/**
* Gets the VirtualSocket's state value
*/
int get_state();
/**
* default ctor
*/
VirtualSocket();
/**
* dtor
*/
~VirtualSocket();
};
#ifdef __cplusplus
}
#endif
#endif // _H

File diff suppressed because it is too large Load Diff

View File

@@ -1,443 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* VirtualSocket management layer
*/
#include "libztDefs.h"
namespace ZeroTier {
class Mutex;
struct InetAddress;
}
class VirtualSocket;
class VirtualTap;
extern ZeroTier::Mutex _multiplexer_lock;
VirtualSocket *get_virt_socket(int fd);
int del_virt_socket(int fd);
int add_unassigned_virt_socket(int fd, VirtualSocket *vs);
int del_unassigned_virt_socket(int fd);
int add_assigned_virt_socket(void *tap, VirtualSocket *vs, int fd);
int del_assigned_virt_socket(void *tap, VirtualSocket *vs, int fd);
//void *get_assigned_virtual_pair(int fd);
/**
* @brief Stops all VirtualTap interfaces and associated I/O loops
*
* @usage For internal use only.
* @param
* @return
*/
void disableTaps();
/**
* @brief Create a socket
*
* This function will return an integer which can be used in much the same way as a
* typical file descriptor, however it is only valid for use with libzt library calls
* as this is merely a facade which is associated with the internal socket representation
* of both the network stacks and drivers.
*
* @usage Call this after virt_start() has succeeded
* @param socket_family Address family (AF_INET, AF_INET6)
* @param socket_type Type of socket (SOCK_STREAM, SOCK_DGRAM, SOCK_RAW)
* @param protocol Protocols supported on this socket
* @return
*/
int virt_socket(int socket_family, int socket_type, int protocol);
/**
* @brief Connect a socket to a remote host
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param addr Remote host address to connect to
* @param addrlen Length of address
* @return
*/
int virt_connect(int fd, const struct sockaddr *addr, socklen_t addrlen);
/**
* @brief Bind a socket to a virtual interface
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param addr Local interface address to bind to
* @param addrlen Length of address
* @return
*/
int virt_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
/**
* @brief Listen for incoming connections
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param backlog Number of backlogged connection allowed
* @return
*/
int virt_listen(int fd, int backlog);
/**
* @brief Accept an incoming connection
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param addr Address of remote host for accepted connection
* @param addrlen Length of address
* @return
*/
int virt_accept(int fd, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Accept an incoming connection
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param addr Address of remote host for accepted connection
* @param addrlen Length of address
* @param flags
* @return
*/
#if defined(__linux__)
int virt_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags);
#endif
/**
* @brief Set socket options
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param level Protocol level to which option name should apply
* @param optname Option name to set
* @param optval Source of option value to set
* @param optlen Length of option value
* @return
*/
int virt_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen);
/**
* @brief Get socket options
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param level Protocol level to which option name should apply
* @param optname Option name to get
* @param optval Where option value will be stored
* @param optlen Length of value
* @return
*/
int virt_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen);
/**
* @brief Get socket name
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param addr Name associated with this socket
* @param addrlen Length of name
* @return
*/
int virt_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Get the peer name for the remote end of a connected socket
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param addr Name associated with remote end of this socket
* @param addrlen Length of name
* @return
*/
int virt_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Gets current hostname
*
* @usage Call this after virt_start() has succeeded
* @param name
* @param len
* @return
*/
int virt_gethostname(char *name, size_t len);
/**
* @brief Sets current hostname
*
* @usage Call this after virt_start() has succeeded
* @param name
* @param len
* @return
*/
int virt_sethostname(const char *name, size_t len);
/**
* @brief Return a pointer to an object with the following structure describing an internet host referenced by name
*
* @usage Call this after virt_start() has succeeded
* @param name
* @return Returns pointer to hostent structure otherwise NULL if failure
*/
struct hostent *virt_gethostbyname(const char *name);
/**
* @brief Close a socket
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @return
*/
int virt_close(int fd);
/**
* @brief Waits for one of a set of file descriptors to become ready to perform I/O.
*
* @usage Call this after virt_start() has succeeded
* @param fds
* @param nfds
* @param timeout
* @return
*/
/*
#ifdef __linux__
int virt_poll(struct pollfd *fds, nfds_t nfds, int timeout);
#endif
*/
/**
* @brief Monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready"
*
* @usage Call this after virt_start() has succeeded
* @param nfds
* @param readfds
* @param writefds
* @param exceptfds
* @param timeout
* @return
*/
int virt_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
/**
* @brief Issue file control commands on a socket
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param cmd
* @param flags
* @return
*/
int virt_fcntl(int fd, int cmd, int flags);
/**
* @brief Control a device
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param request
* @param argp
* @return
*/
int virt_ioctl(int fd, unsigned long request, void *argp);
/**
* @brief Send data to remote host
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param buf Pointer to data buffer
* @param len Length of data to write
* @param flags
* @return
*/
ssize_t virt_send(int fd, const void *buf, size_t len, int flags);
/**
* @brief Send data to remote host
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param buf Pointer to data buffer
* @param len Length of data to write
* @param flags
* @param addr Destination address
* @param addrlen Length of destination address
* @return
*/
ssize_t virt_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen);
/**
* @brief Send message to remote host
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param msg
* @param flags
* @return
*/
ssize_t virt_sendmsg(int fd, const struct msghdr *msg, int flags);
/**
* @brief Receive data from remote host
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param buf Pointer to data buffer
* @param len Length of data buffer
* @param flags
* @return
*/
ssize_t virt_recv(int fd, void *buf, size_t len, int flags);
/**
* @brief Receive data from remote host
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param buf Pointer to data buffer
* @param len Length of data buffer
* @param flags
* @param addr
* @param addrlen
* @return
*/
ssize_t virt_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Receive a message from remote host
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param msg
* @param flags
* @return
*/
ssize_t virt_recvmsg(int fd, struct msghdr *msg,int flags);
/**
* @brief Read bytes from socket onto buffer
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param buf Pointer to data buffer
* @param len Length of data buffer to receive data
* @return
*/
int virt_read(int fd, void *buf, size_t len);
/**
* @brief Write bytes from buffer to socket
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param buf Pointer to data buffer
* @param len Length of buffer to write
* @return
*/
int virt_write(int fd, const void *buf, size_t len);
/**
* @brief Shut down some aspect of a socket (read, write, or both)
*
* @usage Call this after virt_start() has succeeded
* @param fd File descriptor (only valid for use with libzt calls)
* @param how Which aspects of the socket should be shut down
* @return
*/
int virt_shutdown(int fd, int how);
/**
* @brief Adds a DNS nameserver for the network stack to use
*
* @usage Call this after virt_start() has succeeded
* @param addr Address for DNS nameserver
* @return
*/
int virt_add_dns_nameserver(struct sockaddr *addr);
/**
* @brief Removes a DNS nameserver
*
* @usage Call this after virt_start() has succeeded
* @param addr Address for DNS nameserver
* @return
*/
int virt_del_dns_nameserver(struct sockaddr *addr);
/**
* @brief Returns whether one can add a new socket or not. This depends on network stack in use.
*
* @usage Call this after zts_start() has succeeded
* @param socket_type
* @return
*/
bool virt_can_provision_new_socket(int socket_type);
/**
* @brief Returns the number of VirtualSockets either already provisioned or waiting to be
* Some network stacks may have a limit on the number of sockets that they can
* safely handle due to timer construction, this is a way to check that we
* haven't passed that limit. Someday if multiple stacks are used simultaneously
* the logic for this function should change accordingly.
*
* @usage Call this after zts_start() has succeeded
* @return
*/
int virt_num_active_sockets();
/**
* @brief Return the maximum number of sockets allowable by platform/stack configuration
*
* @usage Call this after zts_start() has succeeded
* @param socket_type
* @return
*/
int virt_maxsockets(int socket_type);
/**
* @brief Return the number of currently active picoTCP timers
*
* @usage Call this after zts_start() has succeeded
* @return
*/
//int pico_ntimers();
/**
* @brief Convert a struct sockaddr to a ZeroTier::InetAddress
*
* @usage For internal use only.
* @param socket_family
* @param addr
* @param inet
* @return
*/
void sockaddr2inet(int socket_family, const struct sockaddr *addr, ZeroTier::InetAddress *inet);

View File

@@ -1,712 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* ZeroTier One service control wrapper
*/
/*
#include "libzt.h"
#include "ZT1Service.h"
#include "Phy.hpp"
#include "OneService.hpp"
#include "InetAddress.hpp"
#include "OSUtils.hpp"
#include "Mutex.hpp"
#include <pthread.h>
*/
/*
std::vector<void*> vtaps;
ZeroTier::Mutex _vtaps_lock;
ZeroTier::Mutex _service_lock;
*/
/*
#ifdef __cplusplus
extern "C" {
#endif
static ZeroTier::OneService *zt1Service;
std::string homeDir; // Platform-specific dir we *must* use internally
std::string netDir; // Where network .conf files are to be written
ZeroTier::Mutex _multiplexer_lock;
int servicePort = LIBZT_DEFAULT_PORT;
bool _freeHasBeenCalled = false;
bool _serviceIsShuttingDown = false;
#if defined(_WIN32)
WSADATA wsaData;
#include <Windows.h>
#endif
void api_sleep(int interval_ms);
pthread_t service_thread;
//////////////////////////////////////////////////////////////////////////////
// ZeroTier Core helper functions for libzt - DON'T CALL THESE DIRECTLY //
//////////////////////////////////////////////////////////////////////////////
std::vector<ZT_VirtualNetworkRoute> *zts_get_network_routes(const uint64_t nwid)
{
return zt1Service->getRoutes(nwid);
}
VirtualTap *getTapByNWID(uint64_t nwid)
{
_vtaps_lock.lock();
VirtualTap *s, *tap = nullptr;
for (size_t i=0; i<vtaps.size(); i++) {
s = (VirtualTap*)vtaps[i];
if (s->_nwid == nwid) { tap = s; }
}
_vtaps_lock.unlock();
return tap;
}
VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr)
{
_vtaps_lock.lock();
VirtualTap *s, *tap = nullptr;
//char ipbuf[64], ipbuf2[64], ipbuf3[64];
for (size_t i=0; i<vtaps.size(); i++) {
s = (VirtualTap*)vtaps[i];
// check address schemes
for (int j=0; j<(int)(s->_ips.size()); j++) {
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));
if (s->_ips[j].isEqualPrefix(addr)
|| s->_ips[j].ipsEqual(addr)
|| s->_ips[j].containsAddress(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));
_vtaps_lock.unlock();
return s;
}
}
}
// check managed routes
if (tap == NULL) {
std::vector<ZT_VirtualNetworkRoute> *managed_routes = zt1Service->getRoutes(s->_nwid);
ZeroTier::InetAddress target, nm, via;
for (size_t i=0; i<managed_routes->size(); i++) {
target = managed_routes->at(i).target;
nm = target.netmask();
via = managed_routes->at(i).via;
if (target.containsAddress(addr)) {
// DEBUG_INFO("chose tap with route <target=%s, nm=%s, via=%s>", target.toString(ipbuf),
// nm.toString(ipbuf2), via.toString(ipbuf3));
_vtaps_lock.unlock();
return s;
}
}
}
}
_vtaps_lock.unlock();
return tap;
}
VirtualTap *getTapByName(char *ifname)
{
_vtaps_lock.lock();
VirtualTap *s, *tap = nullptr;
for (size_t i=0; i<vtaps.size(); i++) {
s = (VirtualTap*)vtaps[i];
if (strcmp(s->_dev.c_str(), ifname) == false) {
tap = s;
}
}
_vtaps_lock.unlock();
return tap;
}
VirtualTap *getTapByIndex(size_t index)
{
_vtaps_lock.lock();
VirtualTap *s, *tap = nullptr;
for (size_t i=0; i<vtaps.size(); i++) {
s = (VirtualTap*)vtaps[i];
if (s->ifindex == index) {
tap = s;
}
}
_vtaps_lock.unlock();
return tap;
}
VirtualTap *getAnyTap()
{
_vtaps_lock.lock();
VirtualTap *vtap = NULL;
if (vtaps.size()) {
vtap = (VirtualTap *)vtaps[0];
}
_vtaps_lock.unlock();
return vtap;
}
// Starts a ZeroTier service in the background
#if defined(_WIN32)
DWORD WINAPI zts_start_service(LPVOID thread_id)
#else
void *zts_start_service(void *thread_id)
#endif
{
void *retval;
DEBUG_INFO("identities are stored in path (%s)", homeDir.c_str());
netDir = homeDir + "/networks.d";
zt1Service = (ZeroTier::OneService *)0;
if (!homeDir.length()) {
DEBUG_ERROR("homeDir is empty, could not construct path");
retval = NULL;
} if (zt1Service) {
DEBUG_INFO("service already started, doing nothing");
retval = NULL;
}
try {
std::vector<std::string> hpsp(ZeroTier::OSUtils::split(homeDir.c_str(), ZT_PATH_SEPARATOR_S,"",""));
std::string ptmp;
if (homeDir[0] == ZT_PATH_SEPARATOR) {
ptmp.push_back(ZT_PATH_SEPARATOR);
}
for (std::vector<std::string>::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) {
if (ptmp.length() > 0) {
ptmp.push_back(ZT_PATH_SEPARATOR);
}
ptmp.append(*pi);
if ((*pi != ".")&&(*pi != "..")) {
if (ZeroTier::OSUtils::mkdir(ptmp) == false) {
DEBUG_ERROR("home path does not exist, and could not create");
perror("error\n");
}
}
}
for(;;) {
_service_lock.lock();
zt1Service = OneService::newInstance(homeDir.c_str(),servicePort);
_service_lock.unlock();
switch(zt1Service->run()) {
case OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done
case OneService::ONE_NORMAL_TERMINATION:
break;
case OneService::ONE_UNRECOVERABLE_ERROR:
fprintf(stderr,"fatal error: %s" ZT_EOL_S,zt1Service->fatalErrorMessage().c_str());
break;
case OneService::ONE_IDENTITY_COLLISION: {
delete zt1Service;
zt1Service = (OneService *)0;
std::string oldid;
OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid);
if (oldid.length()) {
OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid);
OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str());
OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str());
}
} continue; // restart!
}
break; // terminate loop -- normally we don't keep restarting
}
_serviceIsShuttingDown = true;
_service_lock.lock();
delete zt1Service;
zt1Service = (OneService *)0;
_service_lock.unlock();
_serviceIsShuttingDown = false;
} catch ( ... ) {
fprintf(stderr,"unexpected exception starting main OneService instance" ZT_EOL_S);
}
pthread_exit(NULL);
}
int zts_get_num_assigned_addresses(const uint64_t nwid)
{
if (!zt1Service) {
return -1;
}
VirtualTap *tap = getTapByNWID(nwid);
if (!tap) {
return -1;
}
int sz;
_vtaps_lock.lock();
sz = tap->_ips.size();
_vtaps_lock.unlock();
return sz;
}
int zts_get_address_at_index(
const uint64_t nwid, const int index, struct sockaddr *addr, socklen_t *addrlen)
{
if (!zt1Service) {
return -1;
}
VirtualTap *tap = getTapByNWID(nwid);
int err = -1;
if (!tap) {
return err;
}
_vtaps_lock.lock();
if (index > -1 && index <= (int)tap->_ips.size()) {
memcpy(addr, &(tap->_ips[index]), *addrlen);
*addrlen = tap->_ips[index].isV4() ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
err = 0;
}
_vtaps_lock.unlock();
return err;
}
//////////////////////////////////////////////////////////////////////////////
// ZeroTier Service Controls //
//////////////////////////////////////////////////////////////////////////////
zts_err_t zts_set_service_port(int portno)
{
zts_err_t retval = ZTS_ERR_OK;
_service_lock.lock();
if (zt1Service) {
DEBUG_INFO("please stop service before attempting to change port");
retval = ZTS_ERR_SERVICE;
}
else {
if (portno > -1 && portno < ZTS_MAX_PORT) {
// 0 is allowed, signals to ZT service to bind to a random port
servicePort = portno;
retval = ZTS_ERR_OK;
}
}
_service_lock.unlock();
return retval;
}
int zts_get_service_port()
{
return servicePort;
}
int zts_get_address(const uint64_t nwid, struct sockaddr_storage *addr,
const int address_family)
{
int err = -1;
if (!zt1Service) {
return ZTS_ERR_SERVICE;
}
VirtualTap *tap = getTapByNWID(nwid);
if (!tap) {
return -1;
}
_vtaps_lock.lock();
socklen_t addrlen = address_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
for (size_t i=0; i<tap->_ips.size(); i++) {
if (address_family == AF_INET) {
if (tap->_ips[i].isV4()) {
memcpy(addr, &(tap->_ips[i]), addrlen);
addr->ss_family = AF_INET;
err = 0;
break;
}
}
if (address_family == AF_INET6) {
if (tap->_ips[i].isV6()) {
memcpy(addr, &(tap->_ips[i]), addrlen);
addr->ss_family = AF_INET6;
err = 0;
break;
}
}
}
_vtaps_lock.unlock();
return err; // nothing found
}
int zts_has_address(const uint64_t nwid)
{
struct sockaddr_storage ss;
memset(&ss, 0, sizeof(ss));
zts_get_address(nwid, &ss, AF_INET);
if (ss.ss_family == AF_INET) {
return true;
}
zts_get_address(nwid, &ss, AF_INET6);
if (ss.ss_family == AF_INET6) {
return true;
}
return false;
}
void zts_get_6plane_addr(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId)
{
ZeroTier::InetAddress _6planeAddr = ZeroTier::InetAddress::makeIpv66plane(nwid,nodeId);
memcpy(addr, _6planeAddr.rawIpData(), sizeof(struct sockaddr_storage));
}
void zts_get_rfc4193_addr(struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId)
{
ZeroTier::InetAddress _rfc4193Addr = ZeroTier::InetAddress::makeIpv6rfc4193(nwid,nodeId);
memcpy(addr, _rfc4193Addr.rawIpData(), sizeof(struct sockaddr_storage));
}
zts_err_t zts_join(const uint64_t nwid, int blocking)
{
zts_err_t retval = ZTS_ERR_OK;
_service_lock.lock();
if (blocking) {
if (!zt1Service) {
retval = ZTS_ERR_SERVICE;
} else {
while (!_zts_node_online()) {
if (_serviceIsShuttingDown) {
retval = ZTS_ERR_SERVICE;
break;
}
api_sleep(ZTO_WRAPPER_CHECK_INTERVAL);
}
}
} else {
if (!zt1Service || !_zts_node_online()) {
retval = ZTS_ERR_SERVICE;
}
}
if (!retval) {
DEBUG_INFO("joining %llx", (unsigned long long)nwid);
if (nwid == 0) {
retval = ZTS_ERR_INVALID_ARG;
}
if (zt1Service) {
zt1Service->join(nwid);
}
// provide ZTO service reference to virtual taps
// TODO: This might prove to be unreliable, but it works for now
_vtaps_lock.lock();
for (size_t i=0;i<vtaps.size(); i++) {
VirtualTap *s = (VirtualTap*)vtaps[i];
s->zt1ServiceRef=(void*)zt1Service;
}
_vtaps_lock.unlock();
}
_service_lock.unlock();
return retval;
}
zts_err_t zts_leave(const uint64_t nwid, int blocking)
{
zts_err_t retval = ZTS_ERR_OK;
_service_lock.lock();
if (blocking) {
if (!zt1Service) {
retval = ZTS_ERR_SERVICE;
} else {
while (!_zts_node_online()) {
if (_serviceIsShuttingDown) {
retval = ZTS_ERR_SERVICE;
break;
}
api_sleep(ZTO_WRAPPER_CHECK_INTERVAL);
}
}
} else {
if (!zt1Service || !_zts_node_online()) {
retval = ZTS_ERR_SERVICE;
}
}
if (!retval) {
DEBUG_INFO("leaving %llx", (unsigned long long)nwid);
if (nwid == 0) {
retval = ZTS_ERR_INVALID_ARG;
}
if (zt1Service) {
zt1Service->leave(nwid);
}
}
_service_lock.unlock();
return retval;
}
int zts_core_running()
{
_service_lock.lock();
int retval = zt1Service == NULL ? false : zt1Service->isRunning();
_service_lock.unlock();
return retval;
}
int zts_stack_running()
{
// PENDING: what if no networks are joined, the stack is still running. semantics need to change here
_service_lock.lock();
_vtaps_lock.lock();
// PENDING: Perhaps a more robust way to check for this
int running = vtaps.size() > 0 ? true : false;
_vtaps_lock.unlock();
_service_lock.unlock();
return running;
}
int zts_ready()
{
return zts_core_running() && zts_stack_running();
}
zts_err_t zts_start(const char *path, int blocking = false)
{
zts_err_t retval = ZTS_ERR_OK;
if (zt1Service) {
return ZTS_ERR_SERVICE; // already initialized
}
if (_freeHasBeenCalled) {
return ZTS_ERR_INVALID_OP; // stack (presumably lwIP) has been dismantled, an application restart is required now
}
if (path) {
homeDir = path;
}
#if defined(_WIN32)
WSAStartup(MAKEWORD(2, 2), &wsaData); // initialize WinSock. Used in Phy for loopback pipe
HANDLE thr = CreateThread(NULL, 0, zts_start_service, NULL, 0, NULL);
#else
retval = pthread_create(&service_thread, NULL, zts_start_service, NULL);
// PENDING: Wait for confirmation that the ZT service has been initialized,
// this wait condition is so brief and so rarely used that it should be
// acceptable even in a non-blocking context.
while(!zt1Service) {
api_sleep(10);
}
#endif
if (blocking) { // block to prevent service calls before we're ready
ZT_NodeStatus status;
status.online = 0;
DEBUG_INFO("waiting for zerotier service thread to start");
while (zts_core_running() == false || zt1Service->getNode() == NULL) {
api_sleep(ZTO_WRAPPER_CHECK_INTERVAL);
}
DEBUG_INFO("waiting for node address assignment");
while (zt1Service->getNode()->address() <= 0) {
api_sleep(ZTO_WRAPPER_CHECK_INTERVAL);
}
DEBUG_INFO("waiting for node to come online. ensure the node is authorized to join the network");
while (true) {
_service_lock.lock();
if (zt1Service && zt1Service->getNode() && zt1Service->getNode()->online()) {
DEBUG_INFO("node is fully online");
_service_lock.unlock();
break;
}
api_sleep(ZTO_WRAPPER_CHECK_INTERVAL);
_service_lock.unlock();
}
DEBUG_INFO("node=%llx", (unsigned long long)zts_get_node_id());
}
return retval;
}
zts_err_t zts_startjoin(const char *path, const uint64_t nwid)
{
zts_err_t retval = ZTS_ERR_OK;
if ((retval = zts_start(path, true)) < 0) {
return retval;
}
while (true) {
try {
zts_join(nwid);
break;
}
catch( ... ) {
DEBUG_ERROR("there was a problem joining the virtual network %llx",
(unsigned long long)nwid);
api_sleep(ZTO_WRAPPER_CHECK_INTERVAL);
}
}
while (zts_has_address(nwid) == false) {
api_sleep(ZTO_WRAPPER_CHECK_INTERVAL);
}
return retval;
}
zts_err_t zts_stop(int blocking)
{
zts_err_t ret = ZTS_ERR_OK;
_service_lock.lock();
VirtualTap *s;
if (zt1Service) {
zt1Service->terminate();
vtaps.clear();
}
else {
ret = ZTS_ERR_SERVICE; // nothing to do
}
#if defined(_WIN32)
WSACleanup();
#endif
_service_lock.unlock();
if (blocking) {
// block until service thread successfully exits
pthread_join(service_thread, NULL);
}
return ret;
}
zts_err_t zts_free()
{
zts_err_t retval = 0;
_service_lock.lock();
if (_freeHasBeenCalled) {
retval = ZTS_ERR_INVALID_OP;
_service_lock.unlock();
} else {
_freeHasBeenCalled = true;
_service_lock.unlock();
retval = zts_stop();
}
// PENDING: add stack shutdown logic
return retval;
}
zts_err_t zts_get_path(char *homePath, size_t *len)
{
zts_err_t retval = ZTS_ERR_OK;
if (!homePath || *len <= 0 || *len > ZT_HOME_PATH_MAX_LEN) {
*len = 0; // signal that nothing was copied to the buffer
retval = ZTS_ERR_INVALID_ARG;
} else if (homeDir.length()) {
memset(homePath, 0, *len);
size_t buf_len = *len < homeDir.length() ? *len : homeDir.length();
memcpy(homePath, homeDir.c_str(), buf_len);
*len = buf_len;
}
return retval;
}
uint64_t zts_get_node_id()
{
uint64_t nodeId = 0;
_service_lock.lock();
if (_can_perform_service_operation()) {
nodeId = zt1Service->getNode()->address();
}
_service_lock.unlock();
return nodeId;
}
uint64_t zts_get_node_id_from_file(const char *filepath)
{
std::string fname("identity.public");
std::string fpath(filepath);
std::string oldid;
if (ZeroTier::OSUtils::fileExists((fpath + ZT_PATH_SEPARATOR_S + fname).c_str(), false)) {
ZeroTier::OSUtils::readFile((fpath + ZT_PATH_SEPARATOR_S + fname).c_str(), oldid);
return Utils::hexStrToU64(oldid.c_str());
}
return 0;
}
int zts_get_peer_count()
{
unsigned int peerCount = 0;
_service_lock.lock();
if (_can_perform_service_operation()) {
peerCount = zt1Service->getNode()->peers()->peerCount;
} else {
peerCount = ZTS_ERR_SERVICE;
}
_service_lock.unlock();
return peerCount;
}
//////////////////////////////////////////////////////////////////////////////
// Internal ZeroTier Service Controls (user application shall not use these)//
//////////////////////////////////////////////////////////////////////////////
int _zts_node_online()
{
return zt1Service && zt1Service->getNode() && zt1Service->getNode()->online();
}
int _can_perform_service_operation()
{
return zt1Service && zt1Service->isRunning() && zt1Service->getNode() && zt1Service->getNode()->online() && !_serviceIsShuttingDown;
}
bool _ipv6_in_subnet(ZeroTier::InetAddress *subnet, ZeroTier::InetAddress *addr)
{
ZeroTier::InetAddress r(addr);
ZeroTier::InetAddress b(subnet);
const unsigned int bits = subnet->netmaskBits();
switch(r.ss_family) {
case AF_INET:
reinterpret_cast<struct sockaddr_in *>(&r)->sin_addr.s_addr &= ZeroTier::Utils::hton((uint32_t)(0xffffffff << (32 - bits)));
break;
case AF_INET6: {
uint64_t nm[2];
uint64_t nm2[2];
memcpy(nm,reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,16);
memcpy(nm2,reinterpret_cast<struct sockaddr_in6 *>(&b)->sin6_addr.s6_addr,16);
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))));
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))));
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);
}
break;
}
char b0[64], b1[64];
memset(b0, 0, 64);
memset(b1, 0, 64);
return !strcmp(r.toIpString(b0), b.toIpString(b1));
}
void api_sleep(int interval_ms)
{
#if defined(_WIN32)
Sleep(interval_ms);
#else
struct timespec sleepValue = {0};
sleepValue.tv_nsec = interval_ms * 500000;
nanosleep(&sleepValue, NULL);
#endif
}
#ifdef __cplusplus
}
#endif
*/

View File

@@ -1,33 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* ZeroTier One service control wrapper header file
*/

View File

@@ -1,541 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
/**
* @file
*
* Javs JNI wrapper for POSIX-like socket API
* JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
*/
#ifdef SDK_JNI
#if defined(_MSC_VER)
//
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "libzt.h"
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
namespace ZeroTier {
void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr);
void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr);
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, fd_set *dest_fd_set);
void fdset2ztfdset(JNIEnv *env, int nfds, fd_set *src_fd_set, jobject dest_ztfd_set);
//////////////////////////////////////////////////////////////////////////////
// ZeroTier service controls //
//////////////////////////////////////////////////////////////////////////////
/*
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_set_1service_1port(
JNIEnv *env, jobject thisObj, jint port)
{
zts_set_service_port(port);
}
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_get_1service_1port(
JNIEnv *env, jobject thisObj, jint port)
{
return zts_get_service_port();
}
*/
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_start(
JNIEnv *env, jobject thisObj, jstring path, jboolean blocking)
{
if (path) {
const char* utf_string = env->GetStringUTFChars(path, NULL);
zts_start(utf_string, blocking);
env->ReleaseStringUTFChars(path, utf_string);
}
}
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_startjoin(
JNIEnv *env, jobject thisObj, jstring path, jlong nwid)
{
if (path && nwid) {
const char* utf_string = env->GetStringUTFChars(path, NULL);
zts_startjoin(utf_string, (uint64_t)nwid);
env->ReleaseStringUTFChars(path, utf_string);
}
}
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop(
JNIEnv *env, jobject thisObj)
{
zts_stop();
}
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free(
JNIEnv *env, jobject thisObj)
{
zts_free();
}
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_core_1running(
JNIEnv *env, jobject thisObj)
{
return zts_core_running();
}
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_stack_1running(
JNIEnv *env, jobject thisObj)
{
return zts_stack_running();
}
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_ready(
JNIEnv *env, jobject thisObj)
{
return zts_ready();
}
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_get_1service_1port(
JNIEnv *env, jobject thisObj, jint port)
{
return zts_get_num_joined_networks();
}xxx
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join(
JNIEnv *env, jobject thisObj, jlong nwid)
{
return zts_join((uint64_t)nwid);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave(
JNIEnv *env, jobject thisObj, jlong nwid)
{
return zts_leave((uint64_t)nwid);
}
JNIEXPORT jstring JNICALL Java_com_zerotier_libzt_ZeroTier_get_1path(
JNIEnv *env, jobject thisObj)
{
char pathBuf[ZT_HOME_PATH_MAX_LEN];
zts_get_path(pathBuf, ZT_HOME_PATH_MAX_LEN);
return env->NewStringUTF(pathBuf);
}
JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1id(
JNIEnv *env, jobject thisObj)
{
return zts_get_node_id();
}
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_get_1num_1assigned_1addresses(
JNIEnv *env, jobject thisObj, jlong nwid)
{
return zts_get_num_assigned_addresses(nwid);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1address_1at_1index(
JNIEnv *env, jobject thisObj, jlong nwid, jint index, jobject addr)
{
struct sockaddr_storage ss;
socklen_t addrlen = sizeof(struct sockaddr_storage);
int err = zts_get_address_at_index(nwid, index, (struct sockaddr*)&ss, &addrlen);
ss2zta(env, &ss, addr);
return err;
}
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_has_1address(
JNIEnv *env, jobject thisObj, jlong nwid)
{
return zts_has_address(nwid);
}
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_get_1address(
JNIEnv *env, jobject thisObj, jlong nwid, jint address_family, jobject addr)
{
struct sockaddr_storage ss;
int err = zts_get_address((uint64_t)nwid, &ss, address_family);
ss2zta(env, &ss, addr);
return err;
}
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_get_16plane_1addr(
JNIEnv *env, jobject thisObj, jlong nwid, jlong nodeId, jobject addr)
{
struct sockaddr_storage ss;
zts_get_6plane_addr(&ss, nwid, nodeId);
ss2zta(env, &ss, addr);
}
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_get_1rfc4193_1addr(
JNIEnv *env, jobject thisObj, jlong nwid, jlong nodeId, jobject addr)
{
struct sockaddr_storage ss;
zts_get_rfc4193_addr(&ss, nwid, nodeId);
ss2zta(env, &ss, addr);
}
JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1count(
JNIEnv *env, jobject thisObj)
{
return zts_get_peer_count();
}
//////////////////////////////////////////////////////////////////////////////
// ZeroTier Socket API //
//////////////////////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_socket(
JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol)
{
return zts_socket(family, type, protocol);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_connect(
JNIEnv *env, jobject thisObj, jint fd, jobject addr)
{
struct sockaddr_storage ss;
zta2ss(env, &ss, addr);
socklen_t addrlen = ss.ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
return zts_connect(fd, (struct sockaddr *)&ss, addrlen);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_bind(
JNIEnv *env, jobject thisObj, jint fd, jobject addr)
{
struct sockaddr_storage ss;
zta2ss(env, &ss, addr);
socklen_t addrlen = ss.ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
return zts_bind(fd, (struct sockaddr*)&ss, addrlen);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_listen(
JNIEnv *env, jobject thisObj, jint fd, int backlog)
{
return zts_listen(fd, backlog);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept(
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port)
{
struct sockaddr_storage ss;
socklen_t addrlen = sizeof(struct sockaddr_storage);
int err = zts_accept(fd, (struct sockaddr *)&ss, &addrlen);
ss2zta(env, &ss, addr);
return err;
}
#if defined(__linux__)
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept4(
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port, jint flags)
{
struct sockaddr_storage ss;
socklen_t addrlen = sizeof(struct sockaddr_storage);
int err = zts_accept4(fd, (struct sockaddr *)&ss, &addrlen, flags);
ss2zta(env, &ss, addr);
return err;
}
#endif
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_setsockopt(
JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jint optval, jint optlen)
{
return zts_setsockopt(fd, level, optname, (void*)(uintptr_t)optval, optlen);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getsockopt(
JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jint optval, jint optlen)
{
return zts_getsockopt(fd, level, optname, (void*)(uintptr_t)optval, (socklen_t *)optlen);
}
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_getsockname(JNIEnv *env, jobject thisObj,
jint fd, jobject addr)
{
struct sockaddr_storage ss;
socklen_t addrlen = sizeof(struct sockaddr_storage);
int err = zts_getsockname(fd, (struct sockaddr *)&ss, &addrlen);
ss2zta(env, &ss, addr);
return err;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getpeername(JNIEnv *env, jobject thisObj,
jint fd, jobject addr)
{
struct sockaddr_storage ss;
int err = zts_getpeername(fd, (struct sockaddr *)&ss, (socklen_t *)sizeof(struct sockaddr_storage));
ss2zta(env, &ss, addr);
return err;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_close(
JNIEnv *env, jobject thisObj, jint fd)
{
return zts_close(fd);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_fcntl(
JNIEnv *env, jobject thisObj, jint fd, jint cmd, jint flags)
{
return zts_fcntl(fd, cmd, flags);
}
JNIEXPORT int JNICALL Java_com_zerotier_libzt_ZeroTier_ioctl(jint fd, jlong request, void *argp)
{
return zts_ioctl(fd, request, argp);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_send(
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, int flags)
{
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
int w = zts_send(fd, data, env->GetArrayLength(buf), flags);
env->ReleasePrimitiveArrayCritical(buf, data, 0);
return w;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_sendto(
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr)
{
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
struct sockaddr_storage ss;
zta2ss(env, &ss, addr);
socklen_t addrlen = ss.ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
int w = zts_sendto(fd, data, env->GetArrayLength(buf), flags, (struct sockaddr *)&ss, addrlen);
env->ReleasePrimitiveArrayCritical(buf, data, 0);
return w;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recv(JNIEnv *env, jobject thisObj,
jint fd, jbyteArray buf, jint flags)
{
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
int r = zts_recv(fd, data, env->GetArrayLength(buf), flags);
env->ReleasePrimitiveArrayCritical(buf, data, 0);
return r;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recvfrom(
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr)
{
socklen_t addrlen = sizeof(struct sockaddr_storage);
struct sockaddr_storage ss;
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
int r = zts_recvfrom(fd, data, env->GetArrayLength(buf), flags, (struct sockaddr *)&ss, &addrlen);
env->ReleasePrimitiveArrayCritical(buf, data, 0);
ss2zta(env, &ss, addr);
return r;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_read(JNIEnv *env, jobject thisObj,
jint fd, jbyteArray buf)
{
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
int r = zts_read(fd, data, env->GetArrayLength(buf));
env->ReleasePrimitiveArrayCritical(buf, data, 0);
return r;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write(JNIEnv *env, jobject thisObj,
jint fd, jbyteArray buf)
{
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
int w = zts_write(fd, data, env->GetArrayLength(buf));
env->ReleasePrimitiveArrayCritical(buf, data, 0);
return w;
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_shutdown(
JNIEnv *env, jobject thisObj, int fd, int how)
{
return zts_shutdown(fd, how);
}
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_select(JNIEnv *env, jobject thisObj,
jint nfds, jobject readfds, jobject writefds, jobject exceptfds, jint timeout_sec, jint timeout_usec)
{
struct timeval _timeout;
_timeout.tv_sec = timeout_sec;
_timeout.tv_usec = timeout_usec;
fd_set _readfds, _writefds, _exceptfds;
fd_set *r = NULL;
fd_set *w = NULL;
fd_set *e = NULL;
if (readfds) {
r = &_readfds;
ztfdset2fdset(env, nfds, readfds, &_readfds);
}
if (writefds) {
w = &_writefds;
ztfdset2fdset(env, nfds, writefds, &_writefds);
}
if (exceptfds) {
e = &_exceptfds;
ztfdset2fdset(env, nfds, exceptfds, &_exceptfds);
}
int err = zts_select(nfds, r, w, e, &_timeout);
if (readfds) {
fdset2ztfdset(env, nfds, &_readfds, readfds);
}
if (writefds) {
fdset2ztfdset(env, nfds, &_writefds, writefds);
}
if (exceptfds) {
fdset2ztfdset(env, nfds, &_exceptfds, exceptfds);
}
return err;
}
}
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, fd_set *dest_fd_set)
{
jclass c = (*env).GetObjectClass(src_ztfd_set);
if (!c) {
return;
}
FD_ZERO(dest_fd_set);
jfieldID fid = env->GetFieldID(c, "fds_bits", "[B");
jobject fdData = (*env).GetObjectField (src_ztfd_set, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&fdData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
for (int i=0; i<nfds; i++) {
if (data[i] == 0x01) {
FD_SET(i, dest_fd_set);
}
}
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
}
void fdset2ztfdset(JNIEnv *env, int nfds, fd_set *src_fd_set, jobject dest_ztfd_set)
{
jclass c = (*env).GetObjectClass(dest_ztfd_set);
if (!c) {
return;
}
jfieldID fid = env->GetFieldID(c, "fds_bits", "[B");
jobject fdData = (*env).GetObjectField (dest_ztfd_set, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&fdData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
for (int i=0; i<nfds; i++) {
if (FD_ISSET(i, src_fd_set)) {
data[i] = 0x01;
}
}
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
}
//////////////////////////////////////////////////////////////////////////////
// Helpers (for moving data across the JNI barrier) //
//////////////////////////////////////////////////////////////////////////////
void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr)
{
jclass c = (*env).GetObjectClass(addr);
if (!c) {
return;
}
if(ss->ss_family == AF_INET)
{
struct sockaddr_in *in4 = (struct sockaddr_in*)ss;
jfieldID fid = (*env).GetFieldID(c, "_port", "I");
(*env).SetIntField(addr, fid, ntohs(in4->sin_port));
fid = (*env).GetFieldID(c,"_family", "I");
(*env).SetIntField(addr, fid, (in4->sin_family));
fid = env->GetFieldID(c, "_ip4", "[B");
jobject ipData = (*env).GetObjectField (addr, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
memcpy(data, &(in4->sin_addr.s_addr), 4);
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
}
if(ss->ss_family == AF_INET6)
{
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)ss;
jfieldID fid = (*env).GetFieldID(c, "_port", "I");
(*env).SetIntField(addr, fid, ntohs(in6->sin6_port));
fid = (*env).GetFieldID(c,"_family", "I");
(*env).SetIntField(addr, fid, (in6->sin6_family));
fid = env->GetFieldID(c, "_ip6", "[B");
jobject ipData = (*env).GetObjectField (addr, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
memcpy(data, &(in6->sin6_addr.s6_addr), 16);
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
}
}
void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr)
{
jclass c = (*env).GetObjectClass(addr);
if (!c) {
return;
}
jfieldID fid = (*env).GetFieldID(c, "_family", "I");
int family = (*env).GetIntField(addr, fid);
if (family == AF_INET)
{
struct sockaddr_in *in4 = (struct sockaddr_in*)ss;
fid = (*env).GetFieldID(c, "_port", "I");
in4->sin_port = htons((*env).GetIntField(addr, fid));
in4->sin_family = AF_INET;
fid = env->GetFieldID(c, "_ip4", "[B");
jobject ipData = (*env).GetObjectField (addr, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
memcpy(&(in4->sin_addr.s_addr), data, 4);
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
}
if (family == AF_INET6)
{
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)ss;
jfieldID fid = (*env).GetFieldID(c, "_port", "I");
in6->sin6_port = htons((*env).GetIntField(addr, fid));
fid = (*env).GetFieldID(c,"_family", "I");
in6->sin6_family = AF_INET6;
fid = env->GetFieldID(c, "_ip6", "[B");
jobject ipData = (*env).GetObjectField (addr, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
memcpy(&(in6->sin6_addr.s6_addr), data, 16);
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
}
}
#ifdef __cplusplus
}
#endif
#endif // SDK_JNI

File diff suppressed because it is too large Load Diff

View File

@@ -1,222 +0,0 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
#ifndef ZT_PICOTCP_HPP
#define ZT_PICOTCP_HPP
/*
#include "pico_eth.h"
#include "pico_stack.h"
#include "pico_ipv4.h"
#include "pico_icmp4.h"
#include "pico_dev_tap.h"
#include "pico_protocol.h"
#include "pico_socket.h"
#include "pico_device.h"
#include "pico_ipv6.h"
*/
struct pico_socket;
class VirtualSocket;
class VirtualTap;
#include "VirtualTap.h"
/****************************************************************************/
/* PicoTCP API Signatures (See libzt.h for the application-facing API) */
/****************************************************************************/
#define PICO_IPV4_TO_STRING_SIG char *ipbuf, const uint32_t ip
#define PICO_TAP_CREATE_SIG char *name
#define PICO_IPV4_LINK_ADD_SIG struct pico_device *dev, struct pico_ip4 address, struct pico_ip4 netmask
#define PICO_DEVICE_INIT_SIG struct pico_device *dev, const char *name, uint8_t *mac
#define PICO_STACK_RECV_SIG struct pico_device *dev, uint8_t *buffer, uint32_t len
#define PICO_ICMP4_PING_SIG char *dst, int count, int interval, int timeout, int size, void (*cb)(struct pico_icmp4_stats *)
#define PICO_TIMER_ADD_SIG pico_time expire, void (*timer)(pico_time, void *), void *arg
#define PICO_STRING_TO_IPV4_SIG const char *ipstr, uint32_t *ip
#define PICO_STRING_TO_IPV6_SIG const char *ipstr, uint8_t *ip
#define PICO_SOCKET_SETOPTION_SIG struct pico_socket *s, int option, void *value
#define PICO_SOCKET_SEND_SIG struct pico_socket *s, const void *buf, int len
#define PICO_SOCKET_SENDTO_SIG struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port
#define PICO_SOCKET_RECV_SIG struct pico_socket *s, void *buf, int len
#define PICO_SOCKET_RECVFROM_SIG struct pico_socket *s, void *buf, int len, void *orig, uint16_t *remote_port
#define PICO_SOCKET_OPEN_SIG uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s)
#define PICO_SOCKET_BIND_SIG struct pico_socket *s, void *local_addr, uint16_t *port
#define PICO_SOCKET_CONNECT_SIG struct pico_socket *s, const void *srv_addr, uint16_t remote_port
#define PICO_SOCKET_LISTEN_SIG struct pico_socket *s, const int backlog
#define PICO_SOCKET_READ_SIG struct pico_socket *s, void *buf, int len
#define PICO_SOCKET_WRITE_SIG struct pico_socket *s, const void *buf, int len
#define PICO_SOCKET_CLOSE_SIG struct pico_socket *s
#define PICO_SOCKET_SHUTDOWN_SIG struct pico_socket *s, int mode
#define PICO_SOCKET_ACCEPT_SIG struct pico_socket *s, void *orig, uint16_t *port
#define PICO_IPV6_LINK_ADD_SIG struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask
#define PICO_IPV4_ROUTE_ADD_SIG struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link
#define PICO_IPV4_ROUTE_DEL_SIG struct pico_ip4 address, struct pico_ip4 netmask, int metric
#define PICO_IPV6_ROUTE_ADD_SIG struct pico_ip6 address, struct pico_ip6 netmask, struct pico_ip6 gateway, int metric, struct pico_ipv6_link *link
#define PICO_IPV6_ROUTE_DEL_SIG struct pico_ip6 address, struct pico_ip6 netmask, struct pico_ip6 gateway, int metric, struct pico_ipv6_link *link
#define PICO_DNS_CLIENT_NAMESERVER_SIG pico_ip4*, unsigned char
/**
* Send raw frames from the stack to the ZeroTier virtual wire
*/
int rd_pico_eth_tx(struct pico_device *dev, void *buf, int len);
/**
* Read raw frames from RX frame buffer into the stack
*/
int rd_pico_eth_poll(struct pico_device *dev, int loop_score);
/**
* Set up an interface in the network stack for the VirtualTap
*/
bool pico_init_interface(VirtualTap *tap);
/**
* Register an address with the stack
*/
bool pico_register_address(VirtualTap *tap, const InetAddress &ip);
/**
* Adds a route to the picoTCP device
*/
bool rd_pico_route_add(VirtualTap *tap, const InetAddress &addr, const InetAddress &nm, const InetAddress &gw, int metric);
/**
* Deletes a route from the picoTCP device
*/
bool rd_pico_route_del(VirtualTap *tap, const InetAddress &addr, const InetAddress &nm, int metric);
/**
* Registers a DNS nameserver with the network stack
*/
int rd_pico_add_dns_nameserver(struct sockaddr *addr);
/**
* Un-registers a DNS nameserver from the network stack
*/
int rd_pico_del_dns_nameserver(struct sockaddr *addr);
/**
* Main stack loop
*/
void rd_pico_loop(VirtualTap *tap);
/**
* Read bytes from the stack to the RX buffer (prepare to be read by app)
*/
void rd_pico_cb_tcp_read(VirtualTap *tap, struct pico_socket *s);
/**
* Read bytes from the stack to the RX buffer (prepare to be read by app)
*/
void rd_pico_cb_udp_read(VirtualTap *tap, struct pico_socket *s);
/**
* Write bytes from TX buffer to stack (prepare to be sent to ZT virtual wire)
*/
void rd_pico_cb_tcp_write(VirtualTap *tap, struct pico_socket *s);
/**
* Write bytes from TX buffer to stack (prepare to be sent to ZT virtual wire)
*/
void rd_pico_cb_socket_ev(uint16_t ev, struct pico_socket *s);
/**
* Packets from the ZeroTier virtual wire enter the stack here
*/
void rd_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"
*/
int rd_pico_socket(struct pico_socket **p, int socket_family, int socket_type, int protocol);
/**
* Connect to remote host via userspace network stack interface - Called from VirtualTap
*/
int rd_pico_connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen);
/**
* Bind to a userspace network stack interface - Called from VirtualTap
*/
int rd_pico_bind(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen);
/**
* Listen for incoming VirtualSockets - Called from VirtualTap
*/
int rd_pico_listen(VirtualSocket *vs, int backlog);
/**
* Accept an incoming VirtualSocket - Called from VirtualTap
*/
VirtualSocket* rd_pico_accept(VirtualSocket *vs);
/**
* Read from RX buffer to application - Called from VirtualTap
*/
int rd_pico_read(VirtualTap *tap, ZeroTier::PhySocket *sock, VirtualSocket *vs, bool stack_invoked);
/**
* Write to userspace network stack - Called from VirtualTap
*/
int rd_pico_write(VirtualSocket *vs, void *data, ssize_t len);
/**
* Close a VirtualSocket - Called from VirtualTap
*/
int rd_pico_close(VirtualSocket *vs);
/**
* Shuts down some aspect of a VirtualSocket - Called from VirtualTap
*/
int rd_pico_shutdown(VirtualSocket *vs, int how);
/**
* Sets a property of a socket
*/
int rd_pico_setsockopt(VirtualSocket *vs, int level, int optname, const void *optval, socklen_t optlen);
/**
* Gets a property of a socket
*/
int rd_pico_getsockopt(VirtualSocket *vs, int level, int optname, void *optval, socklen_t *optlen);
/**
* Converts a pico_err to its most closely-related errno, and sets errno
*/
int map_pico_err_to_errno(int err);
/**
* Converts picoTCP error codes to pretty string
*/
char *beautify_pico_error(int err);
/**
* Converts picoTCP socket states into pretty string
*/
char *beautify_pico_state(int state);
#endif // _H