2015-04-21 03:33:42 +00:00
/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright ( C ) 2011 - 2015 ZeroTier , Inc .
*
* 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/>.
*
* - -
*
* ZeroTier may be used and distributed under the terms of the GPLv3 , which
* are available at : http : //www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form , please contact ZeroTier Networks
* LLC . Start here : http : //www.zerotier.com/
*/
2015-04-23 02:19:45 +00:00
# include "com_zerotierone_sdk_Node.h"
2023-03-07 21:50:34 +00:00
# include "ZT_jnicache.h"
2015-09-24 23:21:36 +00:00
# include "ZT_jniutils.h"
2015-04-21 03:33:42 +00:00
# include <ZeroTierOne.h>
2015-07-02 03:26:14 +00:00
# include "Mutex.hpp"
2015-04-21 03:33:42 +00:00
# include <map>
2015-04-23 04:14:55 +00:00
# include <string>
2023-03-07 21:50:34 +00:00
# include <cassert>
# include <cstring>
# include <cinttypes> // for PRId64
2015-04-21 03:33:42 +00:00
2023-03-07 21:50:34 +00:00
# define LOG_TAG "Node"
2015-04-21 03:33:42 +00:00
namespace {
2015-04-23 02:19:45 +00:00
struct JniRef
{
2023-03-07 21:50:34 +00:00
JniRef (
int64_t id ,
JavaVM * jvm ,
jobject dataStoreGetListenerLocalIn ,
jobject dataStorePutListenerLocalIn ,
jobject packetSenderLocalIn ,
jobject eventListenerLocalIn ,
jobject frameListenerLocalIn ,
jobject configListenerLocalIn ,
jobject pathCheckerLocalIn )
: id ( id )
, jvm ( jvm )
, node ( )
, dataStoreGetListener ( )
, dataStorePutListener ( )
, packetSender ( )
, eventListener ( )
, frameListener ( )
, configListener ( )
, pathChecker ( )
, inited ( ) {
JNIEnv * env ;
GETENV ( env , jvm ) ;
dataStoreGetListener = env - > NewGlobalRef ( dataStoreGetListenerLocalIn ) ;
dataStorePutListener = env - > NewGlobalRef ( dataStorePutListenerLocalIn ) ;
packetSender = env - > NewGlobalRef ( packetSenderLocalIn ) ;
eventListener = env - > NewGlobalRef ( eventListenerLocalIn ) ;
frameListener = env - > NewGlobalRef ( frameListenerLocalIn ) ;
configListener = env - > NewGlobalRef ( configListenerLocalIn ) ;
pathChecker = env - > NewGlobalRef ( pathCheckerLocalIn ) ;
} ;
2015-04-28 01:38:13 +00:00
2015-04-30 02:29:35 +00:00
~ JniRef ( )
{
2023-03-07 21:50:34 +00:00
JNIEnv * env ;
GETENV ( env , jvm ) ;
2015-04-30 02:29:35 +00:00
env - > DeleteGlobalRef ( dataStoreGetListener ) ;
env - > DeleteGlobalRef ( dataStorePutListener ) ;
env - > DeleteGlobalRef ( packetSender ) ;
env - > DeleteGlobalRef ( eventListener ) ;
env - > DeleteGlobalRef ( frameListener ) ;
env - > DeleteGlobalRef ( configListener ) ;
2017-03-29 19:52:29 +00:00
env - > DeleteGlobalRef ( pathChecker ) ;
2015-04-30 02:29:35 +00:00
}
2017-10-03 18:25:26 +00:00
int64_t id ;
2015-04-23 02:19:45 +00:00
2015-04-28 01:38:13 +00:00
JavaVM * jvm ;
2015-04-23 02:19:45 +00:00
2015-09-24 23:21:36 +00:00
ZT_Node * node ;
2015-04-23 02:19:45 +00:00
jobject dataStoreGetListener ;
jobject dataStorePutListener ;
jobject packetSender ;
2015-04-25 03:13:21 +00:00
jobject eventListener ;
2015-04-23 02:19:45 +00:00
jobject frameListener ;
jobject configListener ;
2017-03-29 19:52:29 +00:00
jobject pathChecker ;
2016-11-22 21:03:36 +00:00
2023-03-07 21:50:34 +00:00
bool inited ;
bool finishInitializing ( ) ;
2015-04-23 02:19:45 +00:00
} ;
2023-03-07 21:50:34 +00:00
/*
* This must return 0 on success . It can return any OS - dependent error code
* on failure , and this results in the network being placed into the
* PORT_ERROR state .
*/
2015-04-25 01:49:52 +00:00
int VirtualNetworkConfigFunctionCallback (
2015-09-24 23:21:36 +00:00
ZT_Node * node ,
2015-04-25 01:49:52 +00:00
void * userData ,
2017-03-29 00:49:00 +00:00
void * threadData ,
2015-04-25 01:49:52 +00:00
uint64_t nwid ,
2023-03-07 21:50:34 +00:00
void * * nuptr ,
2015-09-24 23:21:36 +00:00
enum ZT_VirtualNetworkConfigOperation operation ,
const ZT_VirtualNetworkConfig * config )
2015-04-23 02:19:45 +00:00
{
2022-11-28 14:23:45 +00:00
LOGV ( " VirtualNetworkConfigFunctionCallback " ) ;
2015-04-23 02:19:45 +00:00
JniRef * ref = ( JniRef * ) userData ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
2015-04-23 02:19:45 +00:00
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
return - 100 ;
2018-02-12 17:29:44 +00:00
}
2023-03-07 21:50:34 +00:00
if ( ref - > configListener = = NULL ) {
LOGE ( " configListener is NULL " ) ;
return - 101 ;
2015-04-25 01:39:17 +00:00
}
2023-03-07 21:50:34 +00:00
jobject operationObject = createVirtualNetworkConfigOperation ( env , operation ) ;
if ( env - > ExceptionCheck ( ) | | operationObject = = NULL )
2015-04-25 01:39:17 +00:00
{
2023-03-07 21:50:34 +00:00
return - 102 ;
2015-04-25 01:39:17 +00:00
}
2023-03-07 21:50:34 +00:00
if ( config = = NULL ) {
LOGE ( " Config is NULL " ) ;
return - 103 ;
2015-04-25 01:39:17 +00:00
}
jobject networkConfigObject = newNetworkConfig ( env , * config ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) | | networkConfigObject = = NULL )
2015-04-25 01:39:17 +00:00
{
2023-03-07 21:50:34 +00:00
return - 104 ;
2015-04-25 01:39:17 +00:00
}
2023-03-07 21:50:34 +00:00
jint ret = env - > CallIntMethod (
2017-01-13 19:36:48 +00:00
ref - > configListener ,
2023-03-07 21:50:34 +00:00
VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method ,
2023-03-08 21:02:12 +00:00
( jlong ) nwid , ( jobject ) operationObject , ( jobject ) networkConfigObject ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onNetworkConfigurationUpdated " ) ;
return - 105 ;
}
return ret ;
2015-04-23 02:19:45 +00:00
}
2015-11-03 03:18:55 +00:00
void VirtualNetworkFrameFunctionCallback ( ZT_Node * node ,
void * userData ,
2017-03-29 00:49:00 +00:00
void * threadData ,
2015-04-25 01:49:52 +00:00
uint64_t nwid ,
2023-03-07 21:50:34 +00:00
void * * nuptr ,
2015-04-25 01:49:52 +00:00
uint64_t sourceMac ,
uint64_t destMac ,
unsigned int etherType ,
unsigned int vlanid ,
const void * frameData ,
unsigned int frameLength )
2015-04-23 02:19:45 +00:00
{
2015-06-10 02:38:05 +00:00
LOGV ( " VirtualNetworkFrameFunctionCallback " ) ;
2018-02-12 17:29:44 +00:00
# ifndef NDEBUG
2023-03-07 21:50:34 +00:00
if ( frameLength > = 14 ) {
unsigned char * local = ( unsigned char * ) frameData ;
LOGV ( " Type Bytes: 0x%02x%02x " , local [ 12 ] , local [ 13 ] ) ;
}
2018-02-12 17:29:44 +00:00
# endif
2015-04-23 02:19:45 +00:00
JniRef * ref = ( JniRef * ) userData ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
2015-04-23 02:19:45 +00:00
assert ( ref - > node = = node ) ;
2023-03-07 21:50:34 +00:00
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
2015-04-23 02:19:45 +00:00
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
2015-04-28 01:38:13 +00:00
return ;
2015-04-25 01:49:52 +00:00
}
2023-03-07 21:50:34 +00:00
if ( ref - > frameListener = = NULL ) {
LOGE ( " frameListener is NULL " ) ;
2015-04-28 01:38:13 +00:00
return ;
2015-04-25 01:49:52 +00:00
}
2023-03-07 21:50:34 +00:00
const unsigned char * bytes = static_cast < const unsigned char * > ( frameData ) ;
jbyteArray dataArray = newByteArray ( env , bytes , frameLength ) ;
2015-06-02 03:03:28 +00:00
if ( env - > ExceptionCheck ( ) | | dataArray = = NULL )
{
return ;
}
2015-04-25 01:49:52 +00:00
2023-03-08 21:02:12 +00:00
env - > CallVoidMethod ( ref - > frameListener , VirtualNetworkFrameListener_onVirtualNetworkFrame_method , ( jlong ) nwid , ( jlong ) sourceMac , ( jlong ) destMac , ( jlong ) etherType , ( jlong ) vlanid , ( jbyteArray ) dataArray ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onVirtualNetworkFrame " ) ;
2015-06-02 03:03:28 +00:00
return ;
}
2015-04-23 02:19:45 +00:00
}
2015-04-25 01:49:52 +00:00
2015-11-03 03:18:55 +00:00
void EventCallback ( ZT_Node * node ,
void * userData ,
2017-03-29 00:49:00 +00:00
void * threadData ,
2017-01-13 19:36:48 +00:00
enum ZT_Event event ,
2017-07-12 18:34:53 +00:00
const void * data ) {
2015-06-10 02:38:05 +00:00
LOGV ( " EventCallback " ) ;
2017-07-12 18:34:53 +00:00
JniRef * ref = ( JniRef * ) userData ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
2017-07-12 18:34:53 +00:00
if ( ref - > node ! = node & & event ! = ZT_EVENT_UP ) {
2015-07-02 03:26:14 +00:00
LOGE ( " Nodes not equal. ref->node %p, node %p. Event: %d " , ref - > node , node , event ) ;
2015-07-02 01:13:39 +00:00
return ;
}
2023-03-07 21:50:34 +00:00
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
2015-04-25 03:13:21 +00:00
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
2015-04-28 01:38:13 +00:00
return ;
2015-04-25 03:13:21 +00:00
}
2023-03-07 21:50:34 +00:00
if ( ref - > eventListener = = NULL ) {
LOGE ( " eventListener is NULL " ) ;
2015-04-28 01:38:13 +00:00
return ;
2015-04-25 03:13:21 +00:00
}
jobject eventObject = createEvent ( env , event ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) | | eventObject = = NULL ) {
2015-04-25 03:13:21 +00:00
return ;
}
2017-07-12 18:34:53 +00:00
switch ( event ) {
case ZT_EVENT_UP : {
LOGD ( " Event Up " ) ;
2023-03-08 21:02:12 +00:00
env - > CallVoidMethod ( ref - > eventListener , EventListener_onEvent_method , ( jobject ) eventObject ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onEvent " ) ;
return ;
}
2017-07-12 18:34:53 +00:00
break ;
}
case ZT_EVENT_OFFLINE : {
LOGD ( " Event Offline " ) ;
2023-03-08 21:02:12 +00:00
env - > CallVoidMethod ( ref - > eventListener , EventListener_onEvent_method , ( jobject ) eventObject ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onEvent " ) ;
return ;
}
2017-07-12 18:34:53 +00:00
break ;
}
case ZT_EVENT_ONLINE : {
LOGD ( " Event Online " ) ;
2023-03-08 21:02:12 +00:00
env - > CallVoidMethod ( ref - > eventListener , EventListener_onEvent_method , ( jobject ) eventObject ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onEvent " ) ;
return ;
}
2017-07-12 18:34:53 +00:00
break ;
}
case ZT_EVENT_DOWN : {
LOGD ( " Event Down " ) ;
2023-03-08 21:02:12 +00:00
env - > CallVoidMethod ( ref - > eventListener , EventListener_onEvent_method , ( jobject ) eventObject ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onEvent " ) ;
return ;
}
2017-07-12 18:34:53 +00:00
break ;
}
case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION : {
LOGV ( " Identity Collision " ) ;
// call onEvent()
2023-03-08 21:02:12 +00:00
env - > CallVoidMethod ( ref - > eventListener , EventListener_onEvent_method , ( jobject ) eventObject ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onEvent " ) ;
return ;
}
2017-07-12 18:34:53 +00:00
}
break ;
case ZT_EVENT_TRACE : {
LOGV ( " Trace Event " ) ;
// call onTrace()
2023-03-07 21:50:34 +00:00
if ( data = = NULL ) {
break ;
}
const char * message = ( const char * ) data ;
jstring messageStr = env - > NewStringUTF ( message ) ;
if ( env - > ExceptionCheck ( ) | | messageStr = = NULL ) {
LOGE ( " Exception creating new string " ) ;
return ;
}
2023-03-08 21:02:12 +00:00
env - > CallVoidMethod ( ref - > eventListener , EventListener_onTrace_method , ( jstring ) messageStr ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onTrace " ) ;
return ;
2017-07-12 18:34:53 +00:00
}
}
break ;
case ZT_EVENT_USER_MESSAGE :
2017-10-03 18:25:26 +00:00
case ZT_EVENT_REMOTE_TRACE :
2017-07-12 18:34:53 +00:00
break ;
2015-11-04 03:14:11 +00:00
}
2017-07-12 18:34:53 +00:00
}
void StatePutFunction (
ZT_Node * node ,
void * userData ,
void * threadData ,
enum ZT_StateObjectType type ,
const uint64_t id [ 2 ] ,
const void * buffer ,
int bufferLength ) {
2023-03-07 21:50:34 +00:00
LOGV ( " StatePutFunction " ) ;
2017-07-12 18:34:53 +00:00
char p [ 4096 ] = { 0 } ;
bool secure = false ;
2023-03-07 21:50:34 +00:00
int res = 0 ;
2017-07-12 18:34:53 +00:00
switch ( type ) {
case ZT_STATE_OBJECT_IDENTITY_PUBLIC :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " identity.public " ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_IDENTITY_SECRET :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " identity.secret " ) ;
2017-07-12 18:34:53 +00:00
secure = true ;
break ;
case ZT_STATE_OBJECT_PLANET :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " planet " ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_MOON :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " moons.d/%.16 " PRIx64 " .moon " , id [ 0 ] ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_NETWORK_CONFIG :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " networks.d/%.16 " PRIx64 " .conf " , id [ 0 ] ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_PEER :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " peers.d/%.10 " PRIx64 , id [ 0 ] ) ;
2017-07-12 18:34:53 +00:00
break ;
2023-03-07 21:50:34 +00:00
case ZT_STATE_OBJECT_NULL :
2017-07-12 18:34:53 +00:00
return ;
2015-11-04 03:14:11 +00:00
}
2017-07-12 18:34:53 +00:00
2023-03-07 21:50:34 +00:00
if ( ! ( 0 < = res & & res < sizeof ( p ) ) ) {
LOGE ( " snprintf error: %d " , res ) ;
2018-02-12 17:29:44 +00:00
return ;
}
2017-07-12 18:34:53 +00:00
JniRef * ref = ( JniRef * ) userData ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
2018-02-12 17:29:44 +00:00
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
2017-07-12 18:34:53 +00:00
return ;
2015-11-04 03:14:11 +00:00
}
2017-07-12 18:34:53 +00:00
2023-03-07 21:50:34 +00:00
if ( ref - > dataStorePutListener = = NULL ) {
LOGE ( " dataStorePutListener is NULL " ) ;
2017-07-12 18:34:53 +00:00
return ;
2015-11-04 03:14:11 +00:00
}
2017-07-12 18:34:53 +00:00
2023-03-07 21:50:34 +00:00
jstring nameStr = env - > NewStringUTF ( p ) ;
if ( env - > ExceptionCheck ( ) | | nameStr = = NULL ) {
LOGE ( " Exception creating new string " ) ;
2017-07-12 18:34:53 +00:00
return ;
2015-04-25 03:13:21 +00:00
}
2017-07-12 18:34:53 +00:00
if ( bufferLength > = 0 ) {
LOGD ( " JNI: Write file: %s " , p ) ;
2023-03-07 21:50:34 +00:00
const unsigned char * bytes = static_cast < const unsigned char * > ( buffer ) ;
jbyteArray bufferObj = newByteArray ( env , bytes , bufferLength ) ;
2017-07-12 18:34:53 +00:00
if ( env - > ExceptionCheck ( ) | | bufferObj = = NULL )
2015-04-25 03:13:21 +00:00
{
2017-07-12 18:34:53 +00:00
return ;
2015-04-25 03:13:21 +00:00
}
2017-07-12 18:34:53 +00:00
2023-03-07 21:50:34 +00:00
int retval = env - > CallIntMethod ( ref - > dataStorePutListener ,
DataStorePutListener_onDataStorePut_method ,
2023-03-08 21:02:12 +00:00
( jstring ) nameStr , ( jbyteArray ) bufferObj , ( jboolean ) secure ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onDataStorePut " ) ;
return ;
}
if ( retval ! = 0 ) {
LOGE ( " onDataStorePut error: %d " , retval ) ;
}
2017-07-12 18:34:53 +00:00
} else {
LOGD ( " JNI: Delete file: %s " , p ) ;
2023-03-08 21:02:12 +00:00
int retval = env - > CallIntMethod ( ref - > dataStorePutListener , DataStorePutListener_onDelete_method , ( jstring ) nameStr ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onDelete " ) ;
return ;
}
if ( retval ! = 0 ) {
LOGE ( " onDelete error: %d " , retval ) ;
}
2015-04-25 03:13:21 +00:00
}
2015-04-23 02:19:45 +00:00
}
2023-03-07 21:50:34 +00:00
/**
* This function should return the number of bytes actually stored to the
* buffer or - 1 if the state object was not found or the buffer was too
* small to store it .
*/
2017-07-12 18:34:53 +00:00
int StateGetFunction (
ZT_Node * node ,
void * userData ,
void * threadData ,
ZT_StateObjectType type ,
const uint64_t id [ 2 ] ,
void * buffer ,
unsigned int bufferLength ) {
2023-03-07 21:50:34 +00:00
LOGV ( " StateGetFunction " ) ;
2017-07-12 18:34:53 +00:00
char p [ 4096 ] = { 0 } ;
2023-03-07 21:50:34 +00:00
int res = 0 ;
2017-07-12 18:34:53 +00:00
switch ( type ) {
case ZT_STATE_OBJECT_IDENTITY_PUBLIC :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " identity.public " ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_IDENTITY_SECRET :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " identity.secret " ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_PLANET :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " planet " ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_MOON :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " moons.d/%.16 " PRIx64 " .moon " , id [ 0 ] ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_NETWORK_CONFIG :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " networks.d/%.16 " PRIx64 " .conf " , id [ 0 ] ) ;
2017-07-12 18:34:53 +00:00
break ;
case ZT_STATE_OBJECT_PEER :
2023-03-07 21:50:34 +00:00
res = snprintf ( p , sizeof ( p ) , " peers.d/%.10 " PRIx64 , id [ 0 ] ) ;
2017-07-12 18:34:53 +00:00
break ;
2023-03-07 21:50:34 +00:00
case ZT_STATE_OBJECT_NULL :
return - 100 ;
2017-07-12 18:34:53 +00:00
}
2023-03-07 21:50:34 +00:00
if ( ! ( 0 < = res & & res < sizeof ( p ) ) ) {
LOGE ( " snprintf error: %d " , res ) ;
return - 101 ;
2018-02-12 17:29:44 +00:00
}
2015-04-23 02:19:45 +00:00
JniRef * ref = ( JniRef * ) userData ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
2018-02-12 17:29:44 +00:00
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
return - 102 ;
2015-04-25 02:11:49 +00:00
}
2023-03-07 21:50:34 +00:00
if ( ref - > dataStoreGetListener = = NULL ) {
LOGE ( " dataStoreGetListener is NULL " ) ;
return - 103 ;
2015-04-25 02:11:49 +00:00
}
2017-07-12 18:34:53 +00:00
jstring nameStr = env - > NewStringUTF ( p ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) | | nameStr = = NULL )
2015-04-26 03:47:21 +00:00
{
2015-04-30 04:20:12 +00:00
LOGE ( " Error creating name string object " ) ;
2023-03-07 21:50:34 +00:00
return - 104 ; // out of memory
2015-04-26 03:47:21 +00:00
}
2023-03-07 21:50:34 +00:00
jbyteArray bufferObj = newByteArray ( env , bufferLength ) ;
if ( env - > ExceptionCheck ( ) | | bufferObj = = NULL )
2015-04-30 04:20:12 +00:00
{
2023-03-07 21:50:34 +00:00
return - 105 ;
2015-04-25 02:28:44 +00:00
}
2017-07-12 18:34:53 +00:00
LOGV ( " Calling onDataStoreGet(%s, %p) " , p , buffer ) ;
2015-04-25 02:28:44 +00:00
2017-07-12 20:12:45 +00:00
int retval = ( int ) env - > CallLongMethod (
2017-07-12 18:34:53 +00:00
ref - > dataStoreGetListener ,
2023-03-07 21:50:34 +00:00
DataStoreGetListener_onDataStoreGet_method ,
2023-03-08 21:02:12 +00:00
( jstring ) nameStr ,
( jbyteArray ) bufferObj ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onDataStoreGet " ) ;
return - 106 ;
}
2017-07-12 20:12:45 +00:00
LOGV ( " onDataStoreGet returned %d " , retval ) ;
if ( retval > 0 )
{
2023-03-07 21:50:34 +00:00
if ( retval > bufferLength ) {
LOGE ( " retval > bufferLength. retval: %d, bufferLength: %u " , retval , bufferLength ) ;
return - 107 ;
}
2017-07-12 20:12:45 +00:00
void * data = env - > GetPrimitiveArrayCritical ( bufferObj , NULL ) ;
memcpy ( buffer , data , retval ) ;
env - > ReleasePrimitiveArrayCritical ( bufferObj , data , 0 ) ;
}
return retval ;
2015-04-23 02:19:45 +00:00
}
2023-03-07 21:50:34 +00:00
/**
* The function must return zero on success and may return any error code
* on failure . Note that success does not ( of course ) guarantee packet
* delivery . It only means that the packet appears to have been sent .
*/
2015-11-03 03:18:55 +00:00
int WirePacketSendFunction ( ZT_Node * node ,
void * userData ,
2017-03-29 00:49:00 +00:00
void * threadData ,
2017-07-12 18:34:53 +00:00
int64_t localSocket ,
2015-09-26 20:47:55 +00:00
const struct sockaddr_storage * remoteAddress ,
2015-04-25 02:43:17 +00:00
const void * buffer ,
2015-11-15 01:40:17 +00:00
unsigned int bufferSize ,
unsigned int ttl )
2015-04-23 02:19:45 +00:00
{
2023-03-07 21:50:34 +00:00
LOGV ( " WirePacketSendFunction(% " PRId64 " , %p, %p, %u, %u) " , localSocket , remoteAddress , buffer , bufferSize , ttl ) ;
2015-04-23 02:19:45 +00:00
JniRef * ref = ( JniRef * ) userData ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
2015-04-23 02:19:45 +00:00
assert ( ref - > node = = node ) ;
2023-03-07 21:50:34 +00:00
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
return - 100 ;
}
2015-04-23 02:19:45 +00:00
2018-02-12 17:29:44 +00:00
if ( ref - > packetSender = = NULL ) {
LOGE ( " packetSender is NULL " ) ;
2023-03-07 21:50:34 +00:00
return - 101 ;
2018-02-12 17:29:44 +00:00
}
2015-04-28 01:38:13 +00:00
2023-03-07 21:50:34 +00:00
//
// may be NULL
//
jobject remoteAddressObj = newInetSocketAddress ( env , * remoteAddress ) ;
if ( env - > ExceptionCheck ( ) ) {
return - 102 ;
2015-04-25 02:43:17 +00:00
}
2023-03-07 21:50:34 +00:00
const unsigned char * bytes = static_cast < const unsigned char * > ( buffer ) ;
jbyteArray bufferObj = newByteArray ( env , bytes , bufferSize ) ;
if ( env - > ExceptionCheck ( ) | | bufferObj = = NULL )
2015-04-25 02:43:17 +00:00
{
2023-03-07 21:50:34 +00:00
return - 103 ;
}
2023-03-08 21:02:12 +00:00
int retval = env - > CallIntMethod ( ref - > packetSender , PacketSender_onSendPacketRequested_method , ( jlong ) localSocket , ( jobject ) remoteAddressObj , ( jbyteArray ) bufferObj , ( jint ) 0 ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onSendPacketRequested " ) ;
return - 104 ;
2015-04-25 02:43:17 +00:00
}
2015-05-28 03:42:54 +00:00
2015-06-10 02:38:05 +00:00
LOGV ( " JNI Packet Sender returned: %d " , retval ) ;
2015-05-28 03:42:54 +00:00
return retval ;
2015-04-23 02:19:45 +00:00
}
2023-03-07 21:50:34 +00:00
/**
* This function must return nonzero ( true ) if the path should be used .
*/
2017-03-29 19:52:29 +00:00
int PathCheckFunction ( ZT_Node * node ,
void * userPtr ,
void * threadPtr ,
uint64_t address ,
2017-07-12 18:34:53 +00:00
int64_t localSocket ,
2017-03-29 19:52:29 +00:00
const struct sockaddr_storage * remoteAddress )
{
2023-03-07 21:50:34 +00:00
LOGV ( " PathCheckFunction " ) ;
2017-03-29 19:52:29 +00:00
JniRef * ref = ( JniRef * ) userPtr ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
2017-03-29 19:52:29 +00:00
assert ( ref - > node = = node ) ;
if ( ref - > pathChecker = = NULL ) {
return true ;
}
2023-03-07 21:50:34 +00:00
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
2017-03-29 19:52:29 +00:00
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
2017-03-29 19:52:29 +00:00
return true ;
}
2022-11-30 17:44:32 +00:00
//
2023-03-07 21:50:34 +00:00
// may be NULL
2022-11-30 17:44:32 +00:00
//
2023-03-07 21:50:34 +00:00
jobject remoteAddressObj = newInetSocketAddress ( env , * remoteAddress ) ;
if ( env - > ExceptionCheck ( ) ) {
return true ;
}
2017-03-29 19:52:29 +00:00
2023-03-08 21:02:12 +00:00
jboolean ret = env - > CallBooleanMethod ( ref - > pathChecker , PathChecker_onPathCheck_method , ( jlong ) address , ( jlong ) localSocket , ( jobject ) remoteAddressObj ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling onPathCheck " ) ;
return true ;
2017-03-29 19:52:29 +00:00
}
2023-03-07 21:50:34 +00:00
return ret ;
2017-03-29 19:52:29 +00:00
}
2023-03-07 21:50:34 +00:00
/**
* It must return a nonzero ( true ) value if the result buffer has been filled with an address .
*/
2017-03-29 19:52:29 +00:00
int PathLookupFunction ( ZT_Node * node ,
void * userPtr ,
void * threadPtr ,
uint64_t address ,
int ss_family ,
struct sockaddr_storage * result )
{
2023-03-07 21:50:34 +00:00
LOGV ( " PathLookupFunction " ) ;
2017-03-29 19:52:29 +00:00
JniRef * ref = ( JniRef * ) userPtr ;
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
2017-03-29 19:52:29 +00:00
assert ( ref - > node = = node ) ;
if ( ref - > pathChecker = = NULL ) {
return false ;
}
2023-03-07 21:50:34 +00:00
JNIEnv * env ;
GETENV ( env , ref - > jvm ) ;
2017-03-29 19:52:29 +00:00
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unhandled pending exception " ) ;
2017-03-29 19:52:29 +00:00
return false ;
}
2023-03-07 21:50:34 +00:00
//
// may be NULL
//
2023-03-08 21:02:12 +00:00
jobject sockAddressObject = env - > CallObjectMethod ( ref - > pathChecker , PathChecker_onPathLookup_method , ( jlong ) address , ( jint ) ss_family ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Unable to call onPathLookup implementation " ) ;
2017-03-29 19:52:29 +00:00
return false ;
}
if ( sockAddressObject = = NULL )
{
LOGE ( " Unable to call onPathLookup implementation " ) ;
return false ;
}
2023-03-07 21:50:34 +00:00
* result = fromSocketAddressObject ( env , sockAddressObject ) ;
if ( env - > ExceptionCheck ( ) | | isSocketAddressEmpty ( * result ) ) {
2017-03-29 19:52:29 +00:00
return false ;
}
2023-03-07 21:50:34 +00:00
return true ;
}
2017-03-29 19:52:29 +00:00
2023-03-07 21:50:34 +00:00
typedef std : : map < int64_t , JniRef * > NodeMap ;
NodeMap nodeMap ;
ZeroTier : : Mutex nodeMapMutex ;
2017-03-29 19:52:29 +00:00
2023-03-07 21:50:34 +00:00
bool isInited ( int64_t nodeId ) {
2017-03-29 19:52:29 +00:00
2023-03-07 21:50:34 +00:00
ZeroTier : : Mutex : : Lock lock ( nodeMapMutex ) ;
NodeMap : : iterator found = nodeMap . find ( nodeId ) ;
2017-03-29 19:52:29 +00:00
2023-03-07 21:50:34 +00:00
if ( found = = nodeMap . end ( ) ) {
//
// not in map yet, or has been removed from map
//
2017-03-29 19:52:29 +00:00
return false ;
}
2023-03-07 21:50:34 +00:00
JniRef * ref = found - > second ;
2017-03-29 19:52:29 +00:00
2023-03-07 21:50:34 +00:00
assert ( ref ) ;
return ref - > inited ;
}
bool JniRef : : finishInitializing ( ) {
ZeroTier : : Mutex : : Lock lock ( nodeMapMutex ) ;
NodeMap : : iterator found = nodeMap . find ( id ) ;
if ( found ! = nodeMap . end ( ) ) {
//
// already in map
//
LOGE ( " Cannot finish initializing; node is already in map " ) ;
2017-03-29 19:52:29 +00:00
return false ;
}
2023-03-07 21:50:34 +00:00
nodeMap . insert ( std : : make_pair ( id , this ) ) ;
assert ( ! inited ) ;
inited = true ;
2017-03-29 19:52:29 +00:00
return true ;
}
2017-10-03 18:25:26 +00:00
ZT_Node * findNode ( int64_t nodeId )
2015-04-24 05:46:54 +00:00
{
2015-07-02 03:26:14 +00:00
ZeroTier : : Mutex : : Lock lock ( nodeMapMutex ) ;
2015-04-24 05:46:54 +00:00
NodeMap : : iterator found = nodeMap . find ( nodeId ) ;
2023-03-07 21:50:34 +00:00
assert ( found ! = nodeMap . end ( ) ) ;
JniRef * ref = found - > second ;
assert ( ref ) ;
return ref - > node ;
}
JniRef * removeRef ( int64_t nodeId ) {
ZeroTier : : Mutex : : Lock lock ( nodeMapMutex ) ;
NodeMap : : iterator found = nodeMap . find ( nodeId ) ;
if ( found = = nodeMap . end ( ) ) {
return nullptr ;
2015-04-24 05:46:54 +00:00
}
2023-03-07 21:50:34 +00:00
JniRef * ref = found - > second ;
assert ( ref ) ;
nodeMap . erase ( nodeId ) ;
return ref ;
2015-04-24 05:46:54 +00:00
}
2015-04-21 03:33:42 +00:00
}
2023-03-07 21:50:34 +00:00
# ifdef __cplusplus
extern " C " {
# endif
2017-01-13 19:36:48 +00:00
JNIEXPORT jint JNICALL JNI_OnLoad ( JavaVM * vm , void * reserved )
2015-05-02 18:20:21 +00:00
{
2023-03-07 21:50:34 +00:00
setupJNICache ( vm ) ;
2015-05-02 18:20:21 +00:00
return JNI_VERSION_1_6 ;
}
JNIEXPORT void JNICALL JNI_OnUnload ( JavaVM * vm , void * reserved )
{
2023-03-07 21:50:34 +00:00
teardownJNICache ( vm ) ;
2015-05-02 18:20:21 +00:00
}
2015-04-21 03:33:42 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-21 03:33:42 +00:00
* Method : node_init
2023-03-07 21:50:34 +00:00
* Signature : ( JLcom / zerotier / sdk / DataStoreGetListener ; Lcom / zerotier / sdk / DataStorePutListener ; Lcom / zerotier / sdk / PacketSender ; Lcom / zerotier / sdk / EventListener ; Lcom / zerotier / sdk / VirtualNetworkFrameListener ; Lcom / zerotier / sdk / VirtualNetworkConfigListener ; Lcom / zerotier / sdk / PathChecker ; ) Lcom / zerotier / sdk / ResultCode ;
2015-04-21 03:33:42 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init (
2023-03-07 21:50:34 +00:00
JNIEnv * env , jobject obj , jlong now , jobject dataStoreGetListener ,
jobject dataStorePutListener , jobject packetSender , jobject eventListener ,
jobject frameListener , jobject configListener ,
jobject pathChecker )
2015-04-21 03:33:42 +00:00
{
2015-09-24 23:21:36 +00:00
LOGV ( " Creating ZT_Node struct " ) ;
2023-03-07 21:50:34 +00:00
jobject resultObject = ResultCode_RESULT_OK_enum ;
JavaVM * vm ;
GETJAVAVM ( env , vm ) ;
assert ( dataStoreGetListener ! = NULL ) ;
assert ( dataStorePutListener ! = NULL ) ;
assert ( packetSender ! = NULL ) ;
assert ( frameListener ! = NULL ) ;
assert ( configListener ! = NULL ) ;
assert ( eventListener ! = NULL ) ;
//
// OPTIONAL, pathChecker may be NULL
//
// assert(pathChecker != NULL);
ZT_Node_Callbacks callbacks { } ;
callbacks . stateGetFunction = & StateGetFunction ;
callbacks . statePutFunction = & StatePutFunction ;
callbacks . wirePacketSendFunction = & WirePacketSendFunction ;
callbacks . virtualNetworkFrameFunction = & VirtualNetworkFrameFunctionCallback ;
callbacks . virtualNetworkConfigFunction = & VirtualNetworkConfigFunctionCallback ;
callbacks . eventCallback = & EventCallback ;
callbacks . pathCheckFunction = & PathCheckFunction ;
callbacks . pathLookupFunction = & PathLookupFunction ;
//
// a bit of a confusing dance here where ref and node both know about each other
//
JniRef * ref = new JniRef (
now ,
vm ,
dataStoreGetListener ,
dataStorePutListener ,
packetSender ,
eventListener ,
frameListener ,
configListener ,
pathChecker ) ;
2015-04-23 02:19:45 +00:00
2015-09-24 23:21:36 +00:00
ZT_Node * node ;
ZT_ResultCode rc = ZT_Node_new (
2015-04-26 03:47:21 +00:00
& node ,
ref ,
2017-03-29 00:49:00 +00:00
NULL ,
2023-03-07 21:50:34 +00:00
& callbacks ,
2017-10-03 18:25:26 +00:00
( int64_t ) now ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception creating Node " ) ;
2015-04-26 03:47:21 +00:00
2023-03-07 21:50:34 +00:00
if ( node )
{
ZT_Node_delete ( node ) ;
node = NULL ;
}
delete ref ;
ref = NULL ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2015-09-24 23:21:36 +00:00
if ( rc ! = ZT_RESULT_OK )
2015-04-26 03:47:21 +00:00
{
LOGE ( " Error creating Node: %d " , rc ) ;
resultObject = createResultObject ( env , rc ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) | | resultObject = = NULL ) {
return NULL ;
}
2015-04-26 03:47:21 +00:00
if ( node )
{
2015-09-24 23:21:36 +00:00
ZT_Node_delete ( node ) ;
2015-04-26 03:47:21 +00:00
node = NULL ;
}
delete ref ;
ref = NULL ;
return resultObject ;
}
2023-03-07 21:50:34 +00:00
//
// node is now updated
//
2015-04-26 03:47:21 +00:00
ref - > node = node ;
2023-03-07 21:50:34 +00:00
if ( ! ref - > finishInitializing ( ) ) {
LOGE ( " finishInitializing() failed " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2017-01-13 19:36:48 +00:00
2015-04-23 02:19:45 +00:00
return resultObject ;
2015-04-21 03:33:42 +00:00
}
2023-03-07 21:50:34 +00:00
/*
* Class : com_zerotier_sdk_Node
* Method : node_isInited
* Signature : ( J ) Z
*/
JNIEXPORT jboolean JNICALL Java_com_zerotier_sdk_Node_node_1isInited
( JNIEnv * env , jobject obj , jlong nodeId ) {
return isInited ( nodeId ) ;
}
2015-04-21 03:33:42 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-21 03:33:42 +00:00
* Method : node_delete
* Signature : ( J ) V
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete (
2015-04-24 06:09:30 +00:00
JNIEnv * env , jobject obj , jlong id )
2015-04-21 03:33:42 +00:00
{
2015-09-24 23:21:36 +00:00
LOGV ( " Destroying ZT_Node struct " ) ;
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-04-23 02:19:45 +00:00
2023-03-07 21:50:34 +00:00
JniRef * ref = removeRef ( nodeId ) ;
2015-07-02 03:26:14 +00:00
2023-03-07 21:50:34 +00:00
if ( ! ref ) {
return ;
}
2015-04-23 02:29:45 +00:00
2023-03-07 21:50:34 +00:00
ZT_Node_delete ( ref - > node ) ;
2015-04-23 02:29:45 +00:00
2023-03-07 21:50:34 +00:00
delete ref ;
2015-04-21 03:33:42 +00:00
}
2015-04-23 02:19:45 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 02:19:45 +00:00
* Method : processVirtualNetworkFrame
2015-05-02 23:54:00 +00:00
* Signature : ( JJJJJII [ B [ J ) Lcom / zerotier / sdk / ResultCode ;
2015-04-23 02:19:45 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame (
2017-01-13 19:36:48 +00:00
JNIEnv * env , jobject obj ,
jlong id ,
jlong in_now ,
2015-04-23 02:19:45 +00:00
jlong in_nwid ,
jlong in_sourceMac ,
jlong in_destMac ,
jint in_etherType ,
jint in_vlanId ,
jbyteArray in_frameData ,
jlongArray out_nextBackgroundTaskDeadline )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2017-01-13 19:36:48 +00:00
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 02:19:45 +00:00
unsigned int nbtd_len = env - > GetArrayLength ( out_nextBackgroundTaskDeadline ) ;
if ( nbtd_len < 1 )
{
// array for next background task length has 0 elements!
2023-03-07 21:50:34 +00:00
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
2015-04-23 02:19:45 +00:00
}
2017-10-03 18:25:26 +00:00
int64_t now = ( int64_t ) in_now ;
2015-04-23 02:19:45 +00:00
uint64_t nwid = ( uint64_t ) in_nwid ;
uint64_t sourceMac = ( uint64_t ) in_sourceMac ;
uint64_t destMac = ( uint64_t ) in_destMac ;
unsigned int etherType = ( unsigned int ) in_etherType ;
unsigned int vlanId = ( unsigned int ) in_vlanId ;
unsigned int frameLength = env - > GetArrayLength ( in_frameData ) ;
2015-06-10 06:12:44 +00:00
void * frameData = env - > GetPrimitiveArrayCritical ( in_frameData , NULL ) ;
2023-03-07 21:50:34 +00:00
//
// need local copy of frameData because arbitrary code may run in ZT_Node_processVirtualNetworkFrame and no other JNI work may happen between GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical
//
2015-06-10 06:12:44 +00:00
void * localData = malloc ( frameLength ) ;
memcpy ( localData , frameData , frameLength ) ;
env - > ReleasePrimitiveArrayCritical ( in_frameData , frameData , 0 ) ;
2015-04-23 02:19:45 +00:00
2017-10-03 18:25:26 +00:00
int64_t nextBackgroundTaskDeadline = 0 ;
2015-04-23 02:19:45 +00:00
2015-09-24 23:21:36 +00:00
ZT_ResultCode rc = ZT_Node_processVirtualNetworkFrame (
2015-04-23 02:19:45 +00:00
node ,
2017-03-29 00:49:00 +00:00
NULL ,
2015-04-23 02:19:45 +00:00
now ,
nwid ,
sourceMac ,
destMac ,
etherType ,
vlanId ,
2015-06-10 06:12:44 +00:00
( const void * ) localData ,
2015-04-23 02:19:45 +00:00
frameLength ,
& nextBackgroundTaskDeadline ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_processVirtualNetworkFrame " ) ;
free ( localData ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
if ( rc ! = ZT_RESULT_OK ) {
LOGE ( " ZT_Node_processVirtualNetworkFrame returned: %d " , rc ) ;
}
free ( localData ) ;
2015-04-23 02:19:45 +00:00
2015-06-10 06:12:44 +00:00
jlong * outDeadline = ( jlong * ) env - > GetPrimitiveArrayCritical ( out_nextBackgroundTaskDeadline , NULL ) ;
outDeadline [ 0 ] = ( jlong ) nextBackgroundTaskDeadline ;
env - > ReleasePrimitiveArrayCritical ( out_nextBackgroundTaskDeadline , outDeadline , 0 ) ;
2015-04-23 02:19:45 +00:00
return createResultObject ( env , rc ) ;
}
2015-04-21 03:33:42 +00:00
2015-04-23 03:21:12 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 03:21:12 +00:00
* Method : processWirePacket
2023-03-07 21:50:34 +00:00
* Signature : ( JJJLjava / net / InetSocketAddress ; [ B [ J ) Lcom / zerotier / sdk / ResultCode ;
2015-04-23 03:21:12 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket (
2017-01-13 19:36:48 +00:00
JNIEnv * env , jobject obj ,
2015-04-23 03:21:12 +00:00
jlong id ,
2017-01-13 19:36:48 +00:00
jlong in_now ,
2017-07-12 18:34:53 +00:00
jlong in_localSocket ,
2015-04-23 03:21:12 +00:00
jobject in_remoteAddress ,
jbyteArray in_packetData ,
jlongArray out_nextBackgroundTaskDeadline )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 03:21:12 +00:00
2017-07-12 18:34:53 +00:00
unsigned int nbtd_len = ( unsigned int ) env - > GetArrayLength ( out_nextBackgroundTaskDeadline ) ;
2015-04-23 03:21:12 +00:00
if ( nbtd_len < 1 )
{
2015-06-04 04:29:07 +00:00
LOGE ( " nbtd_len < 1 " ) ;
2023-03-07 21:50:34 +00:00
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
2015-04-23 03:21:12 +00:00
}
2017-10-03 18:25:26 +00:00
int64_t now = ( int64_t ) in_now ;
2015-04-23 03:21:12 +00:00
2023-03-07 21:50:34 +00:00
sockaddr_storage remoteAddress = fromSocketAddressObject ( env , in_remoteAddress ) ;
if ( env - > ExceptionCheck ( ) | | isSocketAddressEmpty ( remoteAddress ) ) {
return NULL ;
2015-04-23 03:21:12 +00:00
}
2017-07-12 18:34:53 +00:00
unsigned int packetLength = ( unsigned int ) env - > GetArrayLength ( in_packetData ) ;
2015-07-02 03:26:14 +00:00
if ( packetLength = = 0 )
{
LOGE ( " Empty packet?!? " ) ;
2023-03-07 21:50:34 +00:00
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
2015-07-02 03:26:14 +00:00
}
2015-06-10 06:12:44 +00:00
void * packetData = env - > GetPrimitiveArrayCritical ( in_packetData , NULL ) ;
2023-03-07 21:50:34 +00:00
//
// need local copy of packetData because arbitrary code may run in ZT_Node_processWirePacket and no other JNI work may happen between GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical
//
2015-06-10 06:12:44 +00:00
void * localData = malloc ( packetLength ) ;
memcpy ( localData , packetData , packetLength ) ;
env - > ReleasePrimitiveArrayCritical ( in_packetData , packetData , 0 ) ;
2015-04-23 03:21:12 +00:00
2017-10-03 18:25:26 +00:00
int64_t nextBackgroundTaskDeadline = 0 ;
2015-04-23 03:21:12 +00:00
2015-09-24 23:21:36 +00:00
ZT_ResultCode rc = ZT_Node_processWirePacket (
2015-04-23 03:21:12 +00:00
node ,
2017-03-29 00:49:00 +00:00
NULL ,
2015-04-23 03:21:12 +00:00
now ,
2017-07-12 18:34:53 +00:00
in_localSocket ,
2015-04-23 03:21:12 +00:00
& remoteAddress ,
2015-06-10 06:12:44 +00:00
localData ,
2015-04-23 03:21:12 +00:00
packetLength ,
& nextBackgroundTaskDeadline ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_processWirePacket " ) ;
free ( localData ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2017-01-13 19:36:48 +00:00
if ( rc ! = ZT_RESULT_OK )
2015-06-04 04:29:07 +00:00
{
2015-09-26 20:47:55 +00:00
LOGE ( " ZT_Node_processWirePacket returned: %d " , rc ) ;
2015-06-04 04:29:07 +00:00
}
2015-04-23 03:21:12 +00:00
2015-06-10 06:12:44 +00:00
free ( localData ) ;
2015-04-23 03:21:12 +00:00
2015-06-10 06:12:44 +00:00
jlong * outDeadline = ( jlong * ) env - > GetPrimitiveArrayCritical ( out_nextBackgroundTaskDeadline , NULL ) ;
outDeadline [ 0 ] = ( jlong ) nextBackgroundTaskDeadline ;
env - > ReleasePrimitiveArrayCritical ( out_nextBackgroundTaskDeadline , outDeadline , 0 ) ;
2015-04-23 03:21:12 +00:00
2015-04-30 02:29:35 +00:00
return createResultObject ( env , rc ) ;
2015-04-23 03:21:12 +00:00
}
2015-04-23 03:25:35 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 03:25:35 +00:00
* Method : processBackgroundTasks
2015-05-02 23:54:00 +00:00
* Signature : ( JJ [ J ) Lcom / zerotier / sdk / ResultCode ;
2015-04-23 03:25:35 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks (
2017-01-13 19:36:48 +00:00
JNIEnv * env , jobject obj ,
2015-04-23 03:25:35 +00:00
jlong id ,
jlong in_now ,
jlongArray out_nextBackgroundTaskDeadline )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 03:25:35 +00:00
unsigned int nbtd_len = env - > GetArrayLength ( out_nextBackgroundTaskDeadline ) ;
if ( nbtd_len < 1 )
{
2023-03-07 21:50:34 +00:00
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
2015-04-23 03:25:35 +00:00
}
2017-10-03 18:25:26 +00:00
int64_t now = ( int64_t ) in_now ;
int64_t nextBackgroundTaskDeadline = 0 ;
2015-04-23 03:25:35 +00:00
2017-03-29 00:49:00 +00:00
ZT_ResultCode rc = ZT_Node_processBackgroundTasks ( node , NULL , now , & nextBackgroundTaskDeadline ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_processBackgroundTasks " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
if ( rc ! = ZT_RESULT_OK ) {
LOGE ( " ZT_Node_processBackgroundTasks returned: %d " , rc ) ;
}
2015-04-23 03:25:35 +00:00
2015-06-10 06:12:44 +00:00
jlong * outDeadline = ( jlong * ) env - > GetPrimitiveArrayCritical ( out_nextBackgroundTaskDeadline , NULL ) ;
2015-04-23 03:25:35 +00:00
outDeadline [ 0 ] = ( jlong ) nextBackgroundTaskDeadline ;
2015-06-10 06:12:44 +00:00
env - > ReleasePrimitiveArrayCritical ( out_nextBackgroundTaskDeadline , outDeadline , 0 ) ;
2015-04-23 03:25:35 +00:00
return createResultObject ( env , rc ) ;
}
2015-04-21 03:33:42 +00:00
2015-04-23 03:29:34 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 03:29:34 +00:00
* Method : join
2015-05-02 23:54:00 +00:00
* Signature : ( JJ ) Lcom / zerotier / sdk / ResultCode ;
2015-04-23 03:29:34 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join (
2015-04-24 06:09:30 +00:00
JNIEnv * env , jobject obj , jlong id , jlong in_nwid )
2015-04-23 03:29:34 +00:00
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 03:29:34 +00:00
uint64_t nwid = ( uint64_t ) in_nwid ;
2017-03-29 00:49:00 +00:00
ZT_ResultCode rc = ZT_Node_join ( node , nwid , NULL , NULL ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_join " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2015-04-23 03:29:34 +00:00
return createResultObject ( env , rc ) ;
}
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 03:29:34 +00:00
* Method : leave
2015-05-02 23:54:00 +00:00
* Signature : ( JJ ) Lcom / zerotier / sdk / ResultCode ;
2015-04-23 03:29:34 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave (
2015-04-24 06:09:30 +00:00
JNIEnv * env , jobject obj , jlong id , jlong in_nwid )
2015-04-23 03:29:34 +00:00
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 03:29:34 +00:00
uint64_t nwid = ( uint64_t ) in_nwid ;
2017-03-29 00:49:00 +00:00
ZT_ResultCode rc = ZT_Node_leave ( node , nwid , NULL , NULL ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_leave " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2017-01-13 19:36:48 +00:00
2015-04-23 03:29:34 +00:00
return createResultObject ( env , rc ) ;
}
2015-04-23 03:33:38 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 03:33:38 +00:00
* Method : multicastSubscribe
2015-05-02 23:54:00 +00:00
* Signature : ( JJJJ ) Lcom / zerotier / sdk / ResultCode ;
2015-04-23 03:33:38 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe (
2017-01-13 19:36:48 +00:00
JNIEnv * env , jobject obj ,
jlong id ,
2015-04-23 03:33:38 +00:00
jlong in_nwid ,
jlong in_multicastGroup ,
jlong in_multicastAdi )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 03:33:38 +00:00
uint64_t nwid = ( uint64_t ) in_nwid ;
uint64_t multicastGroup = ( uint64_t ) in_multicastGroup ;
2015-05-02 18:20:21 +00:00
unsigned long multicastAdi = ( unsigned long ) in_multicastAdi ;
2015-04-23 03:33:38 +00:00
2015-09-24 23:21:36 +00:00
ZT_ResultCode rc = ZT_Node_multicastSubscribe (
2017-03-29 00:49:00 +00:00
node , NULL , nwid , multicastGroup , multicastAdi ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_multicastSubscribe " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2015-04-23 03:33:38 +00:00
return createResultObject ( env , rc ) ;
}
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 03:33:38 +00:00
* Method : multicastUnsubscribe
2015-05-02 23:54:00 +00:00
* Signature : ( JJJJ ) Lcom / zerotier / sdk / ResultCode ;
2015-04-23 03:33:38 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe (
2017-01-13 19:36:48 +00:00
JNIEnv * env , jobject obj ,
jlong id ,
2015-04-23 03:33:38 +00:00
jlong in_nwid ,
jlong in_multicastGroup ,
jlong in_multicastAdi )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 03:33:38 +00:00
uint64_t nwid = ( uint64_t ) in_nwid ;
uint64_t multicastGroup = ( uint64_t ) in_multicastGroup ;
2015-05-02 19:05:40 +00:00
unsigned long multicastAdi = ( unsigned long ) in_multicastAdi ;
2015-04-23 03:33:38 +00:00
2015-09-24 23:21:36 +00:00
ZT_ResultCode rc = ZT_Node_multicastUnsubscribe (
2015-04-23 03:33:38 +00:00
node , nwid , multicastGroup , multicastAdi ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_multicastUnsubscribe " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2015-04-23 03:33:38 +00:00
return createResultObject ( env , rc ) ;
}
2017-03-29 20:29:02 +00:00
/*
* Class : com_zerotier_sdk_Node
* Method : orbit
* Signature : ( JJJ ) Lcom / zerotier / sdk / ResultCode ;
*/
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_orbit (
JNIEnv * env , jobject obj ,
jlong id ,
jlong in_moonWorldId ,
jlong in_moonSeed )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2017-03-29 20:29:02 +00:00
ZT_Node * node = findNode ( nodeId ) ;
uint64_t moonWorldId = ( uint64_t ) in_moonWorldId ;
uint64_t moonSeed = ( uint64_t ) in_moonSeed ;
ZT_ResultCode rc = ZT_Node_orbit ( node , NULL , moonWorldId , moonSeed ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_orbit " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2017-03-29 20:29:02 +00:00
return createResultObject ( env , rc ) ;
}
/*
* Class : com_zerotier_sdk_Node
* Method : deorbit
* Signature : ( JJ ) L / com / zerotier / sdk / ResultCode ;
*/
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit (
JNIEnv * env , jobject obj ,
jlong id ,
jlong in_moonWorldId )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2017-03-29 20:29:02 +00:00
ZT_Node * node = findNode ( nodeId ) ;
uint64_t moonWorldId = ( uint64_t ) in_moonWorldId ;
ZT_ResultCode rc = ZT_Node_deorbit ( node , NULL , moonWorldId ) ;
2023-03-07 21:50:34 +00:00
if ( env - > ExceptionCheck ( ) ) {
LOGE ( " Exception calling ZT_Node_deorbit " ) ;
return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum ;
}
2017-03-29 20:29:02 +00:00
return createResultObject ( env , rc ) ;
}
2015-04-23 04:29:45 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 04:30:37 +00:00
* Method : address
* Signature : ( J ) J
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address (
2015-04-24 06:09:30 +00:00
JNIEnv * env , jobject obj , jlong id )
2015-04-23 04:30:37 +00:00
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 04:30:37 +00:00
2015-09-24 23:21:36 +00:00
uint64_t address = ZT_Node_address ( node ) ;
2015-04-23 04:30:37 +00:00
return ( jlong ) address ;
}
2015-04-23 04:31:17 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 04:31:17 +00:00
* Method : status
2015-05-02 23:54:00 +00:00
* Signature : ( J ) Lcom / zerotier / sdk / NodeStatus ;
2015-04-23 04:31:17 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
2015-04-23 04:31:17 +00:00
( JNIEnv * env , jobject obj , jlong id )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 04:31:17 +00:00
2015-09-24 23:21:36 +00:00
ZT_NodeStatus nodeStatus ;
ZT_Node_status ( node , & nodeStatus ) ;
2015-04-23 04:31:17 +00:00
2023-03-07 21:50:34 +00:00
return newNodeStatus ( env , nodeStatus ) ;
2015-04-23 04:31:17 +00:00
}
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 04:31:17 +00:00
* Method : networkConfig
2023-03-07 21:50:34 +00:00
* Signature : ( JJ ) Lcom / zerotier / sdk / VirtualNetworkConfig ;
2015-04-23 04:31:17 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig (
2015-04-24 06:09:30 +00:00
JNIEnv * env , jobject obj , jlong id , jlong nwid )
2015-04-23 04:31:17 +00:00
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-23 04:31:17 +00:00
2015-09-24 23:21:36 +00:00
ZT_VirtualNetworkConfig * vnetConfig = ZT_Node_networkConfig ( node , nwid ) ;
2023-03-07 21:50:34 +00:00
if ( vnetConfig = = NULL ) {
LOGE ( " vnetConfig == NULL " ) ;
return NULL ;
}
2017-01-13 19:36:48 +00:00
2015-04-25 01:20:10 +00:00
jobject vnetConfigObject = newNetworkConfig ( env , * vnetConfig ) ;
2015-04-24 04:43:16 +00:00
2015-09-24 23:21:36 +00:00
ZT_Node_freeQueryResult ( node , vnetConfig ) ;
2015-04-24 05:48:56 +00:00
2015-04-25 01:20:10 +00:00
return vnetConfigObject ;
2015-04-23 04:31:17 +00:00
}
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-23 04:29:45 +00:00
* Method : version
2023-03-07 21:50:34 +00:00
* Signature : ( ) Lcom / zerotier / sdk / Version ;
2015-04-23 04:29:45 +00:00
*/
2015-05-02 23:54:00 +00:00
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version (
2015-04-24 06:09:30 +00:00
JNIEnv * env , jobject obj )
2015-04-23 04:29:45 +00:00
{
int major = 0 ;
int minor = 0 ;
int revision = 0 ;
2016-07-08 03:07:07 +00:00
ZT_version ( & major , & minor , & revision ) ;
2015-04-23 04:29:45 +00:00
2016-07-08 03:07:07 +00:00
return newVersion ( env , major , minor , revision ) ;
2015-04-23 04:29:45 +00:00
}
2015-04-23 03:29:34 +00:00
2015-04-24 06:08:28 +00:00
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2015-04-24 06:08:28 +00:00
* Method : peers
2015-05-29 03:36:54 +00:00
* Signature : ( J ) [ Lcom / zerotier / sdk / Peer ;
2015-04-24 06:08:28 +00:00
*/
2015-05-29 03:36:54 +00:00
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers (
2015-04-24 06:08:28 +00:00
JNIEnv * env , jobject obj , jlong id )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-25 01:06:26 +00:00
2015-09-24 23:21:36 +00:00
ZT_PeerList * peerList = ZT_Node_peers ( node ) ;
2017-01-13 19:36:48 +00:00
2015-04-25 01:06:26 +00:00
if ( peerList = = NULL )
{
2015-09-24 23:21:36 +00:00
LOGE ( " ZT_Node_peers returned NULL " ) ;
2015-05-29 03:36:54 +00:00
return NULL ;
}
2023-03-07 21:50:34 +00:00
jobjectArray peerArrayObj = newPeerArray ( env , peerList - > peers , peerList - > peerCount ) ;
2015-04-25 01:06:26 +00:00
2015-09-24 23:21:36 +00:00
ZT_Node_freeQueryResult ( node , peerList ) ;
2015-04-25 01:20:10 +00:00
peerList = NULL ;
2015-05-29 03:36:54 +00:00
return peerArrayObj ;
2015-04-24 06:08:28 +00:00
}
/*
2015-05-02 23:54:00 +00:00
* Class : com_zerotier_sdk_Node
2023-03-07 21:50:34 +00:00
* Method : networkConfigs
2015-05-29 03:36:54 +00:00
* Signature : ( J ) [ Lcom / zerotier / sdk / VirtualNetworkConfig ;
2015-04-24 06:08:28 +00:00
*/
2023-03-07 21:50:34 +00:00
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networkConfigs (
2015-04-24 06:08:28 +00:00
JNIEnv * env , jobject obj , jlong id )
{
2017-10-03 18:25:26 +00:00
int64_t nodeId = ( int64_t ) id ;
2015-09-24 23:21:36 +00:00
ZT_Node * node = findNode ( nodeId ) ;
2015-04-25 01:20:10 +00:00
2015-09-24 23:21:36 +00:00
ZT_VirtualNetworkList * networkList = ZT_Node_networks ( node ) ;
2015-04-25 01:20:10 +00:00
if ( networkList = = NULL )
{
2023-03-07 21:50:34 +00:00
LOGE ( " ZT_Node_networks returned NULL " ) ;
2015-04-25 01:20:10 +00:00
return NULL ;
}
2023-03-07 21:50:34 +00:00
jobjectArray networkListObject = newVirtualNetworkConfigArray ( env , networkList - > networks , networkList - > networkCount ) ;
2015-04-25 01:20:10 +00:00
2015-09-24 23:21:36 +00:00
ZT_Node_freeQueryResult ( node , networkList ) ;
2015-04-25 01:20:10 +00:00
return networkListObject ;
2015-04-24 06:08:28 +00:00
}
2015-04-21 03:33:42 +00:00
# ifdef __cplusplus
} // extern "C"
2023-03-07 21:50:34 +00:00
# endif