Improved reliability and performance, better startup and shutdown semantics, HTTP control plane is now disabled by default

This commit is contained in:
Joseph Henry
2019-01-14 12:01:29 -08:00
parent 8826b317c1
commit 4e0c00aaff
26 changed files with 3550 additions and 1199 deletions

288
include/Constants.hpp Normal file
View File

@@ -0,0 +1,288 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2019 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
*
* Useful constants
*/
#ifndef LIBZT_CONSTANTS_HPP
#define LIBZT_CONSTANTS_HPP
//////////////////////////////////////////////////////////////////////////////
// Error codes returned by libzt API //
//////////////////////////////////////////////////////////////////////////////
typedef int zts_err_t;
#define ZTS_ERR_OK 0
#define ZTS_ERR_INVALID_ARG -1 // A parameter provided by the user application is invalid (e.g. our of range, NULL, etc)
#define ZTS_ERR_SERVICE -2 // The service isn't initialized or is for some other reason currently unavailable
#define ZTS_ERR_INVALID_OP -3 // For some reason this API operation is not permitted (perhaps the service is still starting?)
//////////////////////////////////////////////////////////////////////////////
// libzt config //
//////////////////////////////////////////////////////////////////////////////
/**
* Default port that libzt will use to support all virtual communication
*/
#define ZTS_DEFAULT_PORT 9994
/**
* Maximum port number allowed
*/
#define ZTS_MAX_PORT 65535
/**
* For layer-2 only (this will omit all user-space network stack code)
*/
#define ZTS_NO_STACK 0
/**
* How fast service states are re-checked (in milliseconds)
*/
#define ZTS_WRAPPER_CHECK_INTERVAL 50
/**
* By how much thread I/O and callback loop delays are multiplied (unitless)
*/
#define ZTS_HIBERNATION_MULTIPLIER 50
/**
* Maximum allowed number of networks joined to concurrently
*/
#define ZTS_MAX_JOINED_NETWORKS 64
/**
* Maximum address assignments per network
*/
#define ZTS_MAX_ASSIGNED_ADDRESSES 16
/**
* Maximum routes per network
*/
#define ZTS_MAX_NETWORK_ROUTES 32
/**
* Length of buffer required to hold a ztAddress/nodeID
*/
#define ZTS_ID_LEN 16
/**
* Polling interval (in ms) for file descriptors wrapped in the Phy I/O loop (for raw drivers only)
*/
#define ZTS_PHY_POLL_INTERVAL 1
/**
* Maximum length of libzt/ZeroTier home path (where keys, and config files are stored)
*/
#define ZTS_HOME_PATH_MAX_LEN 256
/**
* Length of human-readable MAC address string
*/
#define ZTS_MAC_ADDRSTRLEN 18
/**
* Interval (in ms) for performing background tasks
*/
#define ZTS_HOUSEKEEPING_INTERVAL 1000
//////////////////////////////////////////////////////////////////////////////
// lwIP driver config //
// For more LWIP configuration options see: include/lwipopts.h //
//////////////////////////////////////////////////////////////////////////////
/*
* The following three quantities are related and govern how incoming frames are fed into the
* network stack's core:
* Every LWIP_GUARDED_BUF_CHECK_INTERVAL milliseconds, a callback will be called from the core and
* will input a maximum of LWIP_FRAMES_HANDLED_PER_CORE_CALL frames before returning control back
* to the core. Meanwhile, incoming frames from the ZeroTier wire will be allocated and their
* pointers will be cached in the receive frame buffer of the size LWIP_MAX_GUARDED_RX_BUF_SZ to
* await the next callback from the core
*/
#define LWIP_GUARDED_BUF_CHECK_INTERVAL 5 // in ms
#define LWIP_MAX_GUARDED_RX_BUF_SZ 1024 // number of frame pointers that can be cached waiting for receipt into core
#define LWIP_FRAMES_HANDLED_PER_CORE_CALL 16 // How many frames are handled per call from core
typedef signed char err_t;
#define ND6_DISCOVERY_INTERVAL 1000
#define ARP_DISCOVERY_INTERVAL ARP_TMR_INTERVAL
//////////////////////////////////////////////////////////////////////////////
// Subset of: ZeroTierOne.h and Constants.hpp //
// We redefine a few ZT structures here so that we don't need to drag the //
// entire ZeroTierOne.h file into the user application //
//////////////////////////////////////////////////////////////////////////////
/**
* Maximum MTU size for ZeroTier
*/
#define ZT_MAX_MTU 10000
/**
* Maximum number of direct network paths to a given peer
*/
#define ZT_MAX_PEER_NETWORK_PATHS 16
//
// This include file also auto-detects and canonicalizes some environment
// information defines:
//
// __LINUX__
// __APPLE__
// __BSD__ (OSX also defines this)
// __UNIX_LIKE__ (Linux, BSD, etc.)
// __WINDOWS__
//
// Also makes sure __BYTE_ORDER is defined reasonably.
//
// Hack: make sure __GCC__ is defined on old GCC compilers
#ifndef __GCC__
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
#define __GCC__
#endif
#endif
#if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
#ifndef __LINUX__
#define __LINUX__
#endif
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#include <endian.h>
#endif
#ifdef __APPLE__
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
#include <TargetConditionals.h>
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#ifndef __BSD__
#define __BSD__
#endif
#include <machine/endian.h>
#endif
// Defined this macro to disable "type punning" on a number of targets that
// have issues with unaligned memory access.
#if defined(__arm__) || defined(__ARMEL__) || (defined(__APPLE__) && ( (defined(TARGET_OS_IPHONE) && (TARGET_OS_IPHONE != 0)) || (defined(TARGET_OS_WATCH) && (TARGET_OS_WATCH != 0)) || (defined(TARGET_IPHONE_SIMULATOR) && (TARGET_IPHONE_SIMULATOR != 0)) ) )
#ifndef ZT_NO_TYPE_PUNNING
#define ZT_NO_TYPE_PUNNING
#endif
#endif
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#ifndef __BSD__
#define __BSD__
#endif
#include <machine/endian.h>
#ifndef __BYTE_ORDER
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#endif
#endif
#if defined(_WIN32) || defined(_WIN64)
#ifndef __WINDOWS__
#define __WINDOWS__
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#pragma warning(disable : 4290)
#pragma warning(disable : 4996)
#pragma warning(disable : 4101)
#undef __UNIX_LIKE__
#undef __BSD__
#define ZT_PATH_SEPARATOR '\\'
#define ZT_PATH_SEPARATOR_S "\\"
#define ZT_EOL_S "\r\n"
#include <WinSock2.h>
#include <Windows.h>
#endif
// Assume little endian if not defined
#if (defined(__APPLE__) || defined(__WINDOWS__)) && (!defined(__BYTE_ORDER))
#undef __BYTE_ORDER
#undef __LITTLE_ENDIAN
#undef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#define __BYTE_ORDER 1234
#endif
#ifdef __UNIX_LIKE__
#define ZT_PATH_SEPARATOR '/'
#define ZT_PATH_SEPARATOR_S "/"
#define ZT_EOL_S "\n"
#endif
#ifndef __BYTE_ORDER
#include <endian.h>
#endif
#ifdef __NetBSD__
#define RTF_MULTICAST 0x20000000
#endif
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
#ifndef likely
#define likely(x) __builtin_expect((x),1)
#endif
#ifndef unlikely
#define unlikely(x) __builtin_expect((x),0)
#endif
#else
#ifndef likely
#define likely(x) (x)
#endif
#ifndef unlikely
#define unlikely(x) (x)
#endif
#endif
#ifdef __WINDOWS__
#define ZT_PACKED_STRUCT(D) __pragma(pack(push,1)) D __pragma(pack(pop))
#else
#define ZT_PACKED_STRUCT(D) D __attribute__((packed))
#endif
#endif // _H

View File

@@ -1,6 +1,6 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
* Copyright (C) 2011-2019 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
@@ -13,7 +13,7 @@
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
@@ -33,19 +33,21 @@
#ifndef LIBZT_DEBUG_HPP
#define LIBZT_DEBUG_HPP
//////////////////////////////////////////////////////////////////////////////
// Debugging Macros //
//////////////////////////////////////////////////////////////////////////////
#if defined(__linux__) || defined(__APPLE__)
#include <sys/syscall.h>
#include <pthread.h>
#include <unistd.h>
#endif
#include <string.h>
#define ZT_MSG_ERROR true // Errors
#define ZT_MSG_INFO true // Information which is generally useful to any developer
#define ZT_MSG_TEST true // For use in selftest
#define ZT_MSG_TRANSFER true // RX/TX specific statements
#define ZT_MSG_EXTRA true // If nothing in your world makes sense
#define ZT_COLOR true
@@ -75,16 +77,6 @@
#define ZT_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) // short
#ifdef __linux__
#define ZT_THREAD_ID syscall(SYS_gettid)
#endif
#ifdef __APPLE__
#define ZT_THREAD_ID (long)0
#endif
#ifdef _WIN32
#define ZT_THREAD_ID (long)0
#endif
#if defined(__JNI_LIB__)
#include <jni.h>
#endif
@@ -93,63 +85,50 @@
#define ZT_LOG_TAG "ZTSDK"
#endif
// Network stack debugging
#if defined(__ANDROID__)
#define DEBUG_STACK(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
"STACK[%ld]: %17s:%5d:%20s: " fmt "\n", ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
#elif defined(_WIN32)
#define DEBUG_STACK(fmt, ...) fprintf(stderr, ZT_YEL "STACK[%ld]: %17s:%5d:%25s: " fmt \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define DEBUG_STACK(fmt, args ...) fprintf(stderr, ZT_YEL "STACK[%ld]: %17s:%5d:%25s: " fmt \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
// Helpful file/line/function debugging macros
#if defined(LIBZT_DEBUG) || defined(LIBZT_TRACE) || defined(__NATIVETEST__)
//
#if ZT_MSG_TEST == true
#if defined(__ANDROID__)
#define DEBUG_TEST(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
"TEST : %17s:%5d:%25s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
#elif defined(_WIN32)
#define DEBUG_TEST(fmt, ...) fprintf(stderr, ZT_CYN "TEST [%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define DEBUG_TEST(fmt, args ...) fprintf(stderr, ZT_CYN "TEST [%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_TEST(fmt, args...)
#endif
//
#if ZT_MSG_ERROR == true
#if defined(__ANDROID__)
#define DEBUG_ERROR(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
"ERROR: %17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
"%17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
#elif defined(_WIN32)
#define DEBUG_ERROR(fmt, ...) fprintf(stderr, ZT_RED "ERROR[%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#define DEBUG_ERROR(fmt, ...) fprintf(stderr, ZT_RED "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define DEBUG_ERROR(fmt, args ...) fprintf(stderr, ZT_RED "ERROR[%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#define DEBUG_ERROR(fmt, args ...) fprintf(stderr, ZT_RED "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_ERROR(fmt, args...)
#endif
//
#if ZT_MSG_TEST == true
#if defined(__ANDROID__)
#define DEBUG_TEST(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
"%17s:%5d:%25s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
#elif defined(_WIN32)
#define DEBUG_TEST(fmt, ...) fprintf(stderr, ZT_CYN "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define DEBUG_TEST(fmt, args ...) fprintf(stderr, ZT_CYN "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_TEST(fmt, args...)
#endif
//
#if ZT_MSG_INFO == true
#if defined(__ANDROID__)
#define DEBUG_INFO(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
"INFO : %17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
"%17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
#elif defined(_WIN32)
#define DEBUG_INFO(fmt, ...) fprintf(stderr, ZT_WHT "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#define DEBUG_INFO(fmt, ...) fprintf(stderr, ZT_WHT "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define DEBUG_INFO(fmt, args ...) fprintf(stderr, ZT_WHT "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#define DEBUG_INFO(fmt, args ...) fprintf(stderr, ZT_WHT "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_INFO(fmt, args...)
@@ -159,52 +138,30 @@
#if ZT_MSG_TRANSFER == true
#if defined(__ANDROID__)
#define DEBUG_TRANS(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
"TRANS: %17s:%5d:%25s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
"%17s:%5d:%25s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
#elif defined(_WIN32)
#define DEBUG_TRANS(fmt, ...) fprintf(stderr, ZT_GRN "TRANS[%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#define DEBUG_TRANS(fmt, ...) fprintf(stderr, ZT_GRN "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define DEBUG_TRANS(fmt, args ...) fprintf(stderr, ZT_GRN "TRANS[%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#define DEBUG_TRANS(fmt, args ...) fprintf(stderr, ZT_GRN "%17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_TRANS(fmt, args...)
#endif
//
#if ZT_MSG_EXTRA == true
#if defined(__ANDROID__)
#define DEBUG_EXTRA(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \
"EXTRA: %17s:%5d:%25s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args))
#elif defined(_WIN32)
#define DEBUG_EXTRA(fmt, ...) fprintf(stderr, ZT_WHT "EXTRA[%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__, (long)0)
#else
#define DEBUG_EXTRA(fmt, args ...) fprintf(stderr, ZT_WHT "EXTRA[%ld]: %17s:%5d:%25s: " fmt "\n" \
ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_EXTRA(fmt, args...)
#endif
#else // !LIBZT_DEBUG || !__NATIVE_TEST__
#if defined(_WIN32)
#define DEBUG_ERROR(...)
#define DEBUG_TEST(...)
#define DEBUG_INFO(...)
#define DEBUG_BLANK(...)
#define DEBUG_ATTN(...)
#define DEBUG_TRANS(...)
#define DEBUG_EXTRA(...)
#else
#define DEBUG_ERROR(fmt, args...)
#define DEBUG_TEST(fmt, args...)
#define DEBUG_INFO(fmt, args...)
#define DEBUG_BLANK(fmt, args...)
#define DEBUG_ATTN(fmt, args...)
#define DEBUG_TRANS(fmt, args...)
#define DEBUG_EXTRA(fmt, args...)
#endif
#endif
#endif // _H
#endif // _H

211
include/Defs.hpp Normal file
View File

@@ -0,0 +1,211 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2019 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
*
* Management of virtual tap interfaces
*/
#ifndef LIBZT_DEFS_HPP
#define LIBZT_DEFS_HPP
#include "Constants.hpp"
#ifndef _USING_LWIP_DEFINITIONS_
#include <sys/socket.h>
#endif
//////////////////////////////////////////////////////////////////////////////
// Subset of: ZeroTierOne.h //
// We redefine a few ZT structures here so that we don't need to drag the //
// entire ZeroTierOne.h file into the user application //
//////////////////////////////////////////////////////////////////////////////
/**
* What trust hierarchy role does this peer have?
*/
enum zts_peer_role
{
ZTS_PEER_ROLE_LEAF = 0, // ordinary node
ZTS_PEER_ROLE_MOON = 1, // moon root
ZTS_PEER_ROLE_PLANET = 2 // planetary root
};
/**
* A structure used to represent a virtual network route
*/
struct zts_virtual_network_route
{
/**
* Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default
*/
struct sockaddr_storage target;
/**
* Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway)
*/
struct sockaddr_storage via;
/**
* Route flags
*/
uint16_t flags;
/**
* Route metric (not currently used)
*/
uint16_t metric;
};
/**
* A structure used to convey network-specific details to the user application
*/
struct zts_network_details
{
/**
* Network ID
*/
uint64_t nwid;
/**
* Maximum Transmission Unit size for this network
*/
int mtu;
/**
* Number of addresses (actually) assigned to the node on this network
*/
short num_addresses;
/**
* Array of IPv4 and IPv6 addresses assigned to the node on this network
*/
struct sockaddr_storage addr[ZTS_MAX_ASSIGNED_ADDRESSES];
/**
* Number of routes
*/
unsigned int num_routes;
/**
* Array of IPv4 and IPv6 addresses assigned to the node on this network
*/
struct zts_virtual_network_route routes[ZTS_MAX_NETWORK_ROUTES];
};
/**
* Physical network path to a peer
*/
struct zts_physical_path
{
/**
* Address of endpoint
*/
struct sockaddr_storage address;
/**
* Time of last send in milliseconds or 0 for never
*/
uint64_t lastSend;
/**
* Time of last receive in milliseconds or 0 for never
*/
uint64_t lastReceive;
/**
* Is this a trusted path? If so this will be its nonzero ID.
*/
uint64_t trustedPathId;
/**
* Is path expired?
*/
int expired;
/**
* Is path preferred?
*/
int preferred;
};
/**
* Peer status result buffer
*/
struct zts_peer_details
{
/**
* ZeroTier address (40 bits)
*/
uint64_t address;
/**
* Remote major version or -1 if not known
*/
int versionMajor;
/**
* Remote minor version or -1 if not known
*/
int versionMinor;
/**
* Remote revision or -1 if not known
*/
int versionRev;
/**
* Last measured latency in milliseconds or -1 if unknown
*/
int latency;
/**
* What trust hierarchy role does this device have?
*/
enum zts_peer_role role;
/**
* Number of paths (size of paths[])
*/
unsigned int pathCount;
/**
* Known network paths to peer
*/
zts_physical_path paths[ZT_MAX_PEER_NETWORK_PATHS];
};
/**
* List of peers
*/
struct zts_peer_list
{
zts_peer_details *peers;
unsigned long peerCount;
};
#endif // _H

View File

@@ -1,6 +1,6 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
* Copyright (C) 2011-2019 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
@@ -13,7 +13,7 @@
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
@@ -36,7 +36,6 @@
#include <cstdint>
#include <stdlib.h>
typedef char bufElementType;
class RingBuffer

373
include/ServiceControls.hpp Normal file
View File

@@ -0,0 +1,373 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2019 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
*
* Header for ZeroTier service controls
*/
#ifndef LIBZT_SERVICE_CONTROLS_HPP
#define LIBZT_SERVICE_CONTROLS_HPP
#ifdef _WIN32
#ifdef ADD_EXPORTS
#define ZT_SOCKET_API __declspec(dllexport)
#else
#define ZT_SOCKET_API __declspec(dllimport)
#endif
#define ZTCALL __cdecl
#else
#define ZT_SOCKET_API
#define ZTCALL
#endif
void api_sleep(int interval_ms);
//////////////////////////////////////////////////////////////////////////////
// ZeroTier Service Controls //
//////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief (optional) Sets the port for the background libzt service. If this function is called
* with a port number between 1-65535 it will attempt to bind to that port. If it is called with
* a port number of 0 it will attempt to randomly search for an available port. If this function
* is never called, the service will try to bind on LIBZT_DEFAULT_PORT which is 9994.
*
* @usage Should be called at the beginning of your application before `zts_startjoin()`
* @param portno Port number
* @return 0 if successful; or -1 if failed
*/
ZT_SOCKET_API int ZTCALL zts_set_service_port(int portno);
/**
* @brief (optional) Returns the port number used by the ZeroTier service
* @usage Can be called if a port number was previously assigned
* @return the port number used by the ZeroTier service
*/
ZT_SOCKET_API int ZTCALL zts_get_service_port();
/**
* @brief Starts the ZeroTier service
*
* @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met:
* - ZeroTier core service has been initialized
* - Cryptographic identity has been generated or loaded from directory specified by `path`
* - Virtual network is successfully joined
* - IP address is assigned by network controller service
* @param path path directory where cryptographic identities and network configuration files are stored and retrieved
* (`identity.public`, `identity.secret`)
* @param blocking whether or not this call will block until the entire service is up and running
* @return 0 if successful; or 1 if failed
*/
ZT_SOCKET_API int ZTCALL zts_start(const char *path, int blocking);
/**
* @brief Starts the ZeroTier service
*
* @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met:
* - ZeroTier core service has been initialized
* - Cryptographic identity has been generated or loaded from directory specified by `path`
* - Virtual network is successfully joined
* - IP address is assigned by network controller service
* @param path path directory where cryptographic identities and network configuration files are stored and retrieved
* (`identity.public`, `identity.secret`)
* @param nwid A 16-digit hexidecimal network identifier (e.g. Earth: `8056c2e21c000001`)
* @return 0 if successful; or 1 if failed
*/
ZT_SOCKET_API int ZTCALL zts_startjoin(const char *path, const uint64_t nwid);
/**
* @brief Stops the ZeroTier service, brings down all virtual interfaces in order to stop all traffic processing.
*
* @usage This should be called when the application anticipates not needing any sort of traffic processing for a
* prolonged period of time. The stack driver (with associated timers) will remain active in case future traffic
* processing is required. Note that the application must tolerate a multi-second startup time if zts_start()
* zts_startjoin() is called again. To stop this background thread and free all resources use zts_free() instead.
* @param blocking whether or not this call will block until the entire service is torn down
* @return Returns 0 on success, -1 on failure
*/
ZT_SOCKET_API int ZTCALL zts_stop(int blocking = 1);
/**
* @brief Stops all background services, brings down all interfaces, frees all resources. After calling this function
* an application restart will be required before the library can be used again. This is a blocking call.
*
* @usage This should be called at the end of your program or when you do not anticipate communicating over ZeroTier
* @return Returns 0 on success, -1 on failure
*/
ZT_SOCKET_API int ZTCALL zts_free();
/**
* @brief Return whether the ZeroTier service is currently running
*
* @usage Call this after zts_start()
* @return 1 if running, 0 if not running
*/
ZT_SOCKET_API int ZTCALL zts_core_running();
/**
* @brief Return whether libzt is ready to handle socket API calls. Alternatively you could
* have just called zts_startjoin(path, nwid)
*
* @usage Call this after zts_start()
* @return 1 if running, 0 if not running
*/
ZT_SOCKET_API int ZTCALL zts_ready();
/**
* @brief Return the number of networks currently joined by this node
*
* @usage Call this after zts_start(), zts_startjoin() and/or zts_join()
* @return Number of networks joined by this node
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_get_num_joined_networks();
/**
* @brief Populates a structure with details for a given network
*
* @usage Call this from the application thread any time after the node has joined a network
* @param nwid A 16-digit hexidecimal virtual network ID
* @param nd Pointer to a zts_network_details structure to populate
* @return ZTS_ERR_SERVICE if failed, 0 if otherwise
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_get_network_details(uint64_t nwid, struct zts_network_details *nd);
/**
* @brief Populates an array of structures with details for any given number of networks
*
* @usage Call this from the application thread any time after the node has joined a network
* @param nds Pointer to an array of zts_network_details structures to populate
* @param num Number of zts_network_details structures available to copy data into, will be updated
* to reflect number of structures that were actually populated
* @return ZTS_ERR_SERVICE if failed, 0 if otherwise
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_get_all_network_details(struct zts_network_details *nds, int *num);
/**
* @brief Join a network
*
* @usage Call this from application thread. Only after zts_start() has succeeded
* @param nwid A 16-digit hexidecimal virtual network ID
* @return 0 if successful, -1 for any failure
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_join(const uint64_t nwid, int blocking = 1);
/**
* @brief Leave a network
*
* @usage Call this from application thread. Only after zts_start() has succeeded
* @param nwid A 16-digit hexidecimal virtual network ID
* @return 0 if successful, -1 for any failure
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_leave(const uint64_t nwid, int blocking = 1);
/**
* @brief Leaves all networks
*
* @usage Call this from application thread. Only after zts_start() has succeeded
* @param nwid A 16-digit hexidecimal virtual network ID
* @return 0 if successful, -1 for any failure
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_leave_all(int blocking = 1);
/**
* @brief Orbits a given moon (user-defined root server)
*
* @usage Call this from application thread. Only after zts_start() has succeeded
* @param moonWorldId A 16-digit hexidecimal world ID
* @param moonSeed A 16-digit hexidecimal seed ID
* @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed);
/**
* @brief De-orbits a given moon (user-defined root server)
*
* @usage Call this from application thread. Only after zts_start() has succeeded
* @param moonWorldId A 16-digit hexidecimal world ID
* @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_deorbit(uint64_t moonWorldId);
/**
* @brief Copies the configuration path used by ZeroTier into the provided buffer
*
* @usage Use this to determine where ZeroTier is storing identity files
* @param homePath Path to ZeroTier configuration files
* @param len Length of destination buffer
* @return 0 if no error, -1 if invalid argument was supplied
*/
ZT_SOCKET_API zts_err_t ZTCALL zts_get_path(char *homePath, size_t *len);
/**
* @brief Returns the node ID of this instance
*
* @usage Call this after zts_start() and/or when zts_running() returns true
* @return
*/
ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id();
/**
* @brief Returns whether any address has been assigned to the SockTap for this network
*
* @usage This is used as an indicator of readiness for service for the ZeroTier core and stack
* @param nwid Network ID
* @return
*/
ZT_SOCKET_API int ZTCALL zts_has_address(const uint64_t nwid);
/**
* @brief Returns the number of addresses assigned to this node for the given nwid
*
* @param nwid Network ID
* @return The number of addresses assigned
*/
ZT_SOCKET_API int ZTCALL zts_get_num_assigned_addresses(const uint64_t nwid);
/**
* @brief Returns the assigned address located at the given index
*
* @usage The indices of each assigned address are not guaranteed and should only
* be used for iterative purposes.
* @param nwid Network ID
* @param index location of assigned address
* @return The number of addresses assigned
*/
ZT_SOCKET_API int ZTCALL zts_get_address_at_index(
const uint64_t nwid, const int index, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Get IP address for this device on a given network
*
* @usage FIXME: Only returns first address found, good enough for most cases
* @param nwid Network ID
* @param addr Destination structure for address
* @param addrlen size of destination address buffer, will be changed to size of returned address
* @return 0 if an address was successfully found, -1 if failure
*/
ZT_SOCKET_API int ZTCALL zts_get_address(
const uint64_t nwid, struct sockaddr_storage *addr, const int address_family);
/**
* @brief Computes a 6PLANE IPv6 address for the given Network ID and Node ID
*
* @usage Can call any time
* @param addr Destination structure for address
* @param nwid Network ID
* @param nodeId Node ID
* @return
*/
ZT_SOCKET_API void ZTCALL zts_get_6plane_addr(
struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId);
/**
* @brief Computes a RFC4193 IPv6 address for the given Network ID and Node ID
*
* @usage Can call any time
* @param addr Destination structure for address
* @param nwid Network ID
* @param nodeId Node ID
* @return
*/
ZT_SOCKET_API void ZTCALL zts_get_rfc4193_addr(
struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId);
/**
* @brief Return the number of peers
*
* @usage Call this after zts_start() has succeeded
* @return
*/
ZT_SOCKET_API zts_err_t zts_get_peer_count();
ZT_SOCKET_API zts_err_t zts_get_peers(struct zts_peer_details *pds, int *num);
/**
* @brief Enables the HTTP backplane management system
*
* @usage Call this after zts_start() has succeeded
* @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE if otherwise
*/
ZT_SOCKET_API zts_err_t zts_enable_http_backplane_mgmt();
/**
* @brief Disables the HTTP backplane management system
*
* @usage Call this after zts_start() has succeeded
* @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_OP if otherwise
*/
ZT_SOCKET_API zts_err_t zts_disable_http_backplane_mgmt();
/**
* @brief Starts a ZeroTier service in the background
*
* @usage For internal use only.
* @param
* @return
*/
#if defined(_WIN32)
DWORD WINAPI _zts_start_service(LPVOID thread_id);
#else
void *_zts_start_service(void *thread_id);
#endif
/**
* @brief [Should not be called from user application] This function must be surrounded by
* ZT service locks. It will determine if it is currently safe and allowed to operate on
* the service.
* @usage Can be called at any time
* @return 1 or 0
*/
int _zts_can_perform_service_operation();
/**
* @brief [Should not be called from user application] Returns whether or not the node is
* online.
* @usage Can be called at any time
* @return 1 or 0
*/
int _zts_node_online();
/**
* @brief [Should not be called from user application] Adjusts the delay multiplier for the
* network stack driver thread.
* @usage Can be called at any time
*/
void _hibernate_if_needed();
#ifdef __cplusplus
}
#endif
#endif // _H

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,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,6 +1,6 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
* Copyright (C) 2011-2019 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
@@ -13,7 +13,7 @@
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
@@ -30,24 +30,20 @@
* Virtual Ethernet tap device
*/
#ifndef ZT_VIRTUALTAP_H
#define ZT_VIRTUALTAP_H
#ifndef LIBZT_VIRTUALTAP_HPP
#define LIBZT_VIRTUALTAP_HPP
#ifndef _MSC_VER
extern int errno;
#endif
#include "Mutex.hpp"
#include "MulticastGroup.hpp"
#include "InetAddress.hpp"
#include "Thread.hpp"
#include "Phy.hpp"
#include "Thread.hpp"
#include "InetAddress.hpp"
#include "MulticastGroup.hpp"
#include "Mutex.hpp"
#include "libzt.h"
#include <vector>
extern std::vector<void*> vtaps;
extern ZeroTier::Mutex _vtaps_lock;
#include "Defs.hpp"
#if defined(_WIN32)
#include <WinSock2.h>
@@ -56,9 +52,9 @@ extern ZeroTier::Mutex _vtaps_lock;
#include <Ifdef.h>
#endif
using namespace ZeroTier;
namespace ZeroTier {
class VirtualSocket;
class Mutex;
/**
* emulates an Ethernet tap device
@@ -70,13 +66,13 @@ class VirtualTap
public:
VirtualTap(
const char *homePath,
const ZeroTier::MAC &mac,
const MAC &mac,
unsigned int mtu,
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *, void *, uint64_t, const ZeroTier::MAC &,
const ZeroTier::MAC &, unsigned int, unsigned int, const void *, unsigned int),
void (*handler)(void *, void *, uint64_t, const MAC &,
const MAC &, unsigned int, unsigned int, const void *, unsigned int),
void *arg);
~VirtualTap();
@@ -87,27 +83,27 @@ public:
/**
* Registers a device with the given address
*/
void registerIpWithStack(const ZeroTier::InetAddress &ip);
void registerIpWithStack(const InetAddress &ip);
/**
* Adds an address to the userspace stack interface associated with this VirtualTap
* - Starts VirtualTap main thread ONLY if successful
*/
bool addIp(const ZeroTier::InetAddress &ip);
bool addIp(const InetAddress &ip);
/**
* Removes an address from the userspace stack interface associated with this VirtualTap
*/
bool removeIp(const ZeroTier::InetAddress &ip);
bool removeIp(const InetAddress &ip);
/**
* Presents data to the userspace stack
*/
void put(const ZeroTier::MAC &from,const ZeroTier::MAC &to,unsigned int etherType,const void *data,
void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,
unsigned int len);
/**
* Get VirtualTap device name (e.g. 'libzt4-17d72843bc2c5760')
* Get VirtualTap device name (e.g. 'libzt17d72843bc2c5760')
*/
std::string deviceName() const;
@@ -124,8 +120,8 @@ public:
/**
* Scan multicast groups
*/
void scanMulticastGroups(std::vector<ZeroTier::MulticastGroup> &added,
std::vector<ZeroTier::MulticastGroup> &removed);
void scanMulticastGroups(std::vector<MulticastGroup> &added,
std::vector<MulticastGroup> &removed);
/**
* Set MTU
@@ -155,49 +151,51 @@ public:
/**
* For moving data onto the ZeroTier virtual wire
*/
void (*_handler)(void *, void *, uint64_t, const ZeroTier::MAC &, const ZeroTier::MAC &, unsigned int, unsigned int,
void (*_handler)(void *, void *, uint64_t, const MAC &, const MAC &, unsigned int, unsigned int,
const void *, unsigned int);
void phyOnUnixClose(ZeroTier::PhySocket *sock, void **uptr);
void phyOnUnixData(ZeroTier::PhySocket *sock, void **uptr, void *data, ssize_t len);
void phyOnUnixWritable(ZeroTier::PhySocket *sock, void **uptr, bool stack_invoked);
void phyOnUnixClose(PhySocket *sock, void **uptr);
void phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len);
void phyOnUnixWritable(PhySocket *sock, void **uptr, bool stack_invoked);
/****************************************************************************/
/* Vars */
/****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
// Vars //
//////////////////////////////////////////////////////////////////////////////
std::vector<std::pair<ZeroTier::InetAddress, ZeroTier::InetAddress> > routes;
std::vector<std::pair<InetAddress, InetAddress> > routes;
void *zt1ServiceRef = NULL;
char vtap_full_name[64];
char vtap_abbr_name[16];
static int devno;
size_t ifindex = 0;
std::vector<ZeroTier::InetAddress> ips() const;
std::vector<ZeroTier::InetAddress> _ips;
std::vector<InetAddress> ips() const;
std::vector<InetAddress> _ips;
std::string _homePath;
void *_arg;
volatile bool _initialized;
volatile bool _enabled;
volatile bool _run;
ZeroTier::MAC _mac;
MAC _mac;
unsigned int _mtu;
uint64_t _nwid;
ZeroTier::PhySocket *_unixListenSocket;
ZeroTier::Phy<VirtualTap *> _phy;
std::vector<VirtualSocket*> _VirtualSockets;
PhySocket *_unixListenSocket;
Phy<VirtualTap *> _phy;
Thread _thread;
int _shutdownSignalPipe[2];
std::string _dev; // path to Unix domain socket
std::vector<MulticastGroup> _multicastGroups;
Mutex _multicastGroups_m;
Mutex _ips_m, _tcpconns_m, _rx_buf_m, _close_m;
struct zts_network_details nd;
/*
* Timestamp of last run of housekeeping
* SEE: ZT_HOUSEKEEPING_INTERVAL in libzt.h
@@ -205,13 +203,13 @@ public:
uint64_t last_housekeeping_ts = 0;
/**
* Disposes of previously-closed VirtualSockets
* Performs miscellaneous background tasks
*/
void Housekeeping();
/****************************************************************************/
/* Not used in this implementation */
/****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
// Not used in this implementation //
//////////////////////////////////////////////////////////////////////////////
void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *local_address,
const struct sockaddr *from,void *data,unsigned long len);
@@ -223,5 +221,6 @@ public:
void phyOnTcpWritable(PhySocket *sock,void **uptr);
};
} // namespace ZeroTier
#endif // _H

View File

@@ -0,0 +1,140 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2019 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
*
* Management of virtual tap interfaces
*/
#include "VirtualTap.hpp"
#include "OneService.hpp"
namespace ZeroTier {
extern std::vector<void*> vtaps;
extern Mutex _vtaps_lock;
class VirtualTap;
/**
* @brief Static utility class for safely handling VirtualTap(s)
*/
class VirtualTapManager
{
public:
static void add_tap(VirtualTap *tap) {
_vtaps_lock.lock();
vtaps.push_back((void*)tap);
_vtaps_lock.unlock();
}
static 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;
}
static size_t get_vtaps_size() {
size_t sz;
_vtaps_lock.lock();
sz = vtaps.size();
_vtaps_lock.unlock();
return sz;
}
// TODO: We shouldn't re-apply the reference to everything all the time
static void update_service_references(void *serviceRef) {
_vtaps_lock.lock();
for (size_t i=0;i<vtaps.size(); i++) {
VirtualTap *s = (VirtualTap*)vtaps[i];
s->zt1ServiceRef=serviceRef;
}
_vtaps_lock.unlock();
}
static void remove_by_nwid(uint64_t nwid) {
_vtaps_lock.lock();
for (size_t i=0;i<vtaps.size(); i++) {
VirtualTap *s = (VirtualTap*)vtaps[i];
if (s->_nwid == nwid) {
vtaps.erase(vtaps.begin() + i);
}
}
_vtaps_lock.unlock();
}
static void clear() {
_vtaps_lock.lock();
vtaps.clear();
_vtaps_lock.unlock();
}
static void get_network_details(uint64_t nwid, struct zts_network_details *nd)
{
VirtualTap *tap;
socklen_t addrlen;
_vtaps_lock.lock();
for (size_t i=0; i<vtaps.size(); i++) {
tap = (VirtualTap*)vtaps[i];
if (tap->_nwid == nwid) {
nd->nwid = tap->_nwid;
nd->mtu = tap->_mtu;
// assigned addresses
nd->num_addresses = tap->_ips.size() < ZTS_MAX_ASSIGNED_ADDRESSES ? tap->_ips.size() : ZTS_MAX_ASSIGNED_ADDRESSES;
for (int j=0; j<nd->num_addresses; j++) {
addrlen = tap->_ips[j].isV4() ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
memcpy(&(nd->addr[j]), &(tap->_ips[j]), addrlen);
}
// routes
nd->num_routes = ZTS_MAX_NETWORK_ROUTES;
OneService *zt1Service = (OneService*)tap->zt1ServiceRef;
zt1Service->getRoutes(nwid, (ZT_VirtualNetworkRoute*)&(nd->routes)[0], &(nd->num_routes));
break;
}
}
_vtaps_lock.unlock();
}
static void get_all_network_details(struct zts_network_details *nds, int *num)
{
VirtualTap *tap;
*num = get_vtaps_size();
for (size_t i=0; i<vtaps.size(); i++) {
tap = (VirtualTap*)vtaps[i];
get_network_details(tap->_nwid, &nds[i]);
}
}
};
} // namespace ZeroTier

View File

@@ -1,6 +1,6 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
* Copyright (C) 2011-2019 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
@@ -13,7 +13,7 @@
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
@@ -24,23 +24,34 @@
* of your own application.
*/
/**
* @file
*
* ZeroTier socket API
*/
#ifndef LIBZT_BRIDGING_HEADER_H
#define LIBZT_BRIDGING_HEADER_H
#include <sys/socket.h>
#include "libzt.h"
// ZT SERVICE CONTROLS
//////////////////////////////////////////////////////////////////////////////
// Service Controls //
//////////////////////////////////////////////////////////////////////////////
int zts_start(const char *path, int blocking);
int zts_startjoin(const char *path, const uint64_t nwid);
void zts_stop();
int zts_core_running();
int zts_stack_running();
int zts_ready();
int zts_join(uint64_t nwid);
int zts_leave(uint64_t nwid);
uint64_t zts_get_node_id();
// SOCKET API
//////////////////////////////////////////////////////////////////////////////
// Socket API //
//////////////////////////////////////////////////////////////////////////////
int zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen);
int zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
int zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen);
@@ -64,7 +75,7 @@ int zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, s
int zts_fcntl(int fd, int cmd, int flags);
int zts_ioctl(int fd, unsigned long request, void *argp);
#endif /* LIBZT_BRIDGING_HEADER_H */
#endif // _H

View File

@@ -1,93 +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
*/
#if defined(_WIN32)
#include <Windows.h>
#endif
#include "ZeroTierOne.h"
#include "InetAddress.hpp"
#include "libztDefs.h"
#include <vector>
#ifndef ZT1SERVICE_H
#define ZT1SERVICE_H
#ifdef __cplusplus
extern "C" {
#endif
class VirtualTap;
class VirtualSocket;
VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr);
VirtualTap *getTapByName(char *ifname);
VirtualTap *getTapByIndex(size_t index);
VirtualTap *getAnyTap();
/**
* @brief Returns a vector of network routes { target, via, metric, etc... }
*
* @usage
* @param nwid 16-digit hexidecimal network identifier
* @return
*/
std::vector<ZT_VirtualNetworkRoute> *zts_get_network_routes(const uint64_t nwid);
/**
* @brief Starts a ZeroTier service in the background
*
* @usage For internal use only.
* @param
* @return
*/
#if defined(_WIN32)
DWORD WINAPI zts_start_service(LPVOID thread_id);
#else
void *zts_start_service(void *thread_id);
#endif
/**
* @brief Returns masked address for subnet comparisons
*
* @usage For internal use only.
* @param socket_type
* @return
*/
bool _ipv6_in_subnet(ZeroTier::InetAddress *subnet, ZeroTier::InetAddress *addr);
#ifdef __cplusplus
}
#endif
#endif // _H

View File

@@ -1,6 +1,6 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
* Copyright (C) 2011-2019 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
@@ -13,7 +13,7 @@
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
@@ -27,33 +27,12 @@
/**
* @file
*
* Application-facing, partially-POSIX-compliant socket API
* ZeroTier socket API
*/
#ifndef LIBZT_H
#define LIBZT_H
#include "libztDebug.h"
#include "libztDefs.h"
#include <stdlib.h>
#include <stdint.h>
#if defined(__linux__) || defined(__APPLE__)
#include <sys/socket.h>
#include <unistd.h>
#endif
#if defined(_WIN32)
#include <WinSock2.h>
#include <stdint.h>
#include <WS2tcpip.h>
#endif
/****************************************************************************/
/* DLL export for Windows */
/****************************************************************************/
#ifdef _WIN32
#ifdef ADD_EXPORTS
#define ZT_SOCKET_API __declspec(dllexport)
@@ -66,211 +45,290 @@
#define ZTCALL
#endif
/****************************************************************************/
/* ZeroTier Service Controls */
/****************************************************************************/
#include <stdint.h>
#include <vector>
#if !defined(_WIN32) && !defined(__ANDROID__)
typedef unsigned int socklen_t;
//#include <sys/socket.h>
#else
typedef int socklen_t;
//#include <sys/socket.h>
#endif
#if defined(_WIN32)
#include <WinSock2.h>
#include <stdint.h>
#include <WS2tcpip.h>
#include <Windows.h>
#endif
#ifdef _USING_LWIP_DEFINITIONS_
#include "lwip/sockets.h"
#endif
#include "Constants.hpp"
#include "Defs.hpp"
#include "ServiceControls.hpp"
class InetAddress;
class VirtualTap;
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
//////////////////////////////////////////////////////////////////////////////
// Common definitions and structures for interacting with the ZT socket API //
// This is a subset of lwip/sockets.h, lwip/arch.h, and lwip/inet.h //
// //
// These re-definitions exist here so that the user application's usage //
// of the API is internally consistent with the underlying network stack. //
// They have an attached prefix so that they can co-exist with the native //
// platform's own definitions and structures. //
//////////////////////////////////////////////////////////////////////////////
// Socket protocol types
#define ZTS_SOCK_STREAM 0x0001
#define ZTS_SOCK_DGRAM 0x0002
#define ZTS_SOCK_RAW 0x0003
// Socket family types
#define ZTS_AF_UNSPEC 0x0000
#define ZTS_AF_INET 0x0002
#define ZTS_AF_INET6 0x000a
#define ZTS_PF_INET ZTS_AF_INET
#define ZTS_PF_INET6 ZTS_AF_INET6
#define ZTS_PF_UNSPEC ZTS_AF_UNSPEC
//
#define ZTS_IPPROTO_IP 0x0000
#define ZTS_IPPROTO_ICMP 0x0001
#define ZTS_IPPROTO_TCP 0x0006
#define ZTS_IPPROTO_UDP 0x0011
#define ZTS_IPPROTO_IPV6 0x0029
#define ZTS_IPPROTO_ICMPV6 0x003a
#define ZTS_IPPROTO_UDPLITE 0x0088
#define ZTS_IPPROTO_RAW 0x00ff
// send() and recv() flags
#define ZTS_MSG_PEEK 0x0001
#define ZTS_MSG_WAITALL 0x0002 // NOT YET SUPPORTED
#define ZTS_MSG_OOB 0x0004 // NOT YET SUPPORTED
#define ZTS_MSG_DONTWAIT 0x0008
#define ZTS_MSG_MORE 0x0010
// fnctl() commands
#define ZTS_F_GETFL 0x0003
#define ZTS_F_SETFL 0x0004
// fnctl() flags
#define ZTS_O_NONBLOCK 0x0001
#define ZTS_O_NDELAY 0x0001
//
#define ZTS_SHUT_RD 0x0000
#define ZTS_SHUT_WR 0x0001
#define ZTS_SHUT_RDWR 0x0002
// Socket level option number
#define ZTS_SOL_SOCKET 0x0fff
// Socket options
#define ZTS_SO_DEBUG 0x0001 // NOT YET SUPPORTED
#define ZTS_SO_ACCEPTCONN 0x0002
#define ZTS_SO_REUSEADDR 0x0004
#define ZTS_SO_KEEPALIVE 0x0008
#define ZTS_SO_DONTROUTE 0x0010 // NOT YET SUPPORTED
#define ZTS_SO_BROADCAST 0x0020
#define ZTS_SO_USELOOPBACK 0x0040 // NOT YET SUPPORTED
#define ZTS_SO_LINGER 0x0080
#define ZTS_SO_DONTLINGER ((int)(~ZTS_SO_LINGER))
#define ZTS_SO_OOBINLINE 0x0100 // NOT YET SUPPORTED
#define ZTS_SO_REUSEPORT 0x0200 // NOT YET SUPPORTED
#define ZTS_SO_SNDBUF 0x1001 // NOT YET SUPPORTED
#define ZTS_SO_RCVBUF 0x1002
#define ZTS_SO_SNDLOWAT 0x1003 // NOT YET SUPPORTED
#define ZTS_SO_RCVLOWAT 0x1004 // NOT YET SUPPORTED
#define ZTS_SO_SNDTIMEO 0x1005
#define ZTS_SO_RCVTIMEO 0x1006
#define ZTS_SO_ERROR 0x1007
#define ZTS_SO_TYPE 0x1008
#define ZTS_SO_CONTIMEO 0x1009
#define ZTS_SO_NO_CHECK 0x100a
// IPPROTO_IP options
#define ZTS_IP_TOS 0x0001
#define ZTS_IP_TTL 0x0002
// IPPROTO_TCP options
#define ZTS_TCP_NODELAY 0x0001
#define ZTS_TCP_KEEPALIVE 0x0002
#define ZTS_TCP_KEEPIDLE 0x0003
#define ZTS_TCP_KEEPINTVL 0x0004
#define ZTS_TCP_KEEPCNT 0x0005
// IPPROTO_IPV6 options
#define ZTS_IPV6_CHECKSUM 0x0007 // RFC3542
#define ZTS_IPV6_V6ONLY 0x001b // RFC3493
//
#define ZTS_IOCPARM_MASK 0x7fU
#define ZTS_IOC_VOID 0x20000000UL
#define ZTS_IOC_OUT 0x40000000UL
#define ZTS_IOC_IN 0x80000000UL
#define ZTS_IOC_INOUT (ZTS_IOC_IN | ZTS_IOC_OUT)
#define ZTS_IO(x,y) (ZTS_IOC_VOID | ((x)<<8)|(y))
#define ZTS_IOR(x,y,t) (ZTS_IOC_OUT | (((long)sizeof(t) & ZTS_IOCPARM_MASK)<<16) | ((x)<<8) | (y))
#define ZTS_IOW(x,y,t) (ZTS_IOC_IN | (((long)sizeof(t) & ZTS_IOCPARM_MASK)<<16) | ((x)<<8) | (y))
//
#define ZTS_FIONREAD ZTS_IOR('f', 127, unsigned long)
#define ZTS_FIONBIO ZTS_IOW('f', 126, unsigned long)
/* FD_SET used for lwip_select */
#ifndef ZTS_FD_SET
#undef ZTS_FD_SETSIZE
// Make FD_SETSIZE match NUM_SOCKETS in socket.c
#define ZTS_FD_SETSIZE MEMP_NUM_NETCONN
#define ZTS_FDSETSAFESET(n, code) do { \
if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
code; }} while(0)
#define ZTS_FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
(code) : 0)
#define ZTS_FD_SET(n, p) ZTS_FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
#define ZTS_FD_CLR(n, p) ZTS_FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
#define ZTS_FD_ISSET(n,p) ZTS_FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
#define ZTS_FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
#elif LWIP_SOCKET_OFFSET
#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
#elif ZTS_FD_SETSIZE < MEMP_NUM_NETCONN
#error "external ZTS_FD_SETSIZE too small for number of sockets"
#endif // FD_SET
#if !defined(_USING_LWIP_DEFINITIONS_)
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief (optional) Sets the port for the background libzt service. If this function is called
* with a port number between 1-65535 it will attempt to bind to that port. If it is called with
* a port number of 0 it will attempt to randomly search for an available port. If this function
* is never called, the service will try to bind on LIBZT_DEFAULT_PORT which is 9994.
*
* @usage Should be called at the beginning of your application before `zts_startjoin()`
* @param portno Port number
* @return 0 if successful; or -1 if failed
typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
typedef uintptr_t mem_ptr_t;
typedef u32_t zts_in_addr_t;
typedef u16_t zts_in_port_t;
typedef u8_t zts_sa_family_t;
struct zts_in_addr {
zts_in_addr_t s_addr;
};
struct zts_in6_addr {
union {
u32_t u32_addr[4];
u8_t u8_addr[16];
} un;
#define s6_addr un.u8_addr
};
struct zts_sockaddr_in {
u8_t sin_len;
zts_sa_family_t sin_family;
zts_in_port_t sin_port;
struct zts_in_addr sin_addr;
#define SIN_ZERO_LEN 8
char sin_zero[SIN_ZERO_LEN];
};
struct zts_sockaddr_in6 {
u8_t sin6_len; /* length of this structure */
zts_sa_family_t sin6_family; /* AF_INET6 */
zts_in_port_t sin6_port; /* Transport layer port # */
u32_t sin6_flowinfo; /* IPv6 flow information */
struct zts_in6_addr sin6_addr; /* IPv6 address */
u32_t sin6_scope_id; /* Set of interfaces for scope */
};
struct zts_sockaddr {
u8_t sa_len;
zts_sa_family_t sa_family;
char sa_data[14];
};
struct zts_sockaddr_storage {
u8_t s2_len;
zts_sa_family_t ss_family;
char s2_data1[2];
u32_t s2_data2[3];
u32_t s2_data3[3];
};
#if !defined(zts_iovec)
struct zts_iovec {
void *iov_base;
size_t iov_len;
};
#endif
struct zts_msghdr {
void *msg_name;
socklen_t msg_namelen;
struct iovec *msg_iov;
int msg_iovlen;
void *msg_control;
socklen_t msg_controllen;
int msg_flags;
};
/*
* Structure used for manipulating linger option.
*/
ZT_SOCKET_API int ZTCALL zts_set_service_port(int portno);
struct zts_linger {
int l_onoff; /* option on/off */
int l_linger; /* linger time in seconds */
};
/**
* @brief Starts libzt
*
* @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met:
* - ZeroTier core service has been initialized
* - Cryptographic identity has been generated or loaded from directory specified by `path`
* - Virtual network is successfully joined
* - IP address is assigned by network controller service
* @param path path directory where cryptographic identities and network configuration files are stored and retrieved
* (`identity.public`, `identity.secret`)
* @param nwid A 16-digit hexidecimal network identifier (e.g. Earth: `8056c2e21c000001`)
* @return 0 if successful; or 1 if failed
*/
ZT_SOCKET_API int ZTCALL zts_start(const char *path, int blocking);
/*
typedef struct fd_set
{
unsigned char fd_bits [(FD_SETSIZE+7)/8];
} fd_set;
*/
/**
* @brief Starts libzt
*
* @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met:
* - ZeroTier core service has been initialized
* - Cryptographic identity has been generated or loaded from directory specified by `path`
* - Virtual network is successfully joined
* - IP address is assigned by network controller service
* @param path path directory where cryptographic identities and network configuration files are stored and retrieved
* (`identity.public`, `identity.secret`)
* @param nwid A 16-digit hexidecimal network identifier (e.g. Earth: `8056c2e21c000001`)
* @return 0 if successful; or 1 if failed
*/
ZT_SOCKET_API int ZTCALL zts_startjoin(const char *path, const uint64_t nwid);
#ifdef __cplusplus
}
#endif
/**
* @brief Stops ZeroTier core services, stack drivers, stack threads, etc
*
* @usage This should be called at the end of your program or when you do not anticipate communicating over ZeroTier
* @return Returns 0 on success, -1 on failure
*/
ZT_SOCKET_API void ZTCALL zts_stop();
#endif // _USING_LWIP_DEFINITIONS_
/**
* @brief Return whether ZeroTier core service is currently running
*
* @usage Call this after zts_start()
* @return 1 if running, 0 if not running
*/
ZT_SOCKET_API int ZTCALL zts_core_running();
//////////////////////////////////////////////////////////////////////////////
// For SOCK_RAW support, it will initially be modeled after linux's API, so //
// below are the various things we need to define in order to make this API //
// work on other platforms. Maybe later down the road we will customize //
// this for each different platform. Maybe. //
//////////////////////////////////////////////////////////////////////////////
/**
* @brief Return whether the userspace network stack is currently running
*
* @usage Call this after zts_start()
* @return 1 if running, 0 if not running
*/
ZT_SOCKET_API int ZTCALL zts_stack_running();
#if !defined(__linux__)
#define SIOCGIFINDEX 101
#define SIOCGIFHWADDR 102
/**
* @brief Return whether libzt is ready to handle socket API calls. Alternatively you could
* have just called zts_startjoin(path, nwid)
*
* @usage Call this after zts_start()
* @return 1 if running, 0 if not running
*/
ZT_SOCKET_API int ZTCALL zts_ready();
// Normally defined in linux/if_packet.h, defined here so we can offer a linux-like
// raw socket API on non-linux platforms
struct sockaddr_ll {
unsigned short sll_family; /* Always AF_PACKET */
unsigned short sll_protocol; /* Physical layer protocol */
int sll_ifindex; /* Interface number */
unsigned short sll_hatype; /* ARP hardware type */
unsigned char sll_pkttype; /* Packet type */
unsigned char sll_halen; /* Length of address */
unsigned char sll_addr[8]; /* Physical layer address */
};
/**
* @brief Join a network
*
* @usage Call this from application thread. Only after zts_start() has succeeded
* @param nwid A 16-digit hexidecimal virtual network ID
* @return 0 if successful, -1 for any failure
*/
ZT_SOCKET_API int ZTCALL zts_join(const uint64_t nwid);
#endif
/**
* @brief Leave a network
*
* @usage Call this from application thread. Only after zts_start() has succeeded
* @param nwid A 16-digit hexidecimal virtual network ID
* @return 0 if successful, -1 for any failure
*/
ZT_SOCKET_API int ZTCALL zts_leave(const uint64_t nwid);
//////////////////////////////////////////////////////////////////////////////
// Socket API //
//////////////////////////////////////////////////////////////////////////////
/**
* @brief Copies the configuration path used by ZeroTier into the provided buffer
*
* @usage
* @param homePath Path to ZeroTier configuration files
* @param len Length of destination buffer
* @return
*/
ZT_SOCKET_API void ZTCALL zts_get_path(char *homePath, const size_t len);
/**
* @brief Returns the node ID of this instance
*
* @usage Call this after zts_start() and/or when zts_running() returns true
* @return
*/
ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id();
/**
* @brief Returns the node ID of this instance (as read from a file)
*
* @usage Call with or without starting the service with zts_start()
* @param filepath Path to ZeroTier configuration files
* @return
*/
ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id_from_file(const char *filepath);
/**
* @brief Returns whether any address has been assigned to the SockTap for this network
*
* @usage This is used as an indicator of readiness for service for the ZeroTier core and stack
* @param nwid Network ID
* @return
*/
ZT_SOCKET_API int ZTCALL zts_has_address(const uint64_t nwid);
/**
* @brief Returns the number of addresses assigned to this node for the given nwid
*
* @param nwid Network ID
* @return The number of addresses assigned
*/
ZT_SOCKET_API int ZTCALL zts_get_num_assigned_addresses(const uint64_t nwid);
/**
* @brief Returns the assigned address located at the given index
*
* @usage The indices of each assigned address are not guaranteed and should only
* be used for iterative purposes.
* @param nwid Network ID
* @param index location of assigned address
* @return The number of addresses assigned
*/
ZT_SOCKET_API int ZTCALL zts_get_address_at_index(
const uint64_t nwid, const int index, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Get IP address for this device on a given network
*
* @usage FIXME: Only returns first address found, good enough for most cases
* @param nwid Network ID
* @param addr Destination structure for address
* @param addrlen size of destination address buffer, will be changed to size of returned address
* @return 0 if an address was successfully found, -1 if failure
*/
ZT_SOCKET_API int ZTCALL zts_get_address(
const uint64_t nwid, struct sockaddr_storage *addr, const int address_family);
/**
* @brief Computes a 6PLANE IPv6 address for the given Network ID and Node ID
*
* @usage Can call any time
* @param addr Destination structure for address
* @param nwid Network ID
* @param nodeId Node ID
* @return
*/
ZT_SOCKET_API void ZTCALL zts_get_6plane_addr(
struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId);
/**
* @brief Computes a RFC4193 IPv6 address for the given Network ID and Node ID
*
* @usage Can call any time
* @param addr Destination structure for address
* @param nwid Network ID
* @param nodeId Node ID
* @return
*/
ZT_SOCKET_API void ZTCALL zts_get_rfc4193_addr(
struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId);
/**
* @brief Return the number of peers
*
* @usage Call this after zts_start() has succeeded
* @return
*/
ZT_SOCKET_API unsigned long zts_get_peer_count();
/****************************************************************************/
/* Socket-like API */
/****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Create a socket
@@ -286,7 +344,7 @@ ZT_SOCKET_API unsigned long zts_get_peer_count();
* @param protocol Protocols supported on this socket
* @return
*/
ZT_SOCKET_API int ZTCALL zts_socket(int socket_family, int socket_type, int protocol);
ZT_SOCKET_API zts_err_t ZTCALL zts_socket(int socket_family, int socket_type, int protocol);
/**
* @brief Connect a socket to a remote host
@@ -297,7 +355,7 @@ ZT_SOCKET_API int ZTCALL zts_socket(int socket_family, int socket_type, int prot
* @param addrlen Length of address
* @return
*/
ZT_SOCKET_API int ZTCALL zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen);
ZT_SOCKET_API zts_err_t ZTCALL zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen);
/**
* @brief Bind a socket to a virtual interface
@@ -308,7 +366,7 @@ ZT_SOCKET_API int ZTCALL zts_connect(int fd, const struct sockaddr *addr, sockle
* @param addrlen Length of address
* @return
*/
ZT_SOCKET_API int ZTCALL zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
ZT_SOCKET_API zts_err_t ZTCALL zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
/**
* @brief Listen for incoming connections
@@ -318,7 +376,7 @@ ZT_SOCKET_API int ZTCALL zts_bind(int fd, const struct sockaddr *addr, socklen_t
* @param backlog Number of backlogged connection allowed
* @return
*/
ZT_SOCKET_API int ZTCALL zts_listen(int fd, int backlog);
ZT_SOCKET_API zts_err_t ZTCALL zts_listen(int fd, int backlog);
/**
* @brief Accept an incoming connection
@@ -329,7 +387,7 @@ ZT_SOCKET_API int ZTCALL zts_listen(int fd, int backlog);
* @param addrlen Length of address
* @return
*/
ZT_SOCKET_API int ZTCALL zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen);
ZT_SOCKET_API zts_err_t ZTCALL zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Accept an incoming connection
@@ -342,7 +400,7 @@ ZT_SOCKET_API int ZTCALL zts_accept(int fd, struct sockaddr *addr, socklen_t *ad
* @return
*/
#if defined(__linux__)
int zts_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags);
zts_err_t zts_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags);
#endif
/**
@@ -356,7 +414,7 @@ ZT_SOCKET_API int ZTCALL zts_accept(int fd, struct sockaddr *addr, socklen_t *ad
* @param optlen Length of option value
* @return
*/
ZT_SOCKET_API int ZTCALL zts_setsockopt(
ZT_SOCKET_API zts_err_t ZTCALL zts_setsockopt(
int fd, int level, int optname, const void *optval, socklen_t optlen);
/**
@@ -370,7 +428,7 @@ ZT_SOCKET_API int ZTCALL zts_setsockopt(
* @param optlen Length of value
* @return
*/
ZT_SOCKET_API int ZTCALL zts_getsockopt(
ZT_SOCKET_API zts_err_t ZTCALL zts_getsockopt(
int fd, int level, int optname, void *optval, socklen_t *optlen);
/**
@@ -382,7 +440,7 @@ ZT_SOCKET_API int ZTCALL zts_getsockopt(
* @param addrlen Length of name
* @return
*/
ZT_SOCKET_API int ZTCALL zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen);
ZT_SOCKET_API zts_err_t ZTCALL zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Get the peer name for the remote end of a connected socket
@@ -393,7 +451,7 @@ ZT_SOCKET_API int ZTCALL zts_getsockname(int fd, struct sockaddr *addr, socklen_
* @param addrlen Length of name
* @return
*/
ZT_SOCKET_API int ZTCALL zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen);
ZT_SOCKET_API zts_err_t ZTCALL zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen);
/**
* @brief Gets current hostname
@@ -403,7 +461,7 @@ ZT_SOCKET_API int ZTCALL zts_getpeername(int fd, struct sockaddr *addr, socklen_
* @param len
* @return
*/
ZT_SOCKET_API int ZTCALL zts_gethostname(char *name, size_t len);
ZT_SOCKET_API zts_err_t ZTCALL zts_gethostname(char *name, size_t len);
/**
* @brief Sets current hostname
@@ -413,7 +471,7 @@ ZT_SOCKET_API int ZTCALL zts_gethostname(char *name, size_t len);
* @param len
* @return
*/
ZT_SOCKET_API int ZTCALL zts_sethostname(const char *name, size_t len);
ZT_SOCKET_API zts_err_t ZTCALL zts_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
@@ -431,7 +489,7 @@ ZT_SOCKET_API struct hostent *zts_gethostbyname(const char *name);
* @param fd File descriptor (only valid for use with libzt calls)
* @return
*/
ZT_SOCKET_API int ZTCALL zts_close(int fd);
ZT_SOCKET_API zts_err_t ZTCALL zts_close(int fd);
/**
* @brief Waits for one of a set of file descriptors to become ready to perform I/O.
@@ -460,7 +518,7 @@ int zts_poll(struct pollfd *fds, nfds_t nfds, int timeout);
* @param timeout
* @return
*/
ZT_SOCKET_API int ZTCALL zts_select(
ZT_SOCKET_API zts_err_t ZTCALL zts_select(
int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
/**
@@ -476,7 +534,7 @@ ZT_SOCKET_API int ZTCALL zts_select(
#define F_SETFL 0
#define O_NONBLOCK 0
#endif
ZT_SOCKET_API int ZTCALL zts_fcntl(int fd, int cmd, int flags);
ZT_SOCKET_API zts_err_t ZTCALL zts_fcntl(int fd, int cmd, int flags);
/**
* @brief Control a device
@@ -487,7 +545,7 @@ ZT_SOCKET_API int ZTCALL zts_fcntl(int fd, int cmd, int flags);
* @param argp
* @return
*/
ZT_SOCKET_API int ZTCALL zts_ioctl(int fd, unsigned long request, void *argp);
ZT_SOCKET_API zts_err_t ZTCALL zts_ioctl(int fd, unsigned long request, void *argp);
/**
* @brief Send data to remote host
@@ -574,7 +632,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_recvmsg(int fd, struct msghdr *msg,int flags);
* @param len Length of data buffer to receive data
* @return
*/
ZT_SOCKET_API int ZTCALL zts_read(int fd, void *buf, size_t len);
ZT_SOCKET_API zts_err_t ZTCALL zts_read(int fd, void *buf, size_t len);
/**
* @brief Write bytes from buffer to socket
@@ -585,7 +643,7 @@ ZT_SOCKET_API int ZTCALL zts_read(int fd, void *buf, size_t len);
* @param len Length of buffer to write
* @return
*/
ZT_SOCKET_API int ZTCALL zts_write(int fd, const void *buf, size_t len);
ZT_SOCKET_API zts_err_t ZTCALL zts_write(int fd, const void *buf, size_t len);
/**
* @brief Shut down some aspect of a socket (read, write, or both)
@@ -595,7 +653,7 @@ ZT_SOCKET_API int ZTCALL zts_write(int fd, const void *buf, size_t len);
* @param how Which aspects of the socket should be shut down
* @return
*/
ZT_SOCKET_API int ZTCALL zts_shutdown(int fd, int how);
ZT_SOCKET_API zts_err_t ZTCALL zts_shutdown(int fd, int how);
/**
* @brief Adds a DNS nameserver for the network stack to use
@@ -604,7 +662,7 @@ ZT_SOCKET_API int ZTCALL zts_shutdown(int fd, int how);
* @param addr Address for DNS nameserver
* @return
*/
ZT_SOCKET_API int ZTCALL zts_add_dns_nameserver(struct sockaddr *addr);
ZT_SOCKET_API zts_err_t ZTCALL zts_add_dns_nameserver(struct sockaddr *addr);
/**
* @brief Removes a DNS nameserver
@@ -613,7 +671,7 @@ ZT_SOCKET_API int ZTCALL zts_add_dns_nameserver(struct sockaddr *addr);
* @param addr Address for DNS nameserver
* @return
*/
ZT_SOCKET_API int ZTCALL zts_del_dns_nameserver(struct sockaddr *addr);
ZT_SOCKET_API zts_err_t ZTCALL zts_del_dns_nameserver(struct sockaddr *addr);
#ifdef __cplusplus
} // extern "C"

View File

@@ -1,307 +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
*
* Application-facing, partially-POSIX-compliant socket API
*/
#ifndef LIBZT_DEFINES_H
#define LIBZT_DEFINES_H
#define LIBZT_IPV4 1
#define LIBZT_IPV6 1
/**
* Default port that libzt will use to support all virtual communication
*/
#define LIBZT_DEFAULT_PORT 9994
#define NO_STACK 0 // for layer-2 only (this will omit all userspace network stack code)
/**
* Maximum MTU size for ZeroTier
*/
#define ZT_MAX_MTU 10000
/**
* How fast service states are re-checked (in milliseconds)
*/
#define ZTO_WRAPPER_CHECK_INTERVAL 100
/**
* Length of buffer required to hold a ztAddress/nodeID
*/
#define ZTO_ID_LEN 16
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
/****************************************************************************/
/* For SOCK_RAW support, it will initially be modeled after linux's API, so */
/* below are the various things we need to define in order to make this API */
/* work on other platforms. Mayber later down the road we will customize */
/* this for each different platform. Maybe. */
/****************************************************************************/
#if !defined(__linux__)
#define SIOCGIFINDEX 101
#define SIOCGIFHWADDR 102
// Normally defined in linux/if_packet.h, defined here so we can offer a linux-like
// raw socket API on non-linux platforms
struct sockaddr_ll {
unsigned short sll_family; /* Always AF_PACKET */
unsigned short sll_protocol; /* Physical layer protocol */
int sll_ifindex; /* Interface number */
unsigned short sll_hatype; /* ARP hardware type */
unsigned char sll_pkttype; /* Packet type */
unsigned char sll_halen; /* Length of address */
unsigned char sll_addr[8]; /* Physical layer address */
};
#endif
/****************************************************************************/
/* lwIP */
/****************************************************************************/
// For LWIP configuration see: include/lwipopts.h
/* The following three quantities are related and govern how incoming frames are fed into the
network stack's core:
Every LWIP_GUARDED_BUF_CHECK_INTERVAL milliseconds, a callback will be called from the core and
will input a maximum of LWIP_FRAMES_HANDLED_PER_CORE_CALL frames before returning control back
to the core. Meanwhile, incoming frames from the ZeroTier wire will be allocated and their
pointers will be cached in the receive frame buffer of the size LWIP_MAX_GUARDED_RX_BUF_SZ to
await the next callback from the core */
#define LWIP_GUARDED_BUF_CHECK_INTERVAL 50 // in ms
#define LWIP_MAX_GUARDED_RX_BUF_SZ 1024 // number of frame pointers that can be cached waiting for receipt into core
#define LWIP_FRAMES_HANDLED_PER_CORE_CALL 16 // How many frames are handled per call from core
typedef signed char err_t;
#define ND6_DISCOVERY_INTERVAL 1000
#define ARP_DISCOVERY_INTERVAL ARP_TMR_INTERVAL
/**
* Specifies the polling interval and the callback function that should
* be called to poll the application. The interval is specified in
* number of TCP coarse grained timer shots, which typically occurs
* twice a second. An interval of 10 means that the application would
* be polled every 5 seconds. (only for raw lwIP driver)
*/
#define LWIP_APPLICATION_POLL_FREQ 2
/**
* TCP timer interval in milliseconds (only for raw lwIP driver)
*/
#define LWIP_TCP_TIMER_INTERVAL 25
/**
* How often we check VirtualSocket statuses in milliseconds (only for raw lwIP driver)
*/
#define LWIP_STATUS_TMR_INTERVAL 500
// #define LWIP_CHKSUM <your_checksum_routine>, See: RFC1071 for inspiration
/****************************************************************************/
/* Defines */
/****************************************************************************/
/**
* Maximum number of sockets that libzt can administer
*/
#define ZT_MAX_SOCKETS 1024
/**
* Maximum MTU size for libzt (must be less than or equal to ZT_MAX_MTU)
*/
#define ZT_SDK_MTU ZT_MAX_MTU
/**
*
*/
#define ZT_LEN_SZ 4
/**
*
*/
#define ZT_ADDR_SZ 128
/**
* Size of message buffer for VirtualSockets
*/
#define ZT_SOCKET_MSG_BUF_SZ ZT_SDK_MTU + ZT_LEN_SZ + ZT_ADDR_SZ
/**
* Polling interval (in ms) for file descriptors wrapped in the Phy I/O loop (for raw drivers only)
*/
#define ZT_PHY_POLL_INTERVAL 5
/**
* State check interval (in ms) for VirtualSocket state
*/
#define ZT_ACCEPT_RECHECK_DELAY 50
/**
* State check interval (in ms) for VirtualSocket state
*/
#define ZT_CONNECT_RECHECK_DELAY 50
/**
* State check interval (in ms) for VirtualSocket state
*/
#define ZT_API_CHECK_INTERVAL 50
/**
* Size of TCP TX buffer for VirtualSockets used in raw network stack drivers
*/
#define ZT_TCP_TX_BUF_SZ 1024 * 1024 * 128
/**
* Size of TCP RX buffer for VirtualSockets used in raw network stack drivers
*/
#define ZT_TCP_RX_BUF_SZ 1024 * 1024 * 128
/**
* Size of UDP TX buffer for VirtualSockets used in raw network stack drivers
*/
#define ZT_UDP_TX_BUF_SZ ZT_MAX_MTU
/**
* Size of UDP RX buffer for VirtualSockets used in raw network stack drivers
*/
#define ZT_UDP_RX_BUF_SZ ZT_MAX_MTU * 10
/**
* Send buffer size for the network stack
* By default picoTCP sets them to 16834, this is good for embedded-scale
* stuff but you might want to consider higher values for desktop and mobile
* applications.
*/
#define ZT_STACK_TCP_SOCKET_TX_SZ ZT_TCP_TX_BUF_SZ
/**
* Receive buffer size for the network stack
* By default picoTCP sets them to 16834, this is good for embedded-scale
* stuff but you might want to consider higher values for desktop and mobile
* applications.
*/
#define ZT_STACK_TCP_SOCKET_RX_SZ ZT_TCP_RX_BUF_SZ
/**
* Maximum size we're allowed to read or write from a stack socket
* This is put in place because picoTCP seems to fail at higher values.
* If you use another stack you can probably bump this up a bit.
*/
#define ZT_STACK_SOCKET_WR_MAX 4096
/**
* Maximum size of read operation from a network stack
*/
#define ZT_STACK_SOCKET_RD_MAX 4096*4
/**
* Maximum length of libzt/ZeroTier home path (where keys, and config files are stored)
*/
#define ZT_HOME_PATH_MAX_LEN 256
/**
* Length of human-readable MAC address string
*/
#define ZT_MAC_ADDRSTRLEN 18
/**
* Everything is ok
*/
#define ZT_ERR_OK 0
/**
* Value returned during an internal failure at the VirtualSocket/VirtualTap layer
*/
#define ZT_ERR_GENERAL_FAILURE -88
/**
* Whether sockets created will have SO_LINGER set by default
*/
#define ZT_SOCK_BEHAVIOR_LINGER false
/**
* Length of time that VirtualSockets should linger (in seconds)
*/
#define ZT_SOCK_BEHAVIOR_LINGER_TIME 3
/**
* Maximum wait time for socket closure if data is still present in the write queue
*/
#define ZT_SDK_CLTIME 60
/**
* Interval for performing background tasks (such as adding routes) on VirtualTap objects (in seconds)
*/
#define ZT_HOUSEKEEPING_INTERVAL 1
/****************************************************************************/
/* Socket API Signatures */
/****************************************************************************/
#define ZT_SETSOCKOPT_SIG int fd, int level, int optname, const void *optval, socklen_t optlen
#define ZT_GETSOCKOPT_SIG int fd, int level, int optname, void *optval, socklen_t *optlen
#define ZT_SENDMSG_SIG int fd, const struct msghdr *msg, int flags
#define ZT_SENDTO_SIG int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen
#define ZT_RECV_SIG int fd, void *buf, size_t len, int flags
#define ZT_RECVFROM_SIG int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen
#define ZT_RECVMSG_SIG int fd, struct msghdr *msg,int flags
#define ZT_SEND_SIG int fd, const void *buf, size_t len, int flags
#define ZT_READ_SIG int fd, void *buf, size_t len
#define ZT_WRITE_SIG int fd, const void *buf, size_t len
#define ZT_SHUTDOWN_SIG int fd, int how
#define ZT_SOCKET_SIG int socket_family, int socket_type, int protocol
#define ZT_CONNECT_SIG int fd, const struct sockaddr *addr, socklen_t addrlen
#define ZT_BIND_SIG int fd, const struct sockaddr *addr, socklen_t addrlen
#define ZT_LISTEN_SIG int fd, int backlog
#define ZT_ACCEPT4_SIG int fd, struct sockaddr *addr, socklen_t *addrlen, int flags
#define ZT_ACCEPT_SIG int fd, struct sockaddr *addr, socklen_t *addrlen
#define ZT_CLOSE_SIG int fd
#define ZT_POLL_SIG struct pollfd *fds, nfds_t nfds, int timeout
#define ZT_SELECT_SIG int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout
#define ZT_GETSOCKNAME_SIG int fd, struct sockaddr *addr, socklen_t *addrlen
#define ZT_GETPEERNAME_SIG int fd, struct sockaddr *addr, socklen_t *addrlen
#define ZT_GETHOSTNAME_SIG char *name, size_t len
#define ZT_SETHOSTNAME_SIG const char *name, size_t len
#define ZT_FCNTL_SIG int fd, int cmd, int flags
#define ZT_IOCTL_SIG int fd, unsigned long request, void *argp
#define ZT_SYSCALL_SIG long number, ...
#define LIBZT_SERVICE_NOT_STARTED_STR "service not started yet, call zts_startjoin()"
#endif // _H

View File

@@ -1,6 +1,6 @@
/*
* ZeroTier SDK - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
* Copyright (C) 2011-2019 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
@@ -13,7 +13,7 @@
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
@@ -33,15 +33,30 @@
#ifndef ZT_LWIP_HPP
#define ZT_LWIP_HPP
#include "libztDefs.h"
#include "Debug.hpp"
#include "lwip/err.h"
namespace ZeroTier {
class MAC;
class Mutex;
class VirtualTap;
struct InetAddress;
}
/**
* @brief Increase the delay multiplier for the main driver loop
*
* @usage This should be called when we know the stack won't be used by any virtual taps
*/
void lwip_hibernate_driver();
/**
* @brief Decrease the delay multiplier for the main driver loop
*
* @usage This should be called when at least one virtual tap is active
*/
void lwip_wake_driver();
/**
* @brief Initialize network stack semaphores, threads, and timers.
*
@@ -50,6 +65,27 @@ namespace ZeroTier {
*/
void lwip_driver_init();
/**
* @brief Shutdown the stack as completely as possible (not officially supported by lwIP)
*
* @usage This is to be called after it is determined that no further network activity will take place.
* The tcpip thread will be stopped, all interfaces will be brought down and all resources will
* be deallocated. A full application restart will be required to bring the stack back online.
* @return
*/
void lwip_driver_shutdown();
/**
* @brief Bring all interfaces down belonging to the given virtual tap interface
*
* @usage This is to be called when the application desires to stop all traffic processing in the
* stack. Unlike lwip_driver_shutdown(), the application can easily resume traffic processing
* by re-adding a virtual tap (and associated lwip netifs)
* @return
*/
void lwip_driver_set_tap_interfaces_down(void *tapref);
void lwip_driver_set_all_interfaces_down();
/**
* @brief Initialize and start the DNS client
*
@@ -99,7 +135,7 @@ err_t lwip_eth_tx(struct netif *netif, struct pbuf *p);
* @param len Length of Ethernet frame
* @return
*/
void lwip_eth_rx(VirtualTap *tap, const ZeroTier::MAC &from, const ZeroTier::MAC &to, unsigned int etherType,
void lwip_eth_rx(ZeroTier::VirtualTap *tap, const ZeroTier::MAC &from, const ZeroTier::MAC &to, unsigned int etherType,
const void *data, unsigned int len);
#endif // _H

View File

@@ -39,13 +39,56 @@
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
/*
* Provides short-named socket macros. Keep disabled
*/
#define LWIP_COMPAT_SOCKETS 0
/**
* Respond to broadcast pings (default is unicast only)
*/
#define LWIP_BROADCAST_PING 0
/**
* Respond to multicast pings (default is unicast only)
*/
#define LWIP_MULTICAST_PING 0
/**
* Enables the ability to forward IP packets across network
* interfaces. If you are going to run lwIP on a device with only one network
* interface, define this to 0.
*/
#define IP_FORWARD 0
/**
* Number of active MAC-IP address pairs cached.
*/
#define ARP_TABLE_SIZE 10
/**
* LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of
* pending data in the network buffer. This is the way windows does it. It's
* the default for lwIP since it is smaller.
* LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next
* pending datagram in bytes. This is the way linux does it. This code is only
* here for compatibility.
*/
#define LWIP_FIONREAD_LINUXMODE 1
/**
* Enable SO_RCVBUF processing.
*/
#define LWIP_SO_RCVBUF 1
/**
* Enable SO_LINGER processing.
*/
#define LWIP_SO_LINGER 0
/*
* Provides its own errno
*/
#if __ANDROID__
#define LWIP_PROVIDE_ERRNO 0
#define SOCKLEN_T_DEFINED
//#define SOCKLEN_T_DEFINED
#elif !defined(_MSC_VER)
#define LWIP_PROVIDE_ERRNO 1
#endif
@@ -53,25 +96,22 @@
/*
* Provides core locking machinery
*/
#define LWIP_TCPIP_CORE_LOCKING 0
#define LWIP_TCPIP_CORE_LOCKING 1
/*
* Provides a macro to spoof the names of the lwip socket functions
*/
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
#define LWIP_NOASSERT 1
/*
*
*/
#define LWIP_NOASSERT 0
/*
*
*/
#define LWIP_TIMERS 1
/*
*
*/
//#define LWIP_COMPAT_MUTEX 1
//#define LWIP_COMPAT_MUTEX_ALLOWED 1
/*
* Provides network/host byte transformation macros
*/
@@ -80,11 +120,6 @@
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
#endif
/*
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
#include "lwip/debug.h"
#define LWIP_IPV6_AUTOCONFIG 1
@@ -134,7 +169,7 @@
// API
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_ON
// other
#define ICMP_DEBUG LWIP_DBG_OFF
#define IGMP_DEBUG LWIP_DBG_OFF
@@ -177,9 +212,12 @@
#define LWIP_CHKSUM_ALGORITHM 2
#undef TCP_MSS
#define TCP_MSS 1460
#define MTU 1500
#define TCP_MSS MTU - 40
#define LWIP_NETIF_API 1
#define LWIP_DEBUG_TIMERNAMES 1
/*
The TCP window size can be adjusted by changing the define TCP_WND. However,
do keep in mind that this should be at least twice the size of TCP_MSS (thus
@@ -194,7 +232,6 @@ remote peer.
#define TCP_WND 0xffff // max = 0xffff, min = TCP_MSS*2
#define LWIP_NOASSERT 1
#define TCP_LISTEN_BACKLOG 0
/*------------------------------------------------------------------------------
@@ -252,12 +289,12 @@ happening sooner than they should.
-------------------------------- Memory options --------------------------------
------------------------------------------------------------------------------*/
//#define MEM_USE_POOLS 1
//#define MEM_USE_POOLS 0
//#define MEMP_USE_CUSTOM_POOLS 1
/* Misc */
#define MEM_LIBC_MALLOC 1
#define MEMP_MEM_MALLOC 1
#define MEM_LIBC_MALLOC 0
#define MEMP_MEM_MALLOC 1 /* if set to 1, all dynamically allocated memory will come from MEM_SIZE */
/**
* MEM_ALIGNMENT: should be set to the alignment of the CPU
@@ -270,7 +307,7 @@ happening sooner than they should.
* MEM_SIZE: the size of the heap memory. If the application will send
* a lot of data that needs to be copied, this should be set high.
*/
#define MEM_SIZE 1024 * 1024 * 64
#define MEM_SIZE 1024 * 1024
#define TCP_SND_BUF 1024 * 63
//#define TCP_OVERSIZE TCP_MSS
@@ -368,7 +405,7 @@ happening sooner than they should.
* MEMP_NUM_NETCONN: the number of struct netconns.
* (only needed if you use the sequential API, like api_lib.c)
*/
#define MEMP_NUM_NETCONN 32
#define MEMP_NUM_NETCONN 256
/**
* MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
@@ -387,7 +424,7 @@ happening sooner than they should.
/**
* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
*/
#define PBUF_POOL_SIZE 4092 /* was 32 */
#define PBUF_POOL_SIZE 128 /* was 32 */
/*------------------------------------------------------------------------------
@@ -595,6 +632,7 @@ happening sooner than they should.
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
*/
#define LWIP_STATS 1
//#define LWIP_STATS_DISPLAY 1
/*------------------------------------------------------------------------------
--------------------------------- PPP Options ----------------------------------
@@ -605,4 +643,11 @@ happening sooner than they should.
*/
#define PPP_SUPPORT 0
/*
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
#include "lwip/debug.h"
#endif /* __LWIPOPTS_H__ */