First Commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
project(ZeroTierOneJNI)
|
||||
|
||||
find_package(Java COMPONENTS Development)
|
||||
message("JAVA_HOME: $ENV{JAVA_HOME}")
|
||||
|
||||
if(WIN32)
|
||||
set(Java_INCLUDE_DIRS $ENV{JAVA_HOME}/include)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(Java_INCLUDE_DIRS "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/JavaVM.framework/Headers")
|
||||
endif()
|
||||
|
||||
message("Java Include Dirs: ${Java_INCLUDE_DIRS}")
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DNOMINMAX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /W3 /MP")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch i386 -arch x86_64 -Wall -O3 -flto -fPIE -fvectorize -fstack-protector -mmacosx-version-min=10.7 -Wno-unused-private-field")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -fno-rtti")
|
||||
endif()
|
||||
|
||||
set(src_files
|
||||
../ext/lz4/lz4.c
|
||||
../ext/json-parser/json.c
|
||||
../ext/http-parser/http_parser.c
|
||||
../node/C25519.cpp
|
||||
../node/CertificateOfMembership.cpp
|
||||
../node/Defaults.cpp
|
||||
../node/Dictionary.cpp
|
||||
../node/Identity.cpp
|
||||
../node/IncomingPacket.cpp
|
||||
../node/InetAddress.cpp
|
||||
../node/Multicaster.cpp
|
||||
../node/Network.cpp
|
||||
../node/NetworkConfig.cpp
|
||||
../node/Node.cpp
|
||||
../node/OutboundMulticast.cpp
|
||||
../node/Packet.cpp
|
||||
../node/Peer.cpp
|
||||
../node/Poly1305.cpp
|
||||
../node/Salsa20.cpp
|
||||
../node/SelfAwareness.cpp
|
||||
../node/SHA512.cpp
|
||||
../node/Switch.cpp
|
||||
../node/Topology.cpp
|
||||
../node/Utils.cpp
|
||||
../osdep/Http.cpp
|
||||
../osdep/OSUtils.cpp
|
||||
jni/com_zerotierone_sdk_Node.cpp
|
||||
jni/ZT_jniutils.cpp
|
||||
jni/ZT_jnicache.cpp
|
||||
)
|
||||
|
||||
set(include_dirs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../node/
|
||||
${Java_INCLUDE_DIRS})
|
||||
|
||||
if(WIN32)
|
||||
set(include_dirs
|
||||
${include_dirs}
|
||||
${Java_INCLUDE_DIRS}/win32)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${include_dirs}
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED ${src_files})
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".jnilib")
|
||||
endif()
|
||||
|
||||
set(link_libs )
|
||||
|
||||
if(WIN32)
|
||||
set(link_libs
|
||||
wsock32
|
||||
ws2_32
|
||||
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${link_libs})
|
||||
@@ -0,0 +1,17 @@
|
||||
ZeroTier One SDK - Android JNI Wrapper
|
||||
=====
|
||||
|
||||
|
||||
Building
|
||||
-----
|
||||
|
||||
Requires:
|
||||
|
||||
* JDK
|
||||
* ANT
|
||||
* Android NDK
|
||||
|
||||
Required Environment Variables:
|
||||
|
||||
* NDK\_BUILD\_LOC - Path do the ndk-build script in the Android NDK
|
||||
* ANDROID\_PLATFORM - path to the directory android.jar lives (on Windows: C:\Users\<username>\AppData\Local\Android\sdk\platforms\android-21)
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
<project default="build_jar" name="ZeroTierOneSDK" basedir=".">
|
||||
<property environment="env"/>
|
||||
|
||||
<condition property="isWindows">
|
||||
<os family="windows"/>
|
||||
</condition>
|
||||
|
||||
<condition property="isMac">
|
||||
<os family="mac"/>
|
||||
</condition>
|
||||
|
||||
<target name="clean_ant">
|
||||
<delete dir="bin" failonerror="false"/>
|
||||
<delete dir="classes" failonerror="false"/>
|
||||
<delete dir="build_win32" failonerror="false"/>
|
||||
<delete dir="build_win64" failonerror="false"/>
|
||||
<delete dir="mac32_64" failonerror="false"/>
|
||||
<delete dir="libs" failonerror="false"/>
|
||||
<delete dir="obj" failonerror="false"/>
|
||||
</target>
|
||||
|
||||
<target name="build_java">
|
||||
<echo message="os.name = ${os.name}"/>
|
||||
<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"
|
||||
destdir="classes"
|
||||
source="1.7"
|
||||
target="1.7"
|
||||
classpath="${env.ANDROID_PLATFORM}/android.jar"
|
||||
includeantruntime="false"/>
|
||||
</target>
|
||||
|
||||
<target name="build_android">
|
||||
<exec dir="jni" executable="${env.NDK_BUILD_LOC}" failonerror="true">
|
||||
<arg value="ZT1=${env.ZT}"/>
|
||||
<arg value="V=1"/>
|
||||
<!-- <arg value="NDK_DEBUG=1"/> -->
|
||||
</exec>
|
||||
<copy file="libs/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="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="classes/lib/x86/libZeroTierOneJNI.so"
|
||||
overwrite="true"/>
|
||||
<copy file="libs/x86_64/libZeroTierOneJNI.so"
|
||||
tofile="classes/lib/x86_64/libZeroTierOneJNI.so"
|
||||
overwrite="true"/>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="windows" if="isWindows">
|
||||
<mkdir dir="build_win32"/>
|
||||
<exec dir="build_win32/" executable="cmake" failonerror="true">
|
||||
<arg line=".. -G"Visual Studio 11 2012" -DCMAKE_BUILD_TYPE=Release"/>
|
||||
</exec>
|
||||
<exec dir="build_win32/" executable="cmake" failonerror="true">
|
||||
<arg line="--build . --config Release"/>
|
||||
</exec>
|
||||
<copy file="build_win32/Release/ZeroTierOneJNI.dll"
|
||||
tofile="classes/lib/ZeroTierOneJNI_win32.dll"
|
||||
overwrite="true"/>
|
||||
|
||||
<mkdir dir="build_win64"/>
|
||||
<exec dir="build_win64/" executable="cmake" failonerror="true">
|
||||
<arg line=".. -G"Visual Studio 11 2012 Win64" -DCMAKE_BUILD_TYPE=Release"/>
|
||||
</exec>
|
||||
<exec dir="build_win64/" executable="cmake" failonerror="true">
|
||||
<arg line="--build . --config Release"/>
|
||||
</exec>
|
||||
<copy file="build_win64/Release/ZeroTierOneJNI.dll"
|
||||
tofile="classes/lib/ZeroTierOneJNI_win64.dll"
|
||||
overwrite="true"/>
|
||||
</target>
|
||||
|
||||
<target name="mac" if="isMac">
|
||||
<mkdir dir="mac32_64"/>
|
||||
<exec dir="mac32_64/" executable="cmake" failonerror="true">
|
||||
<arg line=".. -DCMAKE_BUILD_TYPE=Release"/>
|
||||
</exec>
|
||||
<exec dir="mac32_64/" executable="cmake" failonerror="true">
|
||||
<arg line="--build . --config Release"/>
|
||||
</exec>
|
||||
<copy file="mac32_64/libZeroTierOneJNI.jnilib"
|
||||
tofile="classes/lib/libZeroTierOneJNI.jnilib"
|
||||
overwrite="true"/>
|
||||
</target>
|
||||
|
||||
<target name="build_jar" depends="build_java,build_android,windows,mac">
|
||||
<jar destfile="bin/ZeroTierOneSDK.jar" basedir="classes"/>
|
||||
</target>
|
||||
|
||||
<target name="docs">
|
||||
<echo message="Generating Javadocs"/>
|
||||
<mkdir dir="doc/"/>
|
||||
<javadoc sourcepath="src/"
|
||||
destdir="doc/"/>
|
||||
</target>
|
||||
</project>
|
||||
@@ -0,0 +1,236 @@
|
||||
//
|
||||
// Created by Brenton Bostick on 1/18/23.
|
||||
//
|
||||
|
||||
#include "ZT_jnicache.h"
|
||||
|
||||
#include "ZT_jniutils.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#define LOG_TAG "Cache"
|
||||
|
||||
#define EXCEPTIONANDNULLCHECK(var) \
|
||||
do { \
|
||||
if (env->ExceptionCheck()) { \
|
||||
assert(false && "Exception"); \
|
||||
} \
|
||||
if ((var) == NULL) { \
|
||||
assert(false && #var " is NULL"); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define SETCLASS(classVar, classNameString) \
|
||||
do { \
|
||||
jclass classVar ## _local = env->FindClass(classNameString); \
|
||||
EXCEPTIONANDNULLCHECK(classVar ## _local); \
|
||||
classVar = reinterpret_cast<jclass>(env->NewGlobalRef(classVar ## _local)); \
|
||||
EXCEPTIONANDNULLCHECK(classVar); \
|
||||
env->DeleteLocalRef(classVar ## _local); \
|
||||
} while (false)
|
||||
|
||||
#define SETOBJECT(objectVar, code) \
|
||||
do { \
|
||||
jobject objectVar ## _local = code; \
|
||||
EXCEPTIONANDNULLCHECK(objectVar ## _local); \
|
||||
objectVar = env->NewGlobalRef(objectVar ## _local); \
|
||||
EXCEPTIONANDNULLCHECK(objectVar); \
|
||||
env->DeleteLocalRef(objectVar ## _local); \
|
||||
} while (false)
|
||||
|
||||
|
||||
//
|
||||
// Classes
|
||||
//
|
||||
|
||||
jclass ArrayList_class;
|
||||
jclass DataStoreGetListener_class;
|
||||
jclass DataStorePutListener_class;
|
||||
jclass EventListener_class;
|
||||
jclass Event_class;
|
||||
jclass Inet4Address_class;
|
||||
jclass Inet6Address_class;
|
||||
jclass InetAddress_class;
|
||||
jclass InetSocketAddress_class;
|
||||
jclass NodeStatus_class;
|
||||
jclass Node_class;
|
||||
jclass PacketSender_class;
|
||||
jclass PathChecker_class;
|
||||
jclass PeerPhysicalPath_class;
|
||||
jclass PeerRole_class;
|
||||
jclass Peer_class;
|
||||
jclass ResultCode_class;
|
||||
jclass Version_class;
|
||||
jclass VirtualNetworkConfigListener_class;
|
||||
jclass VirtualNetworkConfigOperation_class;
|
||||
jclass VirtualNetworkConfig_class;
|
||||
jclass VirtualNetworkDNS_class;
|
||||
jclass VirtualNetworkFrameListener_class;
|
||||
jclass VirtualNetworkRoute_class;
|
||||
jclass VirtualNetworkStatus_class;
|
||||
jclass VirtualNetworkType_class;
|
||||
|
||||
//
|
||||
// Instance methods
|
||||
//
|
||||
|
||||
jmethodID ArrayList_add_method;
|
||||
jmethodID ArrayList_ctor;
|
||||
jmethodID DataStoreGetListener_onDataStoreGet_method;
|
||||
jmethodID DataStorePutListener_onDataStorePut_method;
|
||||
jmethodID DataStorePutListener_onDelete_method;
|
||||
jmethodID EventListener_onEvent_method;
|
||||
jmethodID EventListener_onTrace_method;
|
||||
jmethodID InetAddress_getAddress_method;
|
||||
jmethodID InetSocketAddress_ctor;
|
||||
jmethodID InetSocketAddress_getAddress_method;
|
||||
jmethodID InetSocketAddress_getPort_method;
|
||||
jmethodID NodeStatus_ctor;
|
||||
jmethodID PacketSender_onSendPacketRequested_method;
|
||||
jmethodID PathChecker_onPathCheck_method;
|
||||
jmethodID PathChecker_onPathLookup_method;
|
||||
jmethodID PeerPhysicalPath_ctor;
|
||||
jmethodID Peer_ctor;
|
||||
jmethodID Version_ctor;
|
||||
jmethodID VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method;
|
||||
jmethodID VirtualNetworkConfig_ctor;
|
||||
jmethodID VirtualNetworkDNS_ctor;
|
||||
jmethodID VirtualNetworkFrameListener_onVirtualNetworkFrame_method;
|
||||
jmethodID VirtualNetworkRoute_ctor;
|
||||
|
||||
//
|
||||
// Static methods
|
||||
//
|
||||
|
||||
jmethodID Event_fromInt_method;
|
||||
jmethodID InetAddress_getByAddress_method;
|
||||
jmethodID PeerRole_fromInt_method;
|
||||
jmethodID ResultCode_fromInt_method;
|
||||
jmethodID VirtualNetworkConfigOperation_fromInt_method;
|
||||
jmethodID VirtualNetworkStatus_fromInt_method;
|
||||
jmethodID VirtualNetworkType_fromInt_method;
|
||||
|
||||
//
|
||||
// Enums
|
||||
//
|
||||
|
||||
jobject ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum;
|
||||
jobject ResultCode_RESULT_OK_enum;
|
||||
|
||||
void setupJNICache(JavaVM *vm) {
|
||||
|
||||
JNIEnv *env;
|
||||
GETENV(env, vm);
|
||||
|
||||
//
|
||||
// Classes
|
||||
//
|
||||
|
||||
SETCLASS(ArrayList_class, "java/util/ArrayList");
|
||||
SETCLASS(DataStoreGetListener_class, "com/zerotier/sdk/DataStoreGetListener");
|
||||
SETCLASS(DataStorePutListener_class, "com/zerotier/sdk/DataStorePutListener");
|
||||
SETCLASS(EventListener_class, "com/zerotier/sdk/EventListener");
|
||||
SETCLASS(Event_class, "com/zerotier/sdk/Event");
|
||||
SETCLASS(Inet4Address_class, "java/net/Inet4Address");
|
||||
SETCLASS(Inet6Address_class, "java/net/Inet6Address");
|
||||
SETCLASS(InetAddress_class, "java/net/InetAddress");
|
||||
SETCLASS(InetSocketAddress_class, "java/net/InetSocketAddress");
|
||||
SETCLASS(NodeStatus_class, "com/zerotier/sdk/NodeStatus");
|
||||
SETCLASS(Node_class, "com/zerotier/sdk/Node");
|
||||
SETCLASS(PacketSender_class, "com/zerotier/sdk/PacketSender");
|
||||
SETCLASS(PathChecker_class, "com/zerotier/sdk/PathChecker");
|
||||
SETCLASS(PeerPhysicalPath_class, "com/zerotier/sdk/PeerPhysicalPath");
|
||||
SETCLASS(PeerRole_class, "com/zerotier/sdk/PeerRole");
|
||||
SETCLASS(Peer_class, "com/zerotier/sdk/Peer");
|
||||
SETCLASS(ResultCode_class, "com/zerotier/sdk/ResultCode");
|
||||
SETCLASS(Version_class, "com/zerotier/sdk/Version");
|
||||
SETCLASS(VirtualNetworkConfigListener_class, "com/zerotier/sdk/VirtualNetworkConfigListener");
|
||||
SETCLASS(VirtualNetworkConfigOperation_class, "com/zerotier/sdk/VirtualNetworkConfigOperation");
|
||||
SETCLASS(VirtualNetworkConfig_class, "com/zerotier/sdk/VirtualNetworkConfig");
|
||||
SETCLASS(VirtualNetworkDNS_class, "com/zerotier/sdk/VirtualNetworkDNS");
|
||||
SETCLASS(VirtualNetworkFrameListener_class, "com/zerotier/sdk/VirtualNetworkFrameListener");
|
||||
SETCLASS(VirtualNetworkRoute_class, "com/zerotier/sdk/VirtualNetworkRoute");
|
||||
SETCLASS(VirtualNetworkStatus_class, "com/zerotier/sdk/VirtualNetworkStatus");
|
||||
SETCLASS(VirtualNetworkType_class, "com/zerotier/sdk/VirtualNetworkType");
|
||||
|
||||
//
|
||||
// Instance methods
|
||||
//
|
||||
|
||||
EXCEPTIONANDNULLCHECK(ArrayList_add_method = env->GetMethodID(ArrayList_class, "add", "(Ljava/lang/Object;)Z"));
|
||||
EXCEPTIONANDNULLCHECK(ArrayList_ctor = env->GetMethodID(ArrayList_class, "<init>", "(I)V"));
|
||||
EXCEPTIONANDNULLCHECK(DataStoreGetListener_onDataStoreGet_method = env->GetMethodID(DataStoreGetListener_class, "onDataStoreGet", "(Ljava/lang/String;[B)J"));
|
||||
EXCEPTIONANDNULLCHECK(DataStorePutListener_onDataStorePut_method = env->GetMethodID(DataStorePutListener_class, "onDataStorePut", "(Ljava/lang/String;[BZ)I"));
|
||||
EXCEPTIONANDNULLCHECK(DataStorePutListener_onDelete_method = env->GetMethodID(DataStorePutListener_class, "onDelete", "(Ljava/lang/String;)I"));
|
||||
EXCEPTIONANDNULLCHECK(EventListener_onEvent_method = env->GetMethodID(EventListener_class, "onEvent", "(Lcom/zerotier/sdk/Event;)V"));
|
||||
EXCEPTIONANDNULLCHECK(EventListener_onTrace_method = env->GetMethodID(EventListener_class, "onTrace", "(Ljava/lang/String;)V"));
|
||||
EXCEPTIONANDNULLCHECK(InetAddress_getAddress_method = env->GetMethodID(InetAddress_class, "getAddress", "()[B"));
|
||||
EXCEPTIONANDNULLCHECK(InetSocketAddress_ctor = env->GetMethodID(InetSocketAddress_class, "<init>", "(Ljava/net/InetAddress;I)V"));
|
||||
EXCEPTIONANDNULLCHECK(InetSocketAddress_getAddress_method = env->GetMethodID(InetSocketAddress_class, "getAddress", "()Ljava/net/InetAddress;"));
|
||||
EXCEPTIONANDNULLCHECK(InetSocketAddress_getPort_method = env->GetMethodID(InetSocketAddress_class, "getPort", "()I"));
|
||||
EXCEPTIONANDNULLCHECK(NodeStatus_ctor = env->GetMethodID(NodeStatus_class, "<init>", "(JLjava/lang/String;Ljava/lang/String;Z)V"));
|
||||
EXCEPTIONANDNULLCHECK(PacketSender_onSendPacketRequested_method = env->GetMethodID(PacketSender_class, "onSendPacketRequested", "(JLjava/net/InetSocketAddress;[BI)I"));
|
||||
EXCEPTIONANDNULLCHECK(PathChecker_onPathCheck_method = env->GetMethodID(PathChecker_class, "onPathCheck", "(JJLjava/net/InetSocketAddress;)Z"));
|
||||
EXCEPTIONANDNULLCHECK(PathChecker_onPathLookup_method = env->GetMethodID(PathChecker_class, "onPathLookup", "(JI)Ljava/net/InetSocketAddress;"));
|
||||
EXCEPTIONANDNULLCHECK(PeerPhysicalPath_ctor = env->GetMethodID(PeerPhysicalPath_class, "<init>", "(Ljava/net/InetSocketAddress;JJZ)V"));
|
||||
EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "<init>", "(JIIIILcom/zerotier/sdk/PeerRole;[Lcom/zerotier/sdk/PeerPhysicalPath;)V"));
|
||||
EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "<init>", "(III)V"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method = env->GetMethodID(VirtualNetworkConfigListener_class, "onNetworkConfigurationUpdated", "(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_ctor = env->GetMethodID(VirtualNetworkConfig_class, "<init>", "(JJLjava/lang/String;Lcom/zerotier/sdk/VirtualNetworkStatus;Lcom/zerotier/sdk/VirtualNetworkType;IZZZIJ[Ljava/net/InetSocketAddress;[Lcom/zerotier/sdk/VirtualNetworkRoute;Lcom/zerotier/sdk/VirtualNetworkDNS;)V"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_ctor = env->GetMethodID(VirtualNetworkDNS_class, "<init>", "(Ljava/lang/String;Ljava/util/ArrayList;)V"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkFrameListener_onVirtualNetworkFrame_method = env->GetMethodID(VirtualNetworkFrameListener_class, "onVirtualNetworkFrame", "(JJJJJ[B)V"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_ctor = env->GetMethodID(VirtualNetworkRoute_class, "<init>", "(Ljava/net/InetSocketAddress;Ljava/net/InetSocketAddress;II)V"));
|
||||
|
||||
//
|
||||
// Static methods
|
||||
//
|
||||
|
||||
EXCEPTIONANDNULLCHECK(Event_fromInt_method = env->GetStaticMethodID(Event_class, "fromInt", "(I)Lcom/zerotier/sdk/Event;"));
|
||||
EXCEPTIONANDNULLCHECK(InetAddress_getByAddress_method = env->GetStaticMethodID(InetAddress_class, "getByAddress", "([B)Ljava/net/InetAddress;"));
|
||||
EXCEPTIONANDNULLCHECK(PeerRole_fromInt_method = env->GetStaticMethodID(PeerRole_class, "fromInt", "(I)Lcom/zerotier/sdk/PeerRole;"));
|
||||
EXCEPTIONANDNULLCHECK(ResultCode_fromInt_method = env->GetStaticMethodID(ResultCode_class, "fromInt", "(I)Lcom/zerotier/sdk/ResultCode;"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_fromInt_method = env->GetStaticMethodID(VirtualNetworkConfigOperation_class, "fromInt", "(I)Lcom/zerotier/sdk/VirtualNetworkConfigOperation;"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_fromInt_method = env->GetStaticMethodID(VirtualNetworkStatus_class, "fromInt", "(I)Lcom/zerotier/sdk/VirtualNetworkStatus;"));
|
||||
EXCEPTIONANDNULLCHECK(VirtualNetworkType_fromInt_method = env->GetStaticMethodID(VirtualNetworkType_class, "fromInt", "(I)Lcom/zerotier/sdk/VirtualNetworkType;"));
|
||||
|
||||
//
|
||||
// Enums
|
||||
//
|
||||
|
||||
SETOBJECT(ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum, createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL));
|
||||
SETOBJECT(ResultCode_RESULT_OK_enum, createResultObject(env, ZT_RESULT_OK));
|
||||
}
|
||||
|
||||
void teardownJNICache(JavaVM *vm) {
|
||||
|
||||
JNIEnv *env;
|
||||
GETENV(env, vm);
|
||||
|
||||
env->DeleteGlobalRef(ArrayList_class);
|
||||
env->DeleteGlobalRef(DataStoreGetListener_class);
|
||||
env->DeleteGlobalRef(DataStorePutListener_class);
|
||||
env->DeleteGlobalRef(EventListener_class);
|
||||
env->DeleteGlobalRef(Event_class);
|
||||
env->DeleteGlobalRef(InetAddress_class);
|
||||
env->DeleteGlobalRef(InetSocketAddress_class);
|
||||
env->DeleteGlobalRef(NodeStatus_class);
|
||||
env->DeleteGlobalRef(Node_class);
|
||||
env->DeleteGlobalRef(PacketSender_class);
|
||||
env->DeleteGlobalRef(PathChecker_class);
|
||||
env->DeleteGlobalRef(PeerPhysicalPath_class);
|
||||
env->DeleteGlobalRef(PeerRole_class);
|
||||
env->DeleteGlobalRef(Peer_class);
|
||||
env->DeleteGlobalRef(ResultCode_class);
|
||||
env->DeleteGlobalRef(Version_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkConfigListener_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkConfigOperation_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkConfig_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkDNS_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkFrameListener_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkRoute_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkStatus_class);
|
||||
env->DeleteGlobalRef(VirtualNetworkType_class);
|
||||
|
||||
env->DeleteGlobalRef(ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum);
|
||||
env->DeleteGlobalRef(ResultCode_RESULT_OK_enum);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// Created by Brenton Bostick on 1/18/23.
|
||||
//
|
||||
|
||||
#ifndef ZEROTIERANDROID_JNICACHE_H
|
||||
#define ZEROTIERANDROID_JNICACHE_H
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
|
||||
//
|
||||
// Classes
|
||||
//
|
||||
|
||||
extern jclass ArrayList_class;
|
||||
extern jclass DataStoreGetListener_class;
|
||||
extern jclass DataStorePutListener_class;
|
||||
extern jclass EventListener_class;
|
||||
extern jclass Event_class;
|
||||
extern jclass Inet4Address_class;
|
||||
extern jclass Inet6Address_class;
|
||||
extern jclass InetAddress_class;
|
||||
extern jclass InetSocketAddress_class;
|
||||
extern jclass NodeStatus_class;
|
||||
extern jclass Node_class;
|
||||
extern jclass PacketSender_class;
|
||||
extern jclass PathChecker_class;
|
||||
extern jclass PeerPhysicalPath_class;
|
||||
extern jclass PeerRole_class;
|
||||
extern jclass Peer_class;
|
||||
extern jclass ResultCode_class;
|
||||
extern jclass Version_class;
|
||||
extern jclass VirtualNetworkConfigListener_class;
|
||||
extern jclass VirtualNetworkConfigOperation_class;
|
||||
extern jclass VirtualNetworkConfig_class;
|
||||
extern jclass VirtualNetworkDNS_class;
|
||||
extern jclass VirtualNetworkFrameListener_class;
|
||||
extern jclass VirtualNetworkRoute_class;
|
||||
extern jclass VirtualNetworkStatus_class;
|
||||
extern jclass VirtualNetworkType_class;
|
||||
|
||||
//
|
||||
// Instance methods
|
||||
//
|
||||
|
||||
extern jmethodID ArrayList_add_method;
|
||||
extern jmethodID ArrayList_ctor;
|
||||
extern jmethodID DataStoreGetListener_onDataStoreGet_method;
|
||||
extern jmethodID DataStorePutListener_onDataStorePut_method;
|
||||
extern jmethodID DataStorePutListener_onDelete_method;
|
||||
extern jmethodID EventListener_onEvent_method;
|
||||
extern jmethodID EventListener_onTrace_method;
|
||||
extern jmethodID InetAddress_getAddress_method;
|
||||
extern jmethodID InetSocketAddress_ctor;
|
||||
extern jmethodID InetSocketAddress_getAddress_method;
|
||||
extern jmethodID InetSocketAddress_getPort_method;
|
||||
extern jmethodID NodeStatus_ctor;
|
||||
extern jmethodID PacketSender_onSendPacketRequested_method;
|
||||
extern jmethodID PathChecker_onPathCheck_method;
|
||||
extern jmethodID PathChecker_onPathLookup_method;
|
||||
extern jmethodID PeerPhysicalPath_ctor;
|
||||
extern jmethodID Peer_ctor;
|
||||
extern jmethodID Version_ctor;
|
||||
extern jmethodID VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method;
|
||||
extern jmethodID VirtualNetworkConfig_ctor;
|
||||
extern jmethodID VirtualNetworkDNS_ctor;
|
||||
extern jmethodID VirtualNetworkFrameListener_onVirtualNetworkFrame_method;
|
||||
extern jmethodID VirtualNetworkRoute_ctor;
|
||||
|
||||
//
|
||||
// Static methods
|
||||
//
|
||||
|
||||
extern jmethodID Event_fromInt_method;
|
||||
extern jmethodID InetAddress_getByAddress_method;
|
||||
extern jmethodID PeerRole_fromInt_method;
|
||||
extern jmethodID ResultCode_fromInt_method;
|
||||
extern jmethodID VirtualNetworkConfigOperation_fromInt_method;
|
||||
extern jmethodID VirtualNetworkStatus_fromInt_method;
|
||||
extern jmethodID VirtualNetworkType_fromInt_method;
|
||||
|
||||
//
|
||||
// Enums
|
||||
//
|
||||
|
||||
extern jobject ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum;
|
||||
extern jobject ResultCode_RESULT_OK_enum;
|
||||
|
||||
void setupJNICache(JavaVM *vm);
|
||||
void teardownJNICache(JavaVM *vm);
|
||||
|
||||
#endif // ZEROTIERANDROID_JNICACHE_H
|
||||
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "ZT_jniutils.h"
|
||||
|
||||
#include "ZT_jnicache.h"
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define LOG_TAG "Utils"
|
||||
|
||||
jobject createResultObject(JNIEnv *env, ZT_ResultCode code)
|
||||
{
|
||||
jobject resultObject = env->CallStaticObjectMethod(ResultCode_class, ResultCode_fromInt_method, (jint)code);
|
||||
if(env->ExceptionCheck() || resultObject == NULL) {
|
||||
LOGE("Error creating ResultCode object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return resultObject;
|
||||
}
|
||||
|
||||
|
||||
jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status)
|
||||
{
|
||||
jobject statusObject = env->CallStaticObjectMethod(VirtualNetworkStatus_class, VirtualNetworkStatus_fromInt_method, (jint)status);
|
||||
if (env->ExceptionCheck() || statusObject == NULL) {
|
||||
LOGE("Error creating VirtualNetworkStatus object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return statusObject;
|
||||
}
|
||||
|
||||
jobject createEvent(JNIEnv *env, ZT_Event event)
|
||||
{
|
||||
jobject eventObject = env->CallStaticObjectMethod(Event_class, Event_fromInt_method, (jint)event);
|
||||
if (env->ExceptionCheck() || eventObject == NULL) {
|
||||
LOGE("Error creating Event object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return eventObject;
|
||||
}
|
||||
|
||||
jobject createPeerRole(JNIEnv *env, ZT_PeerRole role)
|
||||
{
|
||||
jobject peerRoleObject = env->CallStaticObjectMethod(PeerRole_class, PeerRole_fromInt_method, (jint)role);
|
||||
if (env->ExceptionCheck() || peerRoleObject == NULL) {
|
||||
LOGE("Error creating PeerRole object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return peerRoleObject;
|
||||
}
|
||||
|
||||
jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type)
|
||||
{
|
||||
jobject vntypeObject = env->CallStaticObjectMethod(VirtualNetworkType_class, VirtualNetworkType_fromInt_method, (jint)type);
|
||||
if (env->ExceptionCheck() || vntypeObject == NULL) {
|
||||
LOGE("Error creating VirtualNetworkType object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vntypeObject;
|
||||
}
|
||||
|
||||
jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op)
|
||||
{
|
||||
jobject vnetConfigOpObject = env->CallStaticObjectMethod(VirtualNetworkConfigOperation_class, VirtualNetworkConfigOperation_fromInt_method, (jint)op);
|
||||
if (env->ExceptionCheck() || vnetConfigOpObject == NULL) {
|
||||
LOGE("Error creating VirtualNetworkConfigOperation object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vnetConfigOpObject;
|
||||
}
|
||||
|
||||
jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr)
|
||||
{
|
||||
jobject inetAddressObj = NULL;
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
case AF_INET6:
|
||||
{
|
||||
sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr;
|
||||
const unsigned char *bytes = reinterpret_cast<const unsigned char *>(&ipv6->sin6_addr.s6_addr);
|
||||
|
||||
jbyteArray buff = newByteArray(env, bytes, 16);
|
||||
if(env->ExceptionCheck() || buff == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inetAddressObj = env->CallStaticObjectMethod(
|
||||
InetAddress_class, InetAddress_getByAddress_method, (jbyteArray)buff);
|
||||
}
|
||||
break;
|
||||
case AF_INET:
|
||||
{
|
||||
sockaddr_in *ipv4 = (sockaddr_in*)&addr;
|
||||
const unsigned char *bytes = reinterpret_cast<const unsigned char *>(&ipv4->sin_addr.s_addr);
|
||||
jbyteArray buff = newByteArray(env, bytes, 4);
|
||||
if(env->ExceptionCheck() || buff == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inetAddressObj = env->CallStaticObjectMethod(
|
||||
InetAddress_class, InetAddress_getByAddress_method, (jbyteArray)buff);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
assert(false && "addr.ss_family is neither AF_INET6 nor AF_INET");
|
||||
}
|
||||
}
|
||||
if(env->ExceptionCheck() || inetAddressObj == NULL) {
|
||||
LOGE("Error creating InetAddress object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return inetAddressObj;
|
||||
}
|
||||
|
||||
int addressPort(const sockaddr_storage addr) {
|
||||
|
||||
int port = 0;
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
case AF_INET6:
|
||||
{
|
||||
sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr;
|
||||
port = ntohs(ipv6->sin6_port);
|
||||
}
|
||||
break;
|
||||
case AF_INET:
|
||||
{
|
||||
sockaddr_in *ipv4 = (sockaddr_in*)&addr;
|
||||
port = ntohs(ipv4->sin_port);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
assert(false && "addr.ss_family is neither AF_INET6 nor AF_INET");
|
||||
}
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
//
|
||||
// addr may be empty
|
||||
//
|
||||
// may return NULL
|
||||
//
|
||||
jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr)
|
||||
{
|
||||
if(isSocketAddressEmpty(addr))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject inetAddressObject = newInetAddress(env, addr);
|
||||
|
||||
if(env->ExceptionCheck() || inetAddressObject == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int port = addressPort(addr);
|
||||
|
||||
jobject inetSocketAddressObject = env->NewObject(InetSocketAddress_class, InetSocketAddress_ctor, (jobject)inetAddressObject, (jint)port);
|
||||
if(env->ExceptionCheck() || inetSocketAddressObject == NULL) {
|
||||
LOGE("Error creating InetSocketAddress object");
|
||||
return NULL;
|
||||
}
|
||||
return inetSocketAddressObject;
|
||||
}
|
||||
|
||||
jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp)
|
||||
{
|
||||
//
|
||||
// may be NULL
|
||||
//
|
||||
jobject addressObject = newInetSocketAddress(env, ppp.address);
|
||||
if(env->ExceptionCheck()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject pppObject = env->NewObject(
|
||||
PeerPhysicalPath_class,
|
||||
PeerPhysicalPath_ctor,
|
||||
(jobject)addressObject,
|
||||
(jlong)ppp.lastSend,
|
||||
(jlong)ppp.lastReceive,
|
||||
(jboolean)ppp.preferred); // ANDROID-56: cast to correct size
|
||||
if(env->ExceptionCheck() || pppObject == NULL)
|
||||
{
|
||||
LOGE("Error creating PPP object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pppObject;
|
||||
}
|
||||
|
||||
jobject newPeer(JNIEnv *env, const ZT_Peer &peer)
|
||||
{
|
||||
jobject peerRoleObj = createPeerRole(env, peer.role);
|
||||
if(env->ExceptionCheck() || peerRoleObj == NULL)
|
||||
{
|
||||
return NULL; // out of memory
|
||||
}
|
||||
|
||||
jobjectArray arrayObject = newPeerPhysicalPathArray(env, peer.paths, peer.pathCount);
|
||||
if (env->ExceptionCheck() || arrayObject == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject peerObject = env->NewObject(
|
||||
Peer_class,
|
||||
Peer_ctor,
|
||||
(jlong)peer.address,
|
||||
(jint)peer.versionMajor,
|
||||
(jint)peer.versionMinor,
|
||||
(jint)peer.versionRev,
|
||||
(jint)peer.latency,
|
||||
(jobject)peerRoleObj,
|
||||
(jobjectArray)arrayObject);
|
||||
if(env->ExceptionCheck() || peerObject == NULL)
|
||||
{
|
||||
LOGE("Error creating Peer object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return peerObject;
|
||||
}
|
||||
|
||||
jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig)
|
||||
{
|
||||
jstring nameStr = env->NewStringUTF(vnetConfig.name);
|
||||
if(env->ExceptionCheck() || nameStr == NULL)
|
||||
{
|
||||
LOGE("Exception creating new string");
|
||||
return NULL; // out of memory
|
||||
}
|
||||
|
||||
jobject statusObject = createVirtualNetworkStatus(env, vnetConfig.status);
|
||||
if(env->ExceptionCheck() || statusObject == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject typeObject = createVirtualNetworkType(env, vnetConfig.type);
|
||||
if(env->ExceptionCheck() || typeObject == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobjectArray assignedAddrArrayObj = newInetSocketAddressArray(env, vnetConfig.assignedAddresses, vnetConfig.assignedAddressCount);
|
||||
if (env->ExceptionCheck() || assignedAddrArrayObj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobjectArray routesArrayObj = newVirtualNetworkRouteArray(env, vnetConfig.routes, vnetConfig.routeCount);
|
||||
if (env->ExceptionCheck() || routesArrayObj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// may be NULL
|
||||
//
|
||||
jobject dnsObj = newVirtualNetworkDNS(env, vnetConfig.dns);
|
||||
if(env->ExceptionCheck()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject vnetConfigObj = env->NewObject(
|
||||
VirtualNetworkConfig_class,
|
||||
VirtualNetworkConfig_ctor,
|
||||
(jlong)vnetConfig.nwid,
|
||||
(jlong)vnetConfig.mac,
|
||||
(jstring)nameStr,
|
||||
(jobject)statusObject,
|
||||
(jobject)typeObject,
|
||||
(jint)vnetConfig.mtu,
|
||||
(jboolean)vnetConfig.dhcp, // ANDROID-56: cast to correct size
|
||||
(jboolean)vnetConfig.bridge, // ANDROID-56: cast to correct size
|
||||
(jboolean)vnetConfig.broadcastEnabled, // ANDROID-56: cast to correct size
|
||||
(jint)vnetConfig.portError,
|
||||
(jlong)vnetConfig.netconfRevision,
|
||||
(jobjectArray)assignedAddrArrayObj,
|
||||
(jobjectArray)routesArrayObj,
|
||||
(jobject)dnsObj);
|
||||
if(env->ExceptionCheck() || vnetConfigObj == NULL)
|
||||
{
|
||||
LOGE("Error creating new VirtualNetworkConfig object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vnetConfigObj;
|
||||
}
|
||||
|
||||
jobject newVersion(JNIEnv *env, int major, int minor, int rev)
|
||||
{
|
||||
// create a com.zerotier.sdk.Version object
|
||||
jobject versionObj = env->NewObject(Version_class, Version_ctor, (jint)major, (jint)minor, (jint)rev);
|
||||
if(env->ExceptionCheck() || versionObj == NULL)
|
||||
{
|
||||
LOGE("Error creating new Version object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return versionObj;
|
||||
}
|
||||
|
||||
jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route)
|
||||
{
|
||||
//
|
||||
// may be NULL
|
||||
//
|
||||
jobject targetObj = newInetSocketAddress(env, route.target);
|
||||
if (env->ExceptionCheck()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// may be NULL
|
||||
//
|
||||
jobject viaObj = newInetSocketAddress(env, route.via);
|
||||
if (env->ExceptionCheck()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject routeObj = env->NewObject(
|
||||
VirtualNetworkRoute_class,
|
||||
VirtualNetworkRoute_ctor,
|
||||
(jobject)targetObj,
|
||||
(jobject)viaObj,
|
||||
(jint)route.flags, // ANDROID-56: cast to correct size
|
||||
(jint)route.metric); // ANDROID-56: cast to correct size
|
||||
if(env->ExceptionCheck() || routeObj == NULL)
|
||||
{
|
||||
LOGE("Exception creating VirtualNetworkRoute");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return routeObj;
|
||||
}
|
||||
|
||||
//
|
||||
// may return NULL
|
||||
//
|
||||
jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns)
|
||||
{
|
||||
if (strlen(dns.domain) == 0) {
|
||||
LOGD("dns.domain is empty; returning NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jstring domain = env->NewStringUTF(dns.domain);
|
||||
if (env->ExceptionCheck() || domain == NULL) {
|
||||
LOGE("Exception creating new string");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject addrList = env->NewObject(ArrayList_class, ArrayList_ctor, (jint)0);
|
||||
if (env->ExceptionCheck() || addrList == NULL) {
|
||||
LOGE("Exception creating new ArrayList");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ZT_MAX_DNS_SERVERS; ++i) { //NOLINT
|
||||
|
||||
struct sockaddr_storage tmp = dns.server_addr[i];
|
||||
|
||||
//
|
||||
// may be NULL
|
||||
//
|
||||
jobject addr = newInetSocketAddress(env, tmp);
|
||||
if (env->ExceptionCheck()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
env->CallBooleanMethod(addrList, ArrayList_add_method, (jobject)addr);
|
||||
if(env->ExceptionCheck())
|
||||
{
|
||||
LOGE("Exception calling add");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(addr);
|
||||
}
|
||||
|
||||
jobject dnsObj = env->NewObject(
|
||||
VirtualNetworkDNS_class,
|
||||
VirtualNetworkDNS_ctor,
|
||||
(jstring)domain,
|
||||
(jobject)addrList);
|
||||
if (env->ExceptionCheck() || dnsObj == NULL) {
|
||||
LOGE("Exception creating new VirtualNetworkDNS");
|
||||
return NULL;
|
||||
}
|
||||
return dnsObj;
|
||||
}
|
||||
|
||||
jobject newNodeStatus(JNIEnv *env, const ZT_NodeStatus &status) {
|
||||
|
||||
jstring pubIdentStr = env->NewStringUTF(status.publicIdentity);
|
||||
if(env->ExceptionCheck() || pubIdentStr == NULL)
|
||||
{
|
||||
LOGE("Exception creating new string");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jstring secIdentStr = env->NewStringUTF(status.secretIdentity);
|
||||
if(env->ExceptionCheck() || secIdentStr == NULL)
|
||||
{
|
||||
LOGE("Exception creating new string");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject nodeStatusObj = env->NewObject(
|
||||
NodeStatus_class,
|
||||
NodeStatus_ctor,
|
||||
(jlong)status.address,
|
||||
(jstring)pubIdentStr,
|
||||
(jstring)secIdentStr,
|
||||
(jboolean)status.online);
|
||||
if(env->ExceptionCheck() || nodeStatusObj == NULL) {
|
||||
LOGE("Exception creating new NodeStatus");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nodeStatusObj;
|
||||
}
|
||||
|
||||
jobjectArray newPeerArray(JNIEnv *env, const ZT_Peer *peers, size_t count) {
|
||||
return newArrayObject<ZT_Peer, newPeer>(env, peers, count, Peer_class);
|
||||
}
|
||||
|
||||
jobjectArray newVirtualNetworkConfigArray(JNIEnv *env, const ZT_VirtualNetworkConfig *networks, size_t count) {
|
||||
return newArrayObject<ZT_VirtualNetworkConfig, newNetworkConfig>(env, networks, count, VirtualNetworkConfig_class);
|
||||
}
|
||||
|
||||
jobjectArray newPeerPhysicalPathArray(JNIEnv *env, const ZT_PeerPhysicalPath *paths, size_t count) {
|
||||
return newArrayObject<ZT_PeerPhysicalPath, newPeerPhysicalPath>(env, paths, count, PeerPhysicalPath_class);
|
||||
}
|
||||
|
||||
jobjectArray newInetSocketAddressArray(JNIEnv *env, const sockaddr_storage *addresses, size_t count) {
|
||||
return newArrayObject<sockaddr_storage, newInetSocketAddress>(env, addresses, count, InetSocketAddress_class);
|
||||
}
|
||||
|
||||
jobjectArray newVirtualNetworkRouteArray(JNIEnv *env, const ZT_VirtualNetworkRoute *routes, size_t count) {
|
||||
return newArrayObject<ZT_VirtualNetworkRoute, newVirtualNetworkRoute>(env, routes, count, VirtualNetworkRoute_class);
|
||||
}
|
||||
|
||||
void newArrayObject_logCount(size_t count) {
|
||||
LOGE("count > JSIZE_MAX: %zu", count);
|
||||
}
|
||||
|
||||
void newArrayObject_log(const char *msg) {
|
||||
LOGE("%s", msg);
|
||||
}
|
||||
|
||||
jbyteArray newByteArray(JNIEnv *env, const unsigned char *bytes, size_t count) {
|
||||
|
||||
if (count > JSIZE_MAX) {
|
||||
LOGE("count > JSIZE_MAX: %zu", count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsize jCount = static_cast<jsize>(count);
|
||||
const jbyte *jBytes = reinterpret_cast<const jbyte *>(bytes);
|
||||
|
||||
jbyteArray byteArrayObj = env->NewByteArray(jCount);
|
||||
if(byteArrayObj == NULL)
|
||||
{
|
||||
LOGE("NewByteArray returned NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env->SetByteArrayRegion(byteArrayObj, 0, jCount, jBytes);
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Exception when calling SetByteArrayRegion");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return byteArrayObj;
|
||||
}
|
||||
|
||||
jbyteArray newByteArray(JNIEnv *env, size_t count) {
|
||||
|
||||
if (count > JSIZE_MAX) {
|
||||
LOGE("count > JSIZE_MAX: %zu", count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsize jCount = static_cast<jsize>(count);
|
||||
|
||||
jbyteArray byteArrayObj = env->NewByteArray(jCount);
|
||||
if(byteArrayObj == NULL)
|
||||
{
|
||||
LOGE("NewByteArray returned NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return byteArrayObj;
|
||||
}
|
||||
|
||||
bool isSocketAddressEmpty(const sockaddr_storage addr) {
|
||||
|
||||
//
|
||||
// was:
|
||||
// struct sockaddr_storage nullAddress = {0};
|
||||
//
|
||||
// but was getting this warning:
|
||||
// warning: suggest braces around initialization of subobject
|
||||
//
|
||||
// when building ZeroTierOne
|
||||
//
|
||||
sockaddr_storage emptyAddress; //NOLINT
|
||||
|
||||
//
|
||||
// It is possible to assume knowledge about internals of sockaddr_storage and construct
|
||||
// correct 0-initializer, but it is simpler to just treat sockaddr_storage as opaque and
|
||||
// use memset here to fill with 0
|
||||
//
|
||||
// This is also done in InetAddress.hpp for InetAddress
|
||||
//
|
||||
memset(&emptyAddress, 0, sizeof(sockaddr_storage));
|
||||
|
||||
return (memcmp(&addr, &emptyAddress, sizeof(sockaddr_storage)) == 0); //NOLINT
|
||||
}
|
||||
|
||||
//
|
||||
// returns empty sockaddr_storage on error
|
||||
//
|
||||
sockaddr_storage fromSocketAddressObject(JNIEnv *env, jobject sockAddressObject) {
|
||||
|
||||
sockaddr_storage emptyAddress; //NOLINT
|
||||
|
||||
memset(&emptyAddress, 0, sizeof(sockaddr_storage));
|
||||
|
||||
jint port = env->CallIntMethod(sockAddressObject, InetSocketAddress_getPort_method);
|
||||
if(env->ExceptionCheck())
|
||||
{
|
||||
LOGE("Exception calling getPort");
|
||||
return emptyAddress;
|
||||
}
|
||||
|
||||
jobject addressObject = env->CallObjectMethod(sockAddressObject, InetSocketAddress_getAddress_method);
|
||||
if(env->ExceptionCheck() || addressObject == NULL)
|
||||
{
|
||||
LOGE("Exception calling getAddress");
|
||||
return emptyAddress;
|
||||
}
|
||||
|
||||
jbyteArray addressArrayObj = reinterpret_cast<jbyteArray>(env->CallObjectMethod(addressObject, InetAddress_getAddress_method));
|
||||
if(env->ExceptionCheck() || addressArrayObj == NULL)
|
||||
{
|
||||
LOGE("Exception calling getAddress");
|
||||
return emptyAddress;
|
||||
}
|
||||
|
||||
sockaddr_storage addr = {};
|
||||
|
||||
if (env->IsInstanceOf(addressObject, Inet4Address_class)) {
|
||||
|
||||
// IPV4
|
||||
|
||||
assert(env->GetArrayLength(addressArrayObj) == 4);
|
||||
|
||||
sockaddr_in *addr_4 = reinterpret_cast<sockaddr_in *>(&addr);
|
||||
addr_4->sin_family = AF_INET;
|
||||
addr_4->sin_port = htons(port);
|
||||
|
||||
void *data = env->GetPrimitiveArrayCritical(addressArrayObj, NULL);
|
||||
memcpy(&addr_4->sin_addr.s_addr, data, 4);
|
||||
env->ReleasePrimitiveArrayCritical(addressArrayObj, data, 0);
|
||||
|
||||
} else if (env->IsInstanceOf(addressObject, Inet6Address_class)) {
|
||||
|
||||
// IPV6
|
||||
|
||||
assert(env->GetArrayLength(addressArrayObj) == 16);
|
||||
|
||||
sockaddr_in6 *addr_6 = reinterpret_cast<sockaddr_in6 *>(&addr);
|
||||
addr_6->sin6_family = AF_INET6;
|
||||
addr_6->sin6_port = htons(port);
|
||||
|
||||
void *data = env->GetPrimitiveArrayCritical(addressArrayObj, NULL);
|
||||
memcpy(&addr_6->sin6_addr.s6_addr, data, 16);
|
||||
env->ReleasePrimitiveArrayCritical(addressArrayObj, data, 0);
|
||||
|
||||
} else {
|
||||
assert(false && "addressObject is neither Inet4Address nor Inet6Address");
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef ZT_jniutils_h_
|
||||
#define ZT_jniutils_h_
|
||||
|
||||
#include <jni.h>
|
||||
#include <ZeroTierOne.h>
|
||||
|
||||
#include <limits> // for numeric_limits
|
||||
#include <sys/socket.h> // for sockaddr_storage
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
||||
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
#else
|
||||
#define LOGV(...)
|
||||
#define LOGD(...)
|
||||
#endif
|
||||
|
||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
|
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
#else
|
||||
#if !defined(NDEBUG)
|
||||
#define LOGV(...) fprintf(stdout, __VA_ARGS__)
|
||||
#define LOGD(...) fprintf(stdout, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGV(...)
|
||||
#define LOGD(...)
|
||||
#endif
|
||||
|
||||
#define LOGI(...) fprintf(stdout, __VA_ARGS__)
|
||||
#define LOGE(...) fprintf(stdout, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Call GetEnv and assert if there is an error
|
||||
//
|
||||
#define GETENV(env, vm) \
|
||||
do { \
|
||||
jint getEnvRet; \
|
||||
assert(vm); \
|
||||
if ((getEnvRet = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6)) != JNI_OK) { \
|
||||
LOGE("Error calling GetEnv: %d", getEnvRet); \
|
||||
assert(false && "Error calling GetEnv"); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
//
|
||||
// Call GetJavaVM and assert if there is an error
|
||||
//
|
||||
#define GETJAVAVM(env, vm) \
|
||||
do { \
|
||||
jint getJavaVMRet; \
|
||||
if ((getJavaVMRet = env->GetJavaVM(&vm)) != 0) { \
|
||||
LOGE("Error calling GetJavaVM: %d", getJavaVMRet); \
|
||||
assert(false && "Error calling GetJavaVM"); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
|
||||
const jsize JSIZE_MAX = std::numeric_limits<jsize>::max();
|
||||
|
||||
jobject createResultObject(JNIEnv *env, ZT_ResultCode code);
|
||||
jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status);
|
||||
jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type);
|
||||
jobject createEvent(JNIEnv *env, ZT_Event event);
|
||||
jobject createPeerRole(JNIEnv *env, ZT_PeerRole role);
|
||||
jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op);
|
||||
|
||||
jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr);
|
||||
jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr);
|
||||
int addressPort(const sockaddr_storage addr);
|
||||
|
||||
jobject newPeer(JNIEnv *env, const ZT_Peer &peer);
|
||||
jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp);
|
||||
|
||||
jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &config);
|
||||
|
||||
jobject newVersion(JNIEnv *env, int major, int minor, int rev);
|
||||
|
||||
jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route);
|
||||
|
||||
jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns);
|
||||
|
||||
jobject newNodeStatus(JNIEnv *env, const ZT_NodeStatus &status);
|
||||
|
||||
jobjectArray newPeerArray(JNIEnv *env, const ZT_Peer *peers, size_t count);
|
||||
|
||||
jobjectArray newVirtualNetworkConfigArray(JNIEnv *env, const ZT_VirtualNetworkConfig *networks, size_t count);
|
||||
|
||||
jobjectArray newPeerPhysicalPathArray(JNIEnv *env, const ZT_PeerPhysicalPath *paths, size_t count);
|
||||
|
||||
jobjectArray newInetSocketAddressArray(JNIEnv *env, const sockaddr_storage *addresses, size_t count);
|
||||
|
||||
jobjectArray newVirtualNetworkRouteArray(JNIEnv *env, const ZT_VirtualNetworkRoute *routes, size_t count);
|
||||
|
||||
//
|
||||
// log functions only for newArrayObject below
|
||||
//
|
||||
void newArrayObject_logCount(size_t count);
|
||||
void newArrayObject_log(const char *msg);
|
||||
|
||||
//
|
||||
// function template for creating array objects
|
||||
//
|
||||
template <typename T, jobject (*F)(JNIEnv *, const T &)>
|
||||
jobjectArray newArrayObject(JNIEnv *env, const T *buffer, size_t count, jclass clazz) {
|
||||
|
||||
if (count > JSIZE_MAX) {
|
||||
newArrayObject_logCount(count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsize jCount = static_cast<jsize>(count);
|
||||
|
||||
jobjectArray arrayObj = env->NewObjectArray(jCount, clazz, NULL);
|
||||
if (env->ExceptionCheck() || arrayObj == NULL) {
|
||||
newArrayObject_log("Error creating array object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (jsize i = 0; i < jCount; i++) {
|
||||
|
||||
jobject obj = F(env, buffer[i]);
|
||||
if(env->ExceptionCheck() || obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env->SetObjectArrayElement(arrayObj, i, obj);
|
||||
if(env->ExceptionCheck()) {
|
||||
newArrayObject_log("Error assigning object to array");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(obj);
|
||||
}
|
||||
|
||||
return arrayObj;
|
||||
}
|
||||
|
||||
jbyteArray newByteArray(JNIEnv *env, const unsigned char *bytes, size_t count);
|
||||
|
||||
jbyteArray newByteArray(JNIEnv *env, size_t count);
|
||||
|
||||
bool isSocketAddressEmpty(const sockaddr_storage addr);
|
||||
|
||||
sockaddr_storage fromSocketAddressObject(JNIEnv *env, jobject sockAddressObject);
|
||||
|
||||
#endif // ZT_jniutils_h_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,141 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_zerotier_sdk_Node */
|
||||
|
||||
#ifndef _Included_com_zerotierone_sdk_Node
|
||||
#define _Included_com_zerotierone_sdk_Node
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: node_init
|
||||
* Signature: (JLcom/zerotier/sdk/DataStoreGetListener;Lcom/zerotier/sdk/DataStorePutListener;Lcom/zerotier/sdk/PacketSender;Lcom/zerotier/sdk/EventListener;Lcom/zerotier/sdk/VirtualNetworkFrameListener;Lcom/zerotier/sdk/VirtualNetworkConfigListener;Lcom/zerotier/sdk/PathChecker;)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init
|
||||
(JNIEnv *, jobject, jlong, jobject, jobject, jobject, jobject, jobject, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: node_isInited
|
||||
* Signature: (J)Z;
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_zerotier_sdk_Node_node_1isInited
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: node_delete
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: processVirtualNetworkFrame
|
||||
* Signature: (JJJJJII[B[J)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame
|
||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong, jlong, jint, jint, jbyteArray, jlongArray);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: processWirePacket
|
||||
* Signature: (JJJLjava/net/InetSockAddress;[B[J)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket
|
||||
(JNIEnv *, jobject, jlong, jlong, jlong, jobject, jbyteArray, jlongArray);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: processBackgroundTasks
|
||||
* Signature: (JJ[J)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks
|
||||
(JNIEnv *, jobject, jlong, jlong, jlongArray);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: join
|
||||
* Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join
|
||||
(JNIEnv *, jobject, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: leave
|
||||
* Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave
|
||||
(JNIEnv *, jobject, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: multicastSubscribe
|
||||
* Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe
|
||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: multicastUnsubscribe
|
||||
* Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe
|
||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: address
|
||||
* Signature: (J)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: status
|
||||
* Signature: (J)Lcom/zerotier/sdk/NodeStatus;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: networkConfig
|
||||
* Signature: (JJ)Lcom/zerotier/sdk/VirtualNetworkConfig;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig
|
||||
(JNIEnv *, jobject, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: version
|
||||
* Signature: ()Lcom/zerotier/sdk/Version;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: peers
|
||||
* Signature: (J)[Lcom/zerotier/sdk/Peer;
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_zerotier_sdk_Node
|
||||
* Method: networkConfigs
|
||||
* Signature: (J)[Lcom/zerotier/sdk/VirtualNetworkConfig;
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networkConfigs
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
public interface DataStoreGetListener {
|
||||
|
||||
/**
|
||||
* Function to get an object from the data store
|
||||
*
|
||||
* <p>Object names can contain forward slash (/) path separators. They will
|
||||
* never contain .. or backslash (\), so this is safe to map as a Unix-style
|
||||
* path if the underlying storage permits. For security reasons we recommend
|
||||
* returning errors if .. or \ are used.</p>
|
||||
*
|
||||
* <p>The function must return the actual number of bytes read. If the object
|
||||
* doesn't exist, it should return -1. -2 should be returned on other errors
|
||||
* such as errors accessing underlying storage.</p>
|
||||
*
|
||||
* <p>If the read doesn't fit in the buffer, the max number of bytes should be
|
||||
* read. The caller may call the function multiple times to read the whole
|
||||
* object.</p>
|
||||
*
|
||||
* @param name Name of the object in the data store
|
||||
* @param out_buffer buffer to put the object in
|
||||
* @return size of the object
|
||||
*/
|
||||
long onDataStoreGet(
|
||||
String name,
|
||||
byte[] out_buffer);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
public interface DataStorePutListener {
|
||||
|
||||
/**
|
||||
* Function to store an object in the data store
|
||||
*
|
||||
* <p>If secure is true, the file should be set readable and writable only
|
||||
* to the user running ZeroTier One. What this means is platform-specific.</p>
|
||||
*
|
||||
* <p>Name semantics are the same as {@link DataStoreGetListener}. This must return
|
||||
* zero on success. You can return any OS-specific error code on failure, as these
|
||||
* may be visible in logs or error messages and might aid in debugging.</p>
|
||||
*
|
||||
* @param name Object name
|
||||
* @param buffer data to store
|
||||
* @param secure set to user read/write only.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int onDataStorePut(
|
||||
String name,
|
||||
byte[] buffer,
|
||||
boolean secure);
|
||||
|
||||
/**
|
||||
* Function to delete an object from the data store
|
||||
*
|
||||
* @param name Object name
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int onDelete(
|
||||
String name);
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
/**
|
||||
* Status codes sent to status update callback when things happen
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_Event
|
||||
*/
|
||||
public enum Event {
|
||||
|
||||
/**
|
||||
* Node has been initialized
|
||||
* <p>
|
||||
* This is the first event generated, and is always sent. It may occur
|
||||
* before Node's constructor returns.
|
||||
*/
|
||||
EVENT_UP(0),
|
||||
|
||||
/**
|
||||
* Node is offline -- network does not seem to be reachable by any available strategy
|
||||
*/
|
||||
EVENT_OFFLINE(1),
|
||||
|
||||
/**
|
||||
* Node is online -- at least one upstream node appears reachable
|
||||
* <p>
|
||||
* Meta-data: none
|
||||
*/
|
||||
EVENT_ONLINE(2),
|
||||
|
||||
/**
|
||||
* Node is shutting down
|
||||
*
|
||||
* <p>This is generated within Node's destructor when it is being shut down.
|
||||
* It's done for convenience, since cleaning up other state in the event
|
||||
* handler may appear more idiomatic.</p>
|
||||
*/
|
||||
EVENT_DOWN(3),
|
||||
|
||||
/**
|
||||
* Your identity has collided with another node's ZeroTier address
|
||||
*
|
||||
* <p>This happens if two different public keys both hash (via the algorithm
|
||||
* in Identity::generate()) to the same 40-bit ZeroTier address.</p>
|
||||
*
|
||||
* <p>This is something you should "never" see, where "never" is defined as
|
||||
* once per 2^39 new node initializations / identity creations. If you do
|
||||
* see it, you're going to see it very soon after a node is first
|
||||
* initialized.</p>
|
||||
*
|
||||
* <p>This is reported as an event rather than a return code since it's
|
||||
* detected asynchronously via error messages from authoritative nodes.</p>
|
||||
*
|
||||
* <p>If this occurs, you must shut down and delete the node, delete the
|
||||
* identity.secret record/file from the data store, and restart to generate
|
||||
* a new identity. If you don't do this, you will not be able to communicate
|
||||
* with other nodes.</p>
|
||||
*
|
||||
* <p>We'd automate this process, but we don't think silently deleting
|
||||
* private keys or changing our address without telling the calling code
|
||||
* is good form. It violates the principle of least surprise.</p>
|
||||
*
|
||||
* <p>You can technically get away with not handling this, but we recommend
|
||||
* doing so in a mature reliable application. Besides, handling this
|
||||
* condition is a good way to make sure it never arises. It's like how
|
||||
* umbrellas prevent rain and smoke detectors prevent fires. They do, right?</p>
|
||||
*/
|
||||
EVENT_FATAL_ERROR_IDENTITY_COLLISION(4),
|
||||
|
||||
/**
|
||||
* Trace (debugging) message
|
||||
*
|
||||
* <p>These events are only generated if this is a TRACE-enabled build.</p>
|
||||
*
|
||||
* <p>Meta-data: {@link String}, TRACE message</p>
|
||||
*/
|
||||
EVENT_TRACE(5),
|
||||
|
||||
/**
|
||||
* VERB_USER_MESSAGE received
|
||||
* <p>
|
||||
* These are generated when a VERB_USER_MESSAGE packet is received via
|
||||
* ZeroTier VL1.
|
||||
*/
|
||||
EVENT_USER_MESSAGE(6),
|
||||
|
||||
/**
|
||||
* Remote trace received
|
||||
* <p>
|
||||
* These are generated when a VERB_REMOTE_TRACE is received. Note
|
||||
* that any node can fling one of these at us. It is your responsibility
|
||||
* to filter and determine if it's worth paying attention to. If it's
|
||||
* not just drop it. Most nodes that are not active controllers ignore
|
||||
* these, and controllers only save them if they pertain to networks
|
||||
* with remote tracing enabled.
|
||||
*/
|
||||
EVENT_REMOTE_TRACE(7);
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private final int id;
|
||||
|
||||
Event(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static Event fromInt(int id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
return EVENT_UP;
|
||||
case 1:
|
||||
return EVENT_OFFLINE;
|
||||
case 2:
|
||||
return EVENT_ONLINE;
|
||||
case 3:
|
||||
return EVENT_DOWN;
|
||||
case 4:
|
||||
return EVENT_FATAL_ERROR_IDENTITY_COLLISION;
|
||||
case 5:
|
||||
return EVENT_TRACE;
|
||||
case 6:
|
||||
return EVENT_USER_MESSAGE;
|
||||
case 7:
|
||||
return EVENT_REMOTE_TRACE;
|
||||
default:
|
||||
throw new RuntimeException("Unhandled value: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
/**
|
||||
* Interface to handle callbacks for ZeroTier One events.
|
||||
*/
|
||||
public interface EventListener {
|
||||
|
||||
/**
|
||||
* Callback for events with no other associated metadata
|
||||
*
|
||||
* @param event {@link Event} enum
|
||||
*/
|
||||
void onEvent(Event event);
|
||||
|
||||
/**
|
||||
* Trace messages
|
||||
*
|
||||
* <p>These events are only generated if the underlying ZeroTierOne SDK is a TRACE-enabled build.</p>
|
||||
*
|
||||
* @param message the trace message
|
||||
*/
|
||||
void onTrace(String message);
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* A ZeroTier One node
|
||||
*/
|
||||
public class Node {
|
||||
static {
|
||||
System.loadLibrary("ZeroTierOneJNI");
|
||||
}
|
||||
|
||||
private static final String TAG = "NODE";
|
||||
|
||||
/**
|
||||
* Node ID for JNI purposes.
|
||||
* Currently set to the now value passed in at the constructor
|
||||
*/
|
||||
private final long nodeId;
|
||||
|
||||
/**
|
||||
* Create a new ZeroTier One node
|
||||
*
|
||||
* @param now Current clock in milliseconds
|
||||
*/
|
||||
public Node(long now) {
|
||||
this.nodeId = now;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init a new ZeroTier One node
|
||||
*
|
||||
* <p>Note that this can take a few seconds the first time it's called, as it
|
||||
* will generate an identity.</p>
|
||||
*
|
||||
* @param getListener User written instance of the {@link DataStoreGetListener} interface called to get objects from persistent storage. This instance must be unique per Node object.
|
||||
* @param putListener User written instance of the {@link DataStorePutListener} interface called to put objects in persistent storage. This instance must be unique per Node object.
|
||||
* @param sender User written instance of the {@link PacketSender} interface to send ZeroTier packets out over the wire.
|
||||
* @param eventListener User written instance of the {@link EventListener} interface to receive status updates and non-fatal error notices. This instance must be unique per Node object.
|
||||
* @param frameListener User written instance of the {@link VirtualNetworkFrameListener} interface to send a frame out to a virtual network port.
|
||||
* @param configListener User written instance of the {@link VirtualNetworkConfigListener} interface to be called when virtual LANs are created, deleted, or their config parameters change. This instance must be unique per Node object.
|
||||
* @param pathChecker User written instance of the {@link PathChecker} interface. Not required and can be null.
|
||||
*/
|
||||
public ResultCode init(
|
||||
DataStoreGetListener getListener,
|
||||
DataStorePutListener putListener,
|
||||
PacketSender sender,
|
||||
EventListener eventListener,
|
||||
VirtualNetworkFrameListener frameListener,
|
||||
VirtualNetworkConfigListener configListener,
|
||||
PathChecker pathChecker) {
|
||||
return node_init(
|
||||
nodeId,
|
||||
getListener,
|
||||
putListener,
|
||||
sender,
|
||||
eventListener,
|
||||
frameListener,
|
||||
configListener,
|
||||
pathChecker);
|
||||
}
|
||||
|
||||
public boolean isInited() {
|
||||
return node_isInited(nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this Node.
|
||||
*
|
||||
* <p>The Node object can no longer be used once this method is called.</p>
|
||||
*/
|
||||
public void close() {
|
||||
node_delete(nodeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Node(" + nodeId + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a frame from a virtual network port
|
||||
*
|
||||
* @param now Current clock in milliseconds
|
||||
* @param nwid ZeroTier 64-bit virtual network ID
|
||||
* @param sourceMac Source MAC address (least significant 48 bits)
|
||||
* @param destMac Destination MAC address (least significant 48 bits)
|
||||
* @param etherType 16-bit Ethernet frame type
|
||||
* @param vlanId 10-bit VLAN ID or 0 if none
|
||||
* @param frameData Frame payload data
|
||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode processVirtualNetworkFrame(
|
||||
long now,
|
||||
long nwid,
|
||||
long sourceMac,
|
||||
long destMac,
|
||||
int etherType,
|
||||
int vlanId,
|
||||
byte[] frameData,
|
||||
long[] nextBackgroundTaskDeadline) {
|
||||
return processVirtualNetworkFrame(
|
||||
nodeId, now, nwid, sourceMac, destMac, etherType, vlanId,
|
||||
frameData, nextBackgroundTaskDeadline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a packet received from the physical wire
|
||||
*
|
||||
* @param now Current clock in milliseconds
|
||||
* @param localSocket Local socket or -1
|
||||
* @param remoteAddress Origin of packet
|
||||
* @param packetData Packet data
|
||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode processWirePacket(
|
||||
long now,
|
||||
long localSocket,
|
||||
InetSocketAddress remoteAddress,
|
||||
byte[] packetData,
|
||||
long[] nextBackgroundTaskDeadline) {
|
||||
return processWirePacket(
|
||||
nodeId, now, localSocket, remoteAddress, packetData,
|
||||
nextBackgroundTaskDeadline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform periodic background operations
|
||||
*
|
||||
* @param now Current clock in milliseconds
|
||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode processBackgroundTasks(long now, long[] nextBackgroundTaskDeadline) {
|
||||
return processBackgroundTasks(nodeId, now, nextBackgroundTaskDeadline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a network
|
||||
*
|
||||
* <p>This may generate calls to the port config callback before it returns,
|
||||
* or these may be deferred if a netconf is not available yet.</p>
|
||||
*
|
||||
* <p>If we are already a member of the network, nothing is done and OK is
|
||||
* returned.</p>
|
||||
*
|
||||
* @param nwid 64-bit ZeroTier network ID
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode join(long nwid) {
|
||||
return join(nodeId, nwid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a network
|
||||
*
|
||||
* <p>If a port has been configured for this network this will generate a call
|
||||
* to the port config callback with a NULL second parameter to indicate that
|
||||
* the port is now deleted.</p>
|
||||
*
|
||||
* @param nwid 64-bit network ID
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode leave(long nwid) {
|
||||
return leave(nodeId, nwid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to an Ethernet multicast group
|
||||
*
|
||||
* <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
|
||||
* broadcast address) but with an ADI equal to each IPv4 address in host
|
||||
* byte order. This converts ARP from a non-scalable broadcast protocol to
|
||||
* a scalable multicast protocol with perfect address specificity.</p>
|
||||
*
|
||||
* <p>If this is not done, ARP will not work reliably.</p>
|
||||
*
|
||||
* <p>Multiple calls to subscribe to the same multicast address will have no
|
||||
* effect. It is perfectly safe to do this.</p>
|
||||
*
|
||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
||||
*
|
||||
* @param nwid 64-bit network ID
|
||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode multicastSubscribe(
|
||||
long nwid,
|
||||
long multicastGroup) {
|
||||
return multicastSubscribe(nodeId, nwid, multicastGroup, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to an Ethernet multicast group
|
||||
*
|
||||
* <p>ADI stands for additional distinguishing information. This defaults to zero
|
||||
* and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
|
||||
* and this must be done.</p>
|
||||
*
|
||||
* <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
|
||||
* broadcast address) but with an ADI equal to each IPv4 address in host
|
||||
* byte order. This converts ARP from a non-scalable broadcast protocol to
|
||||
* a scalable multicast protocol with perfect address specificity.</p>
|
||||
*
|
||||
* <p>If this is not done, ARP will not work reliably.</p>
|
||||
*
|
||||
* <p>Multiple calls to subscribe to the same multicast address will have no
|
||||
* effect. It is perfectly safe to do this.</p>
|
||||
*
|
||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
||||
*
|
||||
* @param nwid 64-bit network ID
|
||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode multicastSubscribe(
|
||||
long nwid,
|
||||
long multicastGroup,
|
||||
long multicastAdi) {
|
||||
return multicastSubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unsubscribe from an Ethernet multicast group (or all groups)
|
||||
*
|
||||
* <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
|
||||
* you are not subscribed to a group this has no effect.</p>
|
||||
*
|
||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
||||
*
|
||||
* @param nwid 64-bit network ID
|
||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode multicastUnsubscribe(
|
||||
long nwid,
|
||||
long multicastGroup) {
|
||||
return multicastUnsubscribe(nodeId, nwid, multicastGroup, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from an Ethernet multicast group (or all groups)
|
||||
*
|
||||
* <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
|
||||
* you are not subscribed to a group this has no effect.</p>
|
||||
*
|
||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
||||
*
|
||||
* <p>ADI stands for additional distinguishing information. This defaults to zero
|
||||
* and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
|
||||
* and this must be done.</p>
|
||||
*
|
||||
* @param nwid 64-bit network ID
|
||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
public ResultCode multicastUnsubscribe(
|
||||
long nwid,
|
||||
long multicastGroup,
|
||||
long multicastAdi) {
|
||||
return multicastUnsubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or update a moon
|
||||
* <p>
|
||||
* Moons are persisted in the data store in moons.d/, so this can persist
|
||||
* across invocations if the contents of moon.d are scanned and orbit is
|
||||
* called for each on startup.
|
||||
*
|
||||
* @param moonWorldId Moon's world ID
|
||||
* @param moonSeed If non-zero, the ZeroTier address of any member of the moon to query for moon definition
|
||||
* @return Error if moon was invalid or failed to be added
|
||||
*/
|
||||
public ResultCode orbit(
|
||||
long moonWorldId,
|
||||
long moonSeed) {
|
||||
return orbit(nodeId, moonWorldId, moonSeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a moon (does nothing if not present)
|
||||
*
|
||||
* @param moonWorldId World ID of moon to remove
|
||||
* @return Error if anything bad happened
|
||||
*/
|
||||
public ResultCode deorbit(
|
||||
long moonWorldId) {
|
||||
return deorbit(nodeId, moonWorldId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this node's 40-bit ZeroTier address
|
||||
*
|
||||
* @return ZeroTier address (least significant 40 bits of 64-bit int)
|
||||
*/
|
||||
public long address() {
|
||||
return address(nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of this node
|
||||
*
|
||||
* @return @{link NodeStatus} struct with the current node status.
|
||||
*/
|
||||
public NodeStatus status() {
|
||||
return status(nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of known peer nodes
|
||||
*
|
||||
* @return List of known peers or NULL on failure
|
||||
*/
|
||||
public Peer[] peers() {
|
||||
return peers(nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of a virtual network
|
||||
*
|
||||
* @param nwid 64-bit network ID
|
||||
* @return {@link VirtualNetworkConfig} or NULL if we are not a member of this network
|
||||
*/
|
||||
public VirtualNetworkConfig networkConfig(long nwid) {
|
||||
return networkConfig(nodeId, nwid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate and get status of all networks
|
||||
*
|
||||
* @return List of networks or NULL on failure
|
||||
*/
|
||||
public VirtualNetworkConfig[] networkConfigs() {
|
||||
return networkConfigs(nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ZeroTier One version
|
||||
*
|
||||
* @return {@link Version} object with ZeroTierOne version information.
|
||||
*/
|
||||
public Version getVersion() {
|
||||
return version();
|
||||
}
|
||||
|
||||
//
|
||||
// function declarations for JNI
|
||||
//
|
||||
private native ResultCode node_init(
|
||||
long nodeId,
|
||||
DataStoreGetListener dataStoreGetListener,
|
||||
DataStorePutListener dataStorePutListener,
|
||||
PacketSender packetSender,
|
||||
EventListener eventListener,
|
||||
VirtualNetworkFrameListener virtualNetworkFrameListener,
|
||||
VirtualNetworkConfigListener virtualNetworkConfigListener,
|
||||
PathChecker pathChecker);
|
||||
|
||||
private native boolean node_isInited(long nodeId);
|
||||
|
||||
private native void node_delete(long nodeId);
|
||||
|
||||
private native ResultCode processVirtualNetworkFrame(
|
||||
long nodeId,
|
||||
long now,
|
||||
long nwid,
|
||||
long sourceMac,
|
||||
long destMac,
|
||||
int etherType,
|
||||
int vlanId,
|
||||
byte[] frameData,
|
||||
long[] nextBackgroundTaskDeadline);
|
||||
|
||||
private native ResultCode processWirePacket(
|
||||
long nodeId,
|
||||
long now,
|
||||
long localSocket,
|
||||
InetSocketAddress remoteAddress,
|
||||
byte[] packetData,
|
||||
long[] nextBackgroundTaskDeadline);
|
||||
|
||||
private native ResultCode processBackgroundTasks(
|
||||
long nodeId,
|
||||
long now,
|
||||
long[] nextBackgroundTaskDeadline);
|
||||
|
||||
private native ResultCode join(long nodeId, long nwid);
|
||||
|
||||
private native ResultCode leave(long nodeId, long nwid);
|
||||
|
||||
private native ResultCode multicastSubscribe(
|
||||
long nodeId,
|
||||
long nwid,
|
||||
long multicastGroup,
|
||||
long multicastAdi);
|
||||
|
||||
private native ResultCode multicastUnsubscribe(
|
||||
long nodeId,
|
||||
long nwid,
|
||||
long multicastGroup,
|
||||
long multicastAdi);
|
||||
|
||||
private native ResultCode orbit(
|
||||
long nodeId,
|
||||
long moonWorldId,
|
||||
long moonSeed);
|
||||
|
||||
private native ResultCode deorbit(
|
||||
long nodeId,
|
||||
long moonWorldId);
|
||||
|
||||
private native long address(long nodeId);
|
||||
|
||||
private native NodeStatus status(long nodeId);
|
||||
|
||||
private native VirtualNetworkConfig networkConfig(long nodeId, long nwid);
|
||||
|
||||
private native Version version();
|
||||
|
||||
private native Peer[] peers(long nodeId);
|
||||
|
||||
private native VirtualNetworkConfig[] networkConfigs(long nodeId);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
import com.zerotier.sdk.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Current node status
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_NodeStatus
|
||||
*/
|
||||
public class NodeStatus {
|
||||
|
||||
private final long address;
|
||||
|
||||
private final String publicIdentity;
|
||||
|
||||
private final String secretIdentity;
|
||||
|
||||
private final boolean online;
|
||||
|
||||
public NodeStatus(long address, String publicIdentity, String secretIdentity, boolean online) {
|
||||
this.address = address;
|
||||
this.publicIdentity = publicIdentity;
|
||||
this.secretIdentity = secretIdentity;
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NodeStatus(" + StringUtils.addressToString(address) + ", " + publicIdentity + ", " + secretIdentity + ", " + online + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* 40-bit ZeroTier address of this node
|
||||
*/
|
||||
public long getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public identity in string-serialized form (safe to send to others)
|
||||
*
|
||||
* <p>This identity will remain valid as long as the node exists.</p>
|
||||
*/
|
||||
public String getPublicIdentity() {
|
||||
return publicIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full identity including secret key in string-serialized form
|
||||
*
|
||||
* <p>This identity will remain valid as long as the node exists.</p>
|
||||
*/
|
||||
public String getSecretIdentity() {
|
||||
return secretIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if some kind of connectivity appears available
|
||||
*/
|
||||
public boolean isOnline() {
|
||||
return online;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
|
||||
public interface PacketSender {
|
||||
|
||||
/**
|
||||
* Function to send a ZeroTier packet out over the wire
|
||||
*
|
||||
* <p>The function must return zero on success and may return any error code
|
||||
* on failure. Note that success does not (of course) guarantee packet
|
||||
* delivery. It only means that the packet appears to have been sent.</p>
|
||||
*
|
||||
* @param localSocket socket file descriptor to send from. Set to -1 if not specified.
|
||||
* @param remoteAddr {@link InetSocketAddress} to send to
|
||||
* @param packetData data to send
|
||||
* @param ttl TTL is ignored
|
||||
* @return 0 on success, any error code on failure.
|
||||
*/
|
||||
int onSendPacketRequested(
|
||||
long localSocket,
|
||||
InetSocketAddress remoteAddr,
|
||||
byte[] packetData,
|
||||
int ttl);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public interface PathChecker {
|
||||
|
||||
/**
|
||||
* Callback to check whether a path should be used for ZeroTier traffic
|
||||
* <p>
|
||||
* This function must return true if the path should be used.
|
||||
* <p>
|
||||
* If no path check function is specified, ZeroTier will still exclude paths
|
||||
* that overlap with ZeroTier-assigned and managed IP address blocks. But the
|
||||
* use of a path check function is recommended to ensure that recursion does
|
||||
* not occur in cases where addresses are assigned by the OS or managed by
|
||||
* an out of band mechanism like DHCP. The path check function should examine
|
||||
* all configured ZeroTier interfaces and check to ensure that the supplied
|
||||
* addresses will not result in ZeroTier traffic being sent over a ZeroTier
|
||||
* interface (recursion).
|
||||
* <p>
|
||||
* Obviously this is not required in configurations where this can't happen,
|
||||
* such as network containers or embedded.
|
||||
*
|
||||
* @param ztAddress ZeroTier address or 0 for none/any
|
||||
* @param localSocket Local interface socket. -1 if unspecified
|
||||
* @param remoteAddress remote address
|
||||
* @return true if the path should be used
|
||||
*/
|
||||
boolean onPathCheck(long ztAddress, long localSocket, InetSocketAddress remoteAddress);
|
||||
|
||||
/**
|
||||
* Function to get physical addresses for ZeroTier peers
|
||||
* <p>
|
||||
* If provided this function will be occasionally called to get physical
|
||||
* addresses that might be tried to reach a ZeroTier address.
|
||||
*
|
||||
* @param ztAddress ZeroTier address (least significant 40 bits)
|
||||
* @param ss_family desired address family or -1 for any
|
||||
* @return address and port of ztAddress or null
|
||||
*/
|
||||
InetSocketAddress onPathLookup(long ztAddress, int ss_family);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
import com.zerotier.sdk.util.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Peer status result buffer
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_Peer
|
||||
*/
|
||||
public class Peer {
|
||||
|
||||
private final long address;
|
||||
|
||||
private final int versionMajor;
|
||||
|
||||
private final int versionMinor;
|
||||
|
||||
private final int versionRev;
|
||||
|
||||
private final int latency;
|
||||
|
||||
private final PeerRole role;
|
||||
|
||||
private final PeerPhysicalPath[] paths;
|
||||
|
||||
public Peer(long address, int versionMajor, int versionMinor, int versionRev, int latency, PeerRole role, PeerPhysicalPath[] paths) {
|
||||
this.address = address;
|
||||
this.versionMajor = versionMajor;
|
||||
this.versionMinor = versionMinor;
|
||||
this.versionRev = versionRev;
|
||||
this.latency = latency;
|
||||
this.role = role;
|
||||
this.paths = paths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Peer(" + StringUtils.addressToString(address) + ", " + versionMajor + ", " + versionMinor + ", " + versionRev + ", " + latency + ", " + role + ", " + Arrays.toString(paths) + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* ZeroTier address (40 bits)
|
||||
*/
|
||||
public long getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote major version or -1 if not known
|
||||
*/
|
||||
public int getVersionMajor() {
|
||||
return versionMajor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote minor version or -1 if not known
|
||||
*/
|
||||
public int getVersionMinor() {
|
||||
return versionMinor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote revision or -1 if not known
|
||||
*/
|
||||
public int getVersionRev() {
|
||||
return versionRev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Last measured latency in milliseconds or zero if unknown
|
||||
*/
|
||||
public int getLatency() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* What trust hierarchy role does this device have?
|
||||
*/
|
||||
public PeerRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Known network paths to peer
|
||||
*/
|
||||
public PeerPhysicalPath[] getPaths() {
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* Physical network path to a peer
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_PeerPhysicalPath
|
||||
*/
|
||||
public class PeerPhysicalPath {
|
||||
|
||||
private final InetSocketAddress address;
|
||||
|
||||
private final long lastSend;
|
||||
|
||||
private final long lastReceive;
|
||||
|
||||
private final boolean preferred;
|
||||
|
||||
public PeerPhysicalPath(InetSocketAddress address, long lastSend, long lastReceive, boolean preferred) {
|
||||
this.address = address;
|
||||
if (lastSend < 0) {
|
||||
throw new RuntimeException("lastSend < 0: " + lastSend);
|
||||
}
|
||||
this.lastSend = lastSend;
|
||||
if (lastReceive < 0) {
|
||||
throw new RuntimeException("lastReceive < 0: " + lastReceive);
|
||||
}
|
||||
this.lastReceive = lastReceive;
|
||||
this.preferred = preferred;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PeerPhysicalPath(" + address + ", " + lastSend + ", " + lastReceive + ", " + preferred + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Address of endpoint
|
||||
*/
|
||||
public InetSocketAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time of last send in milliseconds or 0 for never
|
||||
*/
|
||||
public long getLastSend() {
|
||||
return lastSend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time of last receive in milliseconds or 0 for never
|
||||
*/
|
||||
public long getLastReceive() {
|
||||
return lastReceive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is path preferred?
|
||||
*/
|
||||
public boolean isPreferred() {
|
||||
return preferred;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
/**
|
||||
* What trust hierarchy role does this peer have?
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_PeerRole
|
||||
*/
|
||||
public enum PeerRole {
|
||||
|
||||
/**
|
||||
* An ordinary node
|
||||
*/
|
||||
PEER_ROLE_LEAF(0),
|
||||
|
||||
/**
|
||||
* moon root
|
||||
*/
|
||||
PEER_ROLE_MOON(1),
|
||||
|
||||
/**
|
||||
* planetary root
|
||||
*/
|
||||
PEER_ROLE_PLANET(2);
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private final int id;
|
||||
|
||||
PeerRole(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static PeerRole fromInt(int id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
return PEER_ROLE_LEAF;
|
||||
case 1:
|
||||
return PEER_ROLE_MOON;
|
||||
case 2:
|
||||
return PEER_ROLE_PLANET;
|
||||
default:
|
||||
throw new RuntimeException("Unhandled value: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
/**
|
||||
* Function return code: OK (0) or error results
|
||||
*
|
||||
* <p>Use {@link ResultCode#isFatal) to check for a fatal error. If a fatal error
|
||||
* occurs, the node should be considered to not be working correctly. These
|
||||
* indicate serious problems like an inaccessible data store or a compile
|
||||
* problem.</p>
|
||||
*
|
||||
* Defined in ZeroTierOne.h as ZT_ResultCode
|
||||
*/
|
||||
public enum ResultCode {
|
||||
|
||||
/**
|
||||
* Operation completed normally
|
||||
*/
|
||||
RESULT_OK(0),
|
||||
|
||||
/**
|
||||
* Call produced no error but no action was taken
|
||||
*/
|
||||
RESULT_OK_IGNORED(1),
|
||||
|
||||
// Fatal errors (>=100, <1000)
|
||||
/**
|
||||
* Ran out of memory
|
||||
*/
|
||||
RESULT_FATAL_ERROR_OUT_OF_MEMORY(100),
|
||||
|
||||
/**
|
||||
* Data store is not writable or has failed
|
||||
*/
|
||||
RESULT_FATAL_ERROR_DATA_STORE_FAILED(101),
|
||||
|
||||
/**
|
||||
* Internal error (e.g. unexpected exception indicating bug or build problem)
|
||||
*/
|
||||
RESULT_FATAL_ERROR_INTERNAL(102),
|
||||
|
||||
// non-fatal errors
|
||||
|
||||
/**
|
||||
* Network ID not valid
|
||||
*/
|
||||
RESULT_ERROR_NETWORK_NOT_FOUND(1000),
|
||||
|
||||
RESULT_ERROR_UNSUPPORTED_OPERATION(1001),
|
||||
|
||||
RESULT_ERROR_BAD_PARAMETER(1002);
|
||||
|
||||
private final int id;
|
||||
|
||||
ResultCode(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static ResultCode fromInt(int id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
return RESULT_OK;
|
||||
case 1:
|
||||
return RESULT_OK_IGNORED;
|
||||
case 100:
|
||||
return RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
case 101:
|
||||
return RESULT_FATAL_ERROR_DATA_STORE_FAILED;
|
||||
case 102:
|
||||
return RESULT_FATAL_ERROR_INTERNAL;
|
||||
case 1000:
|
||||
return RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
case 1001:
|
||||
return RESULT_ERROR_UNSUPPORTED_OPERATION;
|
||||
case 1002:
|
||||
return RESULT_ERROR_BAD_PARAMETER;
|
||||
default:
|
||||
throw new RuntimeException("Unhandled value: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFatal() {
|
||||
return (id >= 100 && id < 1000);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
public class Version {
|
||||
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int revision;
|
||||
|
||||
public Version(int major, int minor, int revision) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.zerotier.sdk.util.StringUtils;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Virtual network configuration
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_VirtualNetworkConfig
|
||||
*/
|
||||
public class VirtualNetworkConfig implements Comparable<VirtualNetworkConfig> {
|
||||
|
||||
private final static String TAG = "VirtualNetworkConfig";
|
||||
|
||||
public static final int MAX_MULTICAST_SUBSCRIPTIONS = 4096;
|
||||
public static final int ZT_MAX_ZT_ASSIGNED_ADDRESSES = 16;
|
||||
|
||||
private final long nwid;
|
||||
|
||||
private final long mac;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final VirtualNetworkStatus status;
|
||||
|
||||
private final VirtualNetworkType type;
|
||||
|
||||
private final int mtu;
|
||||
|
||||
private final boolean dhcp;
|
||||
|
||||
private final boolean bridge;
|
||||
|
||||
private final boolean broadcastEnabled;
|
||||
|
||||
private final int portError;
|
||||
|
||||
private final long netconfRevision;
|
||||
|
||||
private final InetSocketAddress[] assignedAddresses;
|
||||
|
||||
private final VirtualNetworkRoute[] routes;
|
||||
|
||||
private final VirtualNetworkDNS dns;
|
||||
|
||||
public VirtualNetworkConfig(long nwid, long mac, String name, VirtualNetworkStatus status, VirtualNetworkType type, int mtu, boolean dhcp, boolean bridge, boolean broadcastEnabled, int portError, long netconfRevision, InetSocketAddress[] assignedAddresses, VirtualNetworkRoute[] routes, VirtualNetworkDNS dns) {
|
||||
this.nwid = nwid;
|
||||
this.mac = mac;
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.type = type;
|
||||
if (mtu < 0) {
|
||||
throw new RuntimeException("mtu < 0: " + mtu);
|
||||
}
|
||||
this.mtu = mtu;
|
||||
this.dhcp = dhcp;
|
||||
this.bridge = bridge;
|
||||
this.broadcastEnabled = broadcastEnabled;
|
||||
this.portError = portError;
|
||||
if (netconfRevision < 0) {
|
||||
throw new RuntimeException("netconfRevision < 0: " + netconfRevision);
|
||||
}
|
||||
this.netconfRevision = netconfRevision;
|
||||
this.assignedAddresses = assignedAddresses;
|
||||
this.routes = routes;
|
||||
this.dns = dns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VirtualNetworkConfig(" + StringUtils.networkIdToString(nwid) + ", " + StringUtils.macAddressToString(mac) + ", " + name + ", " + status + ", " + type + ", " + mtu + ", " + dhcp + ", " + bridge + ", " + broadcastEnabled + ", " + portError + ", " + netconfRevision + ", " + Arrays.toString(assignedAddresses) + ", " + Arrays.toString(routes) + ", " + dns + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == null) {
|
||||
Log.i(TAG, "Old is null");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(o instanceof VirtualNetworkConfig)) {
|
||||
Log.i(TAG, "Old is not an instance of VirtualNetworkConfig: " + o);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VirtualNetworkConfig old = (VirtualNetworkConfig) o;
|
||||
|
||||
if (this.nwid != old.nwid) {
|
||||
Log.i(TAG, "NetworkID Changed. New: " + StringUtils.networkIdToString(this.nwid) + " (" + this.nwid + "), " +
|
||||
"Old: " + StringUtils.networkIdToString(old.nwid) + " (" + old.nwid + ")");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.mac != old.mac) {
|
||||
Log.i(TAG, "MAC Changed. New: " + StringUtils.macAddressToString(this.mac) + ", Old: " + StringUtils.macAddressToString(old.mac));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.name.equals(old.name)) {
|
||||
Log.i(TAG, "Name Changed. New: " + this.name + ", Old: " + old.name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.status != old.status) {
|
||||
Log.i(TAG, "Status Changed. New: " + this.status + ", Old: " + old.status);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.type != old.type) {
|
||||
Log.i(TAG, "Type changed. New: " + this.type + ", Old: " + old.type);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.mtu != old.mtu) {
|
||||
Log.i(TAG, "MTU Changed. New: " + this.mtu + ", Old: " + old.mtu);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.dhcp != old.dhcp) {
|
||||
Log.i(TAG, "DHCP Flag Changed. New: " + this.dhcp + ", Old: " + old.dhcp);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.bridge != old.bridge) {
|
||||
Log.i(TAG, "Bridge Flag Changed. New: " + this.bridge + ", Old: " + old.bridge);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.broadcastEnabled != old.broadcastEnabled) {
|
||||
Log.i(TAG, "Broadcast Flag Changed. New: "+ this.broadcastEnabled + ", Old: " + old.broadcastEnabled);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.portError != old.portError) {
|
||||
Log.i(TAG, "Port Error Changed. New: " + this.portError + ", Old: " + old.portError);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.netconfRevision != old.netconfRevision) {
|
||||
Log.i(TAG, "NetConfRevision Changed. New: " + this.netconfRevision + ", Old: " + old.netconfRevision);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(assignedAddresses, old.assignedAddresses)) {
|
||||
|
||||
ArrayList<String> aaNew = new ArrayList<>();
|
||||
ArrayList<String> aaOld = new ArrayList<>();
|
||||
for (InetSocketAddress s : assignedAddresses) {
|
||||
aaNew.add(s.toString());
|
||||
}
|
||||
for (InetSocketAddress s : old.assignedAddresses) {
|
||||
aaOld.add(s.toString());
|
||||
}
|
||||
Collections.sort(aaNew);
|
||||
Collections.sort(aaOld);
|
||||
|
||||
Log.i(TAG, "Assigned Addresses Changed");
|
||||
Log.i(TAG, "New:");
|
||||
for (String s : aaNew) {
|
||||
Log.i(TAG, " " + s);
|
||||
}
|
||||
Log.i(TAG, "");
|
||||
Log.i(TAG, "Old:");
|
||||
for (String s : aaOld) {
|
||||
Log.i(TAG, " " +s);
|
||||
}
|
||||
Log.i(TAG, "");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(routes, old.routes)) {
|
||||
|
||||
ArrayList<String> rNew = new ArrayList<>();
|
||||
ArrayList<String> rOld = new ArrayList<>();
|
||||
for (VirtualNetworkRoute r : routes) {
|
||||
rNew.add(r.toString());
|
||||
}
|
||||
for (VirtualNetworkRoute r : old.routes) {
|
||||
rOld.add(r.toString());
|
||||
}
|
||||
Collections.sort(rNew);
|
||||
Collections.sort(rOld);
|
||||
|
||||
Log.i(TAG, "Managed Routes Changed");
|
||||
Log.i(TAG, "New:");
|
||||
for (String s : rNew) {
|
||||
Log.i(TAG, " " + s);
|
||||
}
|
||||
Log.i(TAG, "");
|
||||
Log.i(TAG, "Old:");
|
||||
for (String s : rOld) {
|
||||
Log.i(TAG, " " + s);
|
||||
}
|
||||
Log.i(TAG, "");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean dnsEquals;
|
||||
if (this.dns == null) {
|
||||
//noinspection RedundantIfStatement
|
||||
if (old.dns == null) {
|
||||
dnsEquals = true;
|
||||
} else {
|
||||
dnsEquals = false;
|
||||
}
|
||||
} else {
|
||||
if (old.dns == null) {
|
||||
dnsEquals = false;
|
||||
} else {
|
||||
dnsEquals = this.dns.equals(old.dns);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dnsEquals) {
|
||||
Log.i(TAG, "DNS Changed. New: " + this.dns + ", Old: " + old.dns);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(VirtualNetworkConfig cfg) {
|
||||
return Long.compare(this.nwid, cfg.nwid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
result = 37 * result + (int) (nwid ^ (nwid >>> 32));
|
||||
result = 37 * result + (int) (mac ^ (mac >>> 32));
|
||||
result = 37 * result + name.hashCode();
|
||||
result = 37 * result + status.hashCode();
|
||||
result = 37 * result + type.hashCode();
|
||||
result = 37 * result + mtu;
|
||||
result = 37 * result + (dhcp ? 1 : 0);
|
||||
result = 37 * result + (bridge ? 1 : 0);
|
||||
result = 37 * result + (broadcastEnabled ? 1 : 0);
|
||||
result = 37 * result + portError;
|
||||
result = 37 * result + (int) (netconfRevision ^ (netconfRevision >>> 32));
|
||||
result = 37 * result + Arrays.hashCode(assignedAddresses);
|
||||
result = 37 * result + Arrays.hashCode(routes);
|
||||
result = 37 * result + (dns == null ? 0 : dns.hashCode());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 64-bit ZeroTier network ID
|
||||
*/
|
||||
public long getNwid() {
|
||||
return nwid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ethernet MAC (48 bits) that should be assigned to port
|
||||
*/
|
||||
public long getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Network name (from network configuration master)
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Network configuration request status
|
||||
*/
|
||||
public VirtualNetworkStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Network type
|
||||
*/
|
||||
public VirtualNetworkType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum interface MTU
|
||||
*/
|
||||
public int getMtu() {
|
||||
return mtu;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the network this port belongs to indicates DHCP availability
|
||||
*
|
||||
* <p>This is a suggestion. The underlying implementation is free to ignore it
|
||||
* for security or other reasons. This is simply a netconf parameter that
|
||||
* means 'DHCP is available on this network.'</p>
|
||||
*/
|
||||
public boolean isDhcp() {
|
||||
return dhcp;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this port is allowed to bridge to other networks
|
||||
*
|
||||
* <p>This is informational. If this is false, bridged packets will simply
|
||||
* be dropped and bridging won't work.</p>
|
||||
*/
|
||||
public boolean isBridge() {
|
||||
return bridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic
|
||||
*/
|
||||
public boolean isBroadcastEnabled() {
|
||||
return broadcastEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the network is in PORT_ERROR state, this is the error most recently returned by the port config callback
|
||||
*/
|
||||
public int getPortError() {
|
||||
return portError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Network config revision as reported by netconf master
|
||||
*
|
||||
* <p>If this is zero, it means we're still waiting for our netconf.</p>
|
||||
*/
|
||||
public long getNetconfRevision() {
|
||||
return netconfRevision;
|
||||
}
|
||||
|
||||
/**
|
||||
* ZeroTier-assigned addresses (in {@link InetSocketAddress} objects)
|
||||
* <p>
|
||||
* For IP, the port number of the sockaddr_XX structure contains the number
|
||||
* of bits in the address netmask. Only the IP address and port are used.
|
||||
* Other fields like interface number can be ignored.
|
||||
* <p>
|
||||
* This is only used for ZeroTier-managed address assignments sent by the
|
||||
* virtual network's configuration master.
|
||||
*/
|
||||
public InetSocketAddress[] getAssignedAddresses() {
|
||||
return assignedAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* ZeroTier-assigned routes (in {@link VirtualNetworkRoute} objects)
|
||||
*/
|
||||
public VirtualNetworkRoute[] getRoutes() {
|
||||
return routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Network specific DNS configuration
|
||||
*/
|
||||
public VirtualNetworkDNS getDns() {
|
||||
return dns;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
|
||||
public interface VirtualNetworkConfigListener {
|
||||
|
||||
/**
|
||||
* Callback called to update virtual network port configuration
|
||||
*
|
||||
* <p>This can be called at any time to update the configuration of a virtual
|
||||
* network port. The parameter after the network ID specifies whether this
|
||||
* port is being brought up, updated, brought down, or permanently deleted.
|
||||
* <p>
|
||||
* This in turn should be used by the underlying implementation to create
|
||||
* and configure tap devices at the OS (or virtual network stack) layer.</P>
|
||||
*
|
||||
* This should not call {@link Node#multicastSubscribe(long, long)} or other network-modifying
|
||||
* methods, as this could cause a deadlock in multithreaded or interrupt
|
||||
* driven environments.
|
||||
* <p>
|
||||
* This must return 0 on success. It can return any OS-dependent error code
|
||||
* on failure, and this results in the network being placed into the
|
||||
* PORT_ERROR state.
|
||||
*
|
||||
* @param nwid network id
|
||||
* @param op {@link VirtualNetworkConfigOperation} enum describing the configuration operation
|
||||
* @param config {@link VirtualNetworkConfig} object with the new configuration
|
||||
* @return 0 on success
|
||||
*/
|
||||
int onNetworkConfigurationUpdated(
|
||||
long nwid,
|
||||
VirtualNetworkConfigOperation op,
|
||||
VirtualNetworkConfig config);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
/**
|
||||
* Virtual network configuration update type
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_VirtualNetworkConfigOperation
|
||||
*/
|
||||
public enum VirtualNetworkConfigOperation {
|
||||
|
||||
/**
|
||||
* Network is coming up (either for the first time or after service restart)
|
||||
*/
|
||||
VIRTUAL_NETWORK_CONFIG_OPERATION_UP(1),
|
||||
|
||||
/**
|
||||
* Network configuration has been updated
|
||||
*/
|
||||
VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE(2),
|
||||
|
||||
/**
|
||||
* Network is going down (not permanently)
|
||||
*/
|
||||
VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN(3),
|
||||
|
||||
/**
|
||||
* Network is going down permanently (leave/delete)
|
||||
*/
|
||||
VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY(4);
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private final int id;
|
||||
|
||||
VirtualNetworkConfigOperation(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static VirtualNetworkConfigOperation fromInt(int id) {
|
||||
switch (id) {
|
||||
case 1:
|
||||
return VIRTUAL_NETWORK_CONFIG_OPERATION_UP;
|
||||
case 2:
|
||||
return VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE;
|
||||
case 3:
|
||||
return VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN;
|
||||
case 4:
|
||||
return VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY;
|
||||
default:
|
||||
throw new RuntimeException("Unhandled value: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2020 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DNS configuration to be pushed on a virtual network
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_VirtualNetworkDNS
|
||||
*/
|
||||
public class VirtualNetworkDNS implements Comparable<VirtualNetworkDNS> {
|
||||
|
||||
private final String domain;
|
||||
private final ArrayList<InetSocketAddress> servers;
|
||||
|
||||
public VirtualNetworkDNS(String domain, ArrayList<InetSocketAddress> servers) {
|
||||
this.domain = domain;
|
||||
this.servers = servers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VirtualNetworkDNS(" + domain + ", " + servers + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(o instanceof VirtualNetworkDNS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VirtualNetworkDNS d = (VirtualNetworkDNS) o;
|
||||
|
||||
if (!domain.equals(d.domain)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//noinspection RedundantIfStatement
|
||||
if (!servers.equals(d.servers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(VirtualNetworkDNS o) {
|
||||
return domain.compareTo(o.domain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
result = 37 * result + domain.hashCode();
|
||||
result = 37 * result + servers.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public ArrayList<InetSocketAddress> getServers() {
|
||||
return servers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
public interface VirtualNetworkFrameListener {
|
||||
|
||||
/**
|
||||
* Function to send a frame out to a virtual network port
|
||||
*
|
||||
* @param nwid ZeroTier One network ID
|
||||
* @param srcMac source MAC address
|
||||
* @param destMac destination MAC address
|
||||
* @param etherType EtherType
|
||||
* @param vlanId VLAN ID
|
||||
* @param frameData data to send
|
||||
*/
|
||||
void onVirtualNetworkFrame(
|
||||
long nwid,
|
||||
long srcMac,
|
||||
long destMac,
|
||||
long etherType,
|
||||
long vlanId,
|
||||
byte[] frameData);
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* A route to be pushed on a virtual network
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_VirtualNetworkRoute
|
||||
*/
|
||||
public class VirtualNetworkRoute implements Comparable<VirtualNetworkRoute>
|
||||
{
|
||||
/**
|
||||
* Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default
|
||||
*/
|
||||
private final InetSocketAddress target;
|
||||
|
||||
/**
|
||||
* Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway)
|
||||
*/
|
||||
private final InetSocketAddress via;
|
||||
|
||||
/**
|
||||
* Route flags
|
||||
*/
|
||||
private final int flags;
|
||||
|
||||
/**
|
||||
* Route metric (not currently used)
|
||||
*/
|
||||
private final int metric;
|
||||
|
||||
public VirtualNetworkRoute(InetSocketAddress target, InetSocketAddress via, int flags, int metric) {
|
||||
this.target = target;
|
||||
this.via = via;
|
||||
this.flags = flags;
|
||||
this.metric = metric;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VirtualNetworkRoute(" + target + ", " + via + ", " + flags + ", " + metric + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(VirtualNetworkRoute other) {
|
||||
throw new RuntimeException("Unimplemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (!(o instanceof VirtualNetworkRoute)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VirtualNetworkRoute other = (VirtualNetworkRoute) o;
|
||||
|
||||
boolean targetEquals;
|
||||
if (target == null) {
|
||||
//noinspection RedundantIfStatement
|
||||
if (other.target == null) {
|
||||
targetEquals = true;
|
||||
} else {
|
||||
targetEquals = false;
|
||||
}
|
||||
} else {
|
||||
if (other.target == null) {
|
||||
targetEquals = false;
|
||||
} else {
|
||||
targetEquals = target.equals(other.target);
|
||||
}
|
||||
}
|
||||
|
||||
if (!targetEquals) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean viaEquals;
|
||||
if (via == null) {
|
||||
//noinspection RedundantIfStatement
|
||||
if (other.via == null) {
|
||||
viaEquals = true;
|
||||
} else {
|
||||
viaEquals = false;
|
||||
}
|
||||
} else {
|
||||
if (other.via == null) {
|
||||
viaEquals = false;
|
||||
} else {
|
||||
viaEquals = via.equals(other.via);
|
||||
}
|
||||
}
|
||||
|
||||
if (!viaEquals) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flags != other.flags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//noinspection RedundantIfStatement
|
||||
if (metric != other.metric) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
result = 37 * result + (target == null ? 0 : target.hashCode());
|
||||
result = 37 * result + (via == null ? 0 : via.hashCode());
|
||||
result = 37 * result + flags;
|
||||
result = 37 * result + metric;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public InetSocketAddress getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public InetSocketAddress getVia() {
|
||||
return via;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int getMetric() {
|
||||
return metric;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
/**
|
||||
* Virtual network status codes
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_VirtualNetworkStatus
|
||||
*/
|
||||
public enum VirtualNetworkStatus {
|
||||
|
||||
/**
|
||||
* Waiting for network configuration (also means revision == 0)
|
||||
*/
|
||||
NETWORK_STATUS_REQUESTING_CONFIGURATION(0),
|
||||
|
||||
/**
|
||||
* Configuration received and we are authorized
|
||||
*/
|
||||
NETWORK_STATUS_OK(1),
|
||||
|
||||
/**
|
||||
* Netconf master told us 'nope'
|
||||
*/
|
||||
NETWORK_STATUS_ACCESS_DENIED(2),
|
||||
|
||||
/**
|
||||
* Netconf master exists, but this virtual network does not
|
||||
*/
|
||||
NETWORK_STATUS_NOT_FOUND(3),
|
||||
|
||||
/**
|
||||
* Initialization of network failed or other internal error
|
||||
*/
|
||||
NETWORK_STATUS_PORT_ERROR(4),
|
||||
|
||||
/**
|
||||
* ZeroTier One version too old
|
||||
*/
|
||||
NETWORK_STATUS_CLIENT_TOO_OLD(5),
|
||||
|
||||
/**
|
||||
* External authentication is required (e.g. SSO)
|
||||
*/
|
||||
NETWORK_STATUS_AUTHENTICATION_REQUIRED(6);
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private final int id;
|
||||
|
||||
VirtualNetworkStatus(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static VirtualNetworkStatus fromInt(int id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
return NETWORK_STATUS_REQUESTING_CONFIGURATION;
|
||||
case 1:
|
||||
return NETWORK_STATUS_OK;
|
||||
case 2:
|
||||
return NETWORK_STATUS_ACCESS_DENIED;
|
||||
case 3:
|
||||
return NETWORK_STATUS_NOT_FOUND;
|
||||
case 4:
|
||||
return NETWORK_STATUS_PORT_ERROR;
|
||||
case 5:
|
||||
return NETWORK_STATUS_CLIENT_TOO_OLD;
|
||||
case 6:
|
||||
return NETWORK_STATUS_AUTHENTICATION_REQUIRED;
|
||||
default:
|
||||
throw new RuntimeException("Unhandled value: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.sdk;
|
||||
|
||||
/**
|
||||
* Virtual network type codes
|
||||
* <p>
|
||||
* Defined in ZeroTierOne.h as ZT_VirtualNetworkType
|
||||
*/
|
||||
public enum VirtualNetworkType {
|
||||
|
||||
/**
|
||||
* Private networks are authorized via certificates of membership
|
||||
*/
|
||||
NETWORK_TYPE_PRIVATE(0),
|
||||
|
||||
/**
|
||||
* Public networks have no access control -- they'll always be AUTHORIZED
|
||||
*/
|
||||
NETWORK_TYPE_PUBLIC(1);
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private final int id;
|
||||
|
||||
VirtualNetworkType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static VirtualNetworkType fromInt(int id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
return NETWORK_TYPE_PRIVATE;
|
||||
case 1:
|
||||
return NETWORK_TYPE_PUBLIC;
|
||||
default:
|
||||
throw new RuntimeException("Unhandled value: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2023 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
package com.zerotier.sdk.util;
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
/**
|
||||
* Convert mac address to string.
|
||||
*
|
||||
* @param mac MAC address
|
||||
* @return string in XX:XX:XX:XX:XX:XX format
|
||||
*/
|
||||
public static String macAddressToString(long mac) {
|
||||
|
||||
int[] macChars = new int[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
macChars[i] = (int) (mac % 256);
|
||||
mac >>= 8;
|
||||
}
|
||||
|
||||
return String.format("%02x:%02x:%02x:%02x:%02x:%02x", macChars[5], macChars[4], macChars[3], macChars[2], macChars[1], macChars[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert long to hex string.
|
||||
*
|
||||
* @param networkId long
|
||||
* @return string with 0 padding
|
||||
*/
|
||||
public static String networkIdToString(long networkId) {
|
||||
return String.format("%016x", networkId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert node address to string.
|
||||
*
|
||||
* Node addresses are 40 bits, so print 10 hex characters.
|
||||
*
|
||||
* @param address Node address
|
||||
* @return formatted string
|
||||
*/
|
||||
public static String addressToString(long address) {
|
||||
return String.format("%010x", address);
|
||||
}
|
||||
|
||||
public static String etherTypeToString(long etherType) {
|
||||
return String.format("%04x", etherType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2023 ZeroTier, Inc. https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
package com.zerotier.sdk.util;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class StringUtilsTest {
|
||||
|
||||
public StringUtilsTest() {
|
||||
}
|
||||
|
||||
public String oldMacDisplay(long mac) {
|
||||
|
||||
String macStr = Long.toHexString(mac);
|
||||
|
||||
if (macStr.length() > 12) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
while (macStr.length() < 12) {
|
||||
//noinspection StringConcatenationInLoop
|
||||
macStr = "0" + macStr;
|
||||
}
|
||||
|
||||
//noinspection StringBufferReplaceableByString
|
||||
StringBuilder displayMac = new StringBuilder();
|
||||
displayMac.append(macStr.charAt(0));
|
||||
displayMac.append(macStr.charAt(1));
|
||||
displayMac.append(':');
|
||||
displayMac.append(macStr.charAt(2));
|
||||
displayMac.append(macStr.charAt(3));
|
||||
displayMac.append(':');
|
||||
displayMac.append(macStr.charAt(4));
|
||||
displayMac.append(macStr.charAt(5));
|
||||
displayMac.append(':');
|
||||
displayMac.append(macStr.charAt(6));
|
||||
displayMac.append(macStr.charAt(7));
|
||||
displayMac.append(':');
|
||||
displayMac.append(macStr.charAt(8));
|
||||
displayMac.append(macStr.charAt(9));
|
||||
displayMac.append(':');
|
||||
displayMac.append(macStr.charAt(10));
|
||||
displayMac.append(macStr.charAt(11));
|
||||
|
||||
return displayMac.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMacDisplay() {
|
||||
|
||||
long mac1 = 1234567891;
|
||||
assertThat(StringUtils.macAddressToString(mac1)).isEqualTo(oldMacDisplay(mac1));
|
||||
|
||||
long mac2 = 999999999;
|
||||
assertThat(StringUtils.macAddressToString(mac2)).isEqualTo(oldMacDisplay(mac2));
|
||||
|
||||
long mac3 = 0x7fffffffffffL;
|
||||
assertThat(StringUtils.macAddressToString(mac3)).isEqualTo(oldMacDisplay(mac3));
|
||||
assertThat(StringUtils.macAddressToString(mac3)).isEqualTo("7f:ff:ff:ff:ff:ff");
|
||||
|
||||
long mac4 = 0x7fafcf3f8fffL;
|
||||
assertThat(StringUtils.macAddressToString(mac4)).isEqualTo(oldMacDisplay(mac4));
|
||||
assertThat(StringUtils.macAddressToString(mac4)).isEqualTo("7f:af:cf:3f:8f:ff");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user