diff options
Diffstat (limited to 'java/jni')
-rw-r--r-- | java/jni/Android.mk | 35 | ||||
-rw-r--r-- | java/jni/Application.mk | 2 | ||||
-rw-r--r-- | java/jni/ZT_jniutils.cpp | 3 | ||||
-rw-r--r-- | java/jni/ZT_jniutils.h | 32 | ||||
-rw-r--r-- | java/jni/com_zerotierone_sdk_Node.cpp | 518 | ||||
-rw-r--r-- | java/jni/com_zerotierone_sdk_Node.h | 2 |
6 files changed, 325 insertions, 267 deletions
diff --git a/java/jni/Android.mk b/java/jni/Android.mk index ebd89376..8cda2474 100644 --- a/java/jni/Android.mk +++ b/java/jni/Android.mk @@ -3,14 +3,21 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ZeroTierOneJNI -LOCAL_C_INCLUDES := $(ZT1)/include -LOCAL_C_INCLUDES += $(ZT1)/node +LOCAL_C_INCLUDES := \ + $(ZT1)/include \ + $(ZT1)/node \ + $(ZT1)/osdep \ + $(ZT1)/ext/miniupnpc \ + $(ZT1)/ext/libnatpmp + LOCAL_LDLIBS := -llog -latomic # LOCAL_CFLAGS := -g +LOCAL_CFLAGS := -DZT_USE_MINIUPNPC + # ZeroTierOne SDK source files LOCAL_SRC_FILES := \ - $(ZT1)/node/C25519.cpp \ + $(ZT1)/node/C25519.cpp \ $(ZT1)/node/Capability.cpp \ $(ZT1)/node/CertificateOfMembership.cpp \ $(ZT1)/node/CertificateOfOwnership.cpp \ @@ -34,8 +41,28 @@ LOCAL_SRC_FILES := \ $(ZT1)/node/Switch.cpp \ $(ZT1)/node/Tag.cpp \ $(ZT1)/node/Topology.cpp \ - $(ZT1)/node/Utils.cpp + $(ZT1)/node/Trace.cpp \ + $(ZT1)/node/Utils.cpp \ + $(ZT1)/osdep/OSUtils.cpp \ + $(ZT1)/osdep/PortMapper.cpp +# libminiupnpc and libnatpmp files +LOCAL_SRC_FILES += \ + $(ZT1)/ext/miniupnpc/connecthostport.c \ + $(ZT1)/ext/miniupnpc/igd_desc_parse.c \ + $(ZT1)/ext/miniupnpc/minisoap.c \ + $(ZT1)/ext/miniupnpc/minissdpc.c \ + $(ZT1)/ext/miniupnpc/miniupnpc.c \ + $(ZT1)/ext/miniupnpc/miniwget.c \ + $(ZT1)/ext/miniupnpc/minixml.c \ + $(ZT1)/ext/miniupnpc/portlistingparse.c \ + $(ZT1)/ext/miniupnpc/receivedata.c \ + $(ZT1)/ext/miniupnpc/upnpcommands.c \ + $(ZT1)/ext/miniupnpc/upnpdev.c \ + $(ZT1)/ext/miniupnpc/upnperrors.c \ + $(ZT1)/ext/miniupnpc/upnpreplyparse.c \ + $(ZT1)/ext/libnatpmp/natpmp.c \ + $(ZT1)/ext/libnatpmp/getgateway.c # JNI Files LOCAL_SRC_FILES += \ diff --git a/java/jni/Application.mk b/java/jni/Application.mk index 19891cc8..f5a87ac7 100644 --- a/java/jni/Application.mk +++ b/java/jni/Application.mk @@ -1,5 +1,5 @@ # NDK_TOOLCHAIN_VERSION := clang3.5 APP_STL := c++_static -APP_CPPFLAGS := -O3 -Wall -fstack-protector -fexceptions -fno-strict-aliasing -Wno-deprecated-register -DZT_NO_TYPE_PUNNING=1 +APP_CPPFLAGS := -Wall -fstack-protector -fexceptions -fno-strict-aliasing -Wno-deprecated-register -DZT_NO_TYPE_PUNNING=1 APP_PLATFORM := android-14 APP_ABI := all diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 7bdc7611..c52a2066 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -156,6 +156,9 @@ jobject createEvent(JNIEnv *env, ZT_Event event) break; case ZT_EVENT_USER_MESSAGE: break; + case ZT_EVENT_REMOTE_TRACE: + default: + break; } jfieldID enumField = lookup.findStaticField(eventClass, fieldName.c_str(), "Lcom/zerotier/sdk/Event;"); diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index e35d4f42..56b63179 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -28,17 +28,31 @@ extern "C" { #define LOG_TAG "ZeroTierOneJNI" -#if __ANDROID__ +#if defined(__ANDROID__) + #include <android/log.h> -#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) -#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) -#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) -#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) + + #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 -#define LOGV(...) fprintf(stdout, __VA_ARGS__) -#define LOGI(...) fprintf(stdout, __VA_ARGS__) -#define LOGD(...) fprintf(stdout, __VA_ARGS__) -#define LOGE(...) fprintf(stdout, __VA_ARGS__) + #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 jobject createResultObject(JNIEnv *env, ZT_ResultCode code); diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index defbe7f2..9a36e99b 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -32,6 +32,8 @@ #include <ZeroTierOne.h> #include "Mutex.hpp" +#include "PortMapper.hpp" + #include <map> #include <string> #include <assert.h> @@ -58,6 +60,7 @@ namespace { , configListener(NULL) , pathChecker(NULL) , callbacks(NULL) + , portMapper(NULL) { callbacks = (ZT_Node_Callbacks*)malloc(sizeof(ZT_Node_Callbacks)); memset(callbacks, 0, sizeof(ZT_Node_Callbacks)); @@ -78,9 +81,12 @@ namespace { free(callbacks); callbacks = NULL; + + delete portMapper; + portMapper = NULL; } - uint64_t id; + int64_t id; JavaVM *jvm; @@ -95,6 +101,8 @@ namespace { jobject pathChecker; ZT_Node_Callbacks *callbacks; + + ZeroTier::PortMapper *portMapper; }; @@ -112,6 +120,11 @@ namespace { JNIEnv *env = NULL; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + if (ref->configListener == NULL) { + LOGE("configListener is NULL"); + return -1; + } + jclass configListenerClass = env->GetObjectClass(ref->configListener); if(configListenerClass == NULL) { @@ -161,13 +174,19 @@ namespace { unsigned int frameLength) { LOGV("VirtualNetworkFrameFunctionCallback"); +#ifndef NDEBUG unsigned char* local = (unsigned char*)frameData; LOGV("Type Bytes: 0x%02x%02x", local[12], local[13]); +#endif JniRef *ref = (JniRef*)userData; assert(ref->node == node); JNIEnv *env = NULL; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + if (ref->frameListener == NULL) { + LOGE("frameListener is NULL"); + return; + } jclass frameListenerClass = env->GetObjectClass(ref->frameListener); if(env->ExceptionCheck() || frameListenerClass == NULL) @@ -210,111 +229,230 @@ namespace { void *userData, void *threadData, enum ZT_Event event, - const void *data) - { + const void *data) { LOGV("EventCallback"); - JniRef *ref = (JniRef*)userData; - if(ref->node != node && event != ZT_EVENT_UP) - { + JniRef *ref = (JniRef *) userData; + if (ref->node != node && event != ZT_EVENT_UP) { LOGE("Nodes not equal. ref->node %p, node %p. Event: %d", ref->node, node, event); return; } JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + ref->jvm->GetEnv((void **) &env, JNI_VERSION_1_6); + if (ref->eventListener == NULL) { + LOGE("eventListener is NULL"); + return; + } jclass eventListenerClass = env->GetObjectClass(ref->eventListener); - if(eventListenerClass == NULL) - { + if (eventListenerClass == NULL) { LOGE("Couldn't class for EventListener instance"); return; } jmethodID onEventMethod = lookup.findMethod(eventListenerClass, - "onEvent", "(Lcom/zerotier/sdk/Event;)V"); - if(onEventMethod == NULL) - { + "onEvent", "(Lcom/zerotier/sdk/Event;)V"); + if (onEventMethod == NULL) { LOGE("Couldn't find onEvent method"); return; } jmethodID onTraceMethod = lookup.findMethod(eventListenerClass, - "onTrace", "(Ljava/lang/String;)V"); - if(onTraceMethod == NULL) - { + "onTrace", "(Ljava/lang/String;)V"); + if (onTraceMethod == NULL) { LOGE("Couldn't find onTrace method"); return; } jobject eventObject = createEvent(env, event); - if(eventObject == NULL) - { + if (eventObject == NULL) { return; } - switch(event) - { - case ZT_EVENT_UP: - { - LOGD("Event Up"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); - break; + switch (event) { + case ZT_EVENT_UP: { + LOGD("Event Up"); + env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + break; + } + case ZT_EVENT_OFFLINE: { + LOGD("Event Offline"); + env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + break; + } + case ZT_EVENT_ONLINE: { + LOGD("Event Online"); + env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + break; + } + case ZT_EVENT_DOWN: { + LOGD("Event Down"); + env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + break; + } + case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { + LOGV("Identity Collision"); + // call onEvent() + env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + } + break; + case ZT_EVENT_TRACE: { + LOGV("Trace Event"); + // call onTrace() + if (data != NULL) { + const char *message = (const char *) data; + jstring messageStr = env->NewStringUTF(message); + env->CallVoidMethod(ref->eventListener, onTraceMethod, messageStr); + } + } + break; + case ZT_EVENT_USER_MESSAGE: + case ZT_EVENT_REMOTE_TRACE: + default: + break; } - case ZT_EVENT_OFFLINE: - { - LOGD("Event Offline"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); - break; + } + + void StatePutFunction( + ZT_Node *node, + void *userData, + void *threadData, + enum ZT_StateObjectType type, + const uint64_t id[2], + const void *buffer, + int bufferLength) { + char p[4096] = {0}; + bool secure = false; + switch (type) { + case ZT_STATE_OBJECT_IDENTITY_PUBLIC: + snprintf(p, sizeof(p), "identity.public"); + break; + case ZT_STATE_OBJECT_IDENTITY_SECRET: + snprintf(p, sizeof(p), "identity.secret"); + secure = true; + break; + case ZT_STATE_OBJECT_PLANET: + snprintf(p, sizeof(p), "planet"); + break; + case ZT_STATE_OBJECT_MOON: + snprintf(p, sizeof(p), "moons.d/%.16llx.moon", (unsigned long long)id[0]); + break; + case ZT_STATE_OBJECT_NETWORK_CONFIG: + snprintf(p, sizeof(p), "networks.d/%.16llx.conf", (unsigned long long)id[0]); + break; + case ZT_STATE_OBJECT_PEER: + snprintf(p, sizeof(p), "peers.d/%.10llx", (unsigned long long)id[0]); + break; + default: + return; } - case ZT_EVENT_ONLINE: - { - LOGD("Event Online"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); - break; + + if (strlen(p) < 1) { + return; + } + + JniRef *ref = (JniRef*)userData; + JNIEnv *env = NULL; + ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + + if (ref->dataStorePutListener == NULL) { + LOGE("dataStorePutListener is NULL"); + return; } - case ZT_EVENT_DOWN: + + jclass dataStorePutClass = env->GetObjectClass(ref->dataStorePutListener); + if (dataStorePutClass == NULL) { - LOGD("Event Down"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); - break; + LOGE("Couldn't find class for DataStorePutListener instance"); + return; } - case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: + + jmethodID dataStorePutCallbackMethod = lookup.findMethod( + dataStorePutClass, + "onDataStorePut", + "(Ljava/lang/String;[BZ)I"); + if(dataStorePutCallbackMethod == NULL) { - LOGV("Identity Collision"); - // call onEvent() - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + LOGE("Couldn't find onDataStorePut method"); + return; } - break; - case ZT_EVENT_TRACE: + + jmethodID deleteMethod = lookup.findMethod(dataStorePutClass, + "onDelete", "(Ljava/lang/String;)I"); + if(deleteMethod == NULL) { - LOGV("Trace Event"); - // call onTrace() - if(data != NULL) + LOGE("Couldn't find onDelete method"); + return; + } + + jstring nameStr = env->NewStringUTF(p); + + if (bufferLength >= 0) { + LOGD("JNI: Write file: %s", p); + // set operation + jbyteArray bufferObj = env->NewByteArray(bufferLength); + if(env->ExceptionCheck() || bufferObj == NULL) { - const char* message = (const char*)data; - jstring messageStr = env->NewStringUTF(message); - env->CallVoidMethod(ref->eventListener, onTraceMethod, messageStr); + LOGE("Error creating byte array buffer!"); + return; } - } - break; - case ZT_EVENT_USER_MESSAGE: - break; + + env->SetByteArrayRegion(bufferObj, 0, bufferLength, (jbyte*)buffer); + + env->CallIntMethod(ref->dataStorePutListener, + dataStorePutCallbackMethod, + nameStr, bufferObj, secure); + } else { + LOGD("JNI: Delete file: %s", p); + env->CallIntMethod(ref->dataStorePutListener, deleteMethod, nameStr); } } - long DataStoreGetFunction(ZT_Node *node, - void *userData, - void *threadData, - const char *objectName, - void *buffer, - unsigned long bufferSize, - unsigned long bufferIndex, - unsigned long *out_objectSize) - { + int StateGetFunction( + ZT_Node *node, + void *userData, + void *threadData, + ZT_StateObjectType type, + const uint64_t id[2], + void *buffer, + unsigned int bufferLength) { + char p[4096] = {0}; + switch (type) { + case ZT_STATE_OBJECT_IDENTITY_PUBLIC: + snprintf(p, sizeof(p), "identity.public"); + break; + case ZT_STATE_OBJECT_IDENTITY_SECRET: + snprintf(p, sizeof(p), "identity.secret"); + break; + case ZT_STATE_OBJECT_PLANET: + snprintf(p, sizeof(p), "planet"); + break; + case ZT_STATE_OBJECT_MOON: + snprintf(p, sizeof(p), "moons.d/%.16llx.moon", (unsigned long long)id[0]); + break; + case ZT_STATE_OBJECT_NETWORK_CONFIG: + snprintf(p, sizeof(p), "networks.d/%.16llx.conf", (unsigned long long)id[0]); + break; + case ZT_STATE_OBJECT_PEER: + snprintf(p, sizeof(p), "peers.d/%.10llx", (unsigned long long)id[0]); + break; + default: + return -1; + } + + if (strlen(p) < 1) { + return -1; + } + JniRef *ref = (JniRef*)userData; JNIEnv *env = NULL; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + if (ref->dataStoreGetListener == NULL) { + LOGE("dataStoreGetListener is NULL"); + return -2; + } + jclass dataStoreGetClass = env->GetObjectClass(ref->dataStoreGetListener); if(dataStoreGetClass == NULL) { @@ -323,142 +461,69 @@ namespace { } jmethodID dataStoreGetCallbackMethod = lookup.findMethod( - dataStoreGetClass, - "onDataStoreGet", - "(Ljava/lang/String;[BJ[J)J"); + dataStoreGetClass, + "onDataStoreGet", + "(Ljava/lang/String;[B)J"); if(dataStoreGetCallbackMethod == NULL) { LOGE("Couldn't find onDataStoreGet method"); return -2; } - jstring nameStr = env->NewStringUTF(objectName); + jstring nameStr = env->NewStringUTF(p); if(nameStr == NULL) { LOGE("Error creating name string object"); return -2; // out of memory } - jbyteArray bufferObj = env->NewByteArray(bufferSize); + jbyteArray bufferObj = env->NewByteArray(bufferLength); if(bufferObj == NULL) { - LOGE("Error creating byte[] buffer of size: %lu", bufferSize); + LOGE("Error creating byte[] buffer of size: %u", bufferLength); return -2; } - jlongArray objectSizeObj = env->NewLongArray(1); - if(objectSizeObj == NULL) - { - LOGE("Error creating long[1] array for actual object size"); - return -2; // couldn't create long[1] array - } + LOGV("Calling onDataStoreGet(%s, %p)", p, buffer); - LOGV("Calling onDataStoreGet(%s, %p, %lu, %p)", - objectName, buffer, bufferIndex, objectSizeObj); + int retval = (int)env->CallLongMethod( + ref->dataStoreGetListener, + dataStoreGetCallbackMethod, + nameStr, + bufferObj); - long retval = (long)env->CallLongMethod( - ref->dataStoreGetListener, dataStoreGetCallbackMethod, - nameStr, bufferObj, (jlong)bufferIndex, objectSizeObj); + LOGV("onDataStoreGet returned %d", retval); if(retval > 0) { void *data = env->GetPrimitiveArrayCritical(bufferObj, NULL); memcpy(buffer, data, retval); env->ReleasePrimitiveArrayCritical(bufferObj, data, 0); - - jlong *objSize = (jlong*)env->GetPrimitiveArrayCritical(objectSizeObj, NULL); - *out_objectSize = (unsigned long)objSize[0]; - env->ReleasePrimitiveArrayCritical(objectSizeObj, objSize, 0); } - LOGV("Out Object Size: %lu", *out_objectSize); - return retval; } - int DataStorePutFunction(ZT_Node *node, - void *userData, - void *threadData, - const char *objectName, - const void *buffer, - unsigned long bufferSize, - int secure) - { - JniRef *ref = (JniRef*)userData; - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); - - - jclass dataStorePutClass = env->GetObjectClass(ref->dataStorePutListener); - if(dataStorePutClass == NULL) - { - LOGE("Couldn't find class for DataStorePutListener instance"); - return -1; - } - - jmethodID dataStorePutCallbackMethod = lookup.findMethod( - dataStorePutClass, - "onDataStorePut", - "(Ljava/lang/String;[BZ)I"); - if(dataStorePutCallbackMethod == NULL) - { - LOGE("Couldn't find onDataStorePut method"); - return -2; - } - - jmethodID deleteMethod = lookup.findMethod(dataStorePutClass, - "onDelete", "(Ljava/lang/String;)I"); - if(deleteMethod == NULL) - { - LOGE("Couldn't find onDelete method"); - return -3; - } - - jstring nameStr = env->NewStringUTF(objectName); - - if(buffer == NULL) - { - LOGD("JNI: Delete file: %s", objectName); - // delete operation - return env->CallIntMethod( - ref->dataStorePutListener, deleteMethod, nameStr); - } - else - { - LOGD("JNI: Write file: %s", objectName); - // set operation - jbyteArray bufferObj = env->NewByteArray(bufferSize); - if(env->ExceptionCheck() || bufferObj == NULL) - { - LOGE("Error creating byte array buffer!"); - return -4; - } - - env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer); - bool bsecure = secure != 0; - - return env->CallIntMethod(ref->dataStorePutListener, - dataStorePutCallbackMethod, - nameStr, bufferObj, bsecure); - } - } - int WirePacketSendFunction(ZT_Node *node, void *userData, void *threadData, - const struct sockaddr_storage *localAddress, + int64_t localSocket, const struct sockaddr_storage *remoteAddress, const void *buffer, unsigned int bufferSize, unsigned int ttl) { - LOGV("WirePacketSendFunction(%p, %p, %p, %d)", localAddress, remoteAddress, buffer, bufferSize); + LOGV("WirePacketSendFunction(%lld, %p, %p, %d)", (long long)localSocket, remoteAddress, buffer, bufferSize); JniRef *ref = (JniRef*)userData; assert(ref->node == node); JNIEnv *env = NULL; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + if (ref->packetSender == NULL) { + LOGE("packetSender is NULL"); + return -1; + } jclass packetSenderClass = env->GetObjectClass(ref->packetSender); if(packetSenderClass == NULL) @@ -468,23 +533,17 @@ namespace { } jmethodID packetSenderCallbackMethod = lookup.findMethod(packetSenderClass, - "onSendPacketRequested", "(Ljava/net/InetSocketAddress;Ljava/net/InetSocketAddress;[BI)I"); + "onSendPacketRequested", "(JLjava/net/InetSocketAddress;[BI)I"); if(packetSenderCallbackMethod == NULL) { LOGE("Couldn't find onSendPacketRequested method"); return -2; } - jobject localAddressObj = NULL; - if(memcmp(localAddress, &ZT_SOCKADDR_NULL, sizeof(sockaddr_storage)) != 0) - { - localAddressObj = newInetSocketAddress(env, *localAddress); - } - jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress); jbyteArray bufferObj = env->NewByteArray(bufferSize); env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer); - int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, localAddressObj, remoteAddressObj, bufferObj); + int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, localSocket, remoteAddressObj, bufferObj); LOGV("JNI Packet Sender returned: %d", retval); return retval; @@ -494,7 +553,7 @@ namespace { void *userPtr, void *threadPtr, uint64_t address, - const struct sockaddr_storage *localAddress, + int64_t localSocket, const struct sockaddr_storage *remoteAddress) { JniRef *ref = (JniRef*)userPtr; @@ -515,26 +574,22 @@ namespace { } jmethodID pathCheckCallbackMethod = lookup.findMethod(pathCheckerClass, - "onPathCheck", "(JLjava/net/InetSocketAddress;Ljava/net/InetSocketAddress;)Z"); + "onPathCheck", "(JJLjava/net/InetSocketAddress;)Z"); if(pathCheckCallbackMethod == NULL) { LOGE("Couldn't find onPathCheck method implementation"); return true; } - jobject localAddressObj = NULL; + struct sockaddr_storage nullAddress = {0}; jobject remoteAddressObj = NULL; - if(memcmp(localAddress, &ZT_SOCKADDR_NULL, sizeof(sockaddr_storage)) != 0) - { - localAddressObj = newInetSocketAddress(env, *localAddress); - } - if(memcmp(remoteAddress, &ZT_SOCKADDR_NULL, sizeof(sockaddr_storage)) != 0) + if(memcmp(remoteAddress, &nullAddress, sizeof(sockaddr_storage)) != 0) { remoteAddressObj = newInetSocketAddress(env, *remoteAddress); } - return env->CallBooleanMethod(ref->pathChecker, pathCheckCallbackMethod, address, localAddressObj, remoteAddressObj); + return env->CallBooleanMethod(ref->pathChecker, pathCheckCallbackMethod, address, localSocket, remoteAddressObj); } int PathLookupFunction(ZT_Node *node, @@ -649,11 +704,11 @@ namespace { return true; } - typedef std::map<uint64_t, JniRef*> NodeMap; + typedef std::map<int64_t, JniRef*> NodeMap; static NodeMap nodeMap; ZeroTier::Mutex nodeMapMutex; - ZT_Node* findNode(uint64_t nodeId) + ZT_Node* findNode(int64_t nodeId) { ZeroTier::Mutex::Lock lock(nodeMapMutex); NodeMap::iterator found = nodeMap.find(nodeId); @@ -691,7 +746,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( ZT_Node *node; JniRef *ref = new JniRef; - ref->id = (uint64_t)now; + ref->id = (int64_t)now; env->GetJavaVM(&ref->jvm); jclass cls = env->GetObjectClass(obj); @@ -795,8 +850,8 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( ref->pathChecker = env->NewGlobalRef(tmp); } - ref->callbacks->dataStoreGetFunction = &DataStoreGetFunction; - ref->callbacks->dataStorePutFunction = &DataStorePutFunction; + ref->callbacks->stateGetFunction = &StateGetFunction; + ref->callbacks->statePutFunction = &StatePutFunction; ref->callbacks->wirePacketSendFunction = &WirePacketSendFunction; ref->callbacks->virtualNetworkFrameFunction = &VirtualNetworkFrameFunctionCallback; ref->callbacks->virtualNetworkConfigFunction = &VirtualNetworkConfigFunctionCallback; @@ -809,7 +864,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( ref, NULL, ref->callbacks, - (uint64_t)now); + (int64_t)now); if(rc != ZT_RESULT_OK) { @@ -825,11 +880,17 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( return resultObject; } + uint64_t nodeId = ZT_Node_address(node); + if (nodeId != 0) { + char uniqueName[64]; + snprintf(uniqueName, sizeof(uniqueName), "ZeroTier Android/%.10llx@%u", (unsigned long long)nodeId, 9993); + ref->portMapper = new ZeroTier::PortMapper(9993, uniqueName); + } + ZeroTier::Mutex::Lock lock(nodeMapMutex); ref->node = node; nodeMap.insert(std::make_pair(ref->id, ref)); - return resultObject; } @@ -842,7 +903,7 @@ JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete( JNIEnv *env, jobject obj, jlong id) { LOGV("Destroying ZT_Node struct"); - uint64_t nodeId = (uint64_t)id; + int64_t nodeId = (int64_t)id; NodeMap::iterator found; { @@ -883,7 +944,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( jbyteArray in_frameData, jlongArray out_nextBackgroundTaskDeadline) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) @@ -899,7 +960,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - uint64_t now = (uint64_t)in_now; + int64_t now = (int64_t)in_now; uint64_t nwid = (uint64_t)in_nwid; uint64_t sourceMac = (uint64_t)in_sourceMac; uint64_t destMac = (uint64_t)in_destMac; @@ -912,7 +973,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( memcpy(localData, frameData, frameLength); env->ReleasePrimitiveArrayCritical(in_frameData, frameData, 0); - uint64_t nextBackgroundTaskDeadline = 0; + int64_t nextBackgroundTaskDeadline = 0; ZT_ResultCode rc = ZT_Node_processVirtualNetworkFrame( node, @@ -937,18 +998,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( /* * Class: com_zerotier_sdk_Node * Method: processWirePacket - * Signature: (JJLjava/net/InetSocketAddress;I[B[J)Lcom/zerotier/sdk/ResultCode; + * Signature: (JJJLjava/net/InetSocketAddress;I[B[J)Lcom/zerotier/sdk/ResultCode; */ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( JNIEnv *env, jobject obj, jlong id, jlong in_now, - jobject in_localAddress, + jlong in_localSocket, jobject in_remoteAddress, jbyteArray in_packetData, jlongArray out_nextBackgroundTaskDeadline) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -957,14 +1018,14 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); + unsigned int nbtd_len = (unsigned int)env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) { LOGE("nbtd_len < 1"); return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - uint64_t now = (uint64_t)in_now; + int64_t now = (int64_t)in_now; // get the java.net.InetSocketAddress class and getAddress() method jclass inetAddressClass = lookup.findClass("java/net/InetAddress"); @@ -992,12 +1053,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( jmethodID inetSockGetAddressMethod = lookup.findMethod( InetSocketAddressClass, "getAddress", "()Ljava/net/InetAddress;"); - jobject localAddrObj = NULL; - if(in_localAddress != NULL) - { - localAddrObj = env->CallObjectMethod(in_localAddress, inetSockGetAddressMethod); - } - jobject remoteAddrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod); if(remoteAddrObject == NULL) @@ -1034,47 +1089,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( unsigned int addrSize = env->GetArrayLength(remoteAddressArray); - sockaddr_storage localAddress = {}; - - if(localAddrObj == NULL) - { - localAddress = ZT_SOCKADDR_NULL; - } - else - { - int localPort = env->CallIntMethod(in_localAddress, inetSock_getPort); - jbyteArray localAddressArray = (jbyteArray)env->CallObjectMethod(localAddrObj, getAddressMethod); - if(localAddressArray != NULL) - { - - unsigned int localAddrSize = env->GetArrayLength(localAddressArray); - jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(localAddressArray, NULL); - - if(localAddrSize == 16) - { - sockaddr_in6 ipv6 = {}; - ipv6.sin6_family = AF_INET6; - ipv6.sin6_port = htons(localPort); - memcpy(ipv6.sin6_addr.s6_addr, addr, 16); - memcpy(&localAddress, &ipv6, sizeof(sockaddr_in6)); - } - else if(localAddrSize) - { - // IPV4 address - sockaddr_in ipv4 = {}; - ipv4.sin_family = AF_INET; - ipv4.sin_port = htons(localPort); - memcpy(&ipv4.sin_addr, addr, 4); - memcpy(&localAddress, &ipv4, sizeof(sockaddr_in)); - } - else - { - localAddress = ZT_SOCKADDR_NULL; - } - env->ReleasePrimitiveArrayCritical(localAddressArray, addr, 0); - } - } - // get the address bytes jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(remoteAddressArray, NULL); sockaddr_storage remoteAddress = {}; @@ -1106,7 +1120,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( } env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0); - unsigned int packetLength = env->GetArrayLength(in_packetData); + unsigned int packetLength = (unsigned int)env->GetArrayLength(in_packetData); if(packetLength == 0) { LOGE("Empty packet?!?"); @@ -1117,13 +1131,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( memcpy(localData, packetData, packetLength); env->ReleasePrimitiveArrayCritical(in_packetData, packetData, 0); - uint64_t nextBackgroundTaskDeadline = 0; + int64_t nextBackgroundTaskDeadline = 0; ZT_ResultCode rc = ZT_Node_processWirePacket( node, NULL, now, - &localAddress, + in_localSocket, &remoteAddress, localData, packetLength, @@ -1153,7 +1167,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( jlong in_now, jlongArray out_nextBackgroundTaskDeadline) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1167,8 +1181,8 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } - uint64_t now = (uint64_t)in_now; - uint64_t nextBackgroundTaskDeadline = 0; + int64_t now = (int64_t)in_now; + int64_t nextBackgroundTaskDeadline = 0; ZT_ResultCode rc = ZT_Node_processBackgroundTasks(node, NULL, now, &nextBackgroundTaskDeadline); @@ -1187,7 +1201,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join( JNIEnv *env, jobject obj, jlong id, jlong in_nwid) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1210,7 +1224,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join( JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave( JNIEnv *env, jobject obj, jlong id, jlong in_nwid) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1237,7 +1251,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe( jlong in_multicastGroup, jlong in_multicastAdi) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1267,7 +1281,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe( jlong in_multicastGroup, jlong in_multicastAdi) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1296,7 +1310,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_orbit( jlong in_moonWorldId, jlong in_moonSeed) { - uint64_t nodeId = (uint64_t)id; + int64_t nodeId = (int64_t)id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1320,7 +1334,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit( jlong id, jlong in_moonWorldId) { - uint64_t nodeId = (uint64_t)id; + int64_t nodeId = (int64_t)id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1341,7 +1355,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit( JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address( JNIEnv *env , jobject obj, jlong id) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1361,7 +1375,7 @@ JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address( JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status (JNIEnv *env, jobject obj, jlong id) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1453,7 +1467,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig( JNIEnv *env, jobject obj, jlong id, jlong nwid) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1495,7 +1509,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version( JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( JNIEnv *env, jobject obj, jlong id) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { @@ -1564,7 +1578,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( JNIEnv *env, jobject obj, jlong id) { - uint64_t nodeId = (uint64_t) id; + int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); if(node == NULL) { diff --git a/java/jni/com_zerotierone_sdk_Node.h b/java/jni/com_zerotierone_sdk_Node.h index 7c1011ab..8487d8af 100644 --- a/java/jni/com_zerotierone_sdk_Node.h +++ b/java/jni/com_zerotierone_sdk_Node.h @@ -37,7 +37,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame * Signature: (JJLjava/net/InetSockAddress;Ljava/net/InetSockAddress;[B[J)Lcom/zerotier/sdk/ResultCode; */ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket - (JNIEnv *, jobject, jlong, jlong, jobject, jobject, jbyteArray, jlongArray); + (JNIEnv *, jobject, jlong, jlong, jlong, jobject, jbyteArray, jlongArray); /* * Class: com_zerotier_sdk_Node |