diff options
Diffstat (limited to 'java')
22 files changed, 506 insertions, 838 deletions
diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index 25e32638..008b747b 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -59,6 +59,7 @@ set(src_files set(include_dirs ${CMAKE_CURRENT_SOURCE_DIR}/../include/ + ${CMAKE_CURRENT_SOURCE_DIR}/../node/ ${Java_INCLUDE_DIRS}) if(WIN32) diff --git a/java/build.xml b/java/build.xml index e24a0e13..4604ad66 100644 --- a/java/build.xml +++ b/java/build.xml @@ -1,4 +1,4 @@ -<project default="build" name="ZeroTierOneSDK" basedir="."> +<project default="build_jar" name="ZeroTierOneSDK" basedir="."> <property environment="env"/> <condition property="isWindows"> @@ -9,7 +9,7 @@ <os family="mac"/> </condition> - <target name="clean"> + <target name="clean_ant"> <delete dir="bin" failonerror="false"/> <delete dir="classes" failonerror="false"/> <delete dir="build_win32" failonerror="false"/> @@ -24,6 +24,10 @@ <echo message="os.arch = ${os.arch}"/> <echo message="ant.java.version = ${ant.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="classes"/> <javac srcdir="src" @@ -36,20 +40,30 @@ <target name="build_android"> <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="NDK_DEBUG=1"/> --> </exec> - <copy file="libs/armeabi/libZeroTierOneJNI.so" - tofile="${user.dir}/classes/lib/armeabi/libZeroTierOneJNI.so" - overwrite="true"/> <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"/> <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"/> <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"/> </target> @@ -91,7 +105,7 @@ overwrite="true"/> </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"/> </target> @@ -101,23 +115,4 @@ <javadoc sourcepath="src/" destdir="doc/"/> </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>
\ No newline at end of file diff --git a/java/jni/Android.mk b/java/jni/Android.mk index 4dd4a57a..22dfe4f1 100644 --- a/java/jni/Android.mk +++ b/java/jni/Android.mk @@ -4,7 +4,9 @@ include $(CLEAR_VARS) LOCAL_MODULE := ZeroTierOneJNI LOCAL_C_INCLUDES := $(ZT1)/include +LOCAL_C_INCLUDES += $(ZT1)/node LOCAL_LDLIBS := -llog +# LOCAL_CFLAGS := -g # ZeroTierOne SDK source files LOCAL_SRC_FILES := \ @@ -39,6 +41,6 @@ LOCAL_SRC_FILES := \ LOCAL_SRC_FILES += \ com_zerotierone_sdk_Node.cpp \ ZT_jniutils.cpp \ - ZT_jnicache.cpp + ZT_jnilookup.cpp include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file diff --git a/java/jni/Application.mk b/java/jni/Application.mk index 3118ec2e..2a789787 100644 --- a/java/jni/Application.mk +++ b/java/jni/Application.mk @@ -1,4 +1,5 @@ -APP_ABI := armeabi armeabi-v7a arm64-v8a x86 -APP_STL := gnustl_static -APP_CPPFLAGS += -Wall -fPIE -fstack-protector -fexceptions -DZT_TRACE - +NDK_TOOLCHAIN_VERSION := clang +APP_STL := c++_static +APP_CPPFLAGS := -O3 -fPIC -fPIE -fvectorize -Wall -fstack-protector -fexceptions -fno-strict-aliasing -DZT_NO_TYPE_PUNNING=1 +APP_PLATFORM := android-14 +APP_ABI := all diff --git a/java/jni/ZT1_jnicache.cpp b/java/jni/ZT1_jnicache.cpp deleted file mode 100644 index d8141058..00000000 --- a/java/jni/ZT1_jnicache.cpp +++ /dev/null @@ -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; -}
\ No newline at end of file diff --git a/java/jni/ZT_jnilookup.cpp b/java/jni/ZT_jnilookup.cpp new file mode 100644 index 00000000..be52a366 --- /dev/null +++ b/java/jni/ZT_jnilookup.cpp @@ -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; +}
\ No newline at end of file diff --git a/java/jni/ZT1_jnicache.h b/java/jni/ZT_jnilookup.h index 001c13fe..f5bd97d7 100644 --- a/java/jni/ZT1_jnicache.h +++ b/java/jni/ZT_jnilookup.h @@ -25,8 +25,8 @@ * LLC. Start here: http://www.zerotier.com/ */ -#ifndef ZT_JNICACHE_H_ -#define ZT_JNICACHE_H_ +#ifndef ZT_JNILOOKUP_H_ +#define ZT_JNILOOKUP_H_ #include <jni.h> #include <map> @@ -34,14 +34,13 @@ -class JniCache { +class JniLookup { public: - JniCache(); - JniCache(JavaVM *jvm); - ~JniCache(); + JniLookup(); + JniLookup(JavaVM *jvm); + ~JniLookup(); void setJavaVM(JavaVM *jvm); - void clearCache(); jclass findClass(const std::string &name); 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 findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr); 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; - ClassMap m_classes; - FieldMap m_fields; - FieldMap m_staticFields; - MethodMap m_methods; - MethodMap m_staticMethods; - }; #endif
\ No newline at end of file diff --git a/java/jni/ZT1_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 794a0624..bd8d8708 100644 --- a/java/jni/ZT1_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -1,9 +1,9 @@ #include "ZT_jniutils.h" -#include "ZT_jnicache.h" +#include "ZT_jnilookup.h" #include <string> #include <assert.h> -extern JniCache cache; +extern JniLookup lookup; #ifdef __cplusplus extern "C" { @@ -15,7 +15,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) jobject resultObject = NULL; - resultClass = cache.findClass("com/zerotier/sdk/ResultCode"); + resultClass = lookup.findClass("com/zerotier/sdk/ResultCode"); if(resultClass == NULL) { LOGE("Couldnt find ResultCode class"); @@ -48,7 +48,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) 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) { LOGE("Error on FindStaticField"); @@ -68,7 +68,7 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) { jobject statusObject = NULL; - jclass statusClass = cache.findClass("com/zerotier/sdk/VirtualNetworkStatus"); + jclass statusClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkStatus"); if(statusClass == NULL) { return NULL; // exception thrown @@ -97,7 +97,7 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) 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); @@ -109,7 +109,7 @@ jobject createEvent(JNIEnv *env, ZT_Event event) jclass eventClass = NULL; jobject eventObject = NULL; - eventClass = cache.findClass("com/zerotier/sdk/Event"); + eventClass = lookup.findClass("com/zerotier/sdk/Event"); if(eventClass == NULL) { return NULL; @@ -147,7 +147,7 @@ jobject createEvent(JNIEnv *env, ZT_Event event) 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); @@ -159,7 +159,7 @@ jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) jclass peerRoleClass = NULL; jobject peerRoleObject = NULL; - peerRoleClass = cache.findClass("com/zerotier/sdk/PeerRole"); + peerRoleClass = lookup.findClass("com/zerotier/sdk/PeerRole"); if(peerRoleClass == NULL) { return NULL; @@ -171,15 +171,15 @@ jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) case ZT_PEER_ROLE_LEAF: fieldName = "PEER_ROLE_LEAF"; break; - case ZT_PEER_ROLE_HUB: - fieldName = "PEER_ROLE_HUB"; + case ZT_PEER_ROLE_RELAY: + fieldName = "PEER_ROLE_RELAY"; break; - case ZT_PEER_ROLE_ROOTSERVER: - fieldName = "PEER_ROLE_ROOTSERVER"; + case ZT_PEER_ROLE_ROOT: + fieldName = "PEER_ROLE_ROOTS"; 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); @@ -191,7 +191,7 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) jclass vntypeClass = NULL; jobject vntypeObject = NULL; - vntypeClass = cache.findClass("com/zerotier/sdk/VirtualNetworkType"); + vntypeClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkType"); if(env->ExceptionCheck() || vntypeClass == NULL) { return NULL; @@ -208,7 +208,7 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) 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); return vntypeObject; } @@ -218,7 +218,7 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfig jclass vnetConfigOpClass = NULL; jobject vnetConfigOpObject = NULL; - vnetConfigOpClass = cache.findClass("com/zerotier/sdk/VirtualNetworkConfigOperation"); + vnetConfigOpClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfigOperation"); if(env->ExceptionCheck() || vnetConfigOpClass == NULL) { return NULL; @@ -241,7 +241,7 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfig 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); return vnetConfigOpObject; } @@ -252,14 +252,14 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) jclass inetAddressClass = NULL; jmethodID inetAddress_getByAddress = NULL; - inetAddressClass = cache.findClass("java/net/InetAddress"); + inetAddressClass = lookup.findClass("java/net/InetAddress"); if(env->ExceptionCheck() || inetAddressClass == NULL) { LOGE("Error finding InetAddress class"); return NULL; } - inetAddress_getByAddress = cache.findStaticMethod( + inetAddress_getByAddress = lookup.findStaticMethod( inetAddressClass, "getByAddress", "([B)Ljava/net/InetAddress;"); if(env->ExceptionCheck() || inetAddress_getByAddress == NULL) { @@ -315,7 +315,7 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) jclass inetSocketAddressClass = NULL; jmethodID inetSocketAddress_constructor = NULL; - inetSocketAddressClass = cache.findClass("java/net/InetSocketAddress"); + inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress"); if(env->ExceptionCheck() || inetSocketAddressClass == NULL) { LOGE("Error finding InetSocketAddress Class"); @@ -330,7 +330,7 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) return NULL; } - inetSocketAddress_constructor = cache.findMethod( + inetSocketAddress_constructor = lookup.findMethod( inetSocketAddressClass, "<init>", "(Ljava/net/InetAddress;I)V"); if(env->ExceptionCheck() || inetSocketAddress_constructor == NULL) { @@ -343,18 +343,18 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) { case AF_INET6: { - LOGD("IPV6 Address"); + LOGV("IPV6 Address"); sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr; port = ntohs(ipv6->sin6_port); - LOGD("Port %d", port); + LOGV("Port %d", port); } break; case AF_INET: { - LOGD("IPV4 Address"); + LOGV("IPV4 Address"); sockaddr_in *ipv4 = (sockaddr_in*)&addr; port = ntohs(ipv4->sin_port); - LOGD("Port: %d", port); + LOGV("Port: %d", port); } break; default: @@ -380,13 +380,13 @@ jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc) jfieldID macField = NULL; jfieldID adiField = NULL; - multicastGroupClass = cache.findClass("com/zerotier/sdk/MulticastGroup"); + multicastGroupClass = lookup.findClass("com/zerotier/sdk/MulticastGroup"); if(env->ExceptionCheck() || multicastGroupClass == NULL) { return NULL; } - multicastGroup_constructor = cache.findMethod( + multicastGroup_constructor = lookup.findMethod( multicastGroupClass, "<init>", "()V"); if(env->ExceptionCheck() || multicastGroup_constructor == NULL) { @@ -399,13 +399,13 @@ jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc) return NULL; } - macField = cache.findField(multicastGroupClass, "mac", "J"); + macField = lookup.findField(multicastGroupClass, "mac", "J"); if(env->ExceptionCheck() || macField == NULL) { return NULL; } - adiField = cache.findField(multicastGroupClass, "adi", "J"); + adiField = lookup.findField(multicastGroupClass, "adi", "J"); if(env->ExceptionCheck() || adiField == NULL) { return NULL; @@ -431,56 +431,56 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) jmethodID ppp_constructor = NULL; - pppClass = cache.findClass("com/zerotier/sdk/PeerPhysicalPath"); + pppClass = lookup.findClass("com/zerotier/sdk/PeerPhysicalPath"); if(env->ExceptionCheck() || pppClass == NULL) { LOGE("Error finding PeerPhysicalPath class"); return NULL; } - addressField = cache.findField(pppClass, "address", "Ljava/net/InetSocketAddress;"); + addressField = lookup.findField(pppClass, "address", "Ljava/net/InetSocketAddress;"); if(env->ExceptionCheck() || addressField == NULL) { LOGE("Error finding address field"); return NULL; } - lastSendField = cache.findField(pppClass, "lastSend", "J"); + lastSendField = lookup.findField(pppClass, "lastSend", "J"); if(env->ExceptionCheck() || lastSendField == NULL) { LOGE("Error finding lastSend field"); return NULL; } - lastReceiveField = cache.findField(pppClass, "lastReceive", "J"); + lastReceiveField = lookup.findField(pppClass, "lastReceive", "J"); if(env->ExceptionCheck() || lastReceiveField == NULL) { LOGE("Error finding lastReceive field"); return NULL; } - fixedField = cache.findField(pppClass, "fixed", "Z"); + fixedField = lookup.findField(pppClass, "fixed", "Z"); if(env->ExceptionCheck() || fixedField == NULL) { LOGE("Error finding fixed field"); return NULL; } - activeField = cache.findField(pppClass, "active", "Z"); + activeField = lookup.findField(pppClass, "active", "Z"); if(env->ExceptionCheck() || activeField == NULL) { LOGE("Error finding active field"); return NULL; } - preferredField = cache.findField(pppClass, "preferred", "Z"); + preferredField = lookup.findField(pppClass, "preferred", "Z"); if(env->ExceptionCheck() || preferredField == NULL) { LOGE("Error finding preferred field"); return NULL; } - ppp_constructor = cache.findMethod(pppClass, "<init>", "()V"); + ppp_constructor = lookup.findMethod(pppClass, "<init>", "()V"); if(env->ExceptionCheck() || ppp_constructor == NULL) { LOGE("Error finding PeerPhysicalPath constructor"); @@ -532,77 +532,77 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) jmethodID peer_constructor = NULL; - peerClass = cache.findClass("com/zerotier/sdk/Peer"); + peerClass = lookup.findClass("com/zerotier/sdk/Peer"); if(env->ExceptionCheck() || peerClass == NULL) { LOGE("Error finding Peer class"); return NULL; } - addressField = cache.findField(peerClass, "address", "J"); + addressField = lookup.findField(peerClass, "address", "J"); if(env->ExceptionCheck() || addressField == NULL) { LOGE("Error finding address field of Peer object"); return NULL; } - lastUnicastFrameField = cache.findField(peerClass, "lastUnicastFrame", "J"); + lastUnicastFrameField = lookup.findField(peerClass, "lastUnicastFrame", "J"); if(env->ExceptionCheck() || lastUnicastFrameField == NULL) { LOGE("Error finding lastUnicastFrame field of Peer object"); return NULL; } - lastMulticastFrameField = cache.findField(peerClass, "lastMulticastFrame", "J"); + lastMulticastFrameField = lookup.findField(peerClass, "lastMulticastFrame", "J"); if(env->ExceptionCheck() || lastMulticastFrameField == NULL) { LOGE("Error finding lastMulticastFrame field of Peer object"); return NULL; } - versionMajorField = cache.findField(peerClass, "versionMajor", "I"); + versionMajorField = lookup.findField(peerClass, "versionMajor", "I"); if(env->ExceptionCheck() || versionMajorField == NULL) { LOGE("Error finding versionMajor field of Peer object"); return NULL; } - versionMinorField = cache.findField(peerClass, "versionMinor", "I"); + versionMinorField = lookup.findField(peerClass, "versionMinor", "I"); if(env->ExceptionCheck() || versionMinorField == NULL) { LOGE("Error finding versionMinor field of Peer object"); return NULL; } - versionRevField = cache.findField(peerClass, "versionRev", "I"); + versionRevField = lookup.findField(peerClass, "versionRev", "I"); if(env->ExceptionCheck() || versionRevField == NULL) { LOGE("Error finding versionRev field of Peer object"); return NULL; } - latencyField = cache.findField(peerClass, "latency", "I"); + latencyField = lookup.findField(peerClass, "latency", "I"); if(env->ExceptionCheck() || latencyField == NULL) { LOGE("Error finding latency field of Peer object"); 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) { LOGE("Error finding role field of Peer object"); 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) { LOGE("Error finding paths field of Peer object"); return NULL; } - peer_constructor = cache.findMethod(peerClass, "<init>", "()V"); + peer_constructor = lookup.findMethod(peerClass, "<init>", "()V"); if(env->ExceptionCheck() || peer_constructor == NULL) { LOGE("Error finding Peer constructor"); @@ -625,7 +625,7 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) env->SetIntField(peerObject, latencyField, peer.latency); 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) { LOGE("Error finding PeerPhysicalPath class"); @@ -675,14 +675,14 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) jfieldID multicastSubscriptionsField = NULL; jfieldID assignedAddressesField = NULL; - vnetConfigClass = cache.findClass("com/zerotier/sdk/VirtualNetworkConfig"); + vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig"); if(vnetConfigClass == NULL) { LOGE("Couldn't find com.zerotier.sdk.VirtualNetworkConfig"); return NULL; } - vnetConfig_constructor = cache.findMethod( + vnetConfig_constructor = lookup.findMethod( vnetConfigClass, "<init>", "()V"); if(env->ExceptionCheck() || vnetConfig_constructor == NULL) { @@ -697,98 +697,98 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) return NULL; } - nwidField = cache.findField(vnetConfigClass, "nwid", "J"); + nwidField = lookup.findField(vnetConfigClass, "nwid", "J"); if(env->ExceptionCheck() || nwidField == NULL) { LOGE("Error getting nwid field"); return NULL; } - macField = cache.findField(vnetConfigClass, "mac", "J"); + macField = lookup.findField(vnetConfigClass, "mac", "J"); if(env->ExceptionCheck() || macField == NULL) { LOGE("Error getting mac field"); return NULL; } - nameField = cache.findField(vnetConfigClass, "name", "Ljava/lang/String;"); + nameField = lookup.findField(vnetConfigClass, "name", "Ljava/lang/String;"); if(env->ExceptionCheck() || nameField == NULL) { LOGE("Error getting name field"); 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) { LOGE("Error getting status field"); 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) { LOGE("Error getting type field"); return NULL; } - mtuField = cache.findField(vnetConfigClass, "mtu", "I"); + mtuField = lookup.findField(vnetConfigClass, "mtu", "I"); if(env->ExceptionCheck() || mtuField == NULL) { LOGE("Error getting mtu field"); return NULL; } - dhcpField = cache.findField(vnetConfigClass, "dhcp", "Z"); + dhcpField = lookup.findField(vnetConfigClass, "dhcp", "Z"); if(env->ExceptionCheck() || dhcpField == NULL) { LOGE("Error getting dhcp field"); return NULL; } - bridgeField = cache.findField(vnetConfigClass, "bridge", "Z"); + bridgeField = lookup.findField(vnetConfigClass, "bridge", "Z"); if(env->ExceptionCheck() || bridgeField == NULL) { LOGE("Error getting bridge field"); return NULL; } - broadcastEnabledField = cache.findField(vnetConfigClass, "broadcastEnabled", "Z"); + broadcastEnabledField = lookup.findField(vnetConfigClass, "broadcastEnabled", "Z"); if(env->ExceptionCheck() || broadcastEnabledField == NULL) { LOGE("Error getting broadcastEnabled field"); return NULL; } - portErrorField = cache.findField(vnetConfigClass, "portError", "I"); + portErrorField = lookup.findField(vnetConfigClass, "portError", "I"); if(env->ExceptionCheck() || portErrorField == NULL) { LOGE("Error getting portError field"); return NULL; } - enabledField = cache.findField(vnetConfigClass, "enabled", "Z"); + enabledField = lookup.findField(vnetConfigClass, "enabled", "Z"); if(env->ExceptionCheck() || enabledField == NULL) { LOGE("Error getting enabled field"); return NULL; } - netconfRevisionField = cache.findField(vnetConfigClass, "netconfRevision", "J"); + netconfRevisionField = lookup.findField(vnetConfigClass, "netconfRevision", "J"); if(env->ExceptionCheck() || netconfRevisionField == NULL) { LOGE("Error getting netconfRevision field"); 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) { LOGE("Error getting multicastSubscriptions field"); return NULL; } - assignedAddressesField = cache.findField(vnetConfigClass, "assignedAddresses", "[Ljava/net/InetSocketAddress;"); + assignedAddressesField = lookup.findField(vnetConfigClass, "assignedAddresses", "[Ljava/net/InetSocketAddress;"); if(env->ExceptionCheck() || assignedAddressesField == NULL) { LOGE("Error getting assignedAddresses field"); @@ -818,13 +818,14 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) } 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, bridgeField, vnetConfig.bridge); env->SetBooleanField(vnetConfigObj, broadcastEnabledField, vnetConfig.broadcastEnabled); + env->SetBooleanField(vnetConfigObj, enabledField, vnetConfig.enabled); 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) { LOGE("Error finding MulticastGroup class"); @@ -849,7 +850,7 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) } env->SetObjectField(vnetConfigObj, multicastSubscriptionsField, mcastSubsArrayObj); - jclass inetSocketAddressClass = cache.findClass("java/net/InetSocketAddress"); + jclass inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress"); if(env->ExceptionCheck() || inetSocketAddressClass == NULL) { LOGE("Error finding InetSocketAddress class"); @@ -886,13 +887,13 @@ jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags jclass versionClass = NULL; jmethodID versionConstructor = NULL; - versionClass = cache.findClass("com/zerotier/sdk/Version"); + versionClass = lookup.findClass("com/zerotier/sdk/Version"); if(env->ExceptionCheck() || versionClass == NULL) { return NULL; } - versionConstructor = cache.findMethod( + versionConstructor = lookup.findMethod( versionClass, "<init>", "()V"); if(env->ExceptionCheck() || versionConstructor == NULL) { @@ -911,25 +912,25 @@ jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags jfieldID revisionField = NULL; jfieldID featureFlagsField = NULL; - majorField = cache.findField(versionClass, "major", "I"); + majorField = lookup.findField(versionClass, "major", "I"); if(env->ExceptionCheck() || majorField == NULL) { return NULL; } - minorField = cache.findField(versionClass, "minor", "I"); + minorField = lookup.findField(versionClass, "minor", "I"); if(env->ExceptionCheck() || minorField == NULL) { return NULL; } - revisionField = cache.findField(versionClass, "revision", "I"); + revisionField = lookup.findField(versionClass, "revision", "I"); if(env->ExceptionCheck() || revisionField == NULL) { return NULL; } - featureFlagsField = cache.findField(versionClass, "featureFlags", "J"); + featureFlagsField = lookup.findField(versionClass, "featureFlags", "J"); if(env->ExceptionCheck() || featureFlagsField == NULL) { return NULL; diff --git a/java/jni/ZT1_jniutils.h b/java/jni/ZT_jniutils.h index b76a28c2..b76a28c2 100644 --- a/java/jni/ZT1_jniutils.h +++ b/java/jni/ZT_jniutils.h diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index ff12708a..e6042649 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -27,17 +27,18 @@ #include "com_zerotierone_sdk_Node.h" #include "ZT_jniutils.h" -#include "ZT_jnicache.h" +#include "ZT_jnilookup.h" #include <ZeroTierOne.h> +#include "Mutex.hpp" #include <map> #include <string> #include <assert.h> #include <string.h> -// global static JNI Cache Object -JniCache cache; +// global static JNI Lookup Object +JniLookup lookup; #ifdef __cplusplus extern "C" { @@ -92,7 +93,7 @@ namespace { enum ZT_VirtualNetworkConfigOperation operation, const ZT_VirtualNetworkConfig *config) { - LOGD("VritualNetworkConfigFunctionCallback"); + LOGV("VritualNetworkConfigFunctionCallback"); JniRef *ref = (JniRef*)userData; JNIEnv *env = NULL; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); @@ -104,7 +105,7 @@ namespace { return -1; } - jmethodID configListenerCallbackMethod = cache.findMethod(configListenerClass, + jmethodID configListenerCallbackMethod = lookup.findMethod(configListenerClass, "onNetworkConfigurationUpdated", "(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I"); if(configListenerCallbackMethod == NULL) @@ -142,7 +143,9 @@ namespace { const void *frameData, 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; assert(ref->node == node); JNIEnv *env = NULL; @@ -156,7 +159,7 @@ namespace { return; } - jmethodID frameListenerCallbackMethod = cache.findMethod( + jmethodID frameListenerCallbackMethod = lookup.findMethod( frameListenerClass, "onVirtualNetworkFrame", "(JJJJJ[B)V"); if(env->ExceptionCheck() || frameListenerCallbackMethod == NULL) @@ -172,9 +175,9 @@ namespace { return; } - jbyte *data = env->GetByteArrayElements(dataArray, NULL); + void *data = env->GetPrimitiveArrayCritical(dataArray, NULL); memcpy(data, frameData, frameLength); - env->ReleaseByteArrayElements(dataArray, data, 0); + env->ReleasePrimitiveArrayCritical(dataArray, data, 0); if(env->ExceptionCheck()) { @@ -188,9 +191,13 @@ namespace { void EventCallback(ZT_Node *node,void *userData,enum ZT_Event event, const void *data) { - LOGD("EventCallback"); + LOGV("EventCallback"); 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; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); @@ -202,7 +209,7 @@ namespace { return; } - jmethodID onEventMethod = cache.findMethod(eventListenerClass, + jmethodID onEventMethod = lookup.findMethod(eventListenerClass, "onEvent", "(Lcom/zerotier/sdk/Event;)V"); if(onEventMethod == NULL) { @@ -211,7 +218,7 @@ namespace { } - jmethodID onOutOfDateMethod = cache.findMethod(eventListenerClass, + jmethodID onOutOfDateMethod = lookup.findMethod(eventListenerClass, "onOutOfDate", "(Lcom/zerotier/sdk/Version;)V"); if(onOutOfDateMethod == NULL) { @@ -220,7 +227,7 @@ namespace { } - jmethodID onNetworkErrorMethod = cache.findMethod(eventListenerClass, + jmethodID onNetworkErrorMethod = lookup.findMethod(eventListenerClass, "onNetworkError", "(Lcom/zerotier/sdk/Event;Ljava/net/InetSocketAddress;)V"); if(onNetworkErrorMethod == NULL) { @@ -229,7 +236,7 @@ namespace { } - jmethodID onTraceMethod = cache.findMethod(eventListenerClass, + jmethodID onTraceMethod = lookup.findMethod(eventListenerClass, "onTrace", "(Ljava/lang/String;)V"); if(onTraceMethod == NULL) { @@ -314,7 +321,7 @@ namespace { return -2; } - jmethodID dataStoreGetCallbackMethod = cache.findMethod( + jmethodID dataStoreGetCallbackMethod = lookup.findMethod( dataStoreGetClass, "onDataStoreGet", "(Ljava/lang/String;[BJ[J)J"); @@ -354,16 +361,16 @@ namespace { if(retval > 0) { - jbyte *data = env->GetByteArrayElements(bufferObj, NULL); + void *data = env->GetPrimitiveArrayCritical(bufferObj, NULL); 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]; - 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; } @@ -386,7 +393,7 @@ namespace { return -1; } - jmethodID dataStorePutCallbackMethod = cache.findMethod( + jmethodID dataStorePutCallbackMethod = lookup.findMethod( dataStorePutClass, "onDataStorePut", "(Ljava/lang/String;[BZ)I"); @@ -396,7 +403,7 @@ namespace { return -2; } - jmethodID deleteMethod = cache.findMethod(dataStorePutClass, + jmethodID deleteMethod = lookup.findMethod(dataStorePutClass, "onDelete", "(Ljava/lang/String;)I"); if(deleteMethod == NULL) { @@ -408,18 +415,25 @@ namespace { if(buffer == NULL) { + LOGD("JNI: Delete file: %s", objectName); // delete operation return env->CallIntMethod( ref->dataStorePutListener, deleteMethod, nameStr); } else { + LOGD("JNI: Write file: %s", objectName); // set operation 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); bool bsecure = secure != 0; - return env->CallIntMethod(ref->dataStorePutListener, dataStorePutCallbackMethod, nameStr, bufferObj, bsecure); @@ -427,11 +441,12 @@ namespace { } int WirePacketSendFunction(ZT_Node *node,void *userData,\ - const struct sockaddr_storage *address, + const struct sockaddr_storage *localAddress, + const struct sockaddr_storage *remoteAddress, const void *buffer, 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; assert(ref->node == node); @@ -446,28 +461,36 @@ namespace { return -1; } - jmethodID packetSenderCallbackMethod = cache.findMethod(packetSenderClass, - "onSendPacketRequested", "(Ljava/net/InetSocketAddress;[B)I"); + jmethodID packetSenderCallbackMethod = lookup.findMethod(packetSenderClass, + "onSendPacketRequested", "(Ljava/net/InetSocketAddress;Ljava/net/InetSocketAddress;[B)I"); if(packetSenderCallbackMethod == NULL) { LOGE("Couldn't find onSendPacketRequested method"); 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); 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; } typedef std::map<uint64_t, JniRef*> NodeMap; static NodeMap nodeMap; + ZeroTier::Mutex nodeMapMutex; ZT_Node* findNode(uint64_t nodeId) { + ZeroTier::Mutex::Lock lock(nodeMapMutex); NodeMap::iterator found = nodeMap.find(nodeId); if(found != nodeMap.end()) { @@ -480,13 +503,13 @@ namespace { JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { - cache.setJavaVM(vm); + lookup.setJavaVM(vm); return JNI_VERSION_1_6; } JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { - cache.clearCache(); + } @@ -507,7 +530,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( env->GetJavaVM(&ref->jvm); jclass cls = env->GetObjectClass(obj); - jfieldID fid = cache.findField( + jfieldID fid = lookup.findField( cls, "getListener", "Lcom/zerotier/sdk/DataStoreGetListener;"); if(fid == NULL) @@ -522,7 +545,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( } ref->dataStoreGetListener = env->NewGlobalRef(tmp); - fid = cache.findField( + fid = lookup.findField( cls, "putListener", "Lcom/zerotier/sdk/DataStorePutListener;"); if(fid == NULL) @@ -537,7 +560,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( } ref->dataStorePutListener = env->NewGlobalRef(tmp); - fid = cache.findField( + fid = lookup.findField( cls, "sender", "Lcom/zerotier/sdk/PacketSender;"); if(fid == NULL) { @@ -551,7 +574,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( } ref->packetSender = env->NewGlobalRef(tmp); - fid = cache.findField( + fid = lookup.findField( cls, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;"); if(fid == NULL) { @@ -565,7 +588,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( } ref->frameListener = env->NewGlobalRef(tmp); - fid = cache.findField( + fid = lookup.findField( cls, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;"); if(fid == NULL) { @@ -579,7 +602,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( } ref->configListener = env->NewGlobalRef(tmp); - fid = cache.findField( + fid = lookup.findField( cls, "eventListener", "Lcom/zerotier/sdk/EventListener;"); if(fid == NULL) { @@ -602,7 +625,8 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( &WirePacketSendFunction, &VirtualNetworkFrameFunctionCallback, &VirtualNetworkConfigFunctionCallback, - &EventCallback); + &EventCallback, + NULL); if(rc != ZT_RESULT_OK) { @@ -618,8 +642,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( return resultObject; } + ZeroTier::Mutex::Lock lock(nodeMapMutex); ref->node = node; nodeMap.insert(std::make_pair(ref->id, ref)); + return resultObject; } @@ -635,7 +661,12 @@ JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete( LOGV("Destroying ZT_Node struct"); 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()) { JniRef *ref = found->second; @@ -693,7 +724,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( unsigned int vlanId = (unsigned int)in_vlanId; 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; @@ -705,15 +739,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( destMac, etherType, vlanId, - (const void*)frameData, + (const void*)localData, frameLength, &nextBackgroundTaskDeadline); - jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL); + jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL); outDeadline[0] = (jlong)nextBackgroundTaskDeadline; - env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0); - - env->ReleaseByteArrayElements(in_frameData, frameData, 0); + env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0); return createResultObject(env, rc); } @@ -727,6 +759,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( JNIEnv *env, jobject obj, jlong id, jlong in_now, + jobject in_localAddress, jobject in_remoteAddress, jbyteArray in_packetData, jlongArray out_nextBackgroundTaskDeadline) @@ -736,26 +769,29 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(node == NULL) { // cannot find valid node. We should never get here. + LOGE("Couldn't find a valid node!"); return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) { + LOGE("nbtd_len < 1"); return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t now = (uint64_t)in_now; // 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) { + LOGE("Can't find InetAddress class"); // can't find java.net.InetAddress return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - jmethodID getAddressMethod = cache.findMethod( + jmethodID getAddressMethod = lookup.findMethod( inetAddressClass, "getAddress", "()[B"); if(getAddressMethod == NULL) { @@ -763,23 +799,29 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( 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) { return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - jmethodID inetSockGetAddressMethod = cache.findMethod( + jmethodID inetSockGetAddressMethod = lookup.findMethod( 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); + } + + jobject remoteAddrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod); - if(addrObject == NULL) + if(remoteAddrObject == NULL) { return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - jmethodID inetSock_getPort = cache.findMethod( + jmethodID inetSock_getPort = lookup.findMethod( InetSocketAddressClass, "getPort", "()I"); if(env->ExceptionCheck() || inetSock_getPort == NULL) @@ -789,7 +831,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( } // call InetSocketAddress.getPort() - int port = env->CallIntMethod(in_remoteAddress, inetSock_getPort); + int remotePort = env->CallIntMethod(in_remoteAddress, inetSock_getPort); if(env->ExceptionCheck()) { LOGE("Exception calling InetSocketAddress.getPort()"); @@ -797,18 +839,60 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( } // Call InetAddress.getAddress() - jbyteArray addressArray = (jbyteArray)env->CallObjectMethod(addrObject, getAddressMethod); - if(addressArray == NULL) + jbyteArray remoteAddressArray = (jbyteArray)env->CallObjectMethod(remoteAddrObject, getAddressMethod); + if(remoteAddressArray == NULL) { + LOGE("Unable to call getAddress()"); // unable to call getAddress() return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - unsigned int addrSize = env->GetArrayLength(addressArray); - // get the address bytes - jbyte *addr = env->GetByteArrayElements(addressArray, NULL); + 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 + jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(remoteAddressArray, NULL); sockaddr_storage remoteAddress = {}; if(addrSize == 16) @@ -816,7 +900,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( // IPV6 address sockaddr_in6 ipv6 = {}; ipv6.sin6_family = AF_INET6; - ipv6.sin6_port = htons(port); + ipv6.sin6_port = htons(remotePort); memcpy(ipv6.sin6_addr.s6_addr, addr, 16); memcpy(&remoteAddress, &ipv6, sizeof(sockaddr_in6)); } @@ -825,37 +909,50 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( // IPV4 address sockaddr_in ipv4 = {}; ipv4.sin_family = AF_INET; - ipv4.sin_port = htons(port); + ipv4.sin_port = htons(remotePort); memcpy(&ipv4.sin_addr, addr, 4); memcpy(&remoteAddress, &ipv4, sizeof(sockaddr_in)); } else { + LOGE("Unknown IP version"); // unknown address type - env->ReleaseByteArrayElements(addressArray, addr, 0); + env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0); return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - + env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0); 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; ZT_ResultCode rc = ZT_Node_processWirePacket( node, now, + &localAddress, &remoteAddress, - packetData, + localData, packetLength, &nextBackgroundTaskDeadline); + if(rc != ZT_RESULT_OK) + { + LOGE("ZT_Node_processWirePacket returned: %d", rc); + } - jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL); - outDeadline[0] = (jlong)nextBackgroundTaskDeadline; - env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0); + free(localData); - env->ReleaseByteArrayElements(addressArray, addr, 0); - env->ReleaseByteArrayElements(in_packetData, packetData, 0); + jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL); + outDeadline[0] = (jlong)nextBackgroundTaskDeadline; + env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0); return createResultObject(env, rc); } @@ -890,9 +987,9 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( 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; - env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0); + env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0); return createResultObject(env, rc); } @@ -1043,13 +1140,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status jmethodID nodeStatusConstructor = NULL; // create a com.zerotier.sdk.NodeStatus object - nodeStatusClass = cache.findClass("com/zerotier/sdk/NodeStatus"); + nodeStatusClass = lookup.findClass("com/zerotier/sdk/NodeStatus"); if(nodeStatusClass == NULL) { return NULL; } - nodeStatusConstructor = cache.findMethod( + nodeStatusConstructor = lookup.findMethod( nodeStatusClass, "<init>", "()V"); if(nodeStatusConstructor == NULL) { @@ -1070,25 +1167,25 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status jfieldID secretIdentityField = NULL; jfieldID onlineField = NULL; - addressField = cache.findField(nodeStatusClass, "address", "J"); + addressField = lookup.findField(nodeStatusClass, "address", "J"); if(addressField == NULL) { return NULL; } - publicIdentityField = cache.findField(nodeStatusClass, "publicIdentity", "Ljava/lang/String;"); + publicIdentityField = lookup.findField(nodeStatusClass, "publicIdentity", "Ljava/lang/String;"); if(publicIdentityField == NULL) { return NULL; } - secretIdentityField = cache.findField(nodeStatusClass, "secretIdentity", "Ljava/lang/String;"); + secretIdentityField = lookup.findField(nodeStatusClass, "secretIdentity", "Ljava/lang/String;"); if(secretIdentityField == NULL) { return NULL; } - onlineField = cache.findField(nodeStatusClass, "online", "Z"); + onlineField = lookup.findField(nodeStatusClass, "online", "Z"); if(onlineField == NULL) { return NULL; @@ -1191,7 +1288,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( return NULL; } - jclass peerClass = cache.findClass("com/zerotier/sdk/Peer"); + jclass peerClass = lookup.findClass("com/zerotier/sdk/Peer"); if(env->ExceptionCheck() || peerClass == NULL) { LOGE("Error finding Peer class"); @@ -1249,7 +1346,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( return NULL; } - jclass vnetConfigClass = cache.findClass("com/zerotier/sdk/VirtualNetworkConfig"); + jclass vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig"); if(env->ExceptionCheck() || vnetConfigClass == NULL) { LOGE("Error finding VirtualNetworkConfig class"); diff --git a/java/jni/com_zerotierone_sdk_Node.h b/java/jni/com_zerotierone_sdk_Node.h index b2e3ed2a..7c1011ab 100644 --- a/java/jni/com_zerotierone_sdk_Node.h +++ b/java/jni/com_zerotierone_sdk_Node.h @@ -34,10 +34,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame /* * Class: com_zerotier_sdk_Node * 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 - (JNIEnv *, jobject, jlong, jlong, jobject, jbyteArray, jlongArray); + (JNIEnv *, jobject, jlong, jlong, jobject, jobject, jbyteArray, jlongArray); /* * Class: com_zerotier_sdk_Node diff --git a/java/src/com/zerotier/one/AndroidFileProvider.java b/java/src/com/zerotier/one/AndroidFileProvider.java deleted file mode 100644 index 0988f9df..00000000 --- a/java/src/com/zerotier/one/AndroidFileProvider.java +++ /dev/null @@ -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."); - } - } - -} diff --git a/java/src/com/zerotier/one/DataStore.java b/java/src/com/zerotier/one/DataStore.java deleted file mode 100644 index d15b2d3d..00000000 --- a/java/src/com/zerotier/one/DataStore.java +++ /dev/null @@ -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; - } - } - - -} diff --git a/java/src/com/zerotier/one/DataStoreFileProvider.java b/java/src/com/zerotier/one/DataStoreFileProvider.java deleted file mode 100644 index ffe078eb..00000000 --- a/java/src/com/zerotier/one/DataStoreFileProvider.java +++ /dev/null @@ -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; -} diff --git a/java/src/com/zerotier/one/JavaFileProvider.java b/java/src/com/zerotier/one/JavaFileProvider.java deleted file mode 100644 index 41889e2f..00000000 --- a/java/src/com/zerotier/one/JavaFileProvider.java +++ /dev/null @@ -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); - } - } -} diff --git a/java/src/com/zerotier/one/OneService.java b/java/src/com/zerotier/one/OneService.java deleted file mode 100644 index 1d3e34c8..00000000 --- a/java/src/com/zerotier/one/OneService.java +++ /dev/null @@ -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 - - } -} diff --git a/java/src/com/zerotier/sdk/EventListener.java b/java/src/com/zerotier/sdk/EventListener.java index 078023d9..bb191c1d 100644 --- a/java/src/com/zerotier/sdk/EventListener.java +++ b/java/src/com/zerotier/sdk/EventListener.java @@ -42,7 +42,7 @@ public interface EventListener { public void onEvent(Event event); /** - * Callback for network error events: {@link Event.EVENT_AUTHENTICATION_FAILUER}, {link Event.EVENT_INVALID_PACKET} + * Callback for network error events: {@link Event.EVENT_AUTHENTICATION_FAILURE}, {link Event.EVENT_INVALID_PACKET} * * @param event {@link Event} enum * @param source {@link InetSocketAddress} containing the origin address of the packet diff --git a/java/src/com/zerotier/sdk/MulticastGroup.java b/java/src/com/zerotier/sdk/MulticastGroup.java index 5c4df87a..68114424 100644 --- a/java/src/com/zerotier/sdk/MulticastGroup.java +++ b/java/src/com/zerotier/sdk/MulticastGroup.java @@ -33,6 +33,10 @@ public final class MulticastGroup { private long mac; private long adi; + public boolean equals(MulticastGroup other) { + return mac == other.mac && adi == other.adi; + } + /** * MAC address (least significant 48 bits) */ diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index e5b12697..4bc6e184 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -169,11 +169,12 @@ public class Node { */ public ResultCode processWirePacket( long now, + InetSocketAddress localAddress, InetSocketAddress remoteAddress, byte[] packetData, long[] nextBackgroundTaskDeadline) { return processWirePacket( - nodeId, now, remoteAddress, packetData, + nodeId, now, localAddress, remoteAddress, packetData, nextBackgroundTaskDeadline); } @@ -393,6 +394,7 @@ public class Node { private native ResultCode processWirePacket( long nodeId, long now, + InetSocketAddress localAddress, InetSocketAddress remoteAddress, byte[] packetData, long[] nextBackgroundTaskDeadline); diff --git a/java/src/com/zerotier/sdk/PacketSender.java b/java/src/com/zerotier/sdk/PacketSender.java index 5302f5ce..ab31729b 100644 --- a/java/src/com/zerotier/sdk/PacketSender.java +++ b/java/src/com/zerotier/sdk/PacketSender.java @@ -37,11 +37,13 @@ public interface PacketSender { * on failure. Note that success does not (of course) guarantee packet * 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 * @return 0 on success, any error code on failure. */ public int onSendPacketRequested( - InetSocketAddress addr, + InetSocketAddress localAddr, + InetSocketAddress remoteAddr, byte[] packetData); } diff --git a/java/src/com/zerotier/sdk/PeerRole.java b/java/src/com/zerotier/sdk/PeerRole.java index 7a5156e1..d7d55f05 100644 --- a/java/src/com/zerotier/sdk/PeerRole.java +++ b/java/src/com/zerotier/sdk/PeerRole.java @@ -34,12 +34,12 @@ public enum PeerRole { PEER_ROLE_LEAF, /** - * Locally federated hub + * relay node */ - PEER_ROLE_HUB, + PEER_ROLE_RELAY, /** - * planetary rootserver + * root server */ - PEER_ROLE_ROOTSERVER + PEER_ROLE_ROOT }
\ No newline at end of file diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index 78ac9da5..9816180b 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -27,11 +27,13 @@ package com.zerotier.sdk; +import java.lang.Comparable; +import java.lang.Override; import java.lang.String; import java.util.ArrayList; 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 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 */ |