2019-02-06 22:00:39 -08:00
|
|
|
/*
|
2021-01-30 13:53:49 -08:00
|
|
|
* Copyright (c)2013-2021 ZeroTier, Inc.
|
2019-02-06 22:00:39 -08:00
|
|
|
*
|
2020-04-13 23:38:06 -07:00
|
|
|
* Use of this software is governed by the Business Source License included
|
|
|
|
|
* in the LICENSE.TXT file in the project's root directory.
|
2019-02-06 22:00:39 -08:00
|
|
|
*
|
2021-01-30 13:53:49 -08:00
|
|
|
* Change Date: 2025-01-01
|
2019-02-06 22:00:39 -08:00
|
|
|
*
|
2020-04-13 23:38:06 -07:00
|
|
|
* On the date above, in accordance with the Business Source License, use
|
|
|
|
|
* of this software will be governed by version 2.0 of the Apache License.
|
2019-02-06 22:00:39 -08:00
|
|
|
*/
|
2020-04-13 23:38:06 -07:00
|
|
|
/****/
|
2019-02-06 22:00:39 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
*
|
2021-01-30 13:53:49 -08:00
|
|
|
* Node / Network control interface
|
2019-02-06 22:00:39 -08:00
|
|
|
*/
|
|
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
#include <inttypes.h>
|
|
|
|
|
#include <sys/types.h>
|
2019-02-06 22:00:39 -08:00
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
#include "Constants.hpp"
|
2019-02-06 22:00:39 -08:00
|
|
|
#include "Node.hpp"
|
2020-05-01 19:15:38 -07:00
|
|
|
#include "Mutex.hpp"
|
2019-02-06 22:00:39 -08:00
|
|
|
#include "OSUtils.hpp"
|
2019-03-04 18:04:37 -08:00
|
|
|
|
2021-02-24 01:25:15 -08:00
|
|
|
#include "ZeroTierSockets.h"
|
2019-02-06 22:00:39 -08:00
|
|
|
#include "Debug.hpp"
|
2020-05-01 19:15:38 -07:00
|
|
|
#include "NodeService.hpp"
|
|
|
|
|
#include "VirtualTap.hpp"
|
|
|
|
|
#include "Events.hpp"
|
2021-02-24 01:25:15 -08:00
|
|
|
#include "Signals.hpp"
|
2020-04-13 23:38:06 -07:00
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
using namespace ZeroTier;
|
2019-02-14 17:27:16 -08:00
|
|
|
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-01 19:15:38 -07:00
|
|
|
#include <jni.h>
|
2019-02-06 22:00:39 -08:00
|
|
|
#endif
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
#ifdef __WINDOWS__
|
|
|
|
|
#include <Windows.h>
|
|
|
|
|
WSADATA wsaData;
|
|
|
|
|
#endif
|
2020-05-29 19:24:22 +01:00
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
namespace ZeroTier
|
2019-02-06 22:00:39 -08:00
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
extern NodeService *service;
|
|
|
|
|
extern Mutex serviceLock;
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_PYTHON
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef ZTS_ENABLE_PINVOKE
|
|
|
|
|
extern void (*_userEventCallback)(void *);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef ZTS_C_API_ONLY
|
|
|
|
|
extern void (*_userEventCallback)(void *);
|
|
|
|
|
#endif
|
2020-05-01 19:15:38 -07:00
|
|
|
extern uint8_t allowNetworkCaching;
|
|
|
|
|
extern uint8_t allowPeerCaching;
|
|
|
|
|
extern uint8_t allowLocalConf;
|
2021-01-30 13:53:49 -08:00
|
|
|
extern uint8_t disableLocalStorage; // Off by default
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-01 19:15:38 -07:00
|
|
|
// References to JNI objects and VM kept for future callbacks
|
|
|
|
|
JavaVM *jvm = NULL;
|
|
|
|
|
jobject objRef = NULL;
|
|
|
|
|
jmethodID _userCallbackMethodRef = NULL;
|
2019-02-06 22:00:39 -08:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-01-30 13:53:49 -08:00
|
|
|
int zts_generate_orphan_identity(char *key_pair_str, uint16_t *key_buf_len)
|
|
|
|
|
{
|
|
|
|
|
if (*key_buf_len < ZT_IDENTITY_STRING_BUFFER_LENGTH || key_pair_str == NULL) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
Identity id;
|
|
|
|
|
id.generate();
|
|
|
|
|
char idtmp[1024];
|
|
|
|
|
std::string idser = id.toString(true,idtmp);
|
|
|
|
|
uint16_t key_pair_len = idser.length();
|
|
|
|
|
if (key_pair_len > *key_buf_len) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
memcpy(key_pair_str, idser.c_str(), key_pair_len);
|
|
|
|
|
*key_buf_len = key_pair_len;
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int zts_verify_identity(const char *key_pair_str)
|
|
|
|
|
{
|
|
|
|
|
if (key_pair_str == NULL || strlen(key_pair_str) > ZT_IDENTITY_STRING_BUFFER_LENGTH) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
Identity id;
|
|
|
|
|
if ((strlen(key_pair_str) > 32) && (key_pair_str[10] == ':')) {
|
|
|
|
|
if (id.fromString(key_pair_str)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int zts_get_node_identity(char *key_pair_str, uint16_t *key_buf_len)
|
|
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if (*key_buf_len == 0 || key_pair_str == NULL) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
if (!service) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
service->getIdentity(key_pair_str, key_buf_len);
|
|
|
|
|
return *key_buf_len > 0 ? ZTS_ERR_OK : ZTS_ERR_GENERAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: This logic should be further generalized in the next API redesign
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_PYTHON
|
|
|
|
|
int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
|
|
|
|
|
PythonDirectorCallbackClass *callback, uint16_t port)
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef ZTS_ENABLE_PINVOKE
|
2021-01-30 13:53:49 -08:00
|
|
|
int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
|
|
|
|
|
CppCallback callback, uint16_t port)
|
2021-02-24 01:25:15 -08:00
|
|
|
#endif
|
|
|
|
|
#ifdef ZTS_C_API_ONLY
|
2021-01-30 13:53:49 -08:00
|
|
|
int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
|
|
|
|
|
void (*callback)(void *), uint16_t port)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if (!zts_verify_identity(key_pair_str)) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
Mutex::Lock _l(serviceLock);
|
2021-03-01 22:34:12 -08:00
|
|
|
#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
|
2021-02-24 01:25:15 -08:00
|
|
|
_install_signal_handlers();
|
2021-03-01 22:34:12 -08:00
|
|
|
#endif // ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
|
2021-01-30 13:53:49 -08:00
|
|
|
_lwip_driver_init();
|
|
|
|
|
if (service || _getState(ZTS_STATE_NODE_RUNNING)) {
|
|
|
|
|
// Service is already initialized
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (_getState(ZTS_STATE_FREE_CALLED)) {
|
|
|
|
|
// Stack (presumably lwIP) has been dismantled,
|
|
|
|
|
// an application restart is required now
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
_userEventCallback = callback;
|
2021-02-02 11:36:51 -08:00
|
|
|
if (!_isCallbackRegistered()) {
|
|
|
|
|
// Must have a callback
|
2021-01-30 13:53:49 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-02-02 11:36:51 -08:00
|
|
|
|
2021-01-30 13:53:49 -08:00
|
|
|
serviceParameters *params = new serviceParameters();
|
|
|
|
|
params->port = port;
|
|
|
|
|
params->path = "";
|
|
|
|
|
|
|
|
|
|
Identity id;
|
|
|
|
|
if ((strlen(key_pair_str) > 32) && (key_pair_str[10] == ':')) {
|
|
|
|
|
if (id.fromString(key_pair_str)) {
|
|
|
|
|
id.toString(false, params->publicIdentityStr);
|
|
|
|
|
id.toString(true, params->secretIdentityStr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!id) {
|
2021-02-02 11:36:51 -08:00
|
|
|
delete params;
|
2021-01-30 13:53:49 -08:00
|
|
|
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
|
|
|
|
|
pthread_t service_thread;
|
|
|
|
|
pthread_t callback_thread;
|
|
|
|
|
if ((err = pthread_create(&service_thread, NULL, _runNodeService, (void*)params)) != 0) {
|
|
|
|
|
retval = err;
|
|
|
|
|
}
|
|
|
|
|
if ((err = pthread_create(&callback_thread, NULL, _runCallbacks, NULL)) != 0) {
|
|
|
|
|
retval = err;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(__linux__)
|
|
|
|
|
pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME);
|
|
|
|
|
pthread_setname_np(callback_thread, ZTS_EVENT_CALLBACK_THREAD_NAME);
|
|
|
|
|
#endif
|
|
|
|
|
if (retval != ZTS_ERR_OK) {
|
|
|
|
|
_clrState(ZTS_STATE_CALLBACKS_RUNNING);
|
|
|
|
|
_clrState(ZTS_STATE_NODE_RUNNING);
|
|
|
|
|
_clearRegisteredCallback();
|
|
|
|
|
//delete params;
|
|
|
|
|
}
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
int zts_allow_network_caching(uint8_t allowed = 1)
|
2019-02-27 18:37:00 -08:00
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if(!service) {
|
|
|
|
|
allowNetworkCaching = allowed;
|
|
|
|
|
return ZTS_ERR_OK;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
int zts_allow_peer_caching(uint8_t allowed = 1)
|
2019-02-06 22:00:39 -08:00
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if(!service) {
|
|
|
|
|
allowPeerCaching = allowed;
|
|
|
|
|
return ZTS_ERR_OK;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
int zts_allow_local_conf(uint8_t allowed = 1)
|
2019-02-06 22:00:39 -08:00
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if(!service) {
|
|
|
|
|
allowLocalConf = allowed;
|
|
|
|
|
return ZTS_ERR_OK;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2020-04-15 16:08:40 -07:00
|
|
|
}
|
|
|
|
|
|
2021-01-30 13:53:49 -08:00
|
|
|
int zts_disable_local_storage(uint8_t disabled)
|
|
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if(!service) {
|
|
|
|
|
disableLocalStorage = disabled;
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_PYTHON
|
|
|
|
|
int zts_start(const char *path, PythonDirectorCallbackClass *callback, uint16_t port)
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef ZTS_ENABLE_PINVOKE
|
2021-01-04 21:03:57 -08:00
|
|
|
int zts_start(const char *path, CppCallback callback, uint16_t port)
|
2021-02-24 01:25:15 -08:00
|
|
|
#endif
|
|
|
|
|
#ifdef ZTS_C_API_ONLY
|
2020-05-01 19:15:38 -07:00
|
|
|
int zts_start(const char *path, void (*callback)(void *), uint16_t port)
|
2021-01-04 21:03:57 -08:00
|
|
|
#endif
|
2019-02-06 22:00:39 -08:00
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
Mutex::Lock _l(serviceLock);
|
2021-03-01 22:34:12 -08:00
|
|
|
#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
|
2021-02-24 01:25:15 -08:00
|
|
|
_install_signal_handlers();
|
2021-03-01 22:34:12 -08:00
|
|
|
#endif // ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
|
2020-05-01 19:15:38 -07:00
|
|
|
_lwip_driver_init();
|
|
|
|
|
if (service || _getState(ZTS_STATE_NODE_RUNNING)) {
|
2019-02-06 22:00:39 -08:00
|
|
|
// Service is already initialized
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
if (_getState(ZTS_STATE_FREE_CALLED)) {
|
2019-03-18 14:23:34 -07:00
|
|
|
// Stack (presumably lwIP) has been dismantled,
|
|
|
|
|
// an application restart is required now
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
_userEventCallback = callback;
|
2020-05-01 19:15:38 -07:00
|
|
|
if (!_isCallbackRegistered()) {
|
2019-02-06 22:00:39 -08:00
|
|
|
// Must have a callback
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
if (!path) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
serviceParameters *params = new serviceParameters();
|
|
|
|
|
params->port = port;
|
|
|
|
|
params->path = std::string(path);
|
|
|
|
|
|
|
|
|
|
if (params->path.length() == 0) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
int err;
|
|
|
|
|
int retval = ZTS_ERR_OK;
|
2020-05-01 19:15:38 -07:00
|
|
|
|
|
|
|
|
_setState(ZTS_STATE_CALLBACKS_RUNNING);
|
|
|
|
|
_setState(ZTS_STATE_NODE_RUNNING);
|
2019-02-06 22:00:39 -08:00
|
|
|
// Start the ZT service thread
|
2020-05-01 19:15:38 -07:00
|
|
|
#if defined(__WINDOWS__)
|
2020-05-30 18:29:04 -07:00
|
|
|
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
2020-05-01 19:15:38 -07:00
|
|
|
HANDLE serviceThread = CreateThread(NULL, 0, _runNodeService, (void*)params, 0, NULL);
|
|
|
|
|
HANDLE callbackThread = CreateThread(NULL, 0, _runCallbacks, NULL, 0, NULL);
|
2019-06-18 11:06:05 -07:00
|
|
|
#else
|
|
|
|
|
pthread_t service_thread;
|
|
|
|
|
pthread_t callback_thread;
|
2020-05-01 19:15:38 -07:00
|
|
|
if ((err = pthread_create(&service_thread, NULL, _runNodeService, (void*)params)) != 0) {
|
2019-02-06 22:00:39 -08:00
|
|
|
retval = err;
|
|
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
if ((err = pthread_create(&callback_thread, NULL, _runCallbacks, NULL)) != 0) {
|
2019-02-06 22:00:39 -08:00
|
|
|
retval = err;
|
|
|
|
|
}
|
2019-06-18 11:06:05 -07:00
|
|
|
#endif
|
2019-02-06 22:00:39 -08:00
|
|
|
#if defined(__linux__)
|
|
|
|
|
pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME);
|
|
|
|
|
pthread_setname_np(callback_thread, ZTS_EVENT_CALLBACK_THREAD_NAME);
|
|
|
|
|
#endif
|
|
|
|
|
if (retval != ZTS_ERR_OK) {
|
2020-05-01 19:15:38 -07:00
|
|
|
_clrState(ZTS_STATE_CALLBACKS_RUNNING);
|
|
|
|
|
_clrState(ZTS_STATE_NODE_RUNNING);
|
|
|
|
|
_clearRegisteredCallback();
|
|
|
|
|
//delete params;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-01 19:15:38 -07:00
|
|
|
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_start(
|
2019-02-06 22:00:39 -08:00
|
|
|
JNIEnv *env, jobject thisObj, jstring path, jobject callback, jint port)
|
|
|
|
|
{
|
|
|
|
|
if (!path) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
jclass eventListenerClass = env->GetObjectClass(callback);
|
|
|
|
|
if(eventListenerClass == NULL) {
|
|
|
|
|
DEBUG_ERROR("Couldn't find class for ZeroTierEventListener instance");
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
jmethodID eventListenerCallbackMethod = env->GetMethodID(eventListenerClass, "onZeroTierEvent", "(JI)V");
|
|
|
|
|
if(eventListenerCallbackMethod == NULL) {
|
|
|
|
|
DEBUG_ERROR("Couldn't find onZeroTierEvent method");
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2019-03-18 14:23:34 -07:00
|
|
|
// Reference used for later calls
|
|
|
|
|
objRef = env->NewGlobalRef(callback);
|
2019-02-06 22:00:39 -08:00
|
|
|
_userCallbackMethodRef = eventListenerCallbackMethod;
|
|
|
|
|
const char* utf_string = env->GetStringUTFChars(path, NULL);
|
2019-03-18 14:23:34 -07:00
|
|
|
if (!utf_string) {
|
|
|
|
|
return ZTS_ERR_GENERAL;
|
|
|
|
|
}
|
|
|
|
|
// using _userCallbackMethodRef
|
|
|
|
|
int retval = zts_start(utf_string, NULL, port);
|
2019-02-06 22:00:39 -08:00
|
|
|
env->ReleaseStringUTFChars(path, utf_string);
|
2019-02-28 15:47:49 -08:00
|
|
|
return retval;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-03-04 18:04:37 -08:00
|
|
|
int zts_stop()
|
2019-02-06 22:00:39 -08:00
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if (_canPerformServiceOperation()) {
|
|
|
|
|
_clrState(ZTS_STATE_NODE_RUNNING);
|
2019-02-06 22:00:39 -08:00
|
|
|
service->terminate();
|
2020-05-01 19:15:38 -07:00
|
|
|
#if defined(__WINDOWS__)
|
2019-02-06 22:00:39 -08:00
|
|
|
WSACleanup();
|
|
|
|
|
#endif
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-30 18:29:04 -07:00
|
|
|
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop(
|
2019-02-06 22:00:39 -08:00
|
|
|
JNIEnv *env, jobject thisObj)
|
|
|
|
|
{
|
|
|
|
|
zts_stop();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-02-02 11:36:51 -08:00
|
|
|
// TODO: Make sure this woks with user-provided identities
|
2019-03-27 15:08:27 -07:00
|
|
|
int zts_restart()
|
|
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
serviceLock.lock();
|
2019-03-27 15:08:27 -07:00
|
|
|
// Store callback references
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2019-03-27 17:09:30 -07:00
|
|
|
static jmethodID _tmpUserCallbackMethodRef = _userCallbackMethodRef;
|
|
|
|
|
#endif
|
2020-05-01 19:15:38 -07:00
|
|
|
int userProvidedPort = 0;
|
|
|
|
|
std::string userProvidedPath;
|
|
|
|
|
if (service) {
|
|
|
|
|
userProvidedPort = service->_userProvidedPort;
|
|
|
|
|
userProvidedPath = service->_userProvidedPath;
|
|
|
|
|
}
|
2019-03-27 15:08:27 -07:00
|
|
|
// Stop the service
|
2020-05-01 19:15:38 -07:00
|
|
|
if (_canPerformServiceOperation()) {
|
|
|
|
|
_clrState(ZTS_STATE_NODE_RUNNING);
|
2019-03-27 15:08:27 -07:00
|
|
|
service->terminate();
|
2020-05-01 19:15:38 -07:00
|
|
|
#if defined(__WINDOWS__)
|
2019-03-27 15:08:27 -07:00
|
|
|
WSACleanup();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-05-01 19:15:38 -07:00
|
|
|
serviceLock.unlock();
|
2019-03-27 15:08:27 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
// Start again with same parameters as initial call
|
2020-05-01 19:15:38 -07:00
|
|
|
serviceLock.unlock();
|
2019-03-27 15:08:27 -07:00
|
|
|
while (service) {
|
2020-05-01 19:15:38 -07:00
|
|
|
zts_delay_ms(ZTS_CALLBACK_PROCESSING_INTERVAL);
|
2019-03-27 15:08:27 -07:00
|
|
|
}
|
2019-03-27 17:09:30 -07:00
|
|
|
/* Some of the logic in Java_com_zerotier_libzt_ZeroTier_start
|
|
|
|
|
is replicated here */
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2019-03-27 17:09:30 -07:00
|
|
|
_userCallbackMethodRef = _tmpUserCallbackMethodRef;
|
2020-05-01 19:15:38 -07:00
|
|
|
return zts_start(userProvidedPath.c_str(), NULL, userProvidedPort);
|
2019-03-27 17:09:30 -07:00
|
|
|
#else
|
2021-02-24 01:25:15 -08:00
|
|
|
return ZTS_ERR_OK;
|
2019-03-27 17:09:30 -07:00
|
|
|
#endif
|
2019-03-27 15:08:27 -07:00
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-30 18:29:04 -07:00
|
|
|
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_restart(
|
2019-03-27 15:08:27 -07:00
|
|
|
JNIEnv *env, jobject thisObj)
|
|
|
|
|
{
|
|
|
|
|
zts_restart();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-03-04 18:04:37 -08:00
|
|
|
int zts_free()
|
2019-02-06 22:00:39 -08:00
|
|
|
{
|
2020-05-01 19:15:38 -07:00
|
|
|
if (_getState(ZTS_STATE_FREE_CALLED)) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
_setState(ZTS_STATE_FREE_CALLED);
|
2020-05-30 18:29:04 -07:00
|
|
|
int err = zts_stop();
|
2020-05-01 19:15:38 -07:00
|
|
|
Mutex::Lock _l(serviceLock);
|
2020-05-30 18:29:04 -07:00
|
|
|
_lwip_driver_shutdown();
|
|
|
|
|
return err;
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-30 18:29:04 -07:00
|
|
|
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free(
|
2020-05-01 19:15:38 -07:00
|
|
|
JNIEnv *env, jobject thisObj)
|
|
|
|
|
{
|
2020-05-30 18:29:04 -07:00
|
|
|
zts_free();
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-01 19:15:38 -07:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2020-05-30 18:29:04 -07:00
|
|
|
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_init(
|
2020-05-01 19:15:38 -07:00
|
|
|
JNIEnv *env, jobject thisObj)
|
|
|
|
|
{
|
2021-02-24 01:25:15 -08:00
|
|
|
jint rs = env->GetJavaVM(&jvm);
|
2020-05-01 19:15:38 -07:00
|
|
|
return rs != JNI_OK ? ZTS_ERR_GENERAL : ZTS_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
int zts_join(const uint64_t networkId)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if (!_canPerformServiceOperation()) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-05-30 18:29:04 -07:00
|
|
|
service->join(networkId);
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-30 18:29:04 -07:00
|
|
|
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join(
|
|
|
|
|
JNIEnv *env, jobject thisObj, jlong networkId)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2020-05-30 18:29:04 -07:00
|
|
|
return zts_join((uint64_t)networkId);
|
2020-05-29 19:24:22 +01:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
int zts_leave(const uint64_t networkId)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
if (!_canPerformServiceOperation()) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-05-30 18:29:04 -07:00
|
|
|
service->leave(networkId);
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-30 18:29:04 -07:00
|
|
|
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave(
|
|
|
|
|
JNIEnv *env, jobject thisObj, jlong networkId)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2020-05-30 18:29:04 -07:00
|
|
|
return zts_leave((uint64_t)networkId);
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int zts_orbit(uint64_t moonWorldId, uint64_t moonSeed)
|
|
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
void *tptr = NULL;
|
|
|
|
|
if (!_canPerformServiceOperation()) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
} else {
|
|
|
|
|
service->getNode()->orbit(tptr, moonWorldId, moonSeed);
|
|
|
|
|
}
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-01 19:15:38 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int zts_deorbit(uint64_t moonWorldId)
|
|
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(serviceLock);
|
|
|
|
|
void *tptr = NULL;
|
|
|
|
|
if (!_canPerformServiceOperation()) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
} else {
|
|
|
|
|
service->getNode()->deorbit(tptr, moonWorldId);
|
|
|
|
|
}
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
#ifdef ZTS_ENABLE_JAVA
|
2020-05-01 19:15:38 -07:00
|
|
|
#endif
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
int zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId)
|
2020-04-13 23:38:06 -07:00
|
|
|
{
|
2020-05-30 18:29:04 -07:00
|
|
|
if (!addr || !networkId || !nodeId) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2020-04-13 23:38:06 -07:00
|
|
|
}
|
2020-05-30 18:29:04 -07:00
|
|
|
InetAddress _6planeAddr = InetAddress::makeIpv66plane(networkId,nodeId);
|
2020-04-15 16:08:40 -07:00
|
|
|
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
|
|
|
|
|
memcpy(in6->sin6_addr.s6_addr, _6planeAddr.rawIpData(), sizeof(struct in6_addr));
|
2020-04-20 23:50:21 -07:00
|
|
|
return ZTS_ERR_OK;
|
2020-04-13 23:38:06 -07:00
|
|
|
}
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
int zts_get_rfc4193_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId)
|
2020-04-13 23:38:06 -07:00
|
|
|
{
|
2020-05-30 18:29:04 -07:00
|
|
|
if (!addr || !networkId || !nodeId) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2020-04-13 23:38:06 -07:00
|
|
|
}
|
2020-05-30 18:29:04 -07:00
|
|
|
InetAddress _rfc4193Addr = InetAddress::makeIpv6rfc4193(networkId,nodeId);
|
2020-04-15 16:08:40 -07:00
|
|
|
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
|
|
|
|
|
memcpy(in6->sin6_addr.s6_addr, _rfc4193Addr.rawIpData(), sizeof(struct in6_addr));
|
2020-04-20 23:50:21 -07:00
|
|
|
return ZTS_ERR_OK;
|
2020-04-13 23:38:06 -07:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 11:37:46 -07:00
|
|
|
uint64_t zts_generate_adhoc_nwid_from_range(uint16_t startPortOfRange, uint16_t endPortOfRange)
|
|
|
|
|
{
|
2020-05-30 18:29:04 -07:00
|
|
|
char networkIdStr[INET6_ADDRSTRLEN];
|
|
|
|
|
sprintf(networkIdStr, "ff%04x%04x000000", startPortOfRange, endPortOfRange);
|
|
|
|
|
return strtoull(networkIdStr, NULL, 16);
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
#ifdef __WINDOWS__
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#elif _POSIX_C_SOURCE >= 199309L
|
|
|
|
|
#include <time.h> // for nanosleep
|
|
|
|
|
#else
|
|
|
|
|
#include <unistd.h> // for usleep
|
2019-02-06 22:00:39 -08:00
|
|
|
#endif
|
|
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
void zts_delay_ms(long milliseconds)
|
2019-03-27 15:08:27 -07:00
|
|
|
{
|
2020-05-30 18:29:04 -07:00
|
|
|
#ifdef __WINDOWS__
|
2021-02-24 01:25:15 -08:00
|
|
|
Sleep(milliseconds);
|
2020-05-30 18:29:04 -07:00
|
|
|
#elif _POSIX_C_SOURCE >= 199309L
|
2021-02-24 01:25:15 -08:00
|
|
|
struct timespec ts;
|
|
|
|
|
ts.tv_sec = milliseconds / 1000;
|
|
|
|
|
ts.tv_nsec = (milliseconds % 1000) * 1000000;
|
|
|
|
|
nanosleep(&ts, NULL);
|
2019-03-27 15:08:27 -07:00
|
|
|
#else
|
2021-02-24 01:25:15 -08:00
|
|
|
usleep(milliseconds * 1000);
|
2019-02-26 13:40:04 -08:00
|
|
|
#endif
|
2019-02-06 22:00:39 -08:00
|
|
|
}
|
2020-05-29 19:24:22 +01:00
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
2020-11-29 17:49:18 -06:00
|
|
|
#endif
|