Improvements to language binding facilities. Add custom signal handler

This commit is contained in:
Joseph Henry
2021-02-24 01:25:15 -08:00
parent cfe3811a4a
commit 7a82ef4a03
9 changed files with 367 additions and 108 deletions

View File

@@ -20,6 +20,21 @@
#ifndef ZT_SOCKETS_H #ifndef ZT_SOCKETS_H
#define ZT_SOCKETS_H #define ZT_SOCKETS_H
//////////////////////////////////////////////////////////////////////////////
// Configuration Options //
//////////////////////////////////////////////////////////////////////////////
#ifdef ZTS_ENABLE_PYTHON
/* In some situations (Python comes to mind) a signal may not make its
way to libzt, for this reason we make sure to define a custom signal handler
that can at least process SIGTERMs */
#define ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS 1
#endif
#if !defined(ZTS_ENABLE_PYTHON) && !defined(ZTS_ENABLE_PINVOKE)
#define ZTS_C_API_ONLY 1
#endif
#if !ZTS_NO_STDINT_H #if !ZTS_NO_STDINT_H
#include <stdint.h> #include <stdint.h>
#endif #endif
@@ -39,7 +54,7 @@
extern "C" { extern "C" {
#endif #endif
#ifdef ZTS_PINVOKE #ifdef ZTS_ENABLE_PINVOKE
// Used by P/INVOKE wrappers // Used by P/INVOKE wrappers
typedef void (*CppCallback)(void *msg); typedef void (*CppCallback)(void *msg);
#endif #endif
@@ -735,9 +750,6 @@ struct zts_network_details
} multicastSubscriptions[ZTS_MAX_MULTICAST_SUBSCRIPTIONS]; } multicastSubscriptions[ZTS_MAX_MULTICAST_SUBSCRIPTIONS];
}; };
/** /**
* Physical network path to a peer * Physical network path to a peer
*/ */
@@ -829,6 +841,94 @@ struct zts_peer_list
unsigned long peerCount; unsigned long peerCount;
}; };
//////////////////////////////////////////////////////////////////////////////
// Python bits //
//////////////////////////////////////////////////////////////////////////////
#ifdef ZTS_ENABLE_PYTHON
#include "Python.h"
/**
* Abstract class used as a director. Pointer to an instance of this class
* is provided to the Python layer.
*
* See: https://rawgit.com/swig/swig/master/Doc/Manual/SWIGPlus.html#SWIGPlus_target_language_callbacks
*/
class PythonDirectorCallbackClass
{
public:
/**
* Called by native code on event. Implemented in Python
*/
virtual void on_zerotier_event(struct zts_callback_msg *msg);
virtual ~PythonDirectorCallbackClass() {};
};
extern PythonDirectorCallbackClass *_userEventCallback;
/**
* @brief
*
* @param fd
* @param
* @param
* @param
*
* @return
*/
int zts_sock_bind(int fd, int family, int type, PyObject *addro);
/**
* @brief
*
* @param fd
* @param
* @param
* @param
*
* @return
*/
int zts_sock_connect(int fd, int family, int type, PyObject *addro);
/**
* @brief
*
* @param fd
* @param
* @param
* @param
*
* @return
*/
PyObject * zts_sock_accept(int fd);
/**
* @brief
*
* @param fd
* @param
* @param
* @param
*
* @return
*/
PyObject * zts_sock_recv(int fd, int len, int flags);
/**
* @brief
*
* @param fd
* @param
* @param
* @param
*
* @return
*/
int zts_sock_send(int fd, PyObject *buf, int len, int flags);
#endif
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// ZeroTier Service Controls // // ZeroTier Service Controls //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -849,7 +949,7 @@ struct zts_peer_list
// Central API // // Central API //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef NO_CENTRAL_API #ifdef ZTS_ENABLE_CENTRAL_API
#define CENTRAL_API_DEFAULT_URL "https://my.zerotier.com" #define CENTRAL_API_DEFAULT_URL "https://my.zerotier.com"
#define CENRTAL_API_MAX_URL_LEN 128 #define CENRTAL_API_MAX_URL_LEN 128
@@ -1032,11 +1132,16 @@ ZTS_API int ZTCALL zts_get_node_identity(char *key_pair_str, uint16_t *key_buf_l
* @param port Port that the library should use for talking to other ZeroTier nodes * @param port Port that the library should use for talking to other ZeroTier nodes
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure
*/ */
#ifdef ZTS_PINVOKE #ifdef ZTS_ENABLE_PYTHON
ZTS_API int ZTCALL zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len, 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
int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
CppCallback callback, uint16_t port); CppCallback callback, uint16_t port);
#else #endif
ZTS_API int ZTCALL zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len, #ifdef ZTS_C_API_ONLY
int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
void (*callback)(void *), uint16_t port); void (*callback)(void *), uint16_t port);
#endif #endif
@@ -1100,9 +1205,13 @@ ZTS_API int ZTCALL zts_disable_local_storage(uint8_t disabled);
* @param port Port that the library should use for talking to other ZeroTier nodes * @param port Port that the library should use for talking to other ZeroTier nodes
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure
*/ */
#ifdef ZTS_PINVOKE #ifdef ZTS_ENABLE_PYTHON
ZTS_API int ZTCALL zts_start(const char *path, PythonDirectorCallbackClass *callback, uint16_t port);
#endif
#ifdef ZTS_ENABLE_PINVOKE
ZTS_API int ZTCALL zts_start(const char *path, CppCallback callback, uint16_t port); ZTS_API int ZTCALL zts_start(const char *path, CppCallback callback, uint16_t port);
#else #endif
#ifdef ZTS_C_API_ONLY
ZTS_API int ZTCALL zts_start(const char *path, void (*callback)(void *), uint16_t port); ZTS_API int ZTCALL zts_start(const char *path, void (*callback)(void *), uint16_t port);
#endif #endif
@@ -1234,6 +1343,8 @@ ZTS_API void ZTCALL zts_delay_ms(long interval_ms);
// Statistics // // Statistics //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifdef ZTS_ENABLE_STATS
#define ZTS_STATS_PROTOCOL_LINK 0 #define ZTS_STATS_PROTOCOL_LINK 0
#define ZTS_STATS_PROTOCOL_ETHARP 1 #define ZTS_STATS_PROTOCOL_ETHARP 1
#define ZTS_STATS_PROTOCOL_IP 2 #define ZTS_STATS_PROTOCOL_IP 2
@@ -1325,6 +1436,8 @@ struct zts_stats {
struct zts_stats_proto nd6; struct zts_stats_proto nd6;
}; };
#endif
/** /**
* @brief Return all statistical counters for all protocols (inefficient) * @brief Return all statistical counters for all protocols (inefficient)
* *

View File

@@ -14,7 +14,7 @@
#ifndef ZT_CENTRAL_H #ifndef ZT_CENTRAL_H
#define ZT_CENTRAL_H #define ZT_CENTRAL_H
#ifdef CENTRAL_API #ifdef ZTS_ENABLE_CENTRAL_API
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@@ -25,15 +25,16 @@
#include "Mutex.hpp" #include "Mutex.hpp"
#include "OSUtils.hpp" #include "OSUtils.hpp"
#include "ZeroTierSockets.h"
#include "Debug.hpp" #include "Debug.hpp"
#include "NodeService.hpp" #include "NodeService.hpp"
#include "VirtualTap.hpp" #include "VirtualTap.hpp"
#include "Events.hpp" #include "Events.hpp"
#include "ZeroTierSockets.h" #include "Signals.hpp"
using namespace ZeroTier; using namespace ZeroTier;
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#include <jni.h> #include <jni.h>
#endif #endif
@@ -46,13 +47,20 @@ namespace ZeroTier
{ {
extern NodeService *service; extern NodeService *service;
extern Mutex serviceLock; extern Mutex serviceLock;
extern void (*_userEventCallbackFunc)(void *); #ifdef ZTS_ENABLE_PYTHON
#endif
#ifdef ZTS_ENABLE_PINVOKE
extern void (*_userEventCallback)(void *);
#endif
#ifdef ZTS_C_API_ONLY
extern void (*_userEventCallback)(void *);
#endif
extern uint8_t allowNetworkCaching; extern uint8_t allowNetworkCaching;
extern uint8_t allowPeerCaching; extern uint8_t allowPeerCaching;
extern uint8_t allowLocalConf; extern uint8_t allowLocalConf;
extern uint8_t disableLocalStorage; // Off by default extern uint8_t disableLocalStorage; // Off by default
#ifdef ZTS_ENABLE_JAVA
#ifdef SDK_JNI
// References to JNI objects and VM kept for future callbacks // References to JNI objects and VM kept for future callbacks
JavaVM *jvm = NULL; JavaVM *jvm = NULL;
jobject objRef = NULL; jobject objRef = NULL;
@@ -110,10 +118,15 @@ int zts_get_node_identity(char *key_pair_str, uint16_t *key_buf_len)
} }
// TODO: This logic should be further generalized in the next API redesign // TODO: This logic should be further generalized in the next API redesign
#ifdef ZTS_PINVOKE #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
int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len, int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
CppCallback callback, uint16_t port) CppCallback callback, uint16_t port)
#else #endif
#ifdef ZTS_C_API_ONLY
int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len, int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
void (*callback)(void *), uint16_t port) void (*callback)(void *), uint16_t port)
#endif #endif
@@ -122,6 +135,9 @@ int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
return ZTS_ERR_ARG; return ZTS_ERR_ARG;
} }
Mutex::Lock _l(serviceLock); Mutex::Lock _l(serviceLock);
//#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
_install_signal_handlers();
//#endif // ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
_lwip_driver_init(); _lwip_driver_init();
if (service || _getState(ZTS_STATE_NODE_RUNNING)) { if (service || _getState(ZTS_STATE_NODE_RUNNING)) {
// Service is already initialized // Service is already initialized
@@ -132,11 +148,7 @@ int zts_start_with_identity(const char *key_pair_str, uint16_t key_buf_len,
// an application restart is required now // an application restart is required now
return ZTS_ERR_SERVICE; return ZTS_ERR_SERVICE;
} }
#ifdef SDK_JNI _userEventCallback = callback;
_userEventCallbackFunc = callback;
#else
_userEventCallbackFunc = callback;
#endif
if (!_isCallbackRegistered()) { if (!_isCallbackRegistered()) {
// Must have a callback // Must have a callback
return ZTS_ERR_ARG; return ZTS_ERR_ARG;
@@ -231,13 +243,20 @@ int zts_disable_local_storage(uint8_t disabled)
return ZTS_ERR_SERVICE; return ZTS_ERR_SERVICE;
} }
#ifdef ZTS_PINVOKE #ifdef ZTS_ENABLE_PYTHON
int zts_start(const char *path, PythonDirectorCallbackClass *callback, uint16_t port)
#endif
#ifdef ZTS_ENABLE_PINVOKE
int zts_start(const char *path, CppCallback callback, uint16_t port) int zts_start(const char *path, CppCallback callback, uint16_t port)
#else #endif
#ifdef ZTS_C_API_ONLY
int zts_start(const char *path, void (*callback)(void *), uint16_t port) int zts_start(const char *path, void (*callback)(void *), uint16_t port)
#endif #endif
{ {
Mutex::Lock _l(serviceLock); Mutex::Lock _l(serviceLock);
//#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
_install_signal_handlers();
//#endif // ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
_lwip_driver_init(); _lwip_driver_init();
if (service || _getState(ZTS_STATE_NODE_RUNNING)) { if (service || _getState(ZTS_STATE_NODE_RUNNING)) {
// Service is already initialized // Service is already initialized
@@ -248,11 +267,7 @@ int zts_start(const char *path, void (*callback)(void *), uint16_t port)
// an application restart is required now // an application restart is required now
return ZTS_ERR_SERVICE; return ZTS_ERR_SERVICE;
} }
#ifdef SDK_JNI _userEventCallback = callback;
_userEventCallbackFunc = callback;
#else
_userEventCallbackFunc = callback;
#endif
if (!_isCallbackRegistered()) { if (!_isCallbackRegistered()) {
// Must have a callback // Must have a callback
return ZTS_ERR_ARG; return ZTS_ERR_ARG;
@@ -300,7 +315,7 @@ int zts_start(const char *path, void (*callback)(void *), uint16_t port)
return retval; return retval;
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_start( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_start(
JNIEnv *env, jobject thisObj, jstring path, jobject callback, jint port) JNIEnv *env, jobject thisObj, jstring path, jobject callback, jint port)
{ {
@@ -344,7 +359,7 @@ int zts_stop()
} }
return ZTS_ERR_SERVICE; return ZTS_ERR_SERVICE;
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop( JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop(
JNIEnv *env, jobject thisObj) JNIEnv *env, jobject thisObj)
{ {
@@ -357,11 +372,8 @@ int zts_restart()
{ {
serviceLock.lock(); serviceLock.lock();
// Store callback references // Store callback references
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
static jmethodID _tmpUserCallbackMethodRef = _userCallbackMethodRef; static jmethodID _tmpUserCallbackMethodRef = _userCallbackMethodRef;
#else
void (*_tmpUserEventCallbackFunc)(void *);
_tmpUserEventCallbackFunc = _userEventCallbackFunc;
#endif #endif
int userProvidedPort = 0; int userProvidedPort = 0;
std::string userProvidedPath; std::string userProvidedPath;
@@ -388,15 +400,14 @@ int zts_restart()
} }
/* Some of the logic in Java_com_zerotier_libzt_ZeroTier_start /* Some of the logic in Java_com_zerotier_libzt_ZeroTier_start
is replicated here */ is replicated here */
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
_userCallbackMethodRef = _tmpUserCallbackMethodRef; _userCallbackMethodRef = _tmpUserCallbackMethodRef;
return zts_start(userProvidedPath.c_str(), NULL, userProvidedPort); return zts_start(userProvidedPath.c_str(), NULL, userProvidedPort);
#else #else
return ZTS_ERR_OK; return ZTS_ERR_OK;
//return zts_start(userProvidedPath.c_str(), _tmpUserEventCallbackFunc, userProvidedPort);
#endif #endif
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_restart( JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_restart(
JNIEnv *env, jobject thisObj) JNIEnv *env, jobject thisObj)
{ {
@@ -415,7 +426,7 @@ int zts_free()
_lwip_driver_shutdown(); _lwip_driver_shutdown();
return err; return err;
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free( JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free(
JNIEnv *env, jobject thisObj) JNIEnv *env, jobject thisObj)
{ {
@@ -423,7 +434,7 @@ JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free(
} }
#endif #endif
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
/* /*
* Called from Java, saves a static reference to the VM so it can be used * 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. * later to call a user-specified callback method from C.
@@ -447,7 +458,7 @@ int zts_join(const uint64_t networkId)
} }
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join(
JNIEnv *env, jobject thisObj, jlong networkId) JNIEnv *env, jobject thisObj, jlong networkId)
{ {
@@ -466,7 +477,7 @@ int zts_leave(const uint64_t networkId)
} }
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave(
JNIEnv *env, jobject thisObj, jlong networkId) JNIEnv *env, jobject thisObj, jlong networkId)
{ {
@@ -485,7 +496,7 @@ int zts_orbit(uint64_t moonWorldId, uint64_t moonSeed)
} }
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#endif #endif
int zts_deorbit(uint64_t moonWorldId) int zts_deorbit(uint64_t moonWorldId)
@@ -499,7 +510,7 @@ int zts_deorbit(uint64_t moonWorldId)
} }
return ZTS_ERR_OK; return ZTS_ERR_OK;
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#endif #endif
int zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId) int zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId)

View File

@@ -19,7 +19,7 @@
#include "concurrentqueue.h" #include "concurrentqueue.h"
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#include <jni.h> #include <jni.h>
#endif #endif
@@ -40,6 +40,15 @@
#define ROUTE_EVENT_TYPE(code) code >= ZTS_EVENT_ROUTE_ADDED && code <= ZTS_EVENT_ROUTE_REMOVED #define ROUTE_EVENT_TYPE(code) code >= ZTS_EVENT_ROUTE_ADDED && code <= ZTS_EVENT_ROUTE_REMOVED
#define ADDR_EVENT_TYPE(code) code >= ZTS_EVENT_ADDR_ADDED_IP4 && code <= ZTS_EVENT_ADDR_REMOVED_IP6 #define ADDR_EVENT_TYPE(code) code >= ZTS_EVENT_ADDR_ADDED_IP4 && code <= ZTS_EVENT_ADDR_REMOVED_IP6
#include <execinfo.h>
#include <signal.h>
#ifdef ZTS_ENABLE_PYTHON
#include "Python.h"
PythonDirectorCallbackClass *_userEventCallback = NULL;
void PythonDirectorCallbackClass::on_zerotier_event(struct zts_callback_msg *msg) { }
#endif
namespace ZeroTier { namespace ZeroTier {
extern NodeService *service; extern NodeService *service;
@@ -50,7 +59,12 @@ uint8_t _serviceStateFlags;
// Lock to guard access to callback function pointers. // Lock to guard access to callback function pointers.
Mutex _callbackLock; Mutex _callbackLock;
void (*_userEventCallbackFunc)(void *); #ifdef ZTS_ENABLE_PINVOKE
void (*_userEventCallback)(void *);
#endif
#ifdef ZTS_C_API_ONLY
void (*_userEventCallback)(void *);
#endif
moodycamel::ConcurrentQueue<struct zts_callback_msg*> _callbackMsgQueue; moodycamel::ConcurrentQueue<struct zts_callback_msg*> _callbackMsgQueue;
@@ -100,7 +114,12 @@ void _freeEvent(struct zts_callback_msg *msg)
void _passDequeuedEventToUser(struct zts_callback_msg *msg) void _passDequeuedEventToUser(struct zts_callback_msg *msg)
{ {
bool bShouldStopCallbackThread = (msg->eventCode == ZTS_EVENT_STACK_DOWN); bool bShouldStopCallbackThread = (msg->eventCode == ZTS_EVENT_STACK_DOWN);
#ifdef SDK_JNI #ifdef ZTS_ENABLE_PYTHON
PyGILState_STATE state = PyGILState_Ensure();
_userEventCallback->on_zerotier_event(msg);
PyGILState_Release(state);
#endif
#ifdef ZTS_ENABLE_JAVA
if(_userCallbackMethodRef) { if(_userCallbackMethodRef) {
JNIEnv *env; JNIEnv *env;
#if defined(__ANDROID__) #if defined(__ANDROID__)
@@ -121,14 +140,19 @@ void _passDequeuedEventToUser(struct zts_callback_msg *msg)
id = msg->peer ? msg->peer->address : 0; id = msg->peer ? msg->peer->address : 0;
} }
env->CallVoidMethod(objRef, _userCallbackMethodRef, id, msg->eventCode); env->CallVoidMethod(objRef, _userCallbackMethodRef, id, msg->eventCode);
_freeEvent(msg);
} }
#else #endif // ZTS_ENABLE_JAVA
if (_userEventCallbackFunc) { #ifdef ZTS_ENABLE_PINVOKE
_userEventCallbackFunc(msg); if (_userEventCallback) {
_freeEvent(msg); _userEventCallback(msg);
} }
#endif #endif
#ifdef ZTS_C_API_ONLY
if (_userEventCallback) {
_userEventCallback(msg);
}
#endif
_freeEvent(msg);
if (bShouldStopCallbackThread) { if (bShouldStopCallbackThread) {
/* Ensure last possible callback ZTS_EVENT_STACK_DOWN is /* Ensure last possible callback ZTS_EVENT_STACK_DOWN is
delivered before callback thread is finally stopped. */ delivered before callback thread is finally stopped. */
@@ -140,10 +164,10 @@ bool _isCallbackRegistered()
{ {
_callbackLock.lock(); _callbackLock.lock();
bool retval = false; bool retval = false;
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
retval = (jvm && objRef && _userCallbackMethodRef); retval = (jvm && objRef && _userCallbackMethodRef);
#else #else
retval = _userEventCallbackFunc; retval = _userEventCallback;
#endif #endif
_callbackLock.unlock(); _callbackLock.unlock();
return retval; return retval;
@@ -152,11 +176,11 @@ bool _isCallbackRegistered()
void _clearRegisteredCallback() void _clearRegisteredCallback()
{ {
_callbackLock.lock(); _callbackLock.lock();
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
objRef = NULL; objRef = NULL;
_userCallbackMethodRef = NULL; _userCallbackMethodRef = NULL;
#else #else
_userEventCallbackFunc = NULL; _userEventCallback = NULL;
#endif #endif
_callbackLock.unlock(); _callbackLock.unlock();
} }
@@ -237,7 +261,7 @@ void *_runCallbacks(void *thread_id)
} }
zts_delay_ms(ZTS_CALLBACK_PROCESSING_INTERVAL); zts_delay_ms(ZTS_CALLBACK_PROCESSING_INTERVAL);
} }
#if SDK_JNI #if ZTS_ENABLE_JAVA
JNIEnv *env; JNIEnv *env;
jint rs = jvm->DetachCurrentThread(); jint rs = jvm->DetachCurrentThread();
pthread_exit(0); pthread_exit(0);

View File

@@ -29,7 +29,7 @@
#include <BaseTsd.h> #include <BaseTsd.h>
#endif #endif
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#include <jni.h> #include <jni.h>
#endif #endif
namespace ZeroTier { namespace ZeroTier {
@@ -40,7 +40,7 @@ namespace ZeroTier {
#define ZTS_STATE_CALLBACKS_RUNNING 0x08 #define ZTS_STATE_CALLBACKS_RUNNING 0x08
#define ZTS_STATE_FREE_CALLED 0x10 #define ZTS_STATE_FREE_CALLED 0x10
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
// References to JNI objects and VM kept for future callbacks // References to JNI objects and VM kept for future callbacks
extern JavaVM *jvm; extern JavaVM *jvm;
extern jobject objRef; extern jobject objRef;

View File

@@ -51,7 +51,7 @@
#define stat _stat #define stat _stat
#endif #endif
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#include <jni.h> #include <jni.h>
#endif #endif

70
src/Signals.cpp Normal file
View File

@@ -0,0 +1,70 @@
/*
* Copyright (c)2013-2021 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2025-01-01
*
* 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.
*/
/****/
/**
* @file
*
* Custom signal handler
*/
#include "ZeroTierSockets.h"
#include "Signals.hpp"
#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
#include <signal.h>
#include <execinfo.h>
#include <cstdlib>
void _signal_handler(int signal)
{
/*
switch(signal)
{
case SIGINT:
fprintf(stderr, "SIGINT\n");
break;
case SIGABRT:
fprintf(stderr, "SIGABRT\n");
break;
case SIGILL:
fprintf(stderr, "SIGILL\n");
break;
case SIGSEGV:
fprintf(stderr, "SIGSEGV\n");
break;
case SIGFPE:
fprintf(stderr, "SIGFPE\n");
break;
case SIGTERM:
default:
fprintf(stderr, "SIGTERM\n");
break;
}
*/
exit(signal);
}
void _install_signal_handlers()
{
signal(SIGINT, &_signal_handler);
/*
signal(SIGABRT, &_signal_handler);
signal(SIGFPE, &_signal_handler);
signal(SIGILL, &_signal_handler);
signal(SIGSEGV, &_signal_handler);
signal(SIGTERM, &_signal_handler);
*/
}
#endif

37
src/Signals.hpp Normal file
View File

@@ -0,0 +1,37 @@
/*
* Copyright (c)2013-2021 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2025-01-01
*
* 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.
*/
/****/
/**
* @file
*
* Custom signal handler
*/
#ifndef SIGNALS_HPP
#define SIGNALS_HPP
#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
/**
*
*/
void _signal_handler(int signal);
/**
*
*/
void _install_signal_handlers();
#endif // ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
#endif // _H

View File

@@ -23,7 +23,6 @@
#include "lwip/stats.h" #include "lwip/stats.h"
#include "ZeroTierSockets.h" #include "ZeroTierSockets.h"
//#include "Events.hpp"
#define ZTS_STATE_NODE_RUNNING 0x01 #define ZTS_STATE_NODE_RUNNING 0x01
#define ZTS_STATE_STACK_RUNNING 0x02 #define ZTS_STATE_STACK_RUNNING 0x02
@@ -31,7 +30,7 @@
#define ZTS_STATE_CALLBACKS_RUNNING 0x08 #define ZTS_STATE_CALLBACKS_RUNNING 0x08
#define ZTS_STATE_FREE_CALLED 0x10 #define ZTS_STATE_FREE_CALLED 0x10
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#include <jni.h> #include <jni.h>
#endif #endif
@@ -45,7 +44,7 @@ extern uint8_t _serviceStateFlags;
extern "C" { extern "C" {
#endif #endif
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
void ss2zta(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr); void ss2zta(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr);
void zta2ss(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr); void zta2ss(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr);
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, zts_fd_set *dest_fd_set); void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, zts_fd_set *dest_fd_set);
@@ -59,7 +58,7 @@ int zts_socket(const int socket_family, const int socket_type, const int protoco
} }
return lwip_socket(socket_family, socket_type, protocol); return lwip_socket(socket_family, socket_type, protocol);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_socket( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_socket(
JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol) JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol)
{ {
@@ -81,7 +80,7 @@ int zts_connect(int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen)
} }
return lwip_connect(fd, (sockaddr*)addr, addrlen); return lwip_connect(fd, (sockaddr*)addr, addrlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_connect( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_connect(
JNIEnv *env, jobject thisObj, jint fd, jobject addr) JNIEnv *env, jobject thisObj, jint fd, jobject addr)
{ {
@@ -106,7 +105,8 @@ int zts_bind(int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen)
} }
return lwip_bind(fd, (sockaddr*)addr, addrlen); return lwip_bind(fd, (sockaddr*)addr, addrlen);
} }
#ifdef SDK_JNI
#ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_bind( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_bind(
JNIEnv *env, jobject thisObj, jint fd, jobject addr) JNIEnv *env, jobject thisObj, jint fd, jobject addr)
{ {
@@ -125,7 +125,7 @@ int zts_listen(int fd, int backlog)
} }
return lwip_listen(fd, backlog); return lwip_listen(fd, backlog);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_listen( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_listen(
JNIEnv *env, jobject thisObj, jint fd, int backlog) JNIEnv *env, jobject thisObj, jint fd, int backlog)
{ {
@@ -141,7 +141,7 @@ int zts_accept(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen)
} }
return lwip_accept(fd, (sockaddr*)addr, (socklen_t*)addrlen); return lwip_accept(fd, (sockaddr*)addr, (socklen_t*)addrlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept(
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port) JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port)
{ {
@@ -162,7 +162,7 @@ int zts_accept4(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen, int f
return ZTS_ERR_SERVICE; // TODO return ZTS_ERR_SERVICE; // TODO
} }
#endif #endif
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#if defined(__linux__) #if defined(__linux__)
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept4( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept4(
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port, jint flags) JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port, jint flags)
@@ -183,7 +183,7 @@ int zts_setsockopt(int fd, int level, int optname, const void *optval,zts_sockle
} }
return lwip_setsockopt(fd, level, optname, optval, optlen); return lwip_setsockopt(fd, level, optname, optval, optlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_setsockopt( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_setsockopt(
JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jobject optval) JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jobject optval)
{ {
@@ -236,7 +236,7 @@ int zts_getsockopt(int fd, int level, int optname, void *optval, zts_socklen_t *
} }
return lwip_getsockopt(fd, level, optname, optval, (socklen_t*)optlen); return lwip_getsockopt(fd, level, optname, optval, (socklen_t*)optlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getsockopt( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getsockopt(
JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jobject optval) JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jobject optval)
{ {
@@ -300,7 +300,7 @@ int zts_getsockname(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen)
} }
return lwip_getsockname(fd, (sockaddr*)addr, (socklen_t*)addrlen); return lwip_getsockname(fd, (sockaddr*)addr, (socklen_t*)addrlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_getsockname(JNIEnv *env, jobject thisObj, JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_getsockname(JNIEnv *env, jobject thisObj,
jint fd, jobject addr) jint fd, jobject addr)
{ {
@@ -325,7 +325,7 @@ int zts_getpeername(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen)
} }
return lwip_getpeername(fd, (sockaddr*)addr, (socklen_t*)addrlen); return lwip_getpeername(fd, (sockaddr*)addr, (socklen_t*)addrlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getpeername(JNIEnv *env, jobject thisObj, JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getpeername(JNIEnv *env, jobject thisObj,
jint fd, jobject addr) jint fd, jobject addr)
{ {
@@ -343,7 +343,7 @@ int zts_close(int fd)
} }
return lwip_close(fd); return lwip_close(fd);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_close( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_close(
JNIEnv *env, jobject thisObj, jint fd) JNIEnv *env, jobject thisObj, jint fd)
{ {
@@ -359,7 +359,7 @@ int zts_select(int nfds, zts_fd_set *readfds, zts_fd_set *writefds, zts_fd_set *
} }
return lwip_select(nfds, (fd_set*)readfds, (fd_set*)writefds, (fd_set*)exceptfds, (timeval*)timeout); return lwip_select(nfds, (fd_set*)readfds, (fd_set*)writefds, (fd_set*)exceptfds, (timeval*)timeout);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_select(JNIEnv *env, jobject thisObj, JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_select(JNIEnv *env, jobject thisObj,
jint nfds, jobject readfds, jobject writefds, jobject exceptfds, jint timeout_sec, jint timeout_usec) jint nfds, jobject readfds, jobject writefds, jobject exceptfds, jint timeout_sec, jint timeout_usec)
{ {
@@ -403,7 +403,7 @@ int zts_fcntl(int fd, int cmd, int flags)
} }
return lwip_fcntl(fd, cmd, flags); return lwip_fcntl(fd, cmd, flags);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_fcntl( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_fcntl(
JNIEnv *env, jobject thisObj, jint fd, jint cmd, jint flags) JNIEnv *env, jobject thisObj, jint fd, jint cmd, jint flags)
{ {
@@ -431,7 +431,7 @@ int zts_ioctl(int fd, unsigned long request, void *argp)
} }
return lwip_ioctl(fd, request, argp); return lwip_ioctl(fd, request, argp);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT int JNICALL Java_com_zerotier_libzt_ZeroTier_ioctl( JNIEXPORT int JNICALL Java_com_zerotier_libzt_ZeroTier_ioctl(
JNIEnv *env, jobject thisObj, jint fd, jlong request, jobject argp) JNIEnv *env, jobject thisObj, jint fd, jlong request, jobject argp)
{ {
@@ -466,7 +466,7 @@ ssize_t zts_send(int fd, const void *buf, size_t len, int flags)
} }
return lwip_send(fd, buf, len, flags); return lwip_send(fd, buf, len, flags);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_send( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_send(
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, int flags) JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, int flags)
{ {
@@ -491,7 +491,7 @@ ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags,
} }
return lwip_sendto(fd, buf, len, flags, (sockaddr*)addr, addrlen); return lwip_sendto(fd, buf, len, flags, (sockaddr*)addr, addrlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_sendto( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_sendto(
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr) JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr)
{ {
@@ -512,7 +512,7 @@ ssize_t zts_sendmsg(int fd, const struct msghdr *msg, int flags)
} }
return lwip_sendmsg(fd, msg, flags); return lwip_sendmsg(fd, msg, flags);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#endif #endif
ssize_t zts_recv(int fd, void *buf, size_t len, int flags) ssize_t zts_recv(int fd, void *buf, size_t len, int flags)
@@ -525,7 +525,7 @@ ssize_t zts_recv(int fd, void *buf, size_t len, int flags)
} }
return lwip_recv(fd, buf, len, flags); return lwip_recv(fd, buf, len, flags);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recv(JNIEnv *env, jobject thisObj, JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recv(JNIEnv *env, jobject thisObj,
jint fd, jbyteArray buf, jint flags) jint fd, jbyteArray buf, jint flags)
{ {
@@ -547,7 +547,7 @@ ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags,
} }
return lwip_recvfrom(fd, buf, len, flags, (sockaddr*)addr, (socklen_t*)addrlen); return lwip_recvfrom(fd, buf, len, flags, (sockaddr*)addr, (socklen_t*)addrlen);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recvfrom( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recvfrom(
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr) JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr)
{ {
@@ -572,7 +572,7 @@ ssize_t zts_recvmsg(int fd, struct msghdr *msg, int flags)
} }
return lwip_recvmsg(fd, msg, flags); return lwip_recvmsg(fd, msg, flags);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#endif #endif
ssize_t zts_read(int fd, void *buf, size_t len) ssize_t zts_read(int fd, void *buf, size_t len)
@@ -596,7 +596,7 @@ ssize_t zts_read_offset(int fd, void *buf, size_t offset, size_t len)
char *cbuf = (char*)buf; char *cbuf = (char*)buf;
return lwip_read(fd, &(cbuf[offset]), len); return lwip_read(fd, &(cbuf[offset]), len);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_read(JNIEnv *env, jobject thisObj, JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_read(JNIEnv *env, jobject thisObj,
jint fd, jbyteArray buf) jint fd, jbyteArray buf)
{ {
@@ -642,7 +642,7 @@ ssize_t zts_write(int fd, const void *buf, size_t len)
} }
return lwip_write(fd, buf, len); return lwip_write(fd, buf, len);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write__IB(JNIEnv *env, jobject thisObj, JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write__IB(JNIEnv *env, jobject thisObj,
jint fd, jbyteArray buf) jint fd, jbyteArray buf)
{ {
@@ -683,7 +683,7 @@ int zts_shutdown(int fd, int how)
} }
return lwip_shutdown(fd, how); return lwip_shutdown(fd, how);
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_shutdown( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_shutdown(
JNIEnv *env, jobject thisObj, int fd, int how) JNIEnv *env, jobject thisObj, int fd, int how)
{ {
@@ -698,7 +698,7 @@ int zts_add_dns_nameserver(struct zts_sockaddr *addr)
} }
return ZTS_ERR_SERVICE; // TODO return ZTS_ERR_SERVICE; // TODO
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#endif #endif
int zts_del_dns_nameserver(struct zts_sockaddr *addr) int zts_del_dns_nameserver(struct zts_sockaddr *addr)
@@ -708,7 +708,7 @@ int zts_del_dns_nameserver(struct zts_sockaddr *addr)
} }
return ZTS_ERR_SERVICE; // TODO return ZTS_ERR_SERVICE; // TODO
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
#endif #endif
uint16_t zts_htons(uint16_t n) uint16_t zts_htons(uint16_t n)
@@ -750,6 +750,8 @@ uint32_t zts_inet_addr(const char *cp)
// Statistics // // Statistics //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifdef ZTS_ENABLE_STATS
extern struct stats_ lwip_stats; extern struct stats_ lwip_stats;
int zts_get_all_stats(struct zts_stats *statsDest) int zts_get_all_stats(struct zts_stats *statsDest)
@@ -785,7 +787,7 @@ int zts_get_all_stats(struct zts_stats *statsDest)
return ZTS_ERR_NO_RESULT; return ZTS_ERR_NO_RESULT;
#endif #endif
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
// No implementation for JNI // No implementation for JNI
#endif #endif
@@ -836,7 +838,7 @@ int zts_get_protocol_stats(int protocolType, void *protoStatsDest)
return ZTS_ERR_NO_RESULT; return ZTS_ERR_NO_RESULT;
#endif #endif
} }
#ifdef SDK_JNI #ifdef ZTS_ENABLE_JAVA
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1protocol_1stats( JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1protocol_1stats(
JNIEnv *env, jobject thisObj, jint protocolType, jobject protoStatsObj) JNIEnv *env, jobject thisObj, jint protocolType, jobject protoStatsObj)
{ {
@@ -876,7 +878,9 @@ JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1protocol_1stats(
} }
#endif #endif
#ifdef SDK_JNI #endif // ZTS_ENABLE_STATS
#ifdef ZTS_ENABLE_JAVA
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, zts_fd_set *dest_fd_set) void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, zts_fd_set *dest_fd_set)
{ {
jclass c = env->GetObjectClass(src_ztfd_set); jclass c = env->GetObjectClass(src_ztfd_set);