Change event code numbering scheme, fix Windows startup bug, fix zts_free(), remove vestigial API functions, update documentation

This commit is contained in:
Joseph Henry
2020-05-30 18:29:04 -07:00
parent 2ae7ebb0fe
commit 37c01e18cf
12 changed files with 725 additions and 946 deletions

View File

@@ -20,6 +20,7 @@
#include <inttypes.h>
#include <sys/types.h>
#include "Constants.hpp"
#include "Node.hpp"
#include "Mutex.hpp"
#include "OSUtils.hpp"
@@ -36,7 +37,10 @@ using namespace ZeroTier;
#include <jni.h>
#endif
#ifdef __WINDOWS__
#include <Windows.h>
WSADATA wsaData;
#endif
namespace ZeroTier
{
@@ -55,6 +59,10 @@ namespace ZeroTier
#endif
}
#ifdef __cplusplus
extern "C" {
#endif
int zts_allow_network_caching(uint8_t allowed = 1)
{
Mutex::Lock _l(serviceLock);
@@ -121,15 +129,14 @@ int zts_start(const char *path, void (*callback)(void *), uint16_t port)
if (params->path.length() == 0) {
return ZTS_ERR_ARG;
}
int err;
int retval = ZTS_ERR_OK;
_setState(ZTS_STATE_CALLBACKS_RUNNING);
_setState(ZTS_STATE_NODE_RUNNING);
// Start the ZT service thread
#if defined(__WINDOWS__)
WSAStartup(MAKEWORD(2, 2), &wsaData);
HANDLE serviceThread = CreateThread(NULL, 0, _runNodeService, (void*)params, 0, NULL);
HANDLE callbackThread = CreateThread(NULL, 0, _runCallbacks, NULL, 0, NULL);
#else
@@ -155,11 +162,6 @@ int zts_start(const char *path, void (*callback)(void *), uint16_t port)
return retval;
}
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SDK_JNI
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_start(
JNIEnv *env, jobject thisObj, jstring path, jobject callback, jint port)
@@ -205,7 +207,7 @@ int zts_stop()
return ZTS_ERR_SERVICE;
}
#ifdef SDK_JNI
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop(
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop(
JNIEnv *env, jobject thisObj)
{
zts_stop();
@@ -255,7 +257,7 @@ int zts_restart()
#endif
}
#ifdef SDK_JNI
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_restart(
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_restart(
JNIEnv *env, jobject thisObj)
{
zts_restart();
@@ -264,102 +266,29 @@ int zts_restart()
int zts_free()
{
Mutex::Lock _l(serviceLock);
if (_getState(ZTS_STATE_FREE_CALLED)) {
return ZTS_ERR_SERVICE;
}
_setState(ZTS_STATE_FREE_CALLED);
return zts_stop();
// TODO: add stack shutdown logic
int err = zts_stop();
Mutex::Lock _l(serviceLock);
_lwip_driver_shutdown();
return err;
}
#ifdef SDK_JNI
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free(
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free(
JNIEnv *env, jobject thisObj)
{
zts_free();
}
#endif
uint64_t zts_get_node_id()
{
Mutex::Lock _l(serviceLock);
if (!_canPerformServiceOperation()) {
return ZTS_ERR_OK; // Not really
}
return service->getNode()->address();
}
#ifdef SDK_JNI
JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1id(
JNIEnv *env, jobject thisObj)
{
return zts_get_node_id();
}
#endif
int zts_get_node_status()
{
Mutex::Lock _l(serviceLock);
// Don't check _canPerformServiceOperation() here.
return service
&& service->getNode()
&& service->getNode()->online() ? ZTS_EVENT_NODE_ONLINE : ZTS_EVENT_NODE_OFFLINE;
}
#ifdef SDK_JNI
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1status(
JNIEnv *env, jobject thisObj)
{
return zts_get_node_status();
}
#endif
int zts_get_network_status(uint64_t networkId)
{
Mutex::Lock _l(serviceLock);
if (!networkId) {
return ZTS_ERR_ARG;
}
if (!_canPerformServiceOperation()) {
return ZTS_ERR_SERVICE;
}
/*
TODO:
ZTS_EVENT_NETWORK_READY_IP4
ZTS_EVENT_NETWORK_READY_IP6
ZTS_EVENT_NETWORK_READY_IP4_IP6
*/
return ZTS_ERR_NO_RESULT;
}
#ifdef SDK_JNI
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1network_1status(
JNIEnv *env, jobject thisObj, jlong networkId)
{
return zts_get_network_status(networkId);
}
#endif
int zts_get_peer_status(uint64_t peerId)
{
Mutex::Lock _l(serviceLock);
int retval = ZTS_ERR_OK;
if (!_canPerformServiceOperation()) {
return ZTS_ERR_SERVICE;
}
return service->getPeerStatus(peerId);
}
#ifdef SDK_JNI
JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1status(
JNIEnv *env, jobject thisObj, jlong peerId)
{
return zts_get_peer_status(peerId);
}
#endif
#ifdef SDK_JNI
/*
* Called from Java, saves a static reference to the VM so it can be used
* later to call a user-specified callback method from C.
*/
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_init(
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_init(
JNIEnv *env, jobject thisObj)
{
jint rs = env->GetJavaVM(&jvm);
@@ -367,63 +296,44 @@ int zts_get_peer_status(uint64_t peerId)
}
#endif
int zts_join(const uint64_t nwid)
int zts_join(const uint64_t networkId)
{
Mutex::Lock _l(serviceLock);
if (!_canPerformServiceOperation()) {
return ZTS_ERR_SERVICE;
}
else {
service->join(nwid);
service->join(networkId);
}
return ZTS_ERR_OK;
}
#ifdef SDK_JNI
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join(
JNIEnv *env, jobject thisObj, jlong nwid)
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join(
JNIEnv *env, jobject thisObj, jlong networkId)
{
return zts_join((uint64_t)nwid);
return zts_join((uint64_t)networkId);
}
#endif
#ifdef __cplusplus
}
#endif
int zts_leave(const uint64_t nwid)
int zts_leave(const uint64_t networkId)
{
Mutex::Lock _l(serviceLock);
if (!_canPerformServiceOperation()) {
return ZTS_ERR_SERVICE;
}
else {
service->leave(nwid);
service->leave(networkId);
}
return ZTS_ERR_OK;
}
#ifdef SDK_JNI
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave(
JNIEnv *env, jobject thisObj, jlong nwid)
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave(
JNIEnv *env, jobject thisObj, jlong networkId)
{
return zts_leave((uint64_t)nwid);
return zts_leave((uint64_t)networkId);
}
#endif
int zts_leave_all()
{
Mutex::Lock _l(serviceLock);
if (!_canPerformServiceOperation()) {
return ZTS_ERR_SERVICE;
}
else {
service->leaveAll();
}
return ZTS_ERR_OK;
}
#ifdef SDK_JNI
#endif
int zts_orbit(uint64_t moonWorldId, uint64_t moonSeed)
{
Mutex::Lock _l(serviceLock);
@@ -452,197 +362,57 @@ int zts_deorbit(uint64_t moonWorldId)
#ifdef SDK_JNI
#endif
int zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId)
int zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId)
{
if (!addr || !nwid || !nodeId) {
if (!addr || !networkId || !nodeId) {
return ZTS_ERR_ARG;
}
InetAddress _6planeAddr = InetAddress::makeIpv66plane(nwid,nodeId);
InetAddress _6planeAddr = InetAddress::makeIpv66plane(networkId,nodeId);
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
memcpy(in6->sin6_addr.s6_addr, _6planeAddr.rawIpData(), sizeof(struct in6_addr));
return ZTS_ERR_OK;
}
int zts_get_rfc4193_addr(struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId)
int zts_get_rfc4193_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId)
{
if (!addr || !nwid || !nodeId) {
if (!addr || !networkId || !nodeId) {
return ZTS_ERR_ARG;
}
InetAddress _rfc4193Addr = InetAddress::makeIpv6rfc4193(nwid,nodeId);
InetAddress _rfc4193Addr = InetAddress::makeIpv6rfc4193(networkId,nodeId);
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
memcpy(in6->sin6_addr.s6_addr, _rfc4193Addr.rawIpData(), sizeof(struct in6_addr));
return ZTS_ERR_OK;
}
uint64_t zts_generate_adhoc_nwid_from_range(uint16_t startPortOfRange, uint16_t endPortOfRange)
{
char nwidStr[INET6_ADDRSTRLEN];
sprintf(nwidStr, "ff%04x%04x000000", startPortOfRange, endPortOfRange);
return strtoull(nwidStr, NULL, 16);
char networkIdStr[INET6_ADDRSTRLEN];
sprintf(networkIdStr, "ff%04x%04x000000", startPortOfRange, endPortOfRange);
return strtoull(networkIdStr, NULL, 16);
}
int zts_get_peers(struct zts_peer_details *pds, uint32_t *num)
{
Mutex::Lock _l(serviceLock);
if (!pds || !num) {
return ZTS_ERR_ARG;
}
if (!_canPerformServiceOperation()) {
return ZTS_ERR_SERVICE;
}
ZT_PeerList *pl = service->getNode()->peers();
if (pl) {
if (*num < pl->peerCount) {
service->getNode()->freeQueryResult((void *)pl);
return ZTS_ERR_ARG;
}
*num = pl->peerCount;
for(unsigned long i=0;i<pl->peerCount;++i) {
memcpy(&(pds[i]), &(pl->peers[i]), sizeof(struct zts_peer_details));
for (unsigned int j=0; j<pl->peers[i].pathCount; j++) {
memcpy(&(pds[i].paths[j].address),
&(pl->peers[i].paths[j].address), sizeof(struct sockaddr_storage));
}
}
}
service->getNode()->freeQueryResult((void *)pl);
return ZTS_ERR_OK;
}
#ifdef SDK_JNI
#endif
int zts_get_peer(struct zts_peer_details *pd, uint64_t peerId)
{
Mutex::Lock _l(serviceLock);
if (!pd || !peerId) {
return ZTS_ERR_ARG;
}
if (!_canPerformServiceOperation()) {
return ZTS_ERR_SERVICE;
}
ZT_PeerList *pl = service->getNode()->peers();
int retval = ZTS_ERR_NO_RESULT;
if (pl) {
for(unsigned long i=0;i<pl->peerCount;++i) {
if (pl->peers[i].address == peerId) {
memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details));
for (unsigned int j=0; j<pl->peers[i].pathCount; j++) {
memcpy(&(pd->paths[j].address),
&(pl->peers[i].paths[j].address), sizeof(struct sockaddr_storage));
}
retval = ZTS_ERR_OK;
break;
}
}
}
service->getNode()->freeQueryResult((void *)pl);
return retval;
}
#ifdef SDK_JNI
#endif
void _get_network_details_helper(uint64_t nwid, struct zts_network_details *nd)
{
/*
socklen_t addrlen;
VirtualTap *tap = vtapMap[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;;
service->getRoutes(nwid, (ZT_VirtualNetworkRoute*)&(nd->routes)[0], &(nd->num_routes));
*/
}
void _get_network_details(uint64_t nwid, struct zts_network_details *nd)
{
/*
_vtaps_lock.lock();
_get_network_details_helper(nwid, nd);
_vtaps_lock.unlock();
*/
}
void _get_all_network_details(struct zts_network_details *nds, int *num)
{
/*
_vtaps_lock.lock();
*num = vtapMap.size();
int idx = 0;
std::map<uint64_t, VirtualTap*>::iterator it;
for (it = vtapMap.begin(); it != vtapMap.end(); it++) {
_get_network_details(it->first, &nds[idx]);
idx++;
}
_vtaps_lock.unlock();
*/
}
int zts_get_network_details(uint64_t nwid, struct zts_network_details *nd)
{
/*
serviceLock.lock();
int retval = ZTS_ERR_OK;
if (!nd || nwid == 0) {
retval = ZTS_ERR_ARG;
}
if (!service || _freeHasBeenCalled || _serviceIsShuttingDown) {
retval = ZTS_ERR_SERVICE;
}
if (retval == ZTS_ERR_OK) {
_get_network_details(nwid, nd);
}
serviceLock.unlock();
return retval;
*/
return 0;
}
#ifdef SDK_JNI
#endif
int zts_get_all_network_details(struct zts_network_details *nds, int *num)
{
/*
serviceLock.lock();
int retval = ZTS_ERR_OK;
if (!nds || !num) {
retval = ZTS_ERR_ARG;
}
if (!service || _freeHasBeenCalled || _serviceIsShuttingDown) {
retval = ZTS_ERR_SERVICE;
}
if (retval == ZTS_ERR_OK) {
_get_all_network_details(nds, num);
}
serviceLock.unlock();
return retval;
*/
return 0;
}
#ifdef SDK_JNI
#endif
void zts_delay_ms(long interval_ms)
{
#if defined(__WINDOWS__)
Sleep(interval_ms);
#ifdef __WINDOWS__
#include <windows.h>
#elif _POSIX_C_SOURCE >= 199309L
#include <time.h> // for nanosleep
#else
struct timespec sleepValue = {0};
sleepValue.tv_nsec = interval_ms * 500000;
nanosleep(&sleepValue, NULL);
#include <unistd.h> // for usleep
#endif
void zts_delay_ms(long milliseconds)
{
#ifdef __WINDOWS__
Sleep(milliseconds);
#elif _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
#else
usleep(milliseconds * 1000);
#endif
}
#ifdef __cplusplus
}
#endif