Removed cruft from project

This commit is contained in:
Joseph Henry
2018-07-19 17:19:06 -07:00
parent 50396baaf1
commit 07be7a25a3
38 changed files with 289 additions and 4308 deletions

View File

@@ -30,17 +30,6 @@
* Platform-specific implementations of common functions
*/
#if defined(STACK_LWIP)
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/ip_addr.h"
#include "lwip/netdb.h"
#include "dns.h"
#endif
#if defined(NO_STACK)
#include <sys/socket.h>
#endif
#if defined(__linux__) || defined(__APPLE__)
#include <sys/socket.h>
#include <pthread.h>
@@ -52,18 +41,4 @@
#ifdef __linux__
#include <sys/syscall.h>
#include <unistd.h>
#endif
inline unsigned int gettid()
{
#ifdef _WIN32
//return GetCurrentThreadId();
return 0;
#elif defined(__linux__)
return static_cast<unsigned int>(syscall(__NR_gettid));
#elif defined(__APPLE__)
uint64_t tid64;
pthread_threadid_np(0, &tid64);
return static_cast<unsigned int>(tid64);
#endif
}
#endif

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

File diff suppressed because it is too large Load Diff

View File

@@ -40,18 +40,13 @@ typedef unsigned short u16_t;
#include "libzt.h"
#include "libztDebug.h"
#include "lwIP.h"
#include "picoTCP.h"
#include "ZT1Service.h"
#include "VirtualSocket.h"
#include "VirtualSocketLayer.h"
#include "SysUtils.h"
#include "Mutex.hpp"
#include "InetAddress.hpp"
#include "OneService.hpp"
//class VirtualSocket;
int VirtualTap::devno = 0;
VirtualTap::VirtualTap(
@@ -87,11 +82,8 @@ VirtualTap::VirtualTap(
// set virtual tap interface name (abbreviated)
memset(vtap_abbr_name, 0, sizeof(vtap_abbr_name));
snprintf(vtap_abbr_name, sizeof(vtap_abbr_name), "libzt%d", devno);
#if defined(STACK_LWIP)
// initialize network stacks
lwip_driver_init();
#endif
// start vtap thread and stack I/O loops
// start virtual tap thread and stack I/O loops
_thread = Thread::start(this);
}
@@ -113,44 +105,26 @@ bool VirtualTap::enabled() const
return _enabled;
}
bool VirtualTap::registerIpWithStack(const InetAddress &ip)
void VirtualTap::registerIpWithStack(const InetAddress &ip)
{
#if defined(STACK_LWIP)
lwip_init_interface((void*)this, this->_mac, ip);
#endif
#if defined(STACK_PICO)
pico_register_address(this, ip);
#endif
return true;
}
bool VirtualTap::addIp(const InetAddress &ip)
{
#if defined(NO_STACK)
char ipbuf[INET6_ADDRSTRLEN];
DEBUG_INFO("addIp=%s, nwid=%llx", ip.toString(ipbuf), (unsigned long long)_nwid);
_ips.push_back(ip);
std::sort(_ips.begin(),_ips.end());
return true;
#endif
#if defined(STACK_PICO) || defined(STACK_LWIP)
char ipbuf[INET6_ADDRSTRLEN];
DEBUG_EXTRA("addr=%s, nwid=%llx", ip.toString(ipbuf), (unsigned long long)_nwid);
Mutex::Lock _l(_ips_m);
if (registerIpWithStack(ip)) {
if (std::find(_ips.begin(),_ips.end(),ip) == _ips.end()) {
_ips.push_back(ip);
std::sort(_ips.begin(),_ips.end());
}
return true;
registerIpWithStack(ip);
if (std::find(_ips.begin(),_ips.end(),ip) == _ips.end()) {
_ips.push_back(ip);
std::sort(_ips.begin(),_ips.end());
}
return false;
#endif
return true;
}
bool VirtualTap::removeIp(const InetAddress &ip)
{
DEBUG_EXTRA("");
Mutex::Lock _l(_ips_m);
std::vector<InetAddress>::iterator i(std::find(_ips.begin(),_ips.end(),ip));
//if (i == _ips.end()) {
@@ -158,10 +132,10 @@ bool VirtualTap::removeIp(const InetAddress &ip)
//}
_ips.erase(i);
if (ip.isV4()) {
// FIXME: De-register from network stacks
// FIXME: De-register from network stack
}
if (ip.isV6()) {
// FIXME: De-register from network stacks
// FIXME: De-register from network stack
}
return true;
}
@@ -175,12 +149,7 @@ std::vector<InetAddress> VirtualTap::ips() const
void VirtualTap::put(const MAC &from,const MAC &to,unsigned int etherType,
const void *data,unsigned int len)
{
#if defined(STACK_LWIP)
lwip_eth_rx(this, from, to, etherType, data, len);
#endif
#if defined(STACK_PICO)
rd_pico_eth_rx(this,from,to,etherType,data,len);
#endif
}
std::string VirtualTap::deviceName() const
@@ -238,366 +207,10 @@ void VirtualTap::setMtu(unsigned int mtu)
void VirtualTap::threadMain()
throw()
{
#if defined(STACK_LWIP) && !defined(LIBZT_RAW)
while (true) {
_phy.poll(ZT_PHY_POLL_INTERVAL);
Housekeeping();
}
#endif
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
rd_lwip_loop(this); // use driver loop
#endif
#if defined(STACK_PICO)
pico_init_interface(this);
if (this->should_start_stack) {
rd_pico_loop(this); // use driver loop
}
#endif
}
void VirtualTap::phyOnUnixClose(PhySocket *sock, void **uptr)
{
DEBUG_EXTRA("");
}
void VirtualTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len)
{
DEBUG_EXTRA("");
#if defined(LIBZT_RAW)
VirtualSocket *vs = (VirtualSocket*)*uptr;
if (vs == NULL) {
return;
}
if (len > 0) {
Write(vs, data, len);
}
#endif
}
void VirtualTap::phyOnUnixWritable(PhySocket *sock, void **uptr, bool stack_invoked)
{
DEBUG_EXTRA("");
#if defined(LIBZT_RAW)
if (sock) {
Read(sock,uptr,stack_invoked);
} else {
DEBUG_ERROR("!sock");
}
#endif
}
bool VirtualTap::routeAdd(const InetAddress &ip, const InetAddress &nm, const InetAddress &gw)
{
bool err = false;
DEBUG_EXTRA("");
#if defined(STACK_LWIP)
// general_lwip_init_interface(this, NULL, "n1", _mac, ip, nm, gw);
// general_turn_on_interface(NULL);
return true;
#endif
#if defined(STACK_PICO)
return rd_pico_route_add(this, ip, nm, gw, 0);
#endif
#if defined(NO_STACK)
// nothing to do
#endif
return err;
}
bool VirtualTap::routeDelete(const InetAddress &ip, const InetAddress &nm)
{
bool err = false;
DEBUG_EXTRA("");
#if defined(STACK_LWIP)
// general_lwip_init_interface(this, NULL, "n1", _mac, ip, nm, gw);
// general_turn_on_interface(NULL);
return true;
#endif
#if defined(STACK_PICO)
return rd_pico_route_del(this, ip, nm, 0);
#endif
#if defined(NO_STACK)
// nothing to do
#endif
return err;
}
void VirtualTap::addVirtualSocket(VirtualSocket *vs)
{
#if defined(LIBZT_RAW)
DEBUG_EXTRA("");
Mutex::Lock _l(_tcpconns_m);
_VirtualSockets.push_back(vs);
#endif
}
void VirtualTap::removeVirtualSocket()
{
#if defined(LIBZT_RAW)
DEBUG_EXTRA("");
Mutex::Lock _l(_tcpconns_m);
for (int i=0; i<_VirtualSockets.size(); i++) {
if (vs == _VirtualSockets[i]) {
_VirtualSockets.erase(_VirtualSockets.begin() + i);
break;
}
}
#endif
}
/****************************************************************************/
/* DNS */
/****************************************************************************/
int VirtualTap::add_DNS_Nameserver(struct sockaddr *addr)
{
int err = -1;
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
err = rd_lwip_add_dns_nameserver(addr);
#endif
#if defined(STACK_PICO)
rd_pico_add_dns_nameserver(addr);
#endif
return err;
}
int VirtualTap::del_DNS_Nameserver(struct sockaddr *addr)
{
int err = -1;
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
err = rd_lwip_del_dns_nameserver(addr);
#endif
#if defined(STACK_PICO)
err = rd_pico_del_dns_nameserver(addr);
#endif
return err;
}
/****************************************************************************/
/* SDK Socket API */
/****************************************************************************/
// Connect
int VirtualTap::Connect(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen)
{
#if !defined(LIBZT_RAW)
return -1;
#endif
#if defined(NO_STACK)
return -1;
#endif
int err = -1;
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
err = rd_lwip_connect(vs, addr, addrlen);
#endif
#if defined(STACK_PICO)
Mutex::Lock _l(_tcpconns_m);
err = rd_pico_connect(vs, addr, addrlen);
#endif
return err;
}
// Bind VirtualSocket to a network stack's interface
int VirtualTap::Bind(VirtualSocket *vs, const struct sockaddr *addr, socklen_t addrlen)
{
#if !defined(LIBZT_RAW)
return -1;
#endif
#if defined(NO_STACK)
return -1;
#endif
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
Mutex::Lock _l(_tcpconns_m);
return rd_lwip_bind(this, vs, addr, addrlen);
#endif
#if defined(STACK_PICO)
Mutex::Lock _l(_tcpconns_m);
return rd_pico_bind(vs, addr, addrlen);
#endif
return -1;
}
// Listen for an incoming VirtualSocket
int VirtualTap::Listen(VirtualSocket *vs, int backlog)
{
#if !defined(LIBZT_RAW)
return -1;
#endif
#if defined(NO_STACK)
return -1;
#endif
int err = -1;
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
Mutex::Lock _l(_tcpconns_m);
err = rd_lwip_listen(vs, backlog);
#endif
#if defined(STACK_PICO)
Mutex::Lock _l(_tcpconns_m);
return rd_pico_listen(vs, backlog);
#endif
return err;
}
// Accept a VirtualSocket
VirtualSocket *VirtualTap::Accept(VirtualSocket *vs)
{
#if !defined(LIBZT_RAW)
return NULL;
#endif
VirtualSocket *new_vs = NULL;
#if defined(NO_STACK)
new_vs = NULL;
#endif
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
Mutex::Lock _l(_tcpconns_m);
new_vs = rd_lwip_accept(vs);
#endif
#if defined(STACK_PICO)
// TODO: separation of church and state
Mutex::Lock _l(_tcpconns_m);
new_vs = rd_pico_accept(vs);
#endif
return new_vs;
}
// Read from stack/buffers into the app's socket
int VirtualTap::Read(VirtualSocket *vs, PhySocket *sock, void **uptr, bool stack_invoked)
{
#if !defined(LIBZT_RAW)
return -1;
#endif
#if defined(NO_STACK)
return -1;
#endif
int err = -1;
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
err = rd_lwip_read((VirtualSocket*)*(_phy.getuptr(sock)), stack_invoked);
#endif
#if defined(STACK_PICO)
err = rd_pico_read(this, sock, (VirtualSocket*)uptr, stack_invoked);
#endif
return err;
}
// Write data from app socket to the virtual wire, either raw over VL2, or via network stack
int VirtualTap::Write(VirtualSocket *vs, void *data, ssize_t len)
{
#if !defined(LIBZT_RAW)
return -1;
#endif
#if defined(NO_STACK)
return -1;
#endif
DEBUG_EXTRA("vs=%p, fd=%d, data=%p, len=%lu", vs, vs->app_fd, data, (unsigned long)len);
int err = -1;
#if defined(LIBZT_RAW)
// VL2, SOCK_RAW, no network stack
if (vs->socket_type == SOCK_RAW) {
struct ether_header *eh = (struct ether_header *) data;
MAC src_mac;
MAC dest_mac;
src_mac.setTo(eh->ether_shost, 6);
dest_mac.setTo(eh->ether_dhost, 6);
_handler(_arg,NULL,_nwid,src_mac,dest_mac, Utils::ntoh((uint16_t)eh->ether_type),0, ((char*)data) + sizeof(struct ether_header),len - sizeof(struct ether_header));
return len;
}
#endif
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
err = rd_lwip_write(vs, data, len);
#endif
#if defined(STACK_PICO)
err = rd_pico_write(vs, data, len);
#endif
return err;
}
// 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)
{
#if !defined(ZT_VIRTUAL_SOCKET)
return -1;
#endif
int err = -1;
#if defined(STACK_LWIP) && defined(ZT_VIRTUAL_SOCKET)
if ((err = rd_lwip_connect(vs, addr, addrlen)) < 0) { // implicit
return err;
}
if ((err = rd_lwip_write(vs, (void*)buf, len)) < 0) {
return err;
}
#endif
#if defined(STACK_PICO) && defined(ZT_VIRTUAL_SOCKET)
if ((err = rd_pico_connect(vs, addr, addrlen)) < 0) { // implicit
errno = ENOTCONN;
return err;
}
if ((err = rd_pico_write(vs, (void*)buf, len)) < 0) {
errno = ENOBUFS; // TODO: translate pico err to something more useful
return err;
}
#endif
return err;
}
// Remove VritualSocket from VirtualTap, and instruct network stacks to dismantle their
// respective protocol control structures
int VirtualTap::Close(VirtualSocket *vs)
{
#if !defined(LIBZT_RAW)
return -1;
#endif
int err = 0;
#if defined(LIBZT_RAW)
if (vs == NULL) {
DEBUG_ERROR("invalid VirtualSocket");
return -1;
}
if (vs->sock) {
DEBUG_EXTRA("calling _phy.close()");
_phy.close(vs->sock, true);
}
removeVirtualSocket(vs);
#endif
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
err = rd_lwip_close(vs);
#endif
#if defined(STACK_PICO)
/*
if (vs->get_state() != VS_STATE_CLOSED && vs->get_state() != VS_STATE_LISTENING) {
DEBUG_EXTRA("vs=%p, vs->get_state()=%d, vs->picosock->state=%d", vs, vs->get_state(), vs->picosock->state);
// doesn't make sense to shut down a listening socket, just close it
if ((err = vs->tap->Shutdown(vs, SHUT_RDWR)) < 0) {
DEBUG_ERROR("error while shutting down socket");
return - 1;
}
}
rd_pico_Close(vs);
removeVirtualSocket(vs);
if (vs->socket_type == SOCK_STREAM) {
while (!(vs->picosock->state & PICO_SOCKET_STATE_CLOSED)) {
nanosleep((const struct timespec[]) {{0, (ZT_ACCEPT_RECHECK_DELAY * 1000000)}}, NULL);
DEBUG_EXTRA("virtual lingering on socket, ps=%p, buf remaining=%d",vs->picosock, vs->TXbuf->count());
}
}
*/
#endif
return err;
}
// Shuts down some aspect of a connection
int VirtualTap::Shutdown(VirtualSocket *vs, int how)
{
#if !defined(LIBZT_RAW)
return -1;
#endif
int err = 0;
#if defined(STACK_LWIP) && defined(LIBZT_RAW)
err = rd_lwip_shutdown(vs, how);
#endif
#if defined(STACK_PICO)
err = rd_pico_shutdown(vs, how);
#endif
return err;
}
void VirtualTap::Housekeeping()
@@ -618,6 +231,7 @@ void VirtualTap::Housekeeping()
char ipbuf[INET6_ADDRSTRLEN], ipbuf2[INET6_ADDRSTRLEN], ipbuf3[INET6_ADDRSTRLEN];
// TODO: Rework this when we have time
// check if pushed route exists in tap (add)
/*
for (int i=0; i<ZT_MAX_NETWORK_ROUTES; i++) {
found = false;
target_addr = managed_routes->at(i).target;
@@ -657,6 +271,7 @@ void VirtualTap::Housekeeping()
routeDelete(routes[i].first, routes[i].second);
}
}
*/
}
// TODO: Clean up VirtualSocket objects
last_housekeeping_ts = time_now();

View File

@@ -272,7 +272,7 @@ int zts_get_num_assigned_addresses(const uint64_t nwid)
}
int zts_get_address_at_index(
const uint64_t nwid, const int index, struct sockaddr_storage *addr)
const uint64_t nwid, const int index, struct sockaddr *addr, socklen_t *addrlen)
{
if (!zt1Service) {
return -1;
@@ -283,8 +283,9 @@ int zts_get_address_at_index(
return err;
}
_vtaps_lock.lock();
if (index <= tap->_ips.size()) {
memcpy(addr, &(tap->_ips[index]), sizeof(struct sockaddr_storage));
if (index > -1 && index <= 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();
@@ -514,25 +515,6 @@ unsigned long zts_get_peer_count()
}
}
int zts_get_peer_address(char *peer, const uint64_t nodeId)
{
/*
if (zt1Service) {
ZT_PeerList *pl = zt1Service->getNode()->peers();
// uint64_t addr;
for (size_t i=0; i<pl->peerCount; i++) {
// ZT_Peer *p = &(pl->peers[i]);
// DEBUG_INFO("peer[%d] = %lx", i, p->address);
}
return pl->peerCount;
}
else {
return -1;
}
*/
return -1;
}
bool _ipv6_in_subnet(ZeroTier::InetAddress *subnet, ZeroTier::InetAddress *addr)
{
ZeroTier::InetAddress r(addr);

View File

@@ -27,25 +27,15 @@
/**
* @file
*
* Application-facing, partially-POSIX-compliant socket API
* Application-facing, socket-like API
*/
#include "libztDefs.h"
#if defined(STACK_LWIP)
#include "lwip/sockets.h"
#include "lwip/ip_addr.h"
#include "lwip/netdb.h"
//#include "dns.h"
#endif
#if defined(NO_STACK)
#include <sys/socket.h>
#endif
#if defined(STACK_PICO)
#include <sys/socket.h>
#endif
#include "VirtualSocketLayer.h"
#include "libztDebug.h"
#include <string.h>
@@ -62,104 +52,58 @@ int zts_socket(int socket_family, int socket_type, int protocol)
{
DEBUG_EXTRA("family=%d, type=%d, proto=%d", socket_family, socket_type, protocol);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
/* with this option, the VirtualSocket layer will abstract a stack's raw API
into something that resembles a POSIX socket API, this driver shall be implemented in
src/stack_name.cpp and include/stack_name.h */
return virt_socket(socket_family, socket_type, protocol);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
/* use the lwIP community's own socket API, this provides thread safety and core
locking */
int socket_family_adj = platform_adjusted_socket_family(socket_family);
int err = lwip_socket(socket_family_adj, socket_type, protocol);
return err;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
// return pico_bsd_socket(socket_family, socket_type, protocol);
return -1;
#endif
}
int zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
{
DEBUG_EXTRA("fd=%d",fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_connect(fd, addr, addrlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
struct sockaddr_storage ss;
memcpy(&ss, addr, addrlen);
fix_addr_socket_family((struct sockaddr*)&ss);
return lwip_connect(fd, (struct sockaddr*)&ss, addrlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_bind(fd, addr, addrlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
struct sockaddr_storage ss;
memcpy(&ss, addr, addrlen);
fix_addr_socket_family((struct sockaddr*)&ss);
return lwip_bind(fd, (struct sockaddr*)&ss, addrlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_listen(int fd, int backlog)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_listen(fd, backlog);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_listen(fd, backlog);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_accept(fd, addr, addrlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_accept(fd, addr, addrlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
#if defined(__linux__)
@@ -167,19 +111,11 @@ int zts_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_accept4(fd, addr, addrlen, flags);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
// return lwip_accept4(fd, addr, addrlen, flags);
// lwip_accept4(fd, addr, addrlen, flags);
return -1;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
#endif
@@ -187,120 +123,68 @@ int zts_setsockopt(int fd, int level, int optname, const void *optval, socklen_t
{
DEBUG_EXTRA("fd=%d, level=%d, optname=%d", fd, level, optname);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_setsockopt(fd, level, optname, optval, optlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_setsockopt(fd, level, optname, optval, optlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
{
DEBUG_EXTRA("fd=%d, level=%d, optname=%d", fd, level, optname);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_getsockopt(fd, level, optname, optval, optlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_getsockopt(fd, level, optname, optval, optlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_getsockname(fd, addr, addrlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_getsockname(fd, addr, addrlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_getpeername(fd, addr, addrlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_getpeername(fd, addr, addrlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_gethostname(char *name, size_t len)
{
DEBUG_EXTRA("");
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return -1;
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return -1;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_sethostname(const char *name, size_t len)
{
DEBUG_EXTRA("");
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return -1;
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return -1;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
struct hostent *zts_gethostbyname(const char *name)
{
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return NULL;
}
#if defined(ZT_VIRTUAL_SOCKET)
//return virt_gethostbyname(name);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
// TODO: Test thread safety
/*
char buf[256];
@@ -320,30 +204,16 @@ struct hostent *zts_gethostbyname(const char *name)
return lwip_gethostbyname(name);
*/
return NULL;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
#endif
#if defined(STACK_LWIP)
#endif
return NULL;
}
int zts_close(int fd)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_close(fd);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_close(fd);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
#if defined(__linux__)
@@ -355,17 +225,7 @@ int zts_poll(struct pollfd *fds, nfds_t nfds, int timeout)
DEBUG_ERROR("service not started yet, call zts_startjoin()");
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
//return poll(fds, nfds, timeout);
return -1;
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
//return poll(fds, nfds, timeout);
return -1;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
return poll(fds, nfds, timeout);
}
*/
#endif
@@ -373,35 +233,20 @@ int zts_poll(struct pollfd *fds, nfds_t nfds, int timeout)
int zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)
{
//DEBUG_EXTRA("");
/*
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
*/
#if defined(ZT_VIRTUAL_SOCKET)
return virt_select(nfds, readfds, writefds, exceptfds, timeout);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_select(nfds, readfds, writefds, exceptfds, timeout);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_fcntl(int fd, int cmd, int flags)
{
DEBUG_EXTRA("fd=%d, cmd=%d, flags=%d", fd, cmd, flags);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_fcntl(fd, cmd, flags);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
// translation from platform flag values to stack flag values
int translated_flags = 0;
#if defined(__linux__)
@@ -415,28 +260,16 @@ int zts_fcntl(int fd, int cmd, int flags)
}
#endif
return lwip_fcntl(fd, cmd, translated_flags);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_ioctl(int fd, unsigned long request, void *argp)
{
DEBUG_EXTRA("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_ioctl(fd, request, argp);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_ioctl(fd, request, argp);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags,
@@ -444,76 +277,43 @@ ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags,
{
DEBUG_TRANS("fd=%d, len=%zu", fd, len);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
//return virt_sendto();
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
struct sockaddr_storage ss;
memcpy(&ss, addr, addrlen);
fix_addr_socket_family((struct sockaddr*)&ss);
return lwip_sendto(fd, buf, len, flags, (struct sockaddr*)&ss, addrlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
return -1;
}
ssize_t zts_send(int fd, const void *buf, size_t len, int flags)
{
DEBUG_TRANS("fd=%d, len=%zu", fd, len);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_send(fd, buf, len, flags);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_send(fd, buf, len, flags);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
ssize_t zts_sendmsg(int fd, const struct msghdr *msg, int flags)
{
DEBUG_TRANS("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_sendmsg(fd, msg, flags);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_sendmsg(fd, msg, flags);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
ssize_t zts_recv(int fd, void *buf, size_t len, int flags)
{
DEBUG_TRANS("fd=%d, len=%zu", fd, len);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_recv(fd, buf, len, flags);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_recv(fd, buf, len, flags);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags,
@@ -521,133 +321,73 @@ ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags,
{
DEBUG_TRANS("fd=%d, len=%zu", fd, len);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_recvfrom(fd, buf, len, flags, addr, addrlen);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_recvfrom(fd, buf, len, flags, addr, addrlen);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
ssize_t zts_recvmsg(int fd, struct msghdr *msg, int flags)
{
DEBUG_TRANS("fd=%d", fd);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_recvmsg(fd, msg, flags);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
//return lwip_recvmsg(fd, msg, flags);
return -1;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
return -1; // lwip_recvmsg(fd, msg, flags);
// Not currently implemented by stack
}
int zts_read(int fd, void *buf, size_t len)
{
DEBUG_TRANS("fd=%d, len=%zu", fd, len);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_read(fd, buf, len);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_read(fd, buf, len);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
// return pico_read(fd, buf, len);
#endif
}
int zts_write(int fd, const void *buf, size_t len)
{
DEBUG_TRANS("fd=%d, len=%zu", fd, len);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_write(fd, buf, len);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_write(fd, buf, len);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_shutdown(int fd, int how)
{
DEBUG_EXTRA("fd=%d, how=%d", fd, how);
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
return virt_shutdown(fd, how);
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return lwip_shutdown(fd, how);
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_add_dns_nameserver(struct sockaddr *addr)
{
DEBUG_EXTRA("");
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
// TODO
return -1;
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
struct sockaddr_in *in4 = (struct sockaddr_in*)&addr;
static ip4_addr_t ipaddr;
ipaddr.addr = in4->sin_addr.s_addr;
// TODO: manage DNS server indices
//dns_setserver(0, (const ip_addr_t*)&ipaddr);
return 0;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
int zts_del_dns_nameserver(struct sockaddr *addr)
{
DEBUG_EXTRA("");
if (zts_ready() == false) {
DEBUG_ERROR("service not started yet, call zts_startjoin()");
DEBUG_ERROR(LIBZT_SERVICE_NOT_STARTED_STR);
return -1;
}
#if defined(ZT_VIRTUAL_SOCKET)
// TODO
return -1;
#endif
#if defined(ZT_LWIP_SEQ_SOCKET)
return -1;
#endif
#if defined(ZT_PICO_BSD_SOCKET)
return -1;
#endif
}
/* The rationale for the following correctional methods is as follows:
@@ -689,7 +429,6 @@ void fix_addr_socket_family(struct sockaddr *addr)
#if defined(__linux__) || defined(_WIN32)
/* struct sockaddr on Linux and Windows don't contain an sa_len field
so we must adjust it here before feeding it into the stack. */
#if defined(STACK_LWIP)
if (addr->sa_len == 2) {
if (addr->sa_family == 0) {
addr->sa_family = addr->sa_len;
@@ -702,7 +441,6 @@ void fix_addr_socket_family(struct sockaddr *addr)
addr->sa_len = 0;
}
}
#endif
/* once we've moved the value to its anticipated location, convert it from
its platform-specific value to one that the network stack can work with */
#endif

View File

@@ -48,13 +48,12 @@ extern "C" {
namespace ZeroTier {
// prototype
jobject ss2inet(JNIEnv *env, struct sockaddr_storage *src_ss);
int sockinet2ss(JNIEnv *env, jobject src_inet, struct sockaddr_storage *dest_ss);
void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr);
void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr);
/****************************************************************************/
/* ZeroTier service controls */
/****************************************************************************/
/* ZeroTier service controls */
/****************************************************************************/
JNIEXPORT void JNICALL Java_zerotier_ZeroTier_start(
JNIEnv *env, jobject thisObj, jstring path, jboolean blocking)
@@ -122,23 +121,20 @@ namespace ZeroTier {
return zts_get_node_id();
}
// TODO: ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id_from_file(const char *filepath);
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_get_1num_1assigned_1addresses(
JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_get_1num_1assigned_1addresses(
JNIEnv *env, jobject thisObj, jlong nwid)
{
return zts_get_num_assigned_addresses(nwid);
}
JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_get_1address_1at_1index(
JNIEnv *env, jobject thisObj, jlong nwid, jint index)
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_get_1address_1at_1index(
JNIEnv *env, jobject thisObj, jlong nwid, jint index, jobject addr)
{
struct sockaddr_storage ss;
int err;
if((err = zts_get_address_at_index(nwid, index, &ss)) < 0) {
return NULL;
}
return ss2inet(env, &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_zerotier_ZeroTier_has_1address(
@@ -147,31 +143,29 @@ namespace ZeroTier {
return zts_has_address(nwid);
}
JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_get_1address(
JNIEnv *env, jobject thisObj, jlong nwid, jint address_family)
JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_get_1address(
JNIEnv *env, jobject thisObj, jlong nwid, jint address_family, jobject addr)
{
struct sockaddr_storage ss;
int err;
if ((err = zts_get_address((uint64_t)nwid, &ss, address_family)) < 0) {
return NULL;
}
return ss2inet(env, &ss);
int err = zts_get_address((uint64_t)nwid, &ss, address_family);
ss2zta(env, &ss, addr);
return err;
}
JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_get_6plane_addr(
JNIEnv *env, jobject thisObj, jlong nwid, jlong nodeId)
JNIEXPORT void JNICALL Java_zerotier_ZeroTier_get_6plane_addr(
JNIEnv *env, jobject thisObj, jlong nwid, jlong nodeId, jobject addr)
{
struct sockaddr_storage ss;
zts_get_6plane_addr(&ss, nwid, nodeId);
return ss2inet(env, &ss);
ss2zta(env, &ss, addr);
}
JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_get_rfc4193_addr(
JNIEnv *env, jobject thisObj, jlong nwid, jlong nodeId)
JNIEXPORT void JNICALL Java_zerotier_ZeroTier_get_rfc4193_addr(
JNIEnv *env, jobject thisObj, jlong nwid, jlong nodeId, jobject addr)
{
struct sockaddr_storage ss;
zts_get_rfc4193_addr(&ss, nwid, nodeId);
return ss2inet(env, &ss);
ss2zta(env, &ss, addr);
}
JNIEXPORT jlong JNICALL Java_zerotier_ZeroTier_get_peer_count(
@@ -180,11 +174,9 @@ namespace ZeroTier {
return zts_get_peer_count();
}
// TODO: ZT_SOCKET_API int ZTCALL zts_get_peer_address(char *peer, const uint64_t nodeId);
/****************************************************************************/
/* ZeroTier Socket API */
/****************************************************************************/
/* ZeroTier Socket API */
/****************************************************************************/
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_socket(
JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol)
@@ -196,10 +188,7 @@ namespace ZeroTier {
JNIEnv *env, jobject thisObj, jint fd, jobject addr)
{
struct sockaddr_storage ss;
if(sockinet2ss(env, addr, &ss) < 0) {
return -1; // possibly invalid address format
// TODO: set errno
}
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);
}
@@ -209,14 +198,9 @@ namespace ZeroTier {
{
struct sockaddr_storage ss;
int err;
if(sockinet2ss(env, addr, &ss) < 0) {
return -1; // possibly invalid address format
// TODO: set errno
}
//DEBUG_TEST("RESULT => %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port));
zta2ss(env, &ss, addr);
socklen_t addrlen = ss.ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
err = zts_bind(fd, (struct sockaddr*)&ss, addrlen);
return err;
return zts_bind(fd, (struct sockaddr*)&ss, addrlen);
}
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_listen(
@@ -229,26 +213,20 @@ namespace ZeroTier {
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port)
{
struct sockaddr_storage ss;
int err;
socklen_t addrlen = sizeof(struct sockaddr_storage);
if ((err = zts_accept(fd, (struct sockaddr *)&ss, &addrlen)) < 0) {
return err;
}
addr = ss2inet(env, &ss);
int err = zts_accept(fd, (struct sockaddr *)&ss, &addrlen);
ss2zta(env, &ss, addr);
return err;
}
#if defined(__linux__)
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_accept4(
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port, jint flags)
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port, jint flags)
{
struct sockaddr_storage ss;
int err;
socklen_t addrlen = sizeof(struct sockaddr_storage);
if ((err = zts_accept4(fd, (struct sockaddr *)&ss, &addrlen, flags)) < 0) {
return err;
}
addr = ss2inet(env, &ss);
int err = zts_accept4(fd, (struct sockaddr *)&ss, &addrlen, flags);
ss2zta(env, &ss, addr);
return err;
}
#endif
@@ -265,139 +243,99 @@ namespace ZeroTier {
return zts_getsockopt(fd, level, optname, (void*)(uintptr_t)optval, (socklen_t *)optlen);
}
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_getsockname(JNIEnv *env, jobject thisObj,
jint fd, jobject ztaddr)
JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_getsockname(JNIEnv *env, jobject thisObj,
jint fd, jobject addr)
{
struct sockaddr_in addr;
int err = zts_getsockname(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(struct sockaddr));
jfieldID fid;
jclass c = (*env).GetObjectClass(ztaddr);
if (c) {
fid = (*env).GetFieldID(c, "port", "I");
(*env).SetIntField(ztaddr, fid, addr.sin_port);
fid = (*env).GetFieldID(c,"_rawAddr", "J");
(*env).SetLongField(ztaddr, fid,addr.sin_addr.s_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_zerotier_ZeroTier_getpeername(JNIEnv *env, jobject thisObj,
jint fd, jobject ztaddr)
jint fd, jobject addr)
{
struct sockaddr_in addr;
int err = zts_getpeername(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(struct sockaddr));
jfieldID fid;
jclass c = (*env).GetObjectClass( ztaddr);
if (c) {
fid = (*env).GetFieldID(c, "port", "I");
(*env).SetIntField(ztaddr, fid, addr.sin_port);
fid = (*env).GetFieldID(c,"_rawAddr", "J");
(*env).SetLongField(ztaddr, fid,addr.sin_addr.s_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;
}
// TODO: ZT_SOCKET_API struct hostent *zts_gethostbyname(const char *name);
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_close(
JNIEnv *env, jobject thisObj, jint fd)
{
return zts_close(fd);
}
// TODO: ZT_SOCKET_API int ZTCALL zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_fcntl(
JNIEnv *env, jobject thisObj, jint fd, jint cmd, jint flags)
{
return zts_fcntl(fd, cmd, flags);
}
// TODO: ZT_SOCKET_API int ZTCALL zts_ioctl(int fd, unsigned long request, void *argp);
JNIEXPORT int JNICALL Java_zerotier_ZeroTier_ioctl(jint fd, jlong request, void *argp)
{
return zts_ioctl(fd, request, argp);
}
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_send(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, int flags)
{
jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
char * bufp = (char *)malloc(sizeof(char)*len);
memcpy(bufp, body, len);
int w = zts_send(fd, body, len, flags);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
int written_bytes = zts_write(fd, body, len);
return written_bytes;
return w;
}
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_sendto(
JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, jint flags, jobject ztaddr)
JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, jint flags, jobject addr)
{
struct sockaddr_in addr;
int sent_bytes = 0;
jclass c = (*env).GetObjectClass( ztaddr);
if (c) {
jfieldID f = (*env).GetFieldID(c, "port", "I");
addr.sin_port = htons((*env).GetIntField( ztaddr, f));
f = (*env).GetFieldID(c, "_rawAddr", "J");
addr.sin_addr.s_addr = (*env).GetLongField( ztaddr, f);
addr.sin_family = AF_INET;
//LOGV("zt_sendto(): fd = %d\naddr = %s\nport=%d", fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// TODO: Optimize this
jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
char * bufp = (char *)malloc(sizeof(char)*len);
memcpy(bufp, body, len);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
// "connect" and send buffer contents
sent_bytes = zts_sendto(fd, body, len, flags, (struct sockaddr *)&addr, sizeof(addr));
}
return sent_bytes;
jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
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, body, len, flags, (struct sockaddr *)&ss, addrlen);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
return w;
}
// TODO: ZT_SOCKET_API ssize_t ZTCALL zts_sendmsg(int fd, const struct msghdr *msg, int flags);
// TODO: ZT_SOCKET_API ssize_t ZTCALL zts_recv(int fd, void *buf, size_t len, int flags);
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_recv(JNIEnv *env, jobject thisObj,
jint fd, jarray buf, jint len, jint flags)
{
jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
int r = zts_recv(fd, body, len, flags);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
return r;
}
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_recvfrom(
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint len, jint flags, jobject ztaddr)
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint len, jint flags, jobject addr)
{
/*
struct sockaddr_in addr;
jbyte *body = (*env).GetByteArrayElements( buf, 0);
unsigned char buffer[ZT_SDK_MTU];
int payload_offset = sizeof(int32_t) + sizeof(struct sockaddr_storage);
int rxbytes = zts_recvfrom(fd, &buffer, len, flags, (struct sockaddr *)&addr, (socklen_t *)sizeof(struct sockaddr_storage));
if (rxbytes > 0) {
memcpy(body, (jbyte*)buffer + payload_offset, rxbytes);
}
(*env).ReleaseByteArrayElements( buf, body, 0);
// Update fields of Java ZTAddress object
jfieldID fid;
jclass c = (*env).GetObjectClass( ztaddr);
if (c) {
fid = (*env).GetFieldID(c, "port", "I");
(*env).SetIntField(ztaddr, fid, addr.sin_port);
fid = (*env).GetFieldID(c,"_rawAddr", "J");
(*env).SetLongField(ztaddr, fid,addr.sin_addr.s_addr);
}
*/
return 1;
socklen_t addrlen = sizeof(struct sockaddr_storage);
struct sockaddr_storage ss;
jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
int r = zts_recvfrom(fd, body, len, flags, (struct sockaddr *)&ss, &addrlen);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
ss2zta(env, &ss, addr);
return r;
}
// TODO: ZT_SOCKET_API ssize_t ZTCALL zts_recvmsg(int fd, struct msghdr *msg,int flags);
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_read(JNIEnv *env, jobject thisObj,
jint fd, jarray buf, jint len)
{
jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
int read_bytes = zts_read(fd, body, len);
int r = zts_read(fd, body, len);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
return read_bytes;
return r;
}
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_write(JNIEnv *env, jobject thisObj,
jint fd, jarray buf, jint len)
{
jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
char * bufp = (char *)malloc(sizeof(char)*len);
memcpy(bufp, body, len);
int w = zts_write(fd, body, len);
(*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
int written_bytes = zts_write(fd, body, len);
return written_bytes;
return w;
}
JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_shutdown(
@@ -405,113 +343,88 @@ namespace ZeroTier {
{
return zts_shutdown(fd, how);
}
// TODO: ZT_SOCKET_API int ZTCALL zts_add_dns_nameserver(struct sockaddr *addr);
// TODO: ZT_SOCKET_API int ZTCALL zts_del_dns_nameserver(struct sockaddr *addr);
}
/****************************************************************************/
/* Helpers (for moving data across the JNI barrier) */
/****************************************************************************/
// convenience function
jobject ss2inet(JNIEnv *env, struct sockaddr_storage *src_ss)
void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr)
{
jobject dest_inet;
if(src_ss->ss_family == AF_INET)
{
DEBUG_ERROR("converting from INET");
struct sockaddr_in *in4 = (struct sockaddr_in*)src_ss;
int arrlen = 4;
jbyteArray bytes = (*env).NewByteArray(arrlen);
jbyte *java_address_bytes;
java_address_bytes = (*env).GetByteArrayElements(bytes, NULL);
memcpy(java_address_bytes, &(in4->sin_addr.s_addr), arrlen);
(*env).ReleaseByteArrayElements(bytes, java_address_bytes, 0);
jclass cls = (*env).FindClass("java/net/InetAddress");
jmethodID mid = (*env).GetStaticMethodID(cls, "getByAddress", "([B)Ljava/net/InetAddress;");
dest_inet = (*env).CallStaticObjectMethod(cls, mid, bytes);
(*env).DeleteLocalRef(bytes);
}
if(src_ss->ss_family == AF_INET6)
{
DEBUG_ERROR("converting from INET6");
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)src_ss;
int arrlen = 16;
jbyteArray bytes = (*env).NewByteArray(arrlen);
(*env).SetByteArrayRegion(bytes, 0, 16, (const jbyte *)&(in6->sin6_addr));
jclass cls = (*env).FindClass("java/net/InetAddress");
jmethodID mid = (*env).GetStaticMethodID(cls, "getByAddress", "([B)Ljava/net/InetAddress;");
dest_inet = (*env).CallStaticObjectMethod(cls, mid, bytes);
(*env).DeleteLocalRef(bytes);
}
return dest_inet;
}
int sockinet2ss(JNIEnv *env, jobject src_inet, struct sockaddr_storage *dest_ss)
{
struct sockaddr_in *in4 = (struct sockaddr_in*)dest_ss;
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)dest_ss;
int port = 0;
int socket_family = 0;
socklen_t addrlen;
// ---
jclass c = (*env).GetObjectClass(src_inet);
jclass c = (*env).GetObjectClass(addr);
if (!c) {
return -1;
return;
}
// get port
jmethodID getPort = (*env).GetMethodID(c, "getPort", "()I");
if (!getPort) {
return -1;
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).SetLongField(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;
}
port = (*env).CallIntMethod(src_inet, getPort);
// get internal InetAddress
jobject inetaddr;
jmethodID getAddress = (*env).GetMethodID(c, "getAddress", "()Ljava/net/InetAddress;");
if (!getAddress) {
return -1;
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).SetLongField(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;
}
inetaddr = (*env).CallObjectMethod(src_inet, getAddress);
if (!inetaddr) {
return -1;
}
void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr)
{
jclass c = (*env).GetObjectClass(addr);
if (!c) {
return;
}
jclass inetClass = (*env).GetObjectClass(inetaddr);
if (!inetClass) {
return -1;
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;
}
// string representation of IP address
jmethodID getHostAddress = (*env).GetMethodID(inetClass, "getHostAddress", "()Ljava/lang/String;");
jstring addrstr = (jstring)(*env).CallObjectMethod(inetaddr, getHostAddress);
const char *addr_str = (*env).GetStringUTFChars(addrstr, NULL);
for (int i=0; i<strlen(addr_str); i++) {
if (addr_str[i]=='.') {
DEBUG_INFO("ipv4, inet_addr");
socket_family = AF_INET;
in4->sin_family = AF_INET;
in4->sin_port = htons(port);
in4->sin_addr.s_addr = inet_addr(addr_str);
/*
if (!inet_pton(AF_INET, addr_str, &(in4->sin_addr))) {
DEBUG_ERROR("error converting address %s", addr_str);
}
*/
addrlen = sizeof(struct sockaddr_in);
break;
}
if (addr_str[i]==':') {
DEBUG_INFO("ipv6");
socket_family = AF_INET6;
if (!inet_pton(AF_INET6, addr_str, &(in6->sin6_addr))) {
DEBUG_ERROR("error converting address %s", addr_str);
}
addrlen = sizeof(struct sockaddr_in6);
break;
}
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;
}
(*env).ReleaseStringUTFChars(addrstr, addr_str);
DEBUG_TEST("RESULT => %s : %d", inet_ntoa(in4->sin_addr), ntohs(in4->sin_port));
return 0;
}
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff