mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-25 15:41:05 +00:00
Merge branch 'android-jni-dev' into edge
This commit is contained in:
commit
7756b5bf1c
BIN
artwork/ZeroTierIcon512x512.png
Normal file
BIN
artwork/ZeroTierIcon512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
@ -59,6 +59,7 @@ set(src_files
|
|||||||
|
|
||||||
set(include_dirs
|
set(include_dirs
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../include/
|
${CMAKE_CURRENT_SOURCE_DIR}/../include/
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../node/
|
||||||
${Java_INCLUDE_DIRS})
|
${Java_INCLUDE_DIRS})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<project default="build" name="ZeroTierOneSDK" basedir=".">
|
<project default="build_jar" name="ZeroTierOneSDK" basedir=".">
|
||||||
<property environment="env"/>
|
<property environment="env"/>
|
||||||
|
|
||||||
<condition property="isWindows">
|
<condition property="isWindows">
|
||||||
@ -9,7 +9,7 @@
|
|||||||
<os family="mac"/>
|
<os family="mac"/>
|
||||||
</condition>
|
</condition>
|
||||||
|
|
||||||
<target name="clean">
|
<target name="clean_ant">
|
||||||
<delete dir="bin" failonerror="false"/>
|
<delete dir="bin" failonerror="false"/>
|
||||||
<delete dir="classes" failonerror="false"/>
|
<delete dir="classes" failonerror="false"/>
|
||||||
<delete dir="build_win32" failonerror="false"/>
|
<delete dir="build_win32" failonerror="false"/>
|
||||||
@ -24,6 +24,10 @@
|
|||||||
<echo message="os.arch = ${os.arch}"/>
|
<echo message="os.arch = ${os.arch}"/>
|
||||||
<echo message="ant.java.version = ${ant.java.version}"/>
|
<echo message="ant.java.version = ${ant.java.version}"/>
|
||||||
<echo message="java.version = ${java.version}"/>
|
<echo message="java.version = ${java.version}"/>
|
||||||
|
<echo message="ndk.loc = ${env.NDK_BUILD_LOC}"/>
|
||||||
|
<echo message="sdk.loc = ${env.ANDROID_PLATFORM}"/>
|
||||||
|
<echo message="user.dir = ${user.dir}"/>
|
||||||
|
<echo message="zt1.dir = ${env.ZT}"/>
|
||||||
<mkdir dir="bin"/>
|
<mkdir dir="bin"/>
|
||||||
<mkdir dir="classes"/>
|
<mkdir dir="classes"/>
|
||||||
<javac srcdir="src"
|
<javac srcdir="src"
|
||||||
@ -36,20 +40,30 @@
|
|||||||
|
|
||||||
<target name="build_android">
|
<target name="build_android">
|
||||||
<exec dir="jni" executable="${env.NDK_BUILD_LOC}" failonerror="true">
|
<exec dir="jni" executable="${env.NDK_BUILD_LOC}" failonerror="true">
|
||||||
<arg value="ZT1=${user.dir}/../"/>
|
<arg value="ZT1=${env.ZT}"/>
|
||||||
<arg value="V=1"/>
|
<arg value="V=1"/>
|
||||||
|
<!-- <arg value="NDK_DEBUG=1"/> -->
|
||||||
</exec>
|
</exec>
|
||||||
<copy file="libs/armeabi/libZeroTierOneJNI.so"
|
|
||||||
tofile="${user.dir}/classes/lib/armeabi/libZeroTierOneJNI.so"
|
|
||||||
overwrite="true"/>
|
|
||||||
<copy file="libs/arm64-v8a/libZeroTierOneJNI.so"
|
<copy file="libs/arm64-v8a/libZeroTierOneJNI.so"
|
||||||
tofile="${user.dir}/classes/lib/arm64-v8a/libZeroTierOneJNI.so"
|
tofile="classes/lib/arm64-v8a/libZeroTierOneJNI.so"
|
||||||
|
overwrite="true"/>
|
||||||
|
<copy file="libs/armeabi/libZeroTierOneJNI.so"
|
||||||
|
tofile="classes/lib/armeabi/libZeroTierOneJNI.so"
|
||||||
overwrite="true"/>
|
overwrite="true"/>
|
||||||
<copy file="libs/armeabi-v7a/libZeroTierOneJNI.so"
|
<copy file="libs/armeabi-v7a/libZeroTierOneJNI.so"
|
||||||
tofile="${user.dir}/classes/lib/armeabi-v7a/libZeroTierOneJNI.so"
|
tofile="classes/lib/armeabi-v7a/libZeroTierOneJNI.so"
|
||||||
|
overwrite="true"/>
|
||||||
|
<copy file="libs/mips/libZeroTierOneJNI.so"
|
||||||
|
tofile="classes/lib/mips/libZeroTierOneJNI.so"
|
||||||
|
overwrite="true"/>
|
||||||
|
<copy file="libs/mips64/libZeroTierOneJNI.so"
|
||||||
|
tofile="classes/lib/mips64/libZeroTierOne.so"
|
||||||
overwrite="true"/>
|
overwrite="true"/>
|
||||||
<copy file="libs/x86/libZeroTierOneJNI.so"
|
<copy file="libs/x86/libZeroTierOneJNI.so"
|
||||||
tofile="${user.dir}/classes/lib/x86/libZeroTierOneJNI.so"
|
tofile="classes/lib/x86/libZeroTierOneJNI.so"
|
||||||
|
overwrite="true"/>
|
||||||
|
<copy file="libs/x86_64/libZeroTierOneJNI.so"
|
||||||
|
tofile="classes/lib/x86_64/libZeroTierOneJNI.so"
|
||||||
overwrite="true"/>
|
overwrite="true"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
@ -91,7 +105,7 @@
|
|||||||
overwrite="true"/>
|
overwrite="true"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="build" depends="build_java,build_android,windows,mac">
|
<target name="build_jar" depends="build_java,build_android,windows,mac">
|
||||||
<jar destfile="bin/ZeroTierOneSDK.jar" basedir="classes"/>
|
<jar destfile="bin/ZeroTierOneSDK.jar" basedir="classes"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
@ -101,23 +115,4 @@
|
|||||||
<javadoc sourcepath="src/"
|
<javadoc sourcepath="src/"
|
||||||
destdir="doc/"/>
|
destdir="doc/"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- <target name="android" depends="build">
|
|
||||||
<echo message="OS is Android, installing..."/>
|
|
||||||
<copy file="libs/armeabi/libZeroTierOneJNI.so"
|
|
||||||
tofile="${aproj_loc}/libs/armeabi/libZeroTierOneJNI.so"
|
|
||||||
overwrite="true"/>
|
|
||||||
<copy file="libs/arm64-v8a/libZeroTierOneJNI.so"
|
|
||||||
tofile="${aproj_loc}/libs/arm64-v8a/libZeroTierOneJNI.so"
|
|
||||||
overwrite="true"/>
|
|
||||||
<copy file="libs/armeabi-v7a/libZeroTierOneJNI.so"
|
|
||||||
tofile="${aproj_loc}/libs/armeabi-v7a/libZeroTierOneJNI.so"
|
|
||||||
overwrite="true"/>
|
|
||||||
<copy file="libs/x86/libZeroTierOneJNI.so"
|
|
||||||
tofile="${aproj_loc}/libs/x86/libZeroTierOneJNI.so"
|
|
||||||
overwrite="true"/>
|
|
||||||
<copy file="bin/ZeroTierOneSDK.jar"
|
|
||||||
tofile="${aproj_loc}/libs/ZeroTierOneSDK.jar"
|
|
||||||
overwrite="true"/>
|
|
||||||
</target> -->
|
|
||||||
</project>
|
</project>
|
@ -4,7 +4,9 @@ include $(CLEAR_VARS)
|
|||||||
|
|
||||||
LOCAL_MODULE := ZeroTierOneJNI
|
LOCAL_MODULE := ZeroTierOneJNI
|
||||||
LOCAL_C_INCLUDES := $(ZT1)/include
|
LOCAL_C_INCLUDES := $(ZT1)/include
|
||||||
|
LOCAL_C_INCLUDES += $(ZT1)/node
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
# LOCAL_CFLAGS := -g
|
||||||
|
|
||||||
# ZeroTierOne SDK source files
|
# ZeroTierOne SDK source files
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
@ -13,7 +15,6 @@ LOCAL_SRC_FILES := \
|
|||||||
$(ZT1)/ext/http-parser/http_parser.c \
|
$(ZT1)/ext/http-parser/http_parser.c \
|
||||||
$(ZT1)/node/C25519.cpp \
|
$(ZT1)/node/C25519.cpp \
|
||||||
$(ZT1)/node/CertificateOfMembership.cpp \
|
$(ZT1)/node/CertificateOfMembership.cpp \
|
||||||
$(ZT1)/node/Defaults.cpp \
|
|
||||||
$(ZT1)/node/Dictionary.cpp \
|
$(ZT1)/node/Dictionary.cpp \
|
||||||
$(ZT1)/node/Identity.cpp \
|
$(ZT1)/node/Identity.cpp \
|
||||||
$(ZT1)/node/IncomingPacket.cpp \
|
$(ZT1)/node/IncomingPacket.cpp \
|
||||||
@ -24,6 +25,7 @@ LOCAL_SRC_FILES := \
|
|||||||
$(ZT1)/node/Node.cpp \
|
$(ZT1)/node/Node.cpp \
|
||||||
$(ZT1)/node/OutboundMulticast.cpp \
|
$(ZT1)/node/OutboundMulticast.cpp \
|
||||||
$(ZT1)/node/Packet.cpp \
|
$(ZT1)/node/Packet.cpp \
|
||||||
|
$(ZT1)/node/Path.cpp \
|
||||||
$(ZT1)/node/Peer.cpp \
|
$(ZT1)/node/Peer.cpp \
|
||||||
$(ZT1)/node/Poly1305.cpp \
|
$(ZT1)/node/Poly1305.cpp \
|
||||||
$(ZT1)/node/Salsa20.cpp \
|
$(ZT1)/node/Salsa20.cpp \
|
||||||
@ -39,6 +41,6 @@ LOCAL_SRC_FILES := \
|
|||||||
LOCAL_SRC_FILES += \
|
LOCAL_SRC_FILES += \
|
||||||
com_zerotierone_sdk_Node.cpp \
|
com_zerotierone_sdk_Node.cpp \
|
||||||
ZT_jniutils.cpp \
|
ZT_jniutils.cpp \
|
||||||
ZT_jnicache.cpp
|
ZT_jnilookup.cpp
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
@ -1,4 +1,5 @@
|
|||||||
APP_ABI := armeabi armeabi-v7a arm64-v8a x86
|
NDK_TOOLCHAIN_VERSION := clang
|
||||||
APP_STL := gnustl_static
|
APP_STL := c++_static
|
||||||
APP_CPPFLAGS += -Wall -fPIE -fstack-protector -fexceptions -DZT_TRACE
|
APP_CPPFLAGS := -O3 -fPIC -fPIE -fvectorize -Wall -fstack-protector -fexceptions -fno-strict-aliasing -Wno-deprecated-register -DZT_NO_TYPE_PUNNING=1
|
||||||
|
APP_PLATFORM := android-14
|
||||||
|
APP_ABI := all
|
||||||
|
@ -1,242 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ZT_jnicache.h"
|
|
||||||
#include "ZT_jniutils.h"
|
|
||||||
|
|
||||||
JniCache::JniCache()
|
|
||||||
: m_jvm(NULL)
|
|
||||||
, m_classes()
|
|
||||||
, m_fields()
|
|
||||||
, m_staticFields()
|
|
||||||
, m_methods()
|
|
||||||
, m_staticMethods()
|
|
||||||
{
|
|
||||||
LOGV("JNI Cache Created");
|
|
||||||
}
|
|
||||||
|
|
||||||
JniCache::JniCache(JavaVM *jvm)
|
|
||||||
: m_jvm(jvm)
|
|
||||||
, m_classes()
|
|
||||||
, m_fields()
|
|
||||||
, m_staticFields()
|
|
||||||
, m_methods()
|
|
||||||
, m_staticMethods()
|
|
||||||
{
|
|
||||||
LOGV("JNI Cache Created");
|
|
||||||
}
|
|
||||||
|
|
||||||
JniCache::~JniCache()
|
|
||||||
{
|
|
||||||
LOGV("JNI Cache Destroyed");
|
|
||||||
clearCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
void JniCache::clearCache()
|
|
||||||
{
|
|
||||||
if(m_jvm)
|
|
||||||
{
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(ClassMap::iterator iter = m_classes.begin(), end = m_classes.end();
|
|
||||||
iter != end; ++iter)
|
|
||||||
{
|
|
||||||
env->DeleteGlobalRef(iter->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_classes.clear();
|
|
||||||
m_fields.clear();
|
|
||||||
m_staticFields.clear();
|
|
||||||
m_methods.clear();
|
|
||||||
m_staticMethods.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void JniCache::setJavaVM(JavaVM *jvm)
|
|
||||||
{
|
|
||||||
LOGV("Assigned JVM to object");
|
|
||||||
m_jvm = jvm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jclass JniCache::findClass(const std::string &name)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ClassMap::iterator found = m_classes.find(name);
|
|
||||||
|
|
||||||
if(found == m_classes.end())
|
|
||||||
{
|
|
||||||
// get the class from the JVM
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
LOGE("Error retreiving JNI Environment");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jclass localCls = env->FindClass(name.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
LOGE("Error finding class: %s", name.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jclass cls = (jclass)env->NewGlobalRef(localCls);
|
|
||||||
|
|
||||||
m_classes.insert(std::make_pair(name, cls));
|
|
||||||
|
|
||||||
return cls;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGV("Returning cached %s", name.c_str());
|
|
||||||
return found->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jmethodID JniCache::findMethod(jclass cls, const std::string &methodName, const std::string &methodSig)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
std::string id = methodName + methodSig;
|
|
||||||
|
|
||||||
MethodMap::iterator found = m_methods.find(id);
|
|
||||||
if(found == m_methods.end())
|
|
||||||
{
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodSig.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_methods.insert(std::make_pair(id, mid));
|
|
||||||
|
|
||||||
return mid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID JniCache::findStaticMethod(jclass cls, const std::string &methodName, const std::string &methodSig)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
std::string id = methodName + methodSig;
|
|
||||||
|
|
||||||
MethodMap::iterator found = m_staticMethods.find(id);
|
|
||||||
if(found == m_staticMethods.end())
|
|
||||||
{
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodSig.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_staticMethods.insert(std::make_pair(id, mid));
|
|
||||||
|
|
||||||
return mid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID JniCache::findField(jclass cls, const std::string &fieldName, const std::string &typeStr)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
std::string id = fieldName + typeStr;
|
|
||||||
|
|
||||||
FieldMap::iterator found = m_fields.find(id);
|
|
||||||
if(found == m_fields.end())
|
|
||||||
{
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID fid = env->GetFieldID(cls, fieldName.c_str(), typeStr.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_fields.insert(std::make_pair(id, fid));
|
|
||||||
|
|
||||||
return fid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID JniCache::findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
std::string id = fieldName + typeStr;
|
|
||||||
|
|
||||||
FieldMap::iterator found = m_staticFields.find(id);
|
|
||||||
if(found == m_staticFields.end())
|
|
||||||
{
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID fid = env->GetStaticFieldID(cls, fieldName.c_str(), typeStr.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_staticFields.insert(std::make_pair(id, fid));
|
|
||||||
|
|
||||||
return fid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found->second;
|
|
||||||
}
|
|
158
java/jni/ZT_jnilookup.cpp
Normal file
158
java/jni/ZT_jnilookup.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* 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/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ZT_jnilookup.h"
|
||||||
|
#include "ZT_jniutils.h"
|
||||||
|
|
||||||
|
JniLookup::JniLookup()
|
||||||
|
: m_jvm(NULL)
|
||||||
|
{
|
||||||
|
LOGV("JNI Cache Created");
|
||||||
|
}
|
||||||
|
|
||||||
|
JniLookup::JniLookup(JavaVM *jvm)
|
||||||
|
: m_jvm(jvm)
|
||||||
|
{
|
||||||
|
LOGV("JNI Cache Created");
|
||||||
|
}
|
||||||
|
|
||||||
|
JniLookup::~JniLookup()
|
||||||
|
{
|
||||||
|
LOGV("JNI Cache Destroyed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JniLookup::setJavaVM(JavaVM *jvm)
|
||||||
|
{
|
||||||
|
LOGV("Assigned JVM to object");
|
||||||
|
m_jvm = jvm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
jclass JniLookup::findClass(const std::string &name)
|
||||||
|
{
|
||||||
|
if(!m_jvm)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// get the class from the JVM
|
||||||
|
JNIEnv *env = NULL;
|
||||||
|
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
||||||
|
{
|
||||||
|
LOGE("Error retreiving JNI Environment");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass cls = env->FindClass(name.c_str());
|
||||||
|
if(env->ExceptionCheck())
|
||||||
|
{
|
||||||
|
LOGE("Error finding class: %s", name.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cls;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
jmethodID JniLookup::findMethod(jclass cls, const std::string &methodName, const std::string &methodSig)
|
||||||
|
{
|
||||||
|
if(!m_jvm)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
JNIEnv *env = NULL;
|
||||||
|
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodSig.c_str());
|
||||||
|
if(env->ExceptionCheck())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID JniLookup::findStaticMethod(jclass cls, const std::string &methodName, const std::string &methodSig)
|
||||||
|
{
|
||||||
|
if(!m_jvm)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
JNIEnv *env = NULL;
|
||||||
|
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodSig.c_str());
|
||||||
|
if(env->ExceptionCheck())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID JniLookup::findField(jclass cls, const std::string &fieldName, const std::string &typeStr)
|
||||||
|
{
|
||||||
|
if(!m_jvm)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
JNIEnv *env = NULL;
|
||||||
|
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID fid = env->GetFieldID(cls, fieldName.c_str(), typeStr.c_str());
|
||||||
|
if(env->ExceptionCheck())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fid;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID JniLookup::findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr)
|
||||||
|
{
|
||||||
|
if(!m_jvm)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
JNIEnv *env = NULL;
|
||||||
|
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID fid = env->GetStaticFieldID(cls, fieldName.c_str(), typeStr.c_str());
|
||||||
|
if(env->ExceptionCheck())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fid;
|
||||||
|
}
|
@ -25,8 +25,8 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZT_JNICACHE_H_
|
#ifndef ZT_JNILOOKUP_H_
|
||||||
#define ZT_JNICACHE_H_
|
#define ZT_JNILOOKUP_H_
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -34,14 +34,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class JniCache {
|
class JniLookup {
|
||||||
public:
|
public:
|
||||||
JniCache();
|
JniLookup();
|
||||||
JniCache(JavaVM *jvm);
|
JniLookup(JavaVM *jvm);
|
||||||
~JniCache();
|
~JniLookup();
|
||||||
|
|
||||||
void setJavaVM(JavaVM *jvm);
|
void setJavaVM(JavaVM *jvm);
|
||||||
void clearCache();
|
|
||||||
|
|
||||||
jclass findClass(const std::string &name);
|
jclass findClass(const std::string &name);
|
||||||
jmethodID findMethod(jclass cls, const std::string &methodName, const std::string &methodSig);
|
jmethodID findMethod(jclass cls, const std::string &methodName, const std::string &methodSig);
|
||||||
@ -49,17 +48,7 @@ public:
|
|||||||
jfieldID findField(jclass cls, const std::string &fieldName, const std::string &typeStr);
|
jfieldID findField(jclass cls, const std::string &fieldName, const std::string &typeStr);
|
||||||
jfieldID findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr);
|
jfieldID findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr);
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, jmethodID> MethodMap;
|
|
||||||
typedef std::map<std::string, jfieldID> FieldMap;
|
|
||||||
typedef std::map<std::string, jclass> ClassMap;
|
|
||||||
|
|
||||||
JavaVM *m_jvm;
|
JavaVM *m_jvm;
|
||||||
ClassMap m_classes;
|
|
||||||
FieldMap m_fields;
|
|
||||||
FieldMap m_staticFields;
|
|
||||||
MethodMap m_methods;
|
|
||||||
MethodMap m_staticMethods;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,9 +1,9 @@
|
|||||||
#include "ZT_jniutils.h"
|
#include "ZT_jniutils.h"
|
||||||
#include "ZT_jnicache.h"
|
#include "ZT_jnilookup.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
extern JniCache cache;
|
extern JniLookup lookup;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -15,7 +15,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code)
|
|||||||
|
|
||||||
jobject resultObject = NULL;
|
jobject resultObject = NULL;
|
||||||
|
|
||||||
resultClass = cache.findClass("com/zerotier/sdk/ResultCode");
|
resultClass = lookup.findClass("com/zerotier/sdk/ResultCode");
|
||||||
if(resultClass == NULL)
|
if(resultClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Couldnt find ResultCode class");
|
LOGE("Couldnt find ResultCode class");
|
||||||
@ -48,7 +48,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID enumField = cache.findStaticField(resultClass, fieldName.c_str(), "Lcom/zerotier/sdk/ResultCode;");
|
jfieldID enumField = lookup.findStaticField(resultClass, fieldName.c_str(), "Lcom/zerotier/sdk/ResultCode;");
|
||||||
if(env->ExceptionCheck() || enumField == NULL)
|
if(env->ExceptionCheck() || enumField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error on FindStaticField");
|
LOGE("Error on FindStaticField");
|
||||||
@ -68,7 +68,7 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status)
|
|||||||
{
|
{
|
||||||
jobject statusObject = NULL;
|
jobject statusObject = NULL;
|
||||||
|
|
||||||
jclass statusClass = cache.findClass("com/zerotier/sdk/VirtualNetworkStatus");
|
jclass statusClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkStatus");
|
||||||
if(statusClass == NULL)
|
if(statusClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL; // exception thrown
|
return NULL; // exception thrown
|
||||||
@ -97,7 +97,7 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID enumField = cache.findStaticField(statusClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkStatus;");
|
jfieldID enumField = lookup.findStaticField(statusClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkStatus;");
|
||||||
|
|
||||||
statusObject = env->GetStaticObjectField(statusClass, enumField);
|
statusObject = env->GetStaticObjectField(statusClass, enumField);
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ jobject createEvent(JNIEnv *env, ZT_Event event)
|
|||||||
jclass eventClass = NULL;
|
jclass eventClass = NULL;
|
||||||
jobject eventObject = NULL;
|
jobject eventObject = NULL;
|
||||||
|
|
||||||
eventClass = cache.findClass("com/zerotier/sdk/Event");
|
eventClass = lookup.findClass("com/zerotier/sdk/Event");
|
||||||
if(eventClass == NULL)
|
if(eventClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -133,21 +133,12 @@ jobject createEvent(JNIEnv *env, ZT_Event event)
|
|||||||
case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION:
|
case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION:
|
||||||
fieldName = "EVENT_FATAL_ERROR_IDENTITY_COLLISION";
|
fieldName = "EVENT_FATAL_ERROR_IDENTITY_COLLISION";
|
||||||
break;
|
break;
|
||||||
case ZT_EVENT_SAW_MORE_RECENT_VERSION:
|
|
||||||
fieldName = "EVENT_SAW_MORE_RECENT_VERSION";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_AUTHENTICATION_FAILURE:
|
|
||||||
fieldName = "EVENT_AUTHENTICATION_FAILURE";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_INVALID_PACKET:
|
|
||||||
fieldName = "EVENT_INVALID_PACKET";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_TRACE:
|
case ZT_EVENT_TRACE:
|
||||||
fieldName = "EVENT_TRACE";
|
fieldName = "EVENT_TRACE";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID enumField = cache.findStaticField(eventClass, fieldName.c_str(), "Lcom/zerotier/sdk/Event;");
|
jfieldID enumField = lookup.findStaticField(eventClass, fieldName.c_str(), "Lcom/zerotier/sdk/Event;");
|
||||||
|
|
||||||
eventObject = env->GetStaticObjectField(eventClass, enumField);
|
eventObject = env->GetStaticObjectField(eventClass, enumField);
|
||||||
|
|
||||||
@ -159,7 +150,7 @@ jobject createPeerRole(JNIEnv *env, ZT_PeerRole role)
|
|||||||
jclass peerRoleClass = NULL;
|
jclass peerRoleClass = NULL;
|
||||||
jobject peerRoleObject = NULL;
|
jobject peerRoleObject = NULL;
|
||||||
|
|
||||||
peerRoleClass = cache.findClass("com/zerotier/sdk/PeerRole");
|
peerRoleClass = lookup.findClass("com/zerotier/sdk/PeerRole");
|
||||||
if(peerRoleClass == NULL)
|
if(peerRoleClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -171,15 +162,15 @@ jobject createPeerRole(JNIEnv *env, ZT_PeerRole role)
|
|||||||
case ZT_PEER_ROLE_LEAF:
|
case ZT_PEER_ROLE_LEAF:
|
||||||
fieldName = "PEER_ROLE_LEAF";
|
fieldName = "PEER_ROLE_LEAF";
|
||||||
break;
|
break;
|
||||||
case ZT_PEER_ROLE_HUB:
|
case ZT_PEER_ROLE_RELAY:
|
||||||
fieldName = "PEER_ROLE_HUB";
|
fieldName = "PEER_ROLE_RELAY";
|
||||||
break;
|
break;
|
||||||
case ZT_PEER_ROLE_ROOTSERVER:
|
case ZT_PEER_ROLE_ROOT:
|
||||||
fieldName = "PEER_ROLE_ROOTSERVER";
|
fieldName = "PEER_ROLE_ROOTS";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID enumField = cache.findStaticField(peerRoleClass, fieldName.c_str(), "Lcom/zerotier/sdk/PeerRole;");
|
jfieldID enumField = lookup.findStaticField(peerRoleClass, fieldName.c_str(), "Lcom/zerotier/sdk/PeerRole;");
|
||||||
|
|
||||||
peerRoleObject = env->GetStaticObjectField(peerRoleClass, enumField);
|
peerRoleObject = env->GetStaticObjectField(peerRoleClass, enumField);
|
||||||
|
|
||||||
@ -191,7 +182,7 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type)
|
|||||||
jclass vntypeClass = NULL;
|
jclass vntypeClass = NULL;
|
||||||
jobject vntypeObject = NULL;
|
jobject vntypeObject = NULL;
|
||||||
|
|
||||||
vntypeClass = cache.findClass("com/zerotier/sdk/VirtualNetworkType");
|
vntypeClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkType");
|
||||||
if(env->ExceptionCheck() || vntypeClass == NULL)
|
if(env->ExceptionCheck() || vntypeClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -208,7 +199,7 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID enumField = cache.findStaticField(vntypeClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkType;");
|
jfieldID enumField = lookup.findStaticField(vntypeClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkType;");
|
||||||
vntypeObject = env->GetStaticObjectField(vntypeClass, enumField);
|
vntypeObject = env->GetStaticObjectField(vntypeClass, enumField);
|
||||||
return vntypeObject;
|
return vntypeObject;
|
||||||
}
|
}
|
||||||
@ -218,7 +209,7 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfig
|
|||||||
jclass vnetConfigOpClass = NULL;
|
jclass vnetConfigOpClass = NULL;
|
||||||
jobject vnetConfigOpObject = NULL;
|
jobject vnetConfigOpObject = NULL;
|
||||||
|
|
||||||
vnetConfigOpClass = cache.findClass("com/zerotier/sdk/VirtualNetworkConfigOperation");
|
vnetConfigOpClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfigOperation");
|
||||||
if(env->ExceptionCheck() || vnetConfigOpClass == NULL)
|
if(env->ExceptionCheck() || vnetConfigOpClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -241,7 +232,7 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfig
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID enumField = cache.findStaticField(vnetConfigOpClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;");
|
jfieldID enumField = lookup.findStaticField(vnetConfigOpClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;");
|
||||||
vnetConfigOpObject = env->GetStaticObjectField(vnetConfigOpClass, enumField);
|
vnetConfigOpObject = env->GetStaticObjectField(vnetConfigOpClass, enumField);
|
||||||
return vnetConfigOpObject;
|
return vnetConfigOpObject;
|
||||||
}
|
}
|
||||||
@ -252,14 +243,14 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr)
|
|||||||
jclass inetAddressClass = NULL;
|
jclass inetAddressClass = NULL;
|
||||||
jmethodID inetAddress_getByAddress = NULL;
|
jmethodID inetAddress_getByAddress = NULL;
|
||||||
|
|
||||||
inetAddressClass = cache.findClass("java/net/InetAddress");
|
inetAddressClass = lookup.findClass("java/net/InetAddress");
|
||||||
if(env->ExceptionCheck() || inetAddressClass == NULL)
|
if(env->ExceptionCheck() || inetAddressClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding InetAddress class");
|
LOGE("Error finding InetAddress class");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inetAddress_getByAddress = cache.findStaticMethod(
|
inetAddress_getByAddress = lookup.findStaticMethod(
|
||||||
inetAddressClass, "getByAddress", "([B)Ljava/net/InetAddress;");
|
inetAddressClass, "getByAddress", "([B)Ljava/net/InetAddress;");
|
||||||
if(env->ExceptionCheck() || inetAddress_getByAddress == NULL)
|
if(env->ExceptionCheck() || inetAddress_getByAddress == NULL)
|
||||||
{
|
{
|
||||||
@ -315,7 +306,7 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr)
|
|||||||
jclass inetSocketAddressClass = NULL;
|
jclass inetSocketAddressClass = NULL;
|
||||||
jmethodID inetSocketAddress_constructor = NULL;
|
jmethodID inetSocketAddress_constructor = NULL;
|
||||||
|
|
||||||
inetSocketAddressClass = cache.findClass("java/net/InetSocketAddress");
|
inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
|
||||||
if(env->ExceptionCheck() || inetSocketAddressClass == NULL)
|
if(env->ExceptionCheck() || inetSocketAddressClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding InetSocketAddress Class");
|
LOGE("Error finding InetSocketAddress Class");
|
||||||
@ -330,7 +321,7 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inetSocketAddress_constructor = cache.findMethod(
|
inetSocketAddress_constructor = lookup.findMethod(
|
||||||
inetSocketAddressClass, "<init>", "(Ljava/net/InetAddress;I)V");
|
inetSocketAddressClass, "<init>", "(Ljava/net/InetAddress;I)V");
|
||||||
if(env->ExceptionCheck() || inetSocketAddress_constructor == NULL)
|
if(env->ExceptionCheck() || inetSocketAddress_constructor == NULL)
|
||||||
{
|
{
|
||||||
@ -343,18 +334,18 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr)
|
|||||||
{
|
{
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
{
|
{
|
||||||
LOGD("IPV6 Address");
|
LOGV("IPV6 Address");
|
||||||
sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr;
|
sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr;
|
||||||
port = ntohs(ipv6->sin6_port);
|
port = ntohs(ipv6->sin6_port);
|
||||||
LOGD("Port %d", port);
|
LOGV("Port %d", port);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
{
|
||||||
LOGD("IPV4 Address");
|
LOGV("IPV4 Address");
|
||||||
sockaddr_in *ipv4 = (sockaddr_in*)&addr;
|
sockaddr_in *ipv4 = (sockaddr_in*)&addr;
|
||||||
port = ntohs(ipv4->sin_port);
|
port = ntohs(ipv4->sin_port);
|
||||||
LOGD("Port: %d", port);
|
LOGV("Port: %d", port);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -380,13 +371,13 @@ jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc)
|
|||||||
jfieldID macField = NULL;
|
jfieldID macField = NULL;
|
||||||
jfieldID adiField = NULL;
|
jfieldID adiField = NULL;
|
||||||
|
|
||||||
multicastGroupClass = cache.findClass("com/zerotier/sdk/MulticastGroup");
|
multicastGroupClass = lookup.findClass("com/zerotier/sdk/MulticastGroup");
|
||||||
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
multicastGroup_constructor = cache.findMethod(
|
multicastGroup_constructor = lookup.findMethod(
|
||||||
multicastGroupClass, "<init>", "()V");
|
multicastGroupClass, "<init>", "()V");
|
||||||
if(env->ExceptionCheck() || multicastGroup_constructor == NULL)
|
if(env->ExceptionCheck() || multicastGroup_constructor == NULL)
|
||||||
{
|
{
|
||||||
@ -399,13 +390,13 @@ jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
macField = cache.findField(multicastGroupClass, "mac", "J");
|
macField = lookup.findField(multicastGroupClass, "mac", "J");
|
||||||
if(env->ExceptionCheck() || macField == NULL)
|
if(env->ExceptionCheck() || macField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
adiField = cache.findField(multicastGroupClass, "adi", "J");
|
adiField = lookup.findField(multicastGroupClass, "adi", "J");
|
||||||
if(env->ExceptionCheck() || adiField == NULL)
|
if(env->ExceptionCheck() || adiField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -425,62 +416,54 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp)
|
|||||||
jfieldID addressField = NULL;
|
jfieldID addressField = NULL;
|
||||||
jfieldID lastSendField = NULL;
|
jfieldID lastSendField = NULL;
|
||||||
jfieldID lastReceiveField = NULL;
|
jfieldID lastReceiveField = NULL;
|
||||||
jfieldID fixedField = NULL;
|
|
||||||
jfieldID activeField = NULL;
|
jfieldID activeField = NULL;
|
||||||
jfieldID preferredField = NULL;
|
jfieldID preferredField = NULL;
|
||||||
|
|
||||||
jmethodID ppp_constructor = NULL;
|
jmethodID ppp_constructor = NULL;
|
||||||
|
|
||||||
pppClass = cache.findClass("com/zerotier/sdk/PeerPhysicalPath");
|
pppClass = lookup.findClass("com/zerotier/sdk/PeerPhysicalPath");
|
||||||
if(env->ExceptionCheck() || pppClass == NULL)
|
if(env->ExceptionCheck() || pppClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding PeerPhysicalPath class");
|
LOGE("Error finding PeerPhysicalPath class");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addressField = cache.findField(pppClass, "address", "Ljava/net/InetSocketAddress;");
|
addressField = lookup.findField(pppClass, "address", "Ljava/net/InetSocketAddress;");
|
||||||
if(env->ExceptionCheck() || addressField == NULL)
|
if(env->ExceptionCheck() || addressField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding address field");
|
LOGE("Error finding address field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastSendField = cache.findField(pppClass, "lastSend", "J");
|
lastSendField = lookup.findField(pppClass, "lastSend", "J");
|
||||||
if(env->ExceptionCheck() || lastSendField == NULL)
|
if(env->ExceptionCheck() || lastSendField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding lastSend field");
|
LOGE("Error finding lastSend field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastReceiveField = cache.findField(pppClass, "lastReceive", "J");
|
lastReceiveField = lookup.findField(pppClass, "lastReceive", "J");
|
||||||
if(env->ExceptionCheck() || lastReceiveField == NULL)
|
if(env->ExceptionCheck() || lastReceiveField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding lastReceive field");
|
LOGE("Error finding lastReceive field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedField = cache.findField(pppClass, "fixed", "Z");
|
activeField = lookup.findField(pppClass, "active", "Z");
|
||||||
if(env->ExceptionCheck() || fixedField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding fixed field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
activeField = cache.findField(pppClass, "active", "Z");
|
|
||||||
if(env->ExceptionCheck() || activeField == NULL)
|
if(env->ExceptionCheck() || activeField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding active field");
|
LOGE("Error finding active field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
preferredField = cache.findField(pppClass, "preferred", "Z");
|
preferredField = lookup.findField(pppClass, "preferred", "Z");
|
||||||
if(env->ExceptionCheck() || preferredField == NULL)
|
if(env->ExceptionCheck() || preferredField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding preferred field");
|
LOGE("Error finding preferred field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ppp_constructor = cache.findMethod(pppClass, "<init>", "()V");
|
ppp_constructor = lookup.findMethod(pppClass, "<init>", "()V");
|
||||||
if(env->ExceptionCheck() || ppp_constructor == NULL)
|
if(env->ExceptionCheck() || ppp_constructor == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding PeerPhysicalPath constructor");
|
LOGE("Error finding PeerPhysicalPath constructor");
|
||||||
@ -503,7 +486,6 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp)
|
|||||||
env->SetObjectField(pppObject, addressField, addressObject);
|
env->SetObjectField(pppObject, addressField, addressObject);
|
||||||
env->SetLongField(pppObject, lastSendField, ppp.lastSend);
|
env->SetLongField(pppObject, lastSendField, ppp.lastSend);
|
||||||
env->SetLongField(pppObject, lastReceiveField, ppp.lastReceive);
|
env->SetLongField(pppObject, lastReceiveField, ppp.lastReceive);
|
||||||
env->SetBooleanField(pppObject, fixedField, ppp.fixed);
|
|
||||||
env->SetBooleanField(pppObject, activeField, ppp.active);
|
env->SetBooleanField(pppObject, activeField, ppp.active);
|
||||||
env->SetBooleanField(pppObject, preferredField, ppp.preferred);
|
env->SetBooleanField(pppObject, preferredField, ppp.preferred);
|
||||||
|
|
||||||
@ -532,77 +514,77 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer)
|
|||||||
|
|
||||||
jmethodID peer_constructor = NULL;
|
jmethodID peer_constructor = NULL;
|
||||||
|
|
||||||
peerClass = cache.findClass("com/zerotier/sdk/Peer");
|
peerClass = lookup.findClass("com/zerotier/sdk/Peer");
|
||||||
if(env->ExceptionCheck() || peerClass == NULL)
|
if(env->ExceptionCheck() || peerClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding Peer class");
|
LOGE("Error finding Peer class");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addressField = cache.findField(peerClass, "address", "J");
|
addressField = lookup.findField(peerClass, "address", "J");
|
||||||
if(env->ExceptionCheck() || addressField == NULL)
|
if(env->ExceptionCheck() || addressField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding address field of Peer object");
|
LOGE("Error finding address field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastUnicastFrameField = cache.findField(peerClass, "lastUnicastFrame", "J");
|
lastUnicastFrameField = lookup.findField(peerClass, "lastUnicastFrame", "J");
|
||||||
if(env->ExceptionCheck() || lastUnicastFrameField == NULL)
|
if(env->ExceptionCheck() || lastUnicastFrameField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding lastUnicastFrame field of Peer object");
|
LOGE("Error finding lastUnicastFrame field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastMulticastFrameField = cache.findField(peerClass, "lastMulticastFrame", "J");
|
lastMulticastFrameField = lookup.findField(peerClass, "lastMulticastFrame", "J");
|
||||||
if(env->ExceptionCheck() || lastMulticastFrameField == NULL)
|
if(env->ExceptionCheck() || lastMulticastFrameField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding lastMulticastFrame field of Peer object");
|
LOGE("Error finding lastMulticastFrame field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
versionMajorField = cache.findField(peerClass, "versionMajor", "I");
|
versionMajorField = lookup.findField(peerClass, "versionMajor", "I");
|
||||||
if(env->ExceptionCheck() || versionMajorField == NULL)
|
if(env->ExceptionCheck() || versionMajorField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding versionMajor field of Peer object");
|
LOGE("Error finding versionMajor field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
versionMinorField = cache.findField(peerClass, "versionMinor", "I");
|
versionMinorField = lookup.findField(peerClass, "versionMinor", "I");
|
||||||
if(env->ExceptionCheck() || versionMinorField == NULL)
|
if(env->ExceptionCheck() || versionMinorField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding versionMinor field of Peer object");
|
LOGE("Error finding versionMinor field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
versionRevField = cache.findField(peerClass, "versionRev", "I");
|
versionRevField = lookup.findField(peerClass, "versionRev", "I");
|
||||||
if(env->ExceptionCheck() || versionRevField == NULL)
|
if(env->ExceptionCheck() || versionRevField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding versionRev field of Peer object");
|
LOGE("Error finding versionRev field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
latencyField = cache.findField(peerClass, "latency", "I");
|
latencyField = lookup.findField(peerClass, "latency", "I");
|
||||||
if(env->ExceptionCheck() || latencyField == NULL)
|
if(env->ExceptionCheck() || latencyField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding latency field of Peer object");
|
LOGE("Error finding latency field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
roleField = cache.findField(peerClass, "role", "Lcom/zerotier/sdk/PeerRole;");
|
roleField = lookup.findField(peerClass, "role", "Lcom/zerotier/sdk/PeerRole;");
|
||||||
if(env->ExceptionCheck() || roleField == NULL)
|
if(env->ExceptionCheck() || roleField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding role field of Peer object");
|
LOGE("Error finding role field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pathsField = cache.findField(peerClass, "paths", "[Lcom/zerotier/sdk/PeerPhysicalPath;");
|
pathsField = lookup.findField(peerClass, "paths", "[Lcom/zerotier/sdk/PeerPhysicalPath;");
|
||||||
if(env->ExceptionCheck() || pathsField == NULL)
|
if(env->ExceptionCheck() || pathsField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding paths field of Peer object");
|
LOGE("Error finding paths field of Peer object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_constructor = cache.findMethod(peerClass, "<init>", "()V");
|
peer_constructor = lookup.findMethod(peerClass, "<init>", "()V");
|
||||||
if(env->ExceptionCheck() || peer_constructor == NULL)
|
if(env->ExceptionCheck() || peer_constructor == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding Peer constructor");
|
LOGE("Error finding Peer constructor");
|
||||||
@ -625,7 +607,7 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer)
|
|||||||
env->SetIntField(peerObject, latencyField, peer.latency);
|
env->SetIntField(peerObject, latencyField, peer.latency);
|
||||||
env->SetObjectField(peerObject, roleField, createPeerRole(env, peer.role));
|
env->SetObjectField(peerObject, roleField, createPeerRole(env, peer.role));
|
||||||
|
|
||||||
jclass peerPhysicalPathClass = cache.findClass("com/zerotier/sdk/PeerPhysicalPath");
|
jclass peerPhysicalPathClass = lookup.findClass("com/zerotier/sdk/PeerPhysicalPath");
|
||||||
if(env->ExceptionCheck() || peerPhysicalPathClass == NULL)
|
if(env->ExceptionCheck() || peerPhysicalPathClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding PeerPhysicalPath class");
|
LOGE("Error finding PeerPhysicalPath class");
|
||||||
@ -675,14 +657,14 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig)
|
|||||||
jfieldID multicastSubscriptionsField = NULL;
|
jfieldID multicastSubscriptionsField = NULL;
|
||||||
jfieldID assignedAddressesField = NULL;
|
jfieldID assignedAddressesField = NULL;
|
||||||
|
|
||||||
vnetConfigClass = cache.findClass("com/zerotier/sdk/VirtualNetworkConfig");
|
vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig");
|
||||||
if(vnetConfigClass == NULL)
|
if(vnetConfigClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Couldn't find com.zerotier.sdk.VirtualNetworkConfig");
|
LOGE("Couldn't find com.zerotier.sdk.VirtualNetworkConfig");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
vnetConfig_constructor = cache.findMethod(
|
vnetConfig_constructor = lookup.findMethod(
|
||||||
vnetConfigClass, "<init>", "()V");
|
vnetConfigClass, "<init>", "()V");
|
||||||
if(env->ExceptionCheck() || vnetConfig_constructor == NULL)
|
if(env->ExceptionCheck() || vnetConfig_constructor == NULL)
|
||||||
{
|
{
|
||||||
@ -697,98 +679,98 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nwidField = cache.findField(vnetConfigClass, "nwid", "J");
|
nwidField = lookup.findField(vnetConfigClass, "nwid", "J");
|
||||||
if(env->ExceptionCheck() || nwidField == NULL)
|
if(env->ExceptionCheck() || nwidField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting nwid field");
|
LOGE("Error getting nwid field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
macField = cache.findField(vnetConfigClass, "mac", "J");
|
macField = lookup.findField(vnetConfigClass, "mac", "J");
|
||||||
if(env->ExceptionCheck() || macField == NULL)
|
if(env->ExceptionCheck() || macField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting mac field");
|
LOGE("Error getting mac field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nameField = cache.findField(vnetConfigClass, "name", "Ljava/lang/String;");
|
nameField = lookup.findField(vnetConfigClass, "name", "Ljava/lang/String;");
|
||||||
if(env->ExceptionCheck() || nameField == NULL)
|
if(env->ExceptionCheck() || nameField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting name field");
|
LOGE("Error getting name field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
statusField = cache.findField(vnetConfigClass, "status", "Lcom/zerotier/sdk/VirtualNetworkStatus;");
|
statusField = lookup.findField(vnetConfigClass, "status", "Lcom/zerotier/sdk/VirtualNetworkStatus;");
|
||||||
if(env->ExceptionCheck() || statusField == NULL)
|
if(env->ExceptionCheck() || statusField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting status field");
|
LOGE("Error getting status field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typeField = cache.findField(vnetConfigClass, "type", "Lcom/zerotier/sdk/VirtualNetworkType;");
|
typeField = lookup.findField(vnetConfigClass, "type", "Lcom/zerotier/sdk/VirtualNetworkType;");
|
||||||
if(env->ExceptionCheck() || typeField == NULL)
|
if(env->ExceptionCheck() || typeField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting type field");
|
LOGE("Error getting type field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtuField = cache.findField(vnetConfigClass, "mtu", "I");
|
mtuField = lookup.findField(vnetConfigClass, "mtu", "I");
|
||||||
if(env->ExceptionCheck() || mtuField == NULL)
|
if(env->ExceptionCheck() || mtuField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting mtu field");
|
LOGE("Error getting mtu field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dhcpField = cache.findField(vnetConfigClass, "dhcp", "Z");
|
dhcpField = lookup.findField(vnetConfigClass, "dhcp", "Z");
|
||||||
if(env->ExceptionCheck() || dhcpField == NULL)
|
if(env->ExceptionCheck() || dhcpField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting dhcp field");
|
LOGE("Error getting dhcp field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bridgeField = cache.findField(vnetConfigClass, "bridge", "Z");
|
bridgeField = lookup.findField(vnetConfigClass, "bridge", "Z");
|
||||||
if(env->ExceptionCheck() || bridgeField == NULL)
|
if(env->ExceptionCheck() || bridgeField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting bridge field");
|
LOGE("Error getting bridge field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcastEnabledField = cache.findField(vnetConfigClass, "broadcastEnabled", "Z");
|
broadcastEnabledField = lookup.findField(vnetConfigClass, "broadcastEnabled", "Z");
|
||||||
if(env->ExceptionCheck() || broadcastEnabledField == NULL)
|
if(env->ExceptionCheck() || broadcastEnabledField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting broadcastEnabled field");
|
LOGE("Error getting broadcastEnabled field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
portErrorField = cache.findField(vnetConfigClass, "portError", "I");
|
portErrorField = lookup.findField(vnetConfigClass, "portError", "I");
|
||||||
if(env->ExceptionCheck() || portErrorField == NULL)
|
if(env->ExceptionCheck() || portErrorField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting portError field");
|
LOGE("Error getting portError field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledField = cache.findField(vnetConfigClass, "enabled", "Z");
|
enabledField = lookup.findField(vnetConfigClass, "enabled", "Z");
|
||||||
if(env->ExceptionCheck() || enabledField == NULL)
|
if(env->ExceptionCheck() || enabledField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting enabled field");
|
LOGE("Error getting enabled field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
netconfRevisionField = cache.findField(vnetConfigClass, "netconfRevision", "J");
|
netconfRevisionField = lookup.findField(vnetConfigClass, "netconfRevision", "J");
|
||||||
if(env->ExceptionCheck() || netconfRevisionField == NULL)
|
if(env->ExceptionCheck() || netconfRevisionField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting netconfRevision field");
|
LOGE("Error getting netconfRevision field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
multicastSubscriptionsField = cache.findField(vnetConfigClass, "multicastSubscriptions", "[Lcom/zerotier/sdk/MulticastGroup;");
|
multicastSubscriptionsField = lookup.findField(vnetConfigClass, "multicastSubscriptions", "[Lcom/zerotier/sdk/MulticastGroup;");
|
||||||
if(env->ExceptionCheck() || multicastSubscriptionsField == NULL)
|
if(env->ExceptionCheck() || multicastSubscriptionsField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting multicastSubscriptions field");
|
LOGE("Error getting multicastSubscriptions field");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
assignedAddressesField = cache.findField(vnetConfigClass, "assignedAddresses", "[Ljava/net/InetSocketAddress;");
|
assignedAddressesField = lookup.findField(vnetConfigClass, "assignedAddresses", "[Ljava/net/InetSocketAddress;");
|
||||||
if(env->ExceptionCheck() || assignedAddressesField == NULL)
|
if(env->ExceptionCheck() || assignedAddressesField == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error getting assignedAddresses field");
|
LOGE("Error getting assignedAddresses field");
|
||||||
@ -818,13 +800,14 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig)
|
|||||||
}
|
}
|
||||||
env->SetObjectField(vnetConfigObj, typeField, typeObject);
|
env->SetObjectField(vnetConfigObj, typeField, typeObject);
|
||||||
|
|
||||||
env->SetIntField(vnetConfigObj, mtuField, vnetConfig.mtu);
|
env->SetIntField(vnetConfigObj, mtuField, (int)vnetConfig.mtu);
|
||||||
env->SetBooleanField(vnetConfigObj, dhcpField, vnetConfig.dhcp);
|
env->SetBooleanField(vnetConfigObj, dhcpField, vnetConfig.dhcp);
|
||||||
env->SetBooleanField(vnetConfigObj, bridgeField, vnetConfig.bridge);
|
env->SetBooleanField(vnetConfigObj, bridgeField, vnetConfig.bridge);
|
||||||
env->SetBooleanField(vnetConfigObj, broadcastEnabledField, vnetConfig.broadcastEnabled);
|
env->SetBooleanField(vnetConfigObj, broadcastEnabledField, vnetConfig.broadcastEnabled);
|
||||||
|
env->SetBooleanField(vnetConfigObj, enabledField, vnetConfig.enabled);
|
||||||
env->SetIntField(vnetConfigObj, portErrorField, vnetConfig.portError);
|
env->SetIntField(vnetConfigObj, portErrorField, vnetConfig.portError);
|
||||||
|
|
||||||
jclass multicastGroupClass = cache.findClass("com/zerotier/sdk/MulticastGroup");
|
jclass multicastGroupClass = lookup.findClass("com/zerotier/sdk/MulticastGroup");
|
||||||
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding MulticastGroup class");
|
LOGE("Error finding MulticastGroup class");
|
||||||
@ -849,7 +832,7 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig)
|
|||||||
}
|
}
|
||||||
env->SetObjectField(vnetConfigObj, multicastSubscriptionsField, mcastSubsArrayObj);
|
env->SetObjectField(vnetConfigObj, multicastSubscriptionsField, mcastSubsArrayObj);
|
||||||
|
|
||||||
jclass inetSocketAddressClass = cache.findClass("java/net/InetSocketAddress");
|
jclass inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
|
||||||
if(env->ExceptionCheck() || inetSocketAddressClass == NULL)
|
if(env->ExceptionCheck() || inetSocketAddressClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding InetSocketAddress class");
|
LOGE("Error finding InetSocketAddress class");
|
||||||
@ -886,13 +869,13 @@ jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags
|
|||||||
jclass versionClass = NULL;
|
jclass versionClass = NULL;
|
||||||
jmethodID versionConstructor = NULL;
|
jmethodID versionConstructor = NULL;
|
||||||
|
|
||||||
versionClass = cache.findClass("com/zerotier/sdk/Version");
|
versionClass = lookup.findClass("com/zerotier/sdk/Version");
|
||||||
if(env->ExceptionCheck() || versionClass == NULL)
|
if(env->ExceptionCheck() || versionClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
versionConstructor = cache.findMethod(
|
versionConstructor = lookup.findMethod(
|
||||||
versionClass, "<init>", "()V");
|
versionClass, "<init>", "()V");
|
||||||
if(env->ExceptionCheck() || versionConstructor == NULL)
|
if(env->ExceptionCheck() || versionConstructor == NULL)
|
||||||
{
|
{
|
||||||
@ -911,25 +894,25 @@ jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags
|
|||||||
jfieldID revisionField = NULL;
|
jfieldID revisionField = NULL;
|
||||||
jfieldID featureFlagsField = NULL;
|
jfieldID featureFlagsField = NULL;
|
||||||
|
|
||||||
majorField = cache.findField(versionClass, "major", "I");
|
majorField = lookup.findField(versionClass, "major", "I");
|
||||||
if(env->ExceptionCheck() || majorField == NULL)
|
if(env->ExceptionCheck() || majorField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
minorField = cache.findField(versionClass, "minor", "I");
|
minorField = lookup.findField(versionClass, "minor", "I");
|
||||||
if(env->ExceptionCheck() || minorField == NULL)
|
if(env->ExceptionCheck() || minorField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
revisionField = cache.findField(versionClass, "revision", "I");
|
revisionField = lookup.findField(versionClass, "revision", "I");
|
||||||
if(env->ExceptionCheck() || revisionField == NULL)
|
if(env->ExceptionCheck() || revisionField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
featureFlagsField = cache.findField(versionClass, "featureFlags", "J");
|
featureFlagsField = lookup.findField(versionClass, "featureFlags", "J");
|
||||||
if(env->ExceptionCheck() || featureFlagsField == NULL)
|
if(env->ExceptionCheck() || featureFlagsField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
@ -27,17 +27,18 @@
|
|||||||
|
|
||||||
#include "com_zerotierone_sdk_Node.h"
|
#include "com_zerotierone_sdk_Node.h"
|
||||||
#include "ZT_jniutils.h"
|
#include "ZT_jniutils.h"
|
||||||
#include "ZT_jnicache.h"
|
#include "ZT_jnilookup.h"
|
||||||
|
|
||||||
#include <ZeroTierOne.h>
|
#include <ZeroTierOne.h>
|
||||||
|
#include "Mutex.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// global static JNI Cache Object
|
// global static JNI Lookup Object
|
||||||
JniCache cache;
|
JniLookup lookup;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -92,7 +93,7 @@ namespace {
|
|||||||
enum ZT_VirtualNetworkConfigOperation operation,
|
enum ZT_VirtualNetworkConfigOperation operation,
|
||||||
const ZT_VirtualNetworkConfig *config)
|
const ZT_VirtualNetworkConfig *config)
|
||||||
{
|
{
|
||||||
LOGD("VritualNetworkConfigFunctionCallback");
|
LOGV("VritualNetworkConfigFunctionCallback");
|
||||||
JniRef *ref = (JniRef*)userData;
|
JniRef *ref = (JniRef*)userData;
|
||||||
JNIEnv *env = NULL;
|
JNIEnv *env = NULL;
|
||||||
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||||
@ -104,7 +105,7 @@ namespace {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID configListenerCallbackMethod = cache.findMethod(configListenerClass,
|
jmethodID configListenerCallbackMethod = lookup.findMethod(configListenerClass,
|
||||||
"onNetworkConfigurationUpdated",
|
"onNetworkConfigurationUpdated",
|
||||||
"(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I");
|
"(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I");
|
||||||
if(configListenerCallbackMethod == NULL)
|
if(configListenerCallbackMethod == NULL)
|
||||||
@ -133,7 +134,8 @@ namespace {
|
|||||||
(jlong)nwid, operationObject, networkConfigObject);
|
(jlong)nwid, operationObject, networkConfigObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualNetworkFrameFunctionCallback(ZT_Node *node,void *userData,
|
void VirtualNetworkFrameFunctionCallback(ZT_Node *node,
|
||||||
|
void *userData,
|
||||||
uint64_t nwid,
|
uint64_t nwid,
|
||||||
uint64_t sourceMac,
|
uint64_t sourceMac,
|
||||||
uint64_t destMac,
|
uint64_t destMac,
|
||||||
@ -142,7 +144,9 @@ namespace {
|
|||||||
const void *frameData,
|
const void *frameData,
|
||||||
unsigned int frameLength)
|
unsigned int frameLength)
|
||||||
{
|
{
|
||||||
LOGD("VirtualNetworkFrameFunctionCallback");
|
LOGV("VirtualNetworkFrameFunctionCallback");
|
||||||
|
unsigned char* local = (unsigned char*)frameData;
|
||||||
|
LOGV("Type Bytes: 0x%02x%02x", local[12], local[13]);
|
||||||
JniRef *ref = (JniRef*)userData;
|
JniRef *ref = (JniRef*)userData;
|
||||||
assert(ref->node == node);
|
assert(ref->node == node);
|
||||||
JNIEnv *env = NULL;
|
JNIEnv *env = NULL;
|
||||||
@ -156,7 +160,7 @@ namespace {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID frameListenerCallbackMethod = cache.findMethod(
|
jmethodID frameListenerCallbackMethod = lookup.findMethod(
|
||||||
frameListenerClass,
|
frameListenerClass,
|
||||||
"onVirtualNetworkFrame", "(JJJJJ[B)V");
|
"onVirtualNetworkFrame", "(JJJJJ[B)V");
|
||||||
if(env->ExceptionCheck() || frameListenerCallbackMethod == NULL)
|
if(env->ExceptionCheck() || frameListenerCallbackMethod == NULL)
|
||||||
@ -172,9 +176,9 @@ namespace {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
jbyte *data = env->GetByteArrayElements(dataArray, NULL);
|
void *data = env->GetPrimitiveArrayCritical(dataArray, NULL);
|
||||||
memcpy(data, frameData, frameLength);
|
memcpy(data, frameData, frameLength);
|
||||||
env->ReleaseByteArrayElements(dataArray, data, 0);
|
env->ReleasePrimitiveArrayCritical(dataArray, data, 0);
|
||||||
|
|
||||||
if(env->ExceptionCheck())
|
if(env->ExceptionCheck())
|
||||||
{
|
{
|
||||||
@ -186,11 +190,18 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EventCallback(ZT_Node *node,void *userData,enum ZT_Event event, const void *data)
|
void EventCallback(ZT_Node *node,
|
||||||
|
void *userData,
|
||||||
|
enum ZT_Event event,
|
||||||
|
const void *data)
|
||||||
{
|
{
|
||||||
LOGD("EventCallback");
|
LOGV("EventCallback");
|
||||||
JniRef *ref = (JniRef*)userData;
|
JniRef *ref = (JniRef*)userData;
|
||||||
assert(ref->node == node);
|
if(ref->node != node && event != ZT_EVENT_UP)
|
||||||
|
{
|
||||||
|
LOGE("Nodes not equal. ref->node %p, node %p. Event: %d", ref->node, node, event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
JNIEnv *env = NULL;
|
JNIEnv *env = NULL;
|
||||||
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||||
|
|
||||||
@ -202,7 +213,7 @@ namespace {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID onEventMethod = cache.findMethod(eventListenerClass,
|
jmethodID onEventMethod = lookup.findMethod(eventListenerClass,
|
||||||
"onEvent", "(Lcom/zerotier/sdk/Event;)V");
|
"onEvent", "(Lcom/zerotier/sdk/Event;)V");
|
||||||
if(onEventMethod == NULL)
|
if(onEventMethod == NULL)
|
||||||
{
|
{
|
||||||
@ -210,26 +221,7 @@ namespace {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jmethodID onTraceMethod = lookup.findMethod(eventListenerClass,
|
||||||
jmethodID onOutOfDateMethod = cache.findMethod(eventListenerClass,
|
|
||||||
"onOutOfDate", "(Lcom/zerotier/sdk/Version;)V");
|
|
||||||
if(onOutOfDateMethod == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Couldn't find onOutOfDate method");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jmethodID onNetworkErrorMethod = cache.findMethod(eventListenerClass,
|
|
||||||
"onNetworkError", "(Lcom/zerotier/sdk/Event;Ljava/net/InetSocketAddress;)V");
|
|
||||||
if(onNetworkErrorMethod == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Couldn't find onNetworkError method");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jmethodID onTraceMethod = cache.findMethod(eventListenerClass,
|
|
||||||
"onTrace", "(Ljava/lang/String;)V");
|
"onTrace", "(Ljava/lang/String;)V");
|
||||||
if(onTraceMethod == NULL)
|
if(onTraceMethod == NULL)
|
||||||
{
|
{
|
||||||
@ -246,41 +238,36 @@ namespace {
|
|||||||
switch(event)
|
switch(event)
|
||||||
{
|
{
|
||||||
case ZT_EVENT_UP:
|
case ZT_EVENT_UP:
|
||||||
|
{
|
||||||
|
LOGD("Event Up");
|
||||||
|
env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ZT_EVENT_OFFLINE:
|
case ZT_EVENT_OFFLINE:
|
||||||
|
{
|
||||||
|
LOGD("Event Offline");
|
||||||
|
env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ZT_EVENT_ONLINE:
|
case ZT_EVENT_ONLINE:
|
||||||
|
{
|
||||||
|
LOGD("Event Online");
|
||||||
|
env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ZT_EVENT_DOWN:
|
case ZT_EVENT_DOWN:
|
||||||
|
{
|
||||||
|
LOGD("Event Down");
|
||||||
|
env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION:
|
case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION:
|
||||||
{
|
{
|
||||||
LOGV("Regular Event");
|
LOGV("Identity Collision");
|
||||||
// call onEvent()
|
// call onEvent()
|
||||||
env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
|
env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZT_EVENT_SAW_MORE_RECENT_VERSION:
|
|
||||||
{
|
|
||||||
LOGV("Version Event");
|
|
||||||
// call onOutOfDate()
|
|
||||||
if(data != NULL)
|
|
||||||
{
|
|
||||||
int *version = (int*)data;
|
|
||||||
jobject verisonObj = newVersion(env, version[0], version[1], version[2], 0);
|
|
||||||
env->CallVoidMethod(ref->eventListener, onOutOfDateMethod, verisonObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_AUTHENTICATION_FAILURE:
|
|
||||||
case ZT_EVENT_INVALID_PACKET:
|
|
||||||
{
|
|
||||||
LOGV("Network Error Event");
|
|
||||||
// call onNetworkError()
|
|
||||||
if(data != NULL)
|
|
||||||
{
|
|
||||||
sockaddr_storage *addr = (sockaddr_storage*)data;
|
|
||||||
jobject addressObj = newInetSocketAddress(env, *addr);
|
|
||||||
env->CallVoidMethod(ref->eventListener, onNetworkErrorMethod, addressObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_TRACE:
|
case ZT_EVENT_TRACE:
|
||||||
{
|
{
|
||||||
LOGV("Trace Event");
|
LOGV("Trace Event");
|
||||||
@ -296,7 +283,8 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long DataStoreGetFunction(ZT_Node *node,void *userData,
|
long DataStoreGetFunction(ZT_Node *node,
|
||||||
|
void *userData,
|
||||||
const char *objectName,
|
const char *objectName,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
unsigned long bufferSize,
|
unsigned long bufferSize,
|
||||||
@ -314,7 +302,7 @@ namespace {
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID dataStoreGetCallbackMethod = cache.findMethod(
|
jmethodID dataStoreGetCallbackMethod = lookup.findMethod(
|
||||||
dataStoreGetClass,
|
dataStoreGetClass,
|
||||||
"onDataStoreGet",
|
"onDataStoreGet",
|
||||||
"(Ljava/lang/String;[BJ[J)J");
|
"(Ljava/lang/String;[BJ[J)J");
|
||||||
@ -354,21 +342,22 @@ namespace {
|
|||||||
|
|
||||||
if(retval > 0)
|
if(retval > 0)
|
||||||
{
|
{
|
||||||
jbyte *data = env->GetByteArrayElements(bufferObj, NULL);
|
void *data = env->GetPrimitiveArrayCritical(bufferObj, NULL);
|
||||||
memcpy(buffer, data, retval);
|
memcpy(buffer, data, retval);
|
||||||
env->ReleaseByteArrayElements(bufferObj, data, JNI_ABORT);
|
env->ReleasePrimitiveArrayCritical(bufferObj, data, 0);
|
||||||
|
|
||||||
jlong *objSize = env->GetLongArrayElements(objectSizeObj, NULL);
|
jlong *objSize = (jlong*)env->GetPrimitiveArrayCritical(objectSizeObj, NULL);
|
||||||
*out_objectSize = (unsigned long)objSize[0];
|
*out_objectSize = (unsigned long)objSize[0];
|
||||||
env->ReleaseLongArrayElements(objectSizeObj, objSize, JNI_ABORT);
|
env->ReleasePrimitiveArrayCritical(objectSizeObj, objSize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("Out Object Size: %lu", *out_objectSize);
|
LOGV("Out Object Size: %lu", *out_objectSize);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DataStorePutFunction(ZT_Node *node,void *userData,
|
int DataStorePutFunction(ZT_Node *node,
|
||||||
|
void *userData,
|
||||||
const char *objectName,
|
const char *objectName,
|
||||||
const void *buffer,
|
const void *buffer,
|
||||||
unsigned long bufferSize,
|
unsigned long bufferSize,
|
||||||
@ -386,7 +375,7 @@ namespace {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID dataStorePutCallbackMethod = cache.findMethod(
|
jmethodID dataStorePutCallbackMethod = lookup.findMethod(
|
||||||
dataStorePutClass,
|
dataStorePutClass,
|
||||||
"onDataStorePut",
|
"onDataStorePut",
|
||||||
"(Ljava/lang/String;[BZ)I");
|
"(Ljava/lang/String;[BZ)I");
|
||||||
@ -396,7 +385,7 @@ namespace {
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID deleteMethod = cache.findMethod(dataStorePutClass,
|
jmethodID deleteMethod = lookup.findMethod(dataStorePutClass,
|
||||||
"onDelete", "(Ljava/lang/String;)I");
|
"onDelete", "(Ljava/lang/String;)I");
|
||||||
if(deleteMethod == NULL)
|
if(deleteMethod == NULL)
|
||||||
{
|
{
|
||||||
@ -408,30 +397,39 @@ namespace {
|
|||||||
|
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
|
LOGD("JNI: Delete file: %s", objectName);
|
||||||
// delete operation
|
// delete operation
|
||||||
return env->CallIntMethod(
|
return env->CallIntMethod(
|
||||||
ref->dataStorePutListener, deleteMethod, nameStr);
|
ref->dataStorePutListener, deleteMethod, nameStr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
LOGD("JNI: Write file: %s", objectName);
|
||||||
// set operation
|
// set operation
|
||||||
jbyteArray bufferObj = env->NewByteArray(bufferSize);
|
jbyteArray bufferObj = env->NewByteArray(bufferSize);
|
||||||
|
if(env->ExceptionCheck() || bufferObj == NULL)
|
||||||
|
{
|
||||||
|
LOGE("Error creating byte array buffer!");
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer);
|
env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer);
|
||||||
bool bsecure = secure != 0;
|
bool bsecure = secure != 0;
|
||||||
|
|
||||||
|
|
||||||
return env->CallIntMethod(ref->dataStorePutListener,
|
return env->CallIntMethod(ref->dataStorePutListener,
|
||||||
dataStorePutCallbackMethod,
|
dataStorePutCallbackMethod,
|
||||||
nameStr, bufferObj, bsecure);
|
nameStr, bufferObj, bsecure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int WirePacketSendFunction(ZT_Node *node,void *userData,\
|
int WirePacketSendFunction(ZT_Node *node,
|
||||||
const struct sockaddr_storage *address,
|
void *userData,
|
||||||
|
const struct sockaddr_storage *localAddress,
|
||||||
|
const struct sockaddr_storage *remoteAddress,
|
||||||
const void *buffer,
|
const void *buffer,
|
||||||
unsigned int bufferSize)
|
unsigned int bufferSize)
|
||||||
{
|
{
|
||||||
LOGD("WirePacketSendFunction(%p, %p, %d)", address, buffer, bufferSize);
|
LOGV("WirePacketSendFunction(%p, %p, %p, %d)", localAddress, remoteAddress, buffer, bufferSize);
|
||||||
JniRef *ref = (JniRef*)userData;
|
JniRef *ref = (JniRef*)userData;
|
||||||
assert(ref->node == node);
|
assert(ref->node == node);
|
||||||
|
|
||||||
@ -446,28 +444,36 @@ namespace {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID packetSenderCallbackMethod = cache.findMethod(packetSenderClass,
|
jmethodID packetSenderCallbackMethod = lookup.findMethod(packetSenderClass,
|
||||||
"onSendPacketRequested", "(Ljava/net/InetSocketAddress;[B)I");
|
"onSendPacketRequested", "(Ljava/net/InetSocketAddress;Ljava/net/InetSocketAddress;[B)I");
|
||||||
if(packetSenderCallbackMethod == NULL)
|
if(packetSenderCallbackMethod == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Couldn't find onSendPacketRequested method");
|
LOGE("Couldn't find onSendPacketRequested method");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject addressObj = newInetSocketAddress(env, *address);
|
jobject localAddressObj = NULL;
|
||||||
|
if(memcmp(localAddress, &ZT_SOCKADDR_NULL, sizeof(sockaddr_storage)) != 0)
|
||||||
|
{
|
||||||
|
localAddressObj = newInetSocketAddress(env, *localAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress);
|
||||||
jbyteArray bufferObj = env->NewByteArray(bufferSize);
|
jbyteArray bufferObj = env->NewByteArray(bufferSize);
|
||||||
env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer);
|
env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer);
|
||||||
int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, addressObj, bufferObj);
|
int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, localAddressObj, remoteAddressObj, bufferObj);
|
||||||
|
|
||||||
LOGD("JNI Packet Sender returned: %d", retval);
|
LOGV("JNI Packet Sender returned: %d", retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::map<uint64_t, JniRef*> NodeMap;
|
typedef std::map<uint64_t, JniRef*> NodeMap;
|
||||||
static NodeMap nodeMap;
|
static NodeMap nodeMap;
|
||||||
|
ZeroTier::Mutex nodeMapMutex;
|
||||||
|
|
||||||
ZT_Node* findNode(uint64_t nodeId)
|
ZT_Node* findNode(uint64_t nodeId)
|
||||||
{
|
{
|
||||||
|
ZeroTier::Mutex::Lock lock(nodeMapMutex);
|
||||||
NodeMap::iterator found = nodeMap.find(nodeId);
|
NodeMap::iterator found = nodeMap.find(nodeId);
|
||||||
if(found != nodeMap.end())
|
if(found != nodeMap.end())
|
||||||
{
|
{
|
||||||
@ -480,13 +486,13 @@ namespace {
|
|||||||
|
|
||||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||||
{
|
{
|
||||||
cache.setJavaVM(vm);
|
lookup.setJavaVM(vm);
|
||||||
return JNI_VERSION_1_6;
|
return JNI_VERSION_1_6;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
|
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
|
||||||
{
|
{
|
||||||
cache.clearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -507,7 +513,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
env->GetJavaVM(&ref->jvm);
|
env->GetJavaVM(&ref->jvm);
|
||||||
|
|
||||||
jclass cls = env->GetObjectClass(obj);
|
jclass cls = env->GetObjectClass(obj);
|
||||||
jfieldID fid = cache.findField(
|
jfieldID fid = lookup.findField(
|
||||||
cls, "getListener", "Lcom/zerotier/sdk/DataStoreGetListener;");
|
cls, "getListener", "Lcom/zerotier/sdk/DataStoreGetListener;");
|
||||||
|
|
||||||
if(fid == NULL)
|
if(fid == NULL)
|
||||||
@ -522,7 +528,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
}
|
}
|
||||||
ref->dataStoreGetListener = env->NewGlobalRef(tmp);
|
ref->dataStoreGetListener = env->NewGlobalRef(tmp);
|
||||||
|
|
||||||
fid = cache.findField(
|
fid = lookup.findField(
|
||||||
cls, "putListener", "Lcom/zerotier/sdk/DataStorePutListener;");
|
cls, "putListener", "Lcom/zerotier/sdk/DataStorePutListener;");
|
||||||
|
|
||||||
if(fid == NULL)
|
if(fid == NULL)
|
||||||
@ -537,7 +543,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
}
|
}
|
||||||
ref->dataStorePutListener = env->NewGlobalRef(tmp);
|
ref->dataStorePutListener = env->NewGlobalRef(tmp);
|
||||||
|
|
||||||
fid = cache.findField(
|
fid = lookup.findField(
|
||||||
cls, "sender", "Lcom/zerotier/sdk/PacketSender;");
|
cls, "sender", "Lcom/zerotier/sdk/PacketSender;");
|
||||||
if(fid == NULL)
|
if(fid == NULL)
|
||||||
{
|
{
|
||||||
@ -551,7 +557,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
}
|
}
|
||||||
ref->packetSender = env->NewGlobalRef(tmp);
|
ref->packetSender = env->NewGlobalRef(tmp);
|
||||||
|
|
||||||
fid = cache.findField(
|
fid = lookup.findField(
|
||||||
cls, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;");
|
cls, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;");
|
||||||
if(fid == NULL)
|
if(fid == NULL)
|
||||||
{
|
{
|
||||||
@ -565,7 +571,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
}
|
}
|
||||||
ref->frameListener = env->NewGlobalRef(tmp);
|
ref->frameListener = env->NewGlobalRef(tmp);
|
||||||
|
|
||||||
fid = cache.findField(
|
fid = lookup.findField(
|
||||||
cls, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;");
|
cls, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;");
|
||||||
if(fid == NULL)
|
if(fid == NULL)
|
||||||
{
|
{
|
||||||
@ -579,7 +585,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
}
|
}
|
||||||
ref->configListener = env->NewGlobalRef(tmp);
|
ref->configListener = env->NewGlobalRef(tmp);
|
||||||
|
|
||||||
fid = cache.findField(
|
fid = lookup.findField(
|
||||||
cls, "eventListener", "Lcom/zerotier/sdk/EventListener;");
|
cls, "eventListener", "Lcom/zerotier/sdk/EventListener;");
|
||||||
if(fid == NULL)
|
if(fid == NULL)
|
||||||
{
|
{
|
||||||
@ -618,9 +624,11 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
return resultObject;
|
return resultObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZeroTier::Mutex::Lock lock(nodeMapMutex);
|
||||||
ref->node = node;
|
ref->node = node;
|
||||||
nodeMap.insert(std::make_pair(ref->id, ref));
|
nodeMap.insert(std::make_pair(ref->id, ref));
|
||||||
|
|
||||||
|
|
||||||
return resultObject;
|
return resultObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +643,12 @@ JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete(
|
|||||||
LOGV("Destroying ZT_Node struct");
|
LOGV("Destroying ZT_Node struct");
|
||||||
uint64_t nodeId = (uint64_t)id;
|
uint64_t nodeId = (uint64_t)id;
|
||||||
|
|
||||||
NodeMap::iterator found = nodeMap.find(nodeId);
|
NodeMap::iterator found;
|
||||||
|
{
|
||||||
|
ZeroTier::Mutex::Lock lock(nodeMapMutex);
|
||||||
|
found = nodeMap.find(nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
if(found != nodeMap.end())
|
if(found != nodeMap.end())
|
||||||
{
|
{
|
||||||
JniRef *ref = found->second;
|
JniRef *ref = found->second;
|
||||||
@ -693,7 +706,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame(
|
|||||||
unsigned int vlanId = (unsigned int)in_vlanId;
|
unsigned int vlanId = (unsigned int)in_vlanId;
|
||||||
|
|
||||||
unsigned int frameLength = env->GetArrayLength(in_frameData);
|
unsigned int frameLength = env->GetArrayLength(in_frameData);
|
||||||
jbyte *frameData =env->GetByteArrayElements(in_frameData, NULL);
|
void *frameData = env->GetPrimitiveArrayCritical(in_frameData, NULL);
|
||||||
|
void *localData = malloc(frameLength);
|
||||||
|
memcpy(localData, frameData, frameLength);
|
||||||
|
env->ReleasePrimitiveArrayCritical(in_frameData, frameData, 0);
|
||||||
|
|
||||||
uint64_t nextBackgroundTaskDeadline = 0;
|
uint64_t nextBackgroundTaskDeadline = 0;
|
||||||
|
|
||||||
@ -705,15 +721,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame(
|
|||||||
destMac,
|
destMac,
|
||||||
etherType,
|
etherType,
|
||||||
vlanId,
|
vlanId,
|
||||||
(const void*)frameData,
|
(const void*)localData,
|
||||||
frameLength,
|
frameLength,
|
||||||
&nextBackgroundTaskDeadline);
|
&nextBackgroundTaskDeadline);
|
||||||
|
|
||||||
jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
|
jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
|
||||||
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
|
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
|
||||||
env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
|
env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
|
||||||
|
|
||||||
env->ReleaseByteArrayElements(in_frameData, frameData, 0);
|
|
||||||
|
|
||||||
return createResultObject(env, rc);
|
return createResultObject(env, rc);
|
||||||
}
|
}
|
||||||
@ -727,6 +741,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
|
|||||||
JNIEnv *env, jobject obj,
|
JNIEnv *env, jobject obj,
|
||||||
jlong id,
|
jlong id,
|
||||||
jlong in_now,
|
jlong in_now,
|
||||||
|
jobject in_localAddress,
|
||||||
jobject in_remoteAddress,
|
jobject in_remoteAddress,
|
||||||
jbyteArray in_packetData,
|
jbyteArray in_packetData,
|
||||||
jlongArray out_nextBackgroundTaskDeadline)
|
jlongArray out_nextBackgroundTaskDeadline)
|
||||||
@ -736,26 +751,29 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
|
|||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
// cannot find valid node. We should never get here.
|
// cannot find valid node. We should never get here.
|
||||||
|
LOGE("Couldn't find a valid node!");
|
||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
|
unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
|
||||||
if(nbtd_len < 1)
|
if(nbtd_len < 1)
|
||||||
{
|
{
|
||||||
|
LOGE("nbtd_len < 1");
|
||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t now = (uint64_t)in_now;
|
uint64_t now = (uint64_t)in_now;
|
||||||
|
|
||||||
// get the java.net.InetSocketAddress class and getAddress() method
|
// get the java.net.InetSocketAddress class and getAddress() method
|
||||||
jclass inetAddressClass = cache.findClass("java/net/InetAddress");
|
jclass inetAddressClass = lookup.findClass("java/net/InetAddress");
|
||||||
if(inetAddressClass == NULL)
|
if(inetAddressClass == NULL)
|
||||||
{
|
{
|
||||||
|
LOGE("Can't find InetAddress class");
|
||||||
// can't find java.net.InetAddress
|
// can't find java.net.InetAddress
|
||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID getAddressMethod = cache.findMethod(
|
jmethodID getAddressMethod = lookup.findMethod(
|
||||||
inetAddressClass, "getAddress", "()[B");
|
inetAddressClass, "getAddress", "()[B");
|
||||||
if(getAddressMethod == NULL)
|
if(getAddressMethod == NULL)
|
||||||
{
|
{
|
||||||
@ -763,23 +781,29 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
|
|||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
jclass InetSocketAddressClass = cache.findClass("java/net/InetSocketAddress");
|
jclass InetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
|
||||||
if(InetSocketAddressClass == NULL)
|
if(InetSocketAddressClass == NULL)
|
||||||
{
|
{
|
||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID inetSockGetAddressMethod = cache.findMethod(
|
jmethodID inetSockGetAddressMethod = lookup.findMethod(
|
||||||
InetSocketAddressClass, "getAddress", "()Ljava/net/InetAddress;");
|
InetSocketAddressClass, "getAddress", "()Ljava/net/InetAddress;");
|
||||||
|
|
||||||
jobject addrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod);
|
jobject localAddrObj = NULL;
|
||||||
|
if(in_localAddress != NULL)
|
||||||
|
{
|
||||||
|
localAddrObj = env->CallObjectMethod(in_localAddress, inetSockGetAddressMethod);
|
||||||
|
}
|
||||||
|
|
||||||
if(addrObject == NULL)
|
jobject remoteAddrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod);
|
||||||
|
|
||||||
|
if(remoteAddrObject == NULL)
|
||||||
{
|
{
|
||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID inetSock_getPort = cache.findMethod(
|
jmethodID inetSock_getPort = lookup.findMethod(
|
||||||
InetSocketAddressClass, "getPort", "()I");
|
InetSocketAddressClass, "getPort", "()I");
|
||||||
|
|
||||||
if(env->ExceptionCheck() || inetSock_getPort == NULL)
|
if(env->ExceptionCheck() || inetSock_getPort == NULL)
|
||||||
@ -789,7 +813,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call InetSocketAddress.getPort()
|
// call InetSocketAddress.getPort()
|
||||||
int port = env->CallIntMethod(in_remoteAddress, inetSock_getPort);
|
int remotePort = env->CallIntMethod(in_remoteAddress, inetSock_getPort);
|
||||||
if(env->ExceptionCheck())
|
if(env->ExceptionCheck())
|
||||||
{
|
{
|
||||||
LOGE("Exception calling InetSocketAddress.getPort()");
|
LOGE("Exception calling InetSocketAddress.getPort()");
|
||||||
@ -797,18 +821,60 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call InetAddress.getAddress()
|
// Call InetAddress.getAddress()
|
||||||
jbyteArray addressArray = (jbyteArray)env->CallObjectMethod(addrObject, getAddressMethod);
|
jbyteArray remoteAddressArray = (jbyteArray)env->CallObjectMethod(remoteAddrObject, getAddressMethod);
|
||||||
if(addressArray == NULL)
|
if(remoteAddressArray == NULL)
|
||||||
{
|
{
|
||||||
|
LOGE("Unable to call getAddress()");
|
||||||
// unable to call getAddress()
|
// unable to call getAddress()
|
||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int addrSize = env->GetArrayLength(addressArray);
|
unsigned int addrSize = env->GetArrayLength(remoteAddressArray);
|
||||||
|
|
||||||
|
|
||||||
|
sockaddr_storage localAddress = {};
|
||||||
|
|
||||||
|
if(localAddrObj == NULL)
|
||||||
|
{
|
||||||
|
localAddress = ZT_SOCKADDR_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int localPort = env->CallIntMethod(in_localAddress, inetSock_getPort);
|
||||||
|
jbyteArray localAddressArray = (jbyteArray)env->CallObjectMethod(localAddrObj, getAddressMethod);
|
||||||
|
if(localAddressArray != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned int localAddrSize = env->GetArrayLength(localAddressArray);
|
||||||
|
jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(localAddressArray, NULL);
|
||||||
|
|
||||||
|
if(localAddrSize == 16)
|
||||||
|
{
|
||||||
|
sockaddr_in6 ipv6 = {};
|
||||||
|
ipv6.sin6_family = AF_INET6;
|
||||||
|
ipv6.sin6_port = htons(localPort);
|
||||||
|
memcpy(ipv6.sin6_addr.s6_addr, addr, 16);
|
||||||
|
memcpy(&localAddress, &ipv6, sizeof(sockaddr_in6));
|
||||||
|
}
|
||||||
|
else if(localAddrSize)
|
||||||
|
{
|
||||||
|
// IPV4 address
|
||||||
|
sockaddr_in ipv4 = {};
|
||||||
|
ipv4.sin_family = AF_INET;
|
||||||
|
ipv4.sin_port = htons(localPort);
|
||||||
|
memcpy(&ipv4.sin_addr, addr, 4);
|
||||||
|
memcpy(&localAddress, &ipv4, sizeof(sockaddr_in));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
localAddress = ZT_SOCKADDR_NULL;
|
||||||
|
}
|
||||||
|
env->ReleasePrimitiveArrayCritical(localAddressArray, addr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get the address bytes
|
// get the address bytes
|
||||||
jbyte *addr = env->GetByteArrayElements(addressArray, NULL);
|
jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(remoteAddressArray, NULL);
|
||||||
|
|
||||||
|
|
||||||
sockaddr_storage remoteAddress = {};
|
sockaddr_storage remoteAddress = {};
|
||||||
|
|
||||||
if(addrSize == 16)
|
if(addrSize == 16)
|
||||||
@ -816,7 +882,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
|
|||||||
// IPV6 address
|
// IPV6 address
|
||||||
sockaddr_in6 ipv6 = {};
|
sockaddr_in6 ipv6 = {};
|
||||||
ipv6.sin6_family = AF_INET6;
|
ipv6.sin6_family = AF_INET6;
|
||||||
ipv6.sin6_port = htons(port);
|
ipv6.sin6_port = htons(remotePort);
|
||||||
memcpy(ipv6.sin6_addr.s6_addr, addr, 16);
|
memcpy(ipv6.sin6_addr.s6_addr, addr, 16);
|
||||||
memcpy(&remoteAddress, &ipv6, sizeof(sockaddr_in6));
|
memcpy(&remoteAddress, &ipv6, sizeof(sockaddr_in6));
|
||||||
}
|
}
|
||||||
@ -825,37 +891,50 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
|
|||||||
// IPV4 address
|
// IPV4 address
|
||||||
sockaddr_in ipv4 = {};
|
sockaddr_in ipv4 = {};
|
||||||
ipv4.sin_family = AF_INET;
|
ipv4.sin_family = AF_INET;
|
||||||
ipv4.sin_port = htons(port);
|
ipv4.sin_port = htons(remotePort);
|
||||||
memcpy(&ipv4.sin_addr, addr, 4);
|
memcpy(&ipv4.sin_addr, addr, 4);
|
||||||
memcpy(&remoteAddress, &ipv4, sizeof(sockaddr_in));
|
memcpy(&remoteAddress, &ipv4, sizeof(sockaddr_in));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
LOGE("Unknown IP version");
|
||||||
// unknown address type
|
// unknown address type
|
||||||
env->ReleaseByteArrayElements(addressArray, addr, 0);
|
env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0);
|
||||||
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0);
|
||||||
|
|
||||||
unsigned int packetLength = env->GetArrayLength(in_packetData);
|
unsigned int packetLength = env->GetArrayLength(in_packetData);
|
||||||
jbyte *packetData = env->GetByteArrayElements(in_packetData, NULL);
|
if(packetLength == 0)
|
||||||
|
{
|
||||||
|
LOGE("Empty packet?!?");
|
||||||
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
|
}
|
||||||
|
void *packetData = env->GetPrimitiveArrayCritical(in_packetData, NULL);
|
||||||
|
void *localData = malloc(packetLength);
|
||||||
|
memcpy(localData, packetData, packetLength);
|
||||||
|
env->ReleasePrimitiveArrayCritical(in_packetData, packetData, 0);
|
||||||
|
|
||||||
uint64_t nextBackgroundTaskDeadline = 0;
|
uint64_t nextBackgroundTaskDeadline = 0;
|
||||||
|
|
||||||
ZT_ResultCode rc = ZT_Node_processWirePacket(
|
ZT_ResultCode rc = ZT_Node_processWirePacket(
|
||||||
node,
|
node,
|
||||||
now,
|
now,
|
||||||
|
&localAddress,
|
||||||
&remoteAddress,
|
&remoteAddress,
|
||||||
packetData,
|
localData,
|
||||||
packetLength,
|
packetLength,
|
||||||
&nextBackgroundTaskDeadline);
|
&nextBackgroundTaskDeadline);
|
||||||
|
if(rc != ZT_RESULT_OK)
|
||||||
|
{
|
||||||
|
LOGE("ZT_Node_processWirePacket returned: %d", rc);
|
||||||
|
}
|
||||||
|
|
||||||
jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
|
free(localData);
|
||||||
|
|
||||||
|
jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
|
||||||
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
|
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
|
||||||
env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
|
env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
|
||||||
|
|
||||||
env->ReleaseByteArrayElements(addressArray, addr, 0);
|
|
||||||
env->ReleaseByteArrayElements(in_packetData, packetData, 0);
|
|
||||||
|
|
||||||
return createResultObject(env, rc);
|
return createResultObject(env, rc);
|
||||||
}
|
}
|
||||||
@ -890,9 +969,9 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks(
|
|||||||
|
|
||||||
ZT_ResultCode rc = ZT_Node_processBackgroundTasks(node, now, &nextBackgroundTaskDeadline);
|
ZT_ResultCode rc = ZT_Node_processBackgroundTasks(node, now, &nextBackgroundTaskDeadline);
|
||||||
|
|
||||||
jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
|
jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
|
||||||
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
|
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
|
||||||
env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
|
env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
|
||||||
|
|
||||||
return createResultObject(env, rc);
|
return createResultObject(env, rc);
|
||||||
}
|
}
|
||||||
@ -1043,13 +1122,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
|
|||||||
jmethodID nodeStatusConstructor = NULL;
|
jmethodID nodeStatusConstructor = NULL;
|
||||||
|
|
||||||
// create a com.zerotier.sdk.NodeStatus object
|
// create a com.zerotier.sdk.NodeStatus object
|
||||||
nodeStatusClass = cache.findClass("com/zerotier/sdk/NodeStatus");
|
nodeStatusClass = lookup.findClass("com/zerotier/sdk/NodeStatus");
|
||||||
if(nodeStatusClass == NULL)
|
if(nodeStatusClass == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeStatusConstructor = cache.findMethod(
|
nodeStatusConstructor = lookup.findMethod(
|
||||||
nodeStatusClass, "<init>", "()V");
|
nodeStatusClass, "<init>", "()V");
|
||||||
if(nodeStatusConstructor == NULL)
|
if(nodeStatusConstructor == NULL)
|
||||||
{
|
{
|
||||||
@ -1070,25 +1149,25 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
|
|||||||
jfieldID secretIdentityField = NULL;
|
jfieldID secretIdentityField = NULL;
|
||||||
jfieldID onlineField = NULL;
|
jfieldID onlineField = NULL;
|
||||||
|
|
||||||
addressField = cache.findField(nodeStatusClass, "address", "J");
|
addressField = lookup.findField(nodeStatusClass, "address", "J");
|
||||||
if(addressField == NULL)
|
if(addressField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
publicIdentityField = cache.findField(nodeStatusClass, "publicIdentity", "Ljava/lang/String;");
|
publicIdentityField = lookup.findField(nodeStatusClass, "publicIdentity", "Ljava/lang/String;");
|
||||||
if(publicIdentityField == NULL)
|
if(publicIdentityField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
secretIdentityField = cache.findField(nodeStatusClass, "secretIdentity", "Ljava/lang/String;");
|
secretIdentityField = lookup.findField(nodeStatusClass, "secretIdentity", "Ljava/lang/String;");
|
||||||
if(secretIdentityField == NULL)
|
if(secretIdentityField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
onlineField = cache.findField(nodeStatusClass, "online", "Z");
|
onlineField = lookup.findField(nodeStatusClass, "online", "Z");
|
||||||
if(onlineField == NULL)
|
if(onlineField == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1191,7 +1270,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
jclass peerClass = cache.findClass("com/zerotier/sdk/Peer");
|
jclass peerClass = lookup.findClass("com/zerotier/sdk/Peer");
|
||||||
if(env->ExceptionCheck() || peerClass == NULL)
|
if(env->ExceptionCheck() || peerClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding Peer class");
|
LOGE("Error finding Peer class");
|
||||||
@ -1249,7 +1328,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
jclass vnetConfigClass = cache.findClass("com/zerotier/sdk/VirtualNetworkConfig");
|
jclass vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig");
|
||||||
if(env->ExceptionCheck() || vnetConfigClass == NULL)
|
if(env->ExceptionCheck() || vnetConfigClass == NULL)
|
||||||
{
|
{
|
||||||
LOGE("Error finding VirtualNetworkConfig class");
|
LOGE("Error finding VirtualNetworkConfig class");
|
||||||
|
@ -34,10 +34,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame
|
|||||||
/*
|
/*
|
||||||
* Class: com_zerotier_sdk_Node
|
* Class: com_zerotier_sdk_Node
|
||||||
* Method: processWirePacket
|
* Method: processWirePacket
|
||||||
* Signature: (JJLjava/net/InetSockAddress;[B[J)Lcom/zerotier/sdk/ResultCode;
|
* Signature: (JJLjava/net/InetSockAddress;Ljava/net/InetSockAddress;[B[J)Lcom/zerotier/sdk/ResultCode;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket
|
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket
|
||||||
(JNIEnv *, jobject, jlong, jlong, jobject, jbyteArray, jlongArray);
|
(JNIEnv *, jobject, jlong, jlong, jobject, jobject, jbyteArray, jlongArray);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_zerotier_sdk_Node
|
* Class: com_zerotier_sdk_Node
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class AndroidFileProvider implements DataStoreFileProvider {
|
|
||||||
private static final String TAG = "AndroidFileProvider";
|
|
||||||
|
|
||||||
Context _ctx;
|
|
||||||
|
|
||||||
public AndroidFileProvider(Context ctx) {
|
|
||||||
this._ctx = ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileInputStream getInputFileStream(String name)
|
|
||||||
throws FileNotFoundException {
|
|
||||||
Log.d(TAG, "Returning FileInputStream for: " + name);
|
|
||||||
return _ctx.openFileInput(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileOutputStream getOutputFileStream(String name)
|
|
||||||
throws FileNotFoundException {
|
|
||||||
Log.d(TAG, "Returning FileOutputStream for: " + name);
|
|
||||||
return _ctx.openFileOutput(name, Context.MODE_PRIVATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String name) throws IOException {
|
|
||||||
boolean success = _ctx.deleteFile(name);
|
|
||||||
if(!success)
|
|
||||||
{
|
|
||||||
throw new IOException("Unable to delete file.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.DataStoreGetListener;
|
|
||||||
import com.zerotier.sdk.DataStorePutListener;
|
|
||||||
|
|
||||||
public class DataStore implements DataStoreGetListener, DataStorePutListener {
|
|
||||||
|
|
||||||
private DataStoreFileProvider _provider;
|
|
||||||
|
|
||||||
public DataStore(DataStoreFileProvider provider) {
|
|
||||||
this._provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onDataStorePut(String name, byte[] buffer, boolean secure) {
|
|
||||||
System.out.println("Writing File: " + name);
|
|
||||||
try {
|
|
||||||
FileOutputStream fos = _provider.getOutputFileStream(name);
|
|
||||||
fos.write(buffer);
|
|
||||||
fos.close();
|
|
||||||
return 0;
|
|
||||||
} catch (FileNotFoundException fnf) {
|
|
||||||
fnf.printStackTrace();
|
|
||||||
return -1;
|
|
||||||
} catch (IOException io) {
|
|
||||||
io.printStackTrace();
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onDelete(String name) {
|
|
||||||
System.out.println("Deleting File: " + name);
|
|
||||||
try {
|
|
||||||
_provider.deleteFile(name);
|
|
||||||
return 0;
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long onDataStoreGet(String name, byte[] out_buffer,
|
|
||||||
long bufferIndex, long[] out_objectSize) {
|
|
||||||
System.out.println("Reading File: " + name);
|
|
||||||
try {
|
|
||||||
FileInputStream fin = _provider.getInputFileStream(name);
|
|
||||||
out_objectSize[0] = fin.getChannel().size();
|
|
||||||
if(bufferIndex > 0)
|
|
||||||
{
|
|
||||||
fin.skip(bufferIndex);
|
|
||||||
}
|
|
||||||
int read = fin.read(out_buffer);
|
|
||||||
fin.close();
|
|
||||||
return read;
|
|
||||||
} catch (FileNotFoundException fnf) {
|
|
||||||
// Can't read a file that doesn't exist!
|
|
||||||
out_objectSize[0] = 0;
|
|
||||||
return 0;
|
|
||||||
} catch (IOException io) {
|
|
||||||
io.printStackTrace();
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface DataStoreFileProvider {
|
|
||||||
FileInputStream getInputFileStream(String name) throws FileNotFoundException;
|
|
||||||
FileOutputStream getOutputFileStream(String name) throws FileNotFoundException;
|
|
||||||
void deleteFile(String name) throws IOException;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class JavaFileProvider implements DataStoreFileProvider {
|
|
||||||
private String _path;
|
|
||||||
|
|
||||||
public JavaFileProvider(String path) {
|
|
||||||
this._path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileInputStream getInputFileStream(String name)
|
|
||||||
throws FileNotFoundException {
|
|
||||||
File f = new File(_path + File.separator + name);
|
|
||||||
return new FileInputStream(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileOutputStream getOutputFileStream(String name)
|
|
||||||
throws FileNotFoundException {
|
|
||||||
File f = new File(_path + File.separator + name);
|
|
||||||
if(!f.exists())
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
f.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new FileOutputStream(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String name) throws IOException {
|
|
||||||
File f = new File(_path + File.separator + name);
|
|
||||||
boolean success = f.delete();
|
|
||||||
if(!success) {
|
|
||||||
throw new IOException("Unable to delete file: " + _path + File.pathSeparator + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,204 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.DatagramPacket;
|
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.Event;
|
|
||||||
import com.zerotier.sdk.EventListener;
|
|
||||||
import com.zerotier.sdk.Node;
|
|
||||||
import com.zerotier.sdk.PacketSender;
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
import com.zerotier.sdk.Version;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfigListener;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfigOperation;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkFrameListener;
|
|
||||||
|
|
||||||
public class OneService extends Thread implements Runnable, PacketSender,
|
|
||||||
EventListener, VirtualNetworkConfigListener,
|
|
||||||
VirtualNetworkFrameListener {
|
|
||||||
private Node _node;
|
|
||||||
private int _port;
|
|
||||||
|
|
||||||
private DatagramSocket _udpSocket;
|
|
||||||
private ServerSocket _tcpSocket;
|
|
||||||
private DataStore _ds;
|
|
||||||
private long _nextBackgroundTaskDeadline = 0;
|
|
||||||
|
|
||||||
private final Thread _udpReceiveThread = new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
long[] bgtask = new long[1];
|
|
||||||
byte[] buffer = new byte[16384];
|
|
||||||
while(true) {
|
|
||||||
|
|
||||||
bgtask[0] = 0;
|
|
||||||
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
|
|
||||||
|
|
||||||
try {
|
|
||||||
_udpSocket.receive(p);
|
|
||||||
if(p.getLength() > 0)
|
|
||||||
{
|
|
||||||
System.out.println("Got Data From: " + p.getAddress().toString() +":" + p.getPort());
|
|
||||||
|
|
||||||
_node.processWirePacket(System.currentTimeMillis(), new InetSocketAddress(p.getAddress(), p.getPort()), p.getData(), bgtask);
|
|
||||||
_nextBackgroundTaskDeadline = bgtask[0];
|
|
||||||
}
|
|
||||||
} catch (SocketTimeoutException e) {}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
public OneService(DataStoreFileProvider prov, int port) {
|
|
||||||
this._port = port;
|
|
||||||
this._ds = new DataStore(prov);
|
|
||||||
|
|
||||||
try {
|
|
||||||
_udpSocket = new DatagramSocket(_port);
|
|
||||||
_udpSocket.setSoTimeout(100);
|
|
||||||
_tcpSocket = new ServerSocket();
|
|
||||||
_tcpSocket.bind(new InetSocketAddress("127.0.0.1", _port));
|
|
||||||
} catch (SocketException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_udpReceiveThread.start();
|
|
||||||
|
|
||||||
_node = new Node(
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
_ds,
|
|
||||||
_ds,
|
|
||||||
this,
|
|
||||||
this,
|
|
||||||
this,
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if(_node == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while(true) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
long dl = _nextBackgroundTaskDeadline;
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
if (dl <= now) {
|
|
||||||
long[] returnDeadline = {0};
|
|
||||||
ResultCode rc = _node.processBackgroundTasks(now, returnDeadline);
|
|
||||||
_nextBackgroundTaskDeadline = returnDeadline[0];
|
|
||||||
|
|
||||||
if(rc != ResultCode.RESULT_OK) {
|
|
||||||
System.out.println(rc.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long delay = (dl > now) ? (dl - now) : 100;
|
|
||||||
Thread.sleep(delay);
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println("Exception in run loop: " + ex.getMessage());
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onSendPacketRequested(InetSocketAddress addr, byte[] packetData) {
|
|
||||||
System.out.println("onSendPacketRequested to: " + addr.getHostString() +":"+ addr.getPort() + " ");
|
|
||||||
|
|
||||||
if(_udpSocket == null)
|
|
||||||
return -1;
|
|
||||||
try {
|
|
||||||
DatagramPacket p = new DatagramPacket(packetData, packetData.length, addr);
|
|
||||||
_udpSocket.send(p);
|
|
||||||
System.out.println("Sent");
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("Error sending datagram: " + e.getMessage());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVirtualNetworkFrame(long nwid, long srcMac, long destMac,
|
|
||||||
long etherType, long vlanId, byte[] frameData) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onNetworkConfigurationUpdated(long nwid,
|
|
||||||
VirtualNetworkConfigOperation op, VirtualNetworkConfig config) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEvent(Event event) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNetworkError(Event event, InetSocketAddress source) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onOutOfDate(Version newVersion) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTrace(String message) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -87,31 +87,6 @@ public enum Event {
|
|||||||
*/
|
*/
|
||||||
EVENT_FATAL_ERROR_IDENTITY_COLLISION,
|
EVENT_FATAL_ERROR_IDENTITY_COLLISION,
|
||||||
|
|
||||||
/**
|
|
||||||
* A more recent version was observed on the network
|
|
||||||
*
|
|
||||||
* <p>Right now this is only triggered if a hub or rootserver reports a
|
|
||||||
* more recent version, and only once. It can be used to trigger a
|
|
||||||
* software update check.</p>
|
|
||||||
*
|
|
||||||
* <p>Meta-data: {@link Version}, more recent version number</p>
|
|
||||||
*/
|
|
||||||
EVENT_SAW_MORE_RECENT_VERSION,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A packet failed authentication
|
|
||||||
*
|
|
||||||
* <p>Meta-data: {@link InetSocketAddress} containing origin address of packet</p>
|
|
||||||
*/
|
|
||||||
EVENT_AUTHENTICATION_FAILURE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A received packet was not valid
|
|
||||||
*
|
|
||||||
* <p>Meta-data: {@link InetSocketAddress} containing origin address of packet</p>
|
|
||||||
*/
|
|
||||||
EVENT_INVALID_PACKET,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trace (debugging) message
|
* Trace (debugging) message
|
||||||
*
|
*
|
||||||
|
@ -41,21 +41,6 @@ public interface EventListener {
|
|||||||
*/
|
*/
|
||||||
public void onEvent(Event event);
|
public void onEvent(Event event);
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for network error events: {@link Event.EVENT_AUTHENTICATION_FAILUER}, {link Event.EVENT_INVALID_PACKET}
|
|
||||||
*
|
|
||||||
* @param event {@link Event} enum
|
|
||||||
* @param source {@link InetSocketAddress} containing the origin address of the packet
|
|
||||||
*/
|
|
||||||
public void onNetworkError(Event event, InetSocketAddress source);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback when the node detects that it's out of date.
|
|
||||||
*
|
|
||||||
* @param newVersion {@link Version} object with the latest version of ZeroTier One
|
|
||||||
*/
|
|
||||||
public void onOutOfDate(Version newVersion);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trace messages
|
* Trace messages
|
||||||
*
|
*
|
||||||
|
@ -33,6 +33,10 @@ public final class MulticastGroup {
|
|||||||
private long mac;
|
private long mac;
|
||||||
private long adi;
|
private long adi;
|
||||||
|
|
||||||
|
public boolean equals(MulticastGroup other) {
|
||||||
|
return mac == other.mac && adi == other.adi;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MAC address (least significant 48 bits)
|
* MAC address (least significant 48 bits)
|
||||||
*/
|
*/
|
||||||
|
@ -169,11 +169,12 @@ public class Node {
|
|||||||
*/
|
*/
|
||||||
public ResultCode processWirePacket(
|
public ResultCode processWirePacket(
|
||||||
long now,
|
long now,
|
||||||
|
InetSocketAddress localAddress,
|
||||||
InetSocketAddress remoteAddress,
|
InetSocketAddress remoteAddress,
|
||||||
byte[] packetData,
|
byte[] packetData,
|
||||||
long[] nextBackgroundTaskDeadline) {
|
long[] nextBackgroundTaskDeadline) {
|
||||||
return processWirePacket(
|
return processWirePacket(
|
||||||
nodeId, now, remoteAddress, packetData,
|
nodeId, now, localAddress, remoteAddress, packetData,
|
||||||
nextBackgroundTaskDeadline);
|
nextBackgroundTaskDeadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +394,7 @@ public class Node {
|
|||||||
private native ResultCode processWirePacket(
|
private native ResultCode processWirePacket(
|
||||||
long nodeId,
|
long nodeId,
|
||||||
long now,
|
long now,
|
||||||
|
InetSocketAddress localAddress,
|
||||||
InetSocketAddress remoteAddress,
|
InetSocketAddress remoteAddress,
|
||||||
byte[] packetData,
|
byte[] packetData,
|
||||||
long[] nextBackgroundTaskDeadline);
|
long[] nextBackgroundTaskDeadline);
|
||||||
|
@ -37,11 +37,13 @@ public interface PacketSender {
|
|||||||
* on failure. Note that success does not (of course) guarantee packet
|
* on failure. Note that success does not (of course) guarantee packet
|
||||||
* delivery. It only means that the packet appears to have been sent.</p>
|
* delivery. It only means that the packet appears to have been sent.</p>
|
||||||
*
|
*
|
||||||
* @param addr {@link InetSocketAddress} to send to
|
* @param localAddr {@link InetSocketAddress} to send from. Set to null if not specified.
|
||||||
|
* @param remoteAddr {@link InetSocketAddress} to send to
|
||||||
* @param packetData data to send
|
* @param packetData data to send
|
||||||
* @return 0 on success, any error code on failure.
|
* @return 0 on success, any error code on failure.
|
||||||
*/
|
*/
|
||||||
public int onSendPacketRequested(
|
public int onSendPacketRequested(
|
||||||
InetSocketAddress addr,
|
InetSocketAddress localAddr,
|
||||||
|
InetSocketAddress remoteAddr,
|
||||||
byte[] packetData);
|
byte[] packetData);
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,12 @@ public enum PeerRole {
|
|||||||
PEER_ROLE_LEAF,
|
PEER_ROLE_LEAF,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locally federated hub
|
* relay node
|
||||||
*/
|
*/
|
||||||
PEER_ROLE_HUB,
|
PEER_ROLE_RELAY,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* planetary rootserver
|
* root server
|
||||||
*/
|
*/
|
||||||
PEER_ROLE_ROOTSERVER
|
PEER_ROLE_ROOT
|
||||||
}
|
}
|
@ -27,11 +27,13 @@
|
|||||||
|
|
||||||
package com.zerotier.sdk;
|
package com.zerotier.sdk;
|
||||||
|
|
||||||
|
import java.lang.Comparable;
|
||||||
|
import java.lang.Override;
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
public final class VirtualNetworkConfig {
|
public final class VirtualNetworkConfig implements Comparable<VirtualNetworkConfig> {
|
||||||
public static final int MAX_MULTICAST_SUBSCRIPTIONS = 4096;
|
public static final int MAX_MULTICAST_SUBSCRIPTIONS = 4096;
|
||||||
public static final int ZT_MAX_ZT_ASSIGNED_ADDRESSES = 16;
|
public static final int ZT_MAX_ZT_ASSIGNED_ADDRESSES = 16;
|
||||||
|
|
||||||
@ -54,6 +56,40 @@ public final class VirtualNetworkConfig {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean equals(VirtualNetworkConfig cfg) {
|
||||||
|
boolean aaEqual = true;
|
||||||
|
if(assignedAddresses.length == cfg.assignedAddresses.length) {
|
||||||
|
for(int i = 0; i < assignedAddresses.length; ++i) {
|
||||||
|
if(!assignedAddresses[i].equals(cfg.assignedAddresses[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aaEqual = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nwid == cfg.nwid &&
|
||||||
|
mac == cfg.mac &&
|
||||||
|
name.equals(cfg.name) &&
|
||||||
|
status.equals(cfg.status) &&
|
||||||
|
type.equals(cfg.type) &&
|
||||||
|
mtu == cfg.mtu &&
|
||||||
|
dhcp == cfg.dhcp &&
|
||||||
|
bridge == cfg.bridge &&
|
||||||
|
broadcastEnabled == cfg.broadcastEnabled &&
|
||||||
|
portError == cfg.portError &&
|
||||||
|
enabled == cfg.enabled &&
|
||||||
|
aaEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(VirtualNetworkConfig cfg) {
|
||||||
|
if(cfg.nwid == this.nwid) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return this.nwid > cfg.nwid ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 64-bit ZeroTier network ID
|
* 64-bit ZeroTier network ID
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user