summaryrefslogtreecommitdiff
path: root/java/jni/com_zerotierone_sdk_Node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'java/jni/com_zerotierone_sdk_Node.cpp')
-rw-r--r--java/jni/com_zerotierone_sdk_Node.cpp177
1 files changed, 109 insertions, 68 deletions
diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp
index f0405813..e98342e7 100644
--- a/java/jni/com_zerotierone_sdk_Node.cpp
+++ b/java/jni/com_zerotierone_sdk_Node.cpp
@@ -27,17 +27,18 @@
#include "com_zerotierone_sdk_Node.h"
#include "ZT1_jniutils.h"
-#include "ZT1_jnicache.h"
+#include "ZT1_jnilookup.h"
#include <ZeroTierOne.h>
+#include "Mutex.hpp"
#include <map>
#include <string>
#include <assert.h>
#include <string.h>
-// global static JNI Cache Object
-JniCache cache;
+// global static JNI Lookup Object
+JniLookup lookup;
#ifdef __cplusplus
extern "C" {
@@ -92,7 +93,7 @@ namespace {
enum ZT1_VirtualNetworkConfigOperation operation,
const ZT1_VirtualNetworkConfig *config)
{
- LOGD("VritualNetworkConfigFunctionCallback");
+ LOGV("VritualNetworkConfigFunctionCallback");
JniRef *ref = (JniRef*)userData;
JNIEnv *env = NULL;
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
@@ -104,7 +105,7 @@ namespace {
return -1;
}
- jmethodID configListenerCallbackMethod = cache.findMethod(configListenerClass,
+ jmethodID configListenerCallbackMethod = lookup.findMethod(configListenerClass,
"onNetworkConfigurationUpdated",
"(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I");
if(configListenerCallbackMethod == NULL)
@@ -142,7 +143,9 @@ namespace {
const void *frameData,
unsigned int frameLength)
{
- LOGD("VirtualNetworkFrameFunctionCallback");
+ LOGV("VirtualNetworkFrameFunctionCallback");
+ unsigned char* local = (unsigned char*)frameData;
+ LOGV("Type Bytes: 0x%02x%02x", local[12], local[13]);
JniRef *ref = (JniRef*)userData;
assert(ref->node == node);
JNIEnv *env = NULL;
@@ -156,7 +159,7 @@ namespace {
return;
}
- jmethodID frameListenerCallbackMethod = cache.findMethod(
+ jmethodID frameListenerCallbackMethod = lookup.findMethod(
frameListenerClass,
"onVirtualNetworkFrame", "(JJJJJ[B)V");
if(env->ExceptionCheck() || frameListenerCallbackMethod == NULL)
@@ -172,9 +175,9 @@ namespace {
return;
}
- jbyte *data = env->GetByteArrayElements(dataArray, NULL);
+ void *data = env->GetPrimitiveArrayCritical(dataArray, NULL);
memcpy(data, frameData, frameLength);
- env->ReleaseByteArrayElements(dataArray, data, 0);
+ env->ReleasePrimitiveArrayCritical(dataArray, data, 0);
if(env->ExceptionCheck())
{
@@ -188,9 +191,13 @@ namespace {
void EventCallback(ZT1_Node *node,void *userData,enum ZT1_Event event, const void *data)
{
- LOGD("EventCallback");
+ LOGV("EventCallback");
JniRef *ref = (JniRef*)userData;
- assert(ref->node == node);
+ if(ref->node != node && event != ZT1_EVENT_UP)
+ {
+ LOGE("Nodes not equal. ref->node %p, node %p. Event: %d", ref->node, node, event);
+ return;
+ }
JNIEnv *env = NULL;
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
@@ -202,7 +209,7 @@ namespace {
return;
}
- jmethodID onEventMethod = cache.findMethod(eventListenerClass,
+ jmethodID onEventMethod = lookup.findMethod(eventListenerClass,
"onEvent", "(Lcom/zerotier/sdk/Event;)V");
if(onEventMethod == NULL)
{
@@ -211,7 +218,7 @@ namespace {
}
- jmethodID onOutOfDateMethod = cache.findMethod(eventListenerClass,
+ jmethodID onOutOfDateMethod = lookup.findMethod(eventListenerClass,
"onOutOfDate", "(Lcom/zerotier/sdk/Version;)V");
if(onOutOfDateMethod == NULL)
{
@@ -220,7 +227,7 @@ namespace {
}
- jmethodID onNetworkErrorMethod = cache.findMethod(eventListenerClass,
+ jmethodID onNetworkErrorMethod = lookup.findMethod(eventListenerClass,
"onNetworkError", "(Lcom/zerotier/sdk/Event;Ljava/net/InetSocketAddress;)V");
if(onNetworkErrorMethod == NULL)
{
@@ -229,7 +236,7 @@ namespace {
}
- jmethodID onTraceMethod = cache.findMethod(eventListenerClass,
+ jmethodID onTraceMethod = lookup.findMethod(eventListenerClass,
"onTrace", "(Ljava/lang/String;)V");
if(onTraceMethod == NULL)
{
@@ -314,7 +321,7 @@ namespace {
return -2;
}
- jmethodID dataStoreGetCallbackMethod = cache.findMethod(
+ jmethodID dataStoreGetCallbackMethod = lookup.findMethod(
dataStoreGetClass,
"onDataStoreGet",
"(Ljava/lang/String;[BJ[J)J");
@@ -354,16 +361,16 @@ namespace {
if(retval > 0)
{
- jbyte *data = env->GetByteArrayElements(bufferObj, NULL);
+ void *data = env->GetPrimitiveArrayCritical(bufferObj, NULL);
memcpy(buffer, data, retval);
- env->ReleaseByteArrayElements(bufferObj, data, JNI_ABORT);
+ env->ReleasePrimitiveArrayCritical(bufferObj, data, 0);
- jlong *objSize = env->GetLongArrayElements(objectSizeObj, NULL);
+ jlong *objSize = (jlong*)env->GetPrimitiveArrayCritical(objectSizeObj, NULL);
*out_objectSize = (unsigned long)objSize[0];
- env->ReleaseLongArrayElements(objectSizeObj, objSize, JNI_ABORT);
+ env->ReleasePrimitiveArrayCritical(objectSizeObj, objSize, 0);
}
- LOGI("Out Object Size: %lu", *out_objectSize);
+ LOGV("Out Object Size: %lu", *out_objectSize);
return retval;
}
@@ -386,7 +393,7 @@ namespace {
return -1;
}
- jmethodID dataStorePutCallbackMethod = cache.findMethod(
+ jmethodID dataStorePutCallbackMethod = lookup.findMethod(
dataStorePutClass,
"onDataStorePut",
"(Ljava/lang/String;[BZ)I");
@@ -396,7 +403,7 @@ namespace {
return -2;
}
- jmethodID deleteMethod = cache.findMethod(dataStorePutClass,
+ jmethodID deleteMethod = lookup.findMethod(dataStorePutClass,
"onDelete", "(Ljava/lang/String;)I");
if(deleteMethod == NULL)
{
@@ -408,18 +415,25 @@ namespace {
if(buffer == NULL)
{
+ LOGD("JNI: Delete file: %s", objectName);
// delete operation
return env->CallIntMethod(
ref->dataStorePutListener, deleteMethod, nameStr);
}
else
{
+ LOGD("JNI: Write file: %s", objectName);
// set operation
jbyteArray bufferObj = env->NewByteArray(bufferSize);
+ if(env->ExceptionCheck() || bufferObj == NULL)
+ {
+ LOGE("Error creating byte array buffer!");
+ return -4;
+ }
+
env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer);
bool bsecure = secure != 0;
-
return env->CallIntMethod(ref->dataStorePutListener,
dataStorePutCallbackMethod,
nameStr, bufferObj, bsecure);
@@ -431,7 +445,7 @@ namespace {
const void *buffer,
unsigned int bufferSize)
{
- LOGD("WirePacketSendFunction(%p, %p, %d)", address, buffer, bufferSize);
+ LOGV("WirePacketSendFunction(%p, %p, %d)", address, buffer, bufferSize);
JniRef *ref = (JniRef*)userData;
assert(ref->node == node);
@@ -446,7 +460,7 @@ namespace {
return -1;
}
- jmethodID packetSenderCallbackMethod = cache.findMethod(packetSenderClass,
+ jmethodID packetSenderCallbackMethod = lookup.findMethod(packetSenderClass,
"onSendPacketRequested", "(Ljava/net/InetSocketAddress;[B)I");
if(packetSenderCallbackMethod == NULL)
{
@@ -459,15 +473,17 @@ namespace {
env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer);
int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, addressObj, bufferObj);
- LOGD("JNI Packet Sender returned: %d", retval);
+ LOGV("JNI Packet Sender returned: %d", retval);
return retval;
}
typedef std::map<uint64_t, JniRef*> NodeMap;
static NodeMap nodeMap;
+ ZeroTier::Mutex nodeMapMutex;
ZT1_Node* findNode(uint64_t nodeId)
{
+ ZeroTier::Mutex::Lock lock(nodeMapMutex);
NodeMap::iterator found = nodeMap.find(nodeId);
if(found != nodeMap.end())
{
@@ -480,13 +496,13 @@ namespace {
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
- cache.setJavaVM(vm);
+ lookup.setJavaVM(vm);
return JNI_VERSION_1_6;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
{
- cache.clearCache();
+
}
@@ -507,7 +523,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
env->GetJavaVM(&ref->jvm);
jclass cls = env->GetObjectClass(obj);
- jfieldID fid = cache.findField(
+ jfieldID fid = lookup.findField(
cls, "getListener", "Lcom/zerotier/sdk/DataStoreGetListener;");
if(fid == NULL)
@@ -522,7 +538,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
}
ref->dataStoreGetListener = env->NewGlobalRef(tmp);
- fid = cache.findField(
+ fid = lookup.findField(
cls, "putListener", "Lcom/zerotier/sdk/DataStorePutListener;");
if(fid == NULL)
@@ -537,7 +553,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
}
ref->dataStorePutListener = env->NewGlobalRef(tmp);
- fid = cache.findField(
+ fid = lookup.findField(
cls, "sender", "Lcom/zerotier/sdk/PacketSender;");
if(fid == NULL)
{
@@ -551,7 +567,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
}
ref->packetSender = env->NewGlobalRef(tmp);
- fid = cache.findField(
+ fid = lookup.findField(
cls, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;");
if(fid == NULL)
{
@@ -565,7 +581,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
}
ref->frameListener = env->NewGlobalRef(tmp);
- fid = cache.findField(
+ fid = lookup.findField(
cls, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;");
if(fid == NULL)
{
@@ -579,7 +595,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
}
ref->configListener = env->NewGlobalRef(tmp);
- fid = cache.findField(
+ fid = lookup.findField(
cls, "eventListener", "Lcom/zerotier/sdk/EventListener;");
if(fid == NULL)
{
@@ -604,6 +620,8 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
&VirtualNetworkConfigFunctionCallback,
&EventCallback);
+ LOGI("Node Created.");
+
if(rc != ZT1_RESULT_OK)
{
LOGE("Error creating Node: %d", rc);
@@ -618,8 +636,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
return resultObject;
}
+ ZeroTier::Mutex::Lock lock(nodeMapMutex);
ref->node = node;
nodeMap.insert(std::make_pair(ref->id, ref));
+
return resultObject;
}
@@ -635,7 +655,12 @@ JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete(
LOGV("Destroying ZT1_Node struct");
uint64_t nodeId = (uint64_t)id;
- NodeMap::iterator found = nodeMap.find(nodeId);
+ NodeMap::iterator found;
+ {
+ ZeroTier::Mutex::Lock lock(nodeMapMutex);
+ found = nodeMap.find(nodeId);
+ }
+
if(found != nodeMap.end())
{
JniRef *ref = found->second;
@@ -693,7 +718,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame(
unsigned int vlanId = (unsigned int)in_vlanId;
unsigned int frameLength = env->GetArrayLength(in_frameData);
- jbyte *frameData =env->GetByteArrayElements(in_frameData, NULL);
+ void *frameData = env->GetPrimitiveArrayCritical(in_frameData, NULL);
+ void *localData = malloc(frameLength);
+ memcpy(localData, frameData, frameLength);
+ env->ReleasePrimitiveArrayCritical(in_frameData, frameData, 0);
uint64_t nextBackgroundTaskDeadline = 0;
@@ -705,15 +733,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame(
destMac,
etherType,
vlanId,
- (const void*)frameData,
+ (const void*)localData,
frameLength,
&nextBackgroundTaskDeadline);
- jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
+ jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
- env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
-
- env->ReleaseByteArrayElements(in_frameData, frameData, 0);
+ env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
return createResultObject(env, rc);
}
@@ -736,26 +762,29 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
if(node == NULL)
{
// cannot find valid node. We should never get here.
+ LOGE("Couldn't find a valid node!");
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
if(nbtd_len < 1)
{
+ LOGE("nbtd_len < 1");
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t now = (uint64_t)in_now;
// get the java.net.InetSocketAddress class and getAddress() method
- jclass inetAddressClass = cache.findClass("java/net/InetAddress");
+ jclass inetAddressClass = lookup.findClass("java/net/InetAddress");
if(inetAddressClass == NULL)
{
+ LOGE("Can't find InetAddress class");
// can't find java.net.InetAddress
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
- jmethodID getAddressMethod = cache.findMethod(
+ jmethodID getAddressMethod = lookup.findMethod(
inetAddressClass, "getAddress", "()[B");
if(getAddressMethod == NULL)
{
@@ -763,13 +792,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
- jclass InetSocketAddressClass = cache.findClass("java/net/InetSocketAddress");
+ jclass InetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
if(InetSocketAddressClass == NULL)
{
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
- jmethodID inetSockGetAddressMethod = cache.findMethod(
+ jmethodID inetSockGetAddressMethod = lookup.findMethod(
InetSocketAddressClass, "getAddress", "()Ljava/net/InetAddress;");
jobject addrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod);
@@ -779,7 +808,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
- jmethodID inetSock_getPort = cache.findMethod(
+ jmethodID inetSock_getPort = lookup.findMethod(
InetSocketAddressClass, "getPort", "()I");
if(env->ExceptionCheck() || inetSock_getPort == NULL)
@@ -800,14 +829,14 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
jbyteArray addressArray = (jbyteArray)env->CallObjectMethod(addrObject, getAddressMethod);
if(addressArray == NULL)
{
+ LOGE("Unable to call getAddress()");
// unable to call getAddress()
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
unsigned int addrSize = env->GetArrayLength(addressArray);
// get the address bytes
- jbyte *addr = env->GetByteArrayElements(addressArray, NULL);
-
+ jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(addressArray, NULL);
sockaddr_storage remoteAddress = {};
@@ -831,14 +860,23 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
}
else
{
+ LOGE("Unknown IP version");
// unknown address type
- env->ReleaseByteArrayElements(addressArray, addr, 0);
+ env->ReleasePrimitiveArrayCritical(addressArray, addr, 0);
return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
}
-
+ env->ReleasePrimitiveArrayCritical(addressArray, addr, 0);
unsigned int packetLength = env->GetArrayLength(in_packetData);
- jbyte *packetData = env->GetByteArrayElements(in_packetData, NULL);
+ if(packetLength == 0)
+ {
+ LOGE("Empty packet?!?");
+ return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ }
+ void *packetData = env->GetPrimitiveArrayCritical(in_packetData, NULL);
+ void *localData = malloc(packetLength);
+ memcpy(localData, packetData, packetLength);
+ env->ReleasePrimitiveArrayCritical(in_packetData, packetData, 0);
uint64_t nextBackgroundTaskDeadline = 0;
@@ -846,16 +884,19 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
node,
now,
&remoteAddress,
- packetData,
+ localData,
packetLength,
&nextBackgroundTaskDeadline);
+ if(rc != ZT1_RESULT_OK)
+ {
+ LOGE("ZT1_Node_processWirePacket returned: %d", rc);
+ }
- jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
- outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
- env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
+ free(localData);
- env->ReleaseByteArrayElements(addressArray, addr, 0);
- env->ReleaseByteArrayElements(in_packetData, packetData, 0);
+ jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
+ outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
+ env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
return createResultObject(env, rc);
}
@@ -890,9 +931,9 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks(
ZT1_ResultCode rc = ZT1_Node_processBackgroundTasks(node, now, &nextBackgroundTaskDeadline);
- jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
+ jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
- env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
+ env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
return createResultObject(env, rc);
}
@@ -1043,13 +1084,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
jmethodID nodeStatusConstructor = NULL;
// create a com.zerotier.sdk.NodeStatus object
- nodeStatusClass = cache.findClass("com/zerotier/sdk/NodeStatus");
+ nodeStatusClass = lookup.findClass("com/zerotier/sdk/NodeStatus");
if(nodeStatusClass == NULL)
{
return NULL;
}
- nodeStatusConstructor = cache.findMethod(
+ nodeStatusConstructor = lookup.findMethod(
nodeStatusClass, "<init>", "()V");
if(nodeStatusConstructor == NULL)
{
@@ -1070,25 +1111,25 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
jfieldID secretIdentityField = NULL;
jfieldID onlineField = NULL;
- addressField = cache.findField(nodeStatusClass, "address", "J");
+ addressField = lookup.findField(nodeStatusClass, "address", "J");
if(addressField == NULL)
{
return NULL;
}
- publicIdentityField = cache.findField(nodeStatusClass, "publicIdentity", "Ljava/lang/String;");
+ publicIdentityField = lookup.findField(nodeStatusClass, "publicIdentity", "Ljava/lang/String;");
if(publicIdentityField == NULL)
{
return NULL;
}
- secretIdentityField = cache.findField(nodeStatusClass, "secretIdentity", "Ljava/lang/String;");
+ secretIdentityField = lookup.findField(nodeStatusClass, "secretIdentity", "Ljava/lang/String;");
if(secretIdentityField == NULL)
{
return NULL;
}
- onlineField = cache.findField(nodeStatusClass, "online", "Z");
+ onlineField = lookup.findField(nodeStatusClass, "online", "Z");
if(onlineField == NULL)
{
return NULL;
@@ -1191,7 +1232,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers(
return NULL;
}
- jclass peerClass = cache.findClass("com/zerotier/sdk/Peer");
+ jclass peerClass = lookup.findClass("com/zerotier/sdk/Peer");
if(env->ExceptionCheck() || peerClass == NULL)
{
LOGE("Error finding Peer class");
@@ -1249,7 +1290,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks(
return NULL;
}
- jclass vnetConfigClass = cache.findClass("com/zerotier/sdk/VirtualNetworkConfig");
+ jclass vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig");
if(env->ExceptionCheck() || vnetConfigClass == NULL)
{
LOGE("Error finding VirtualNetworkConfig class");