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.cpp478
1 files changed, 279 insertions, 199 deletions
diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp
index f0405813..2c1b6807 100644
--- a/java/jni/com_zerotierone_sdk_Node.cpp
+++ b/java/jni/com_zerotierone_sdk_Node.cpp
@@ -26,18 +26,19 @@
*/
#include "com_zerotierone_sdk_Node.h"
-#include "ZT1_jniutils.h"
-#include "ZT1_jnicache.h"
+#include "ZT_jniutils.h"
+#include "ZT_jnilookup.h"
#include <ZeroTierOne.h>
+#include "Mutex.hpp"
#include <map>
#include <string>
#include <assert.h>
#include <string.h>
-// global static JNI Cache Object
-JniCache cache;
+// global static JNI Lookup Object
+JniLookup lookup;
#ifdef __cplusplus
extern "C" {
@@ -74,7 +75,7 @@ namespace {
JavaVM *jvm;
- ZT1_Node *node;
+ ZT_Node *node;
jobject dataStoreGetListener;
jobject dataStorePutListener;
@@ -86,13 +87,13 @@ namespace {
int VirtualNetworkConfigFunctionCallback(
- ZT1_Node *node,
+ ZT_Node *node,
void *userData,
uint64_t nwid,
- enum ZT1_VirtualNetworkConfigOperation operation,
- const ZT1_VirtualNetworkConfig *config)
+ enum ZT_VirtualNetworkConfigOperation operation,
+ const ZT_VirtualNetworkConfig *config)
{
- LOGD("VritualNetworkConfigFunctionCallback");
+ LOGV("VritualNetworkConfigFunctionCallback");
JniRef *ref = (JniRef*)userData;
JNIEnv *env = NULL;
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
@@ -104,7 +105,7 @@ namespace {
return -1;
}
- jmethodID configListenerCallbackMethod = cache.findMethod(configListenerClass,
+ jmethodID configListenerCallbackMethod = lookup.findMethod(configListenerClass,
"onNetworkConfigurationUpdated",
"(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I");
if(configListenerCallbackMethod == NULL)
@@ -133,7 +134,8 @@ namespace {
(jlong)nwid, operationObject, networkConfigObject);
}
- void VirtualNetworkFrameFunctionCallback(ZT1_Node *node,void *userData,
+ void VirtualNetworkFrameFunctionCallback(ZT_Node *node,
+ void *userData,
uint64_t nwid,
uint64_t sourceMac,
uint64_t destMac,
@@ -142,7 +144,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 +160,7 @@ namespace {
return;
}
- jmethodID frameListenerCallbackMethod = cache.findMethod(
+ jmethodID frameListenerCallbackMethod = lookup.findMethod(
frameListenerClass,
"onVirtualNetworkFrame", "(JJJJJ[B)V");
if(env->ExceptionCheck() || frameListenerCallbackMethod == NULL)
@@ -172,9 +176,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())
{
@@ -186,11 +190,18 @@ namespace {
}
- void EventCallback(ZT1_Node *node,void *userData,enum ZT1_Event event, const void *data)
+ void EventCallback(ZT_Node *node,
+ void *userData,
+ enum ZT_Event event,
+ const void *data)
{
- LOGD("EventCallback");
+ LOGV("EventCallback");
JniRef *ref = (JniRef*)userData;
- assert(ref->node == node);
+ if(ref->node != node && event != ZT_EVENT_UP)
+ {
+ LOGE("Nodes not equal. ref->node %p, node %p. Event: %d", ref->node, node, event);
+ return;
+ }
JNIEnv *env = NULL;
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
@@ -202,7 +213,7 @@ namespace {
return;
}
- jmethodID onEventMethod = cache.findMethod(eventListenerClass,
+ jmethodID onEventMethod = lookup.findMethod(eventListenerClass,
"onEvent", "(Lcom/zerotier/sdk/Event;)V");
if(onEventMethod == NULL)
{
@@ -210,26 +221,7 @@ namespace {
return;
}
-
- jmethodID onOutOfDateMethod = cache.findMethod(eventListenerClass,
- "onOutOfDate", "(Lcom/zerotier/sdk/Version;)V");
- if(onOutOfDateMethod == NULL)
- {
- LOGE("Couldn't find onOutOfDate method");
- return;
- }
-
-
- jmethodID onNetworkErrorMethod = cache.findMethod(eventListenerClass,
- "onNetworkError", "(Lcom/zerotier/sdk/Event;Ljava/net/InetSocketAddress;)V");
- if(onNetworkErrorMethod == NULL)
- {
- LOGE("Couldn't find onNetworkError method");
- return;
- }
-
-
- jmethodID onTraceMethod = cache.findMethod(eventListenerClass,
+ jmethodID onTraceMethod = lookup.findMethod(eventListenerClass,
"onTrace", "(Ljava/lang/String;)V");
if(onTraceMethod == NULL)
{
@@ -245,43 +237,38 @@ namespace {
switch(event)
{
- case ZT1_EVENT_UP:
- case ZT1_EVENT_OFFLINE:
- case ZT1_EVENT_ONLINE:
- case ZT1_EVENT_DOWN:
- case ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION:
+ case ZT_EVENT_UP:
{
- LOGV("Regular Event");
- // call onEvent()
+ LOGD("Event Up");
env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
+ break;
}
- break;
- case ZT1_EVENT_SAW_MORE_RECENT_VERSION:
+ case ZT_EVENT_OFFLINE:
{
- LOGV("Version Event");
- // call onOutOfDate()
- if(data != NULL)
- {
- int *version = (int*)data;
- jobject verisonObj = newVersion(env, version[0], version[1], version[2], 0);
- env->CallVoidMethod(ref->eventListener, onOutOfDateMethod, verisonObj);
- }
+ LOGD("Event Offline");
+ env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject);
+ break;
}
- break;
- case ZT1_EVENT_AUTHENTICATION_FAILURE:
- case ZT1_EVENT_INVALID_PACKET:
+ case ZT_EVENT_ONLINE:
{
- LOGV("Network Error Event");
- // call onNetworkError()
- if(data != NULL)
- {
- sockaddr_storage *addr = (sockaddr_storage*)data;
- jobject addressObj = newInetSocketAddress(env, *addr);
- env->CallVoidMethod(ref->eventListener, onNetworkErrorMethod, addressObj);
- }
+ 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 ZT1_EVENT_TRACE:
+ case ZT_EVENT_TRACE:
{
LOGV("Trace Event");
// call onTrace()
@@ -296,7 +283,8 @@ namespace {
}
}
- long DataStoreGetFunction(ZT1_Node *node,void *userData,
+ long DataStoreGetFunction(ZT_Node *node,
+ void *userData,
const char *objectName,
void *buffer,
unsigned long bufferSize,
@@ -314,7 +302,7 @@ namespace {
return -2;
}
- jmethodID dataStoreGetCallbackMethod = cache.findMethod(
+ jmethodID dataStoreGetCallbackMethod = lookup.findMethod(
dataStoreGetClass,
"onDataStoreGet",
"(Ljava/lang/String;[BJ[J)J");
@@ -354,21 +342,22 @@ 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;
}
- int DataStorePutFunction(ZT1_Node *node,void *userData,
+ int DataStorePutFunction(ZT_Node *node,
+ void *userData,
const char *objectName,
const void *buffer,
unsigned long bufferSize,
@@ -386,7 +375,7 @@ namespace {
return -1;
}
- jmethodID dataStorePutCallbackMethod = cache.findMethod(
+ jmethodID dataStorePutCallbackMethod = lookup.findMethod(
dataStorePutClass,
"onDataStorePut",
"(Ljava/lang/String;[BZ)I");
@@ -396,7 +385,7 @@ namespace {
return -2;
}
- jmethodID deleteMethod = cache.findMethod(dataStorePutClass,
+ jmethodID deleteMethod = lookup.findMethod(dataStorePutClass,
"onDelete", "(Ljava/lang/String;)I");
if(deleteMethod == NULL)
{
@@ -408,30 +397,40 @@ 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);
}
}
- int WirePacketSendFunction(ZT1_Node *node,void *userData,\
- const struct sockaddr_storage *address,
+ int WirePacketSendFunction(ZT_Node *node,
+ void *userData,
+ const struct sockaddr_storage *localAddress,
+ const struct sockaddr_storage *remoteAddress,
const void *buffer,
- unsigned int bufferSize)
+ unsigned int bufferSize,
+ unsigned int ttl)
{
- LOGD("WirePacketSendFunction(%p, %p, %d)", address, buffer, bufferSize);
+ LOGV("WirePacketSendFunction(%p, %p, %p, %d)", localAddress, remoteAddress, buffer, bufferSize);
JniRef *ref = (JniRef*)userData;
assert(ref->node == node);
@@ -446,28 +445,36 @@ namespace {
return -1;
}
- jmethodID packetSenderCallbackMethod = cache.findMethod(packetSenderClass,
- "onSendPacketRequested", "(Ljava/net/InetSocketAddress;[B)I");
+ jmethodID packetSenderCallbackMethod = lookup.findMethod(packetSenderClass,
+ "onSendPacketRequested", "(Ljava/net/InetSocketAddress;Ljava/net/InetSocketAddress;[BI)I");
if(packetSenderCallbackMethod == NULL)
{
LOGE("Couldn't find onSendPacketRequested method");
return -2;
}
- jobject addressObj = newInetSocketAddress(env, *address);
+ jobject localAddressObj = NULL;
+ if(memcmp(localAddress, &ZT_SOCKADDR_NULL, sizeof(sockaddr_storage)) != 0)
+ {
+ localAddressObj = newInetSocketAddress(env, *localAddress);
+ }
+
+ jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress);
jbyteArray bufferObj = env->NewByteArray(bufferSize);
env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer);
- int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, addressObj, bufferObj);
+ int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, localAddressObj, remoteAddressObj, bufferObj);
- LOGD("JNI Packet Sender returned: %d", retval);
+ LOGV("JNI Packet Sender returned: %d", retval);
return retval;
}
typedef std::map<uint64_t, JniRef*> NodeMap;
static NodeMap nodeMap;
+ ZeroTier::Mutex nodeMapMutex;
- ZT1_Node* findNode(uint64_t nodeId)
+ ZT_Node* findNode(uint64_t nodeId)
{
+ ZeroTier::Mutex::Lock lock(nodeMapMutex);
NodeMap::iterator found = nodeMap.find(nodeId);
if(found != nodeMap.end())
{
@@ -480,13 +487,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();
+
}
@@ -498,16 +505,16 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
JNIEnv *env, jobject obj, jlong now)
{
- LOGV("Creating ZT1_Node struct");
- jobject resultObject = createResultObject(env, ZT1_RESULT_OK);
+ LOGV("Creating ZT_Node struct");
+ jobject resultObject = createResultObject(env, ZT_RESULT_OK);
- ZT1_Node *node;
+ ZT_Node *node;
JniRef *ref = new JniRef;
ref->id = (uint64_t)now;
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 +529,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 +544,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 +558,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 +572,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 +586,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)
{
@@ -593,7 +600,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
}
ref->eventListener = env->NewGlobalRef(tmp);
- ZT1_ResultCode rc = ZT1_Node_new(
+ ZT_ResultCode rc = ZT_Node_new(
&node,
ref,
(uint64_t)now,
@@ -604,13 +611,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
&VirtualNetworkConfigFunctionCallback,
&EventCallback);
- if(rc != ZT1_RESULT_OK)
+ if(rc != ZT_RESULT_OK)
{
LOGE("Error creating Node: %d", rc);
resultObject = createResultObject(env, rc);
if(node)
{
- ZT1_Node_delete(node);
+ ZT_Node_delete(node);
node = NULL;
}
delete ref;
@@ -618,8 +625,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;
}
@@ -632,16 +641,21 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete(
JNIEnv *env, jobject obj, jlong id)
{
- LOGV("Destroying ZT1_Node struct");
+ LOGV("Destroying ZT_Node struct");
uint64_t nodeId = (uint64_t)id;
- NodeMap::iterator found = nodeMap.find(nodeId);
+ NodeMap::iterator found;
+ {
+ ZeroTier::Mutex::Lock lock(nodeMapMutex);
+ found = nodeMap.find(nodeId);
+ }
+
if(found != nodeMap.end())
{
JniRef *ref = found->second;
nodeMap.erase(found);
- ZT1_Node_delete(ref->node);
+ ZT_Node_delete(ref->node);
delete ref;
ref = NULL;
@@ -671,18 +685,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame(
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
if(nbtd_len < 1)
{
// array for next background task length has 0 elements!
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t now = (uint64_t)in_now;
@@ -693,11 +707,14 @@ 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;
- ZT1_ResultCode rc = ZT1_Node_processVirtualNetworkFrame(
+ ZT_ResultCode rc = ZT_Node_processVirtualNetworkFrame(
node,
now,
nwid,
@@ -705,15 +722,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame(
destMac,
etherType,
vlanId,
- (const void*)frameData,
+ (const void*)localData,
frameLength,
&nextBackgroundTaskDeadline);
- jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
+ jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
- env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
-
- env->ReleaseByteArrayElements(in_frameData, frameData, 0);
+ env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
return createResultObject(env, rc);
}
@@ -727,88 +742,140 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
JNIEnv *env, jobject obj,
jlong id,
jlong in_now,
+ jobject in_localAddress,
jobject in_remoteAddress,
jbyteArray in_packetData,
jlongArray out_nextBackgroundTaskDeadline)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ LOGE("Couldn't find a valid node!");
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
if(nbtd_len < 1)
{
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ LOGE("nbtd_len < 1");
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t now = (uint64_t)in_now;
// get the java.net.InetSocketAddress class and getAddress() method
- jclass inetAddressClass = cache.findClass("java/net/InetAddress");
+ jclass inetAddressClass = lookup.findClass("java/net/InetAddress");
if(inetAddressClass == NULL)
{
+ LOGE("Can't find InetAddress class");
// can't find java.net.InetAddress
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
- jmethodID getAddressMethod = cache.findMethod(
+ jmethodID getAddressMethod = lookup.findMethod(
inetAddressClass, "getAddress", "()[B");
if(getAddressMethod == NULL)
{
// cant find InetAddress.getAddres()
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
- jclass InetSocketAddressClass = cache.findClass("java/net/InetSocketAddress");
+ jclass InetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
if(InetSocketAddressClass == NULL)
{
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
- jmethodID inetSockGetAddressMethod = cache.findMethod(
+ jmethodID inetSockGetAddressMethod = lookup.findMethod(
InetSocketAddressClass, "getAddress", "()Ljava/net/InetAddress;");
- jobject addrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod);
+ jobject localAddrObj = NULL;
+ if(in_localAddress != NULL)
+ {
+ localAddrObj = env->CallObjectMethod(in_localAddress, inetSockGetAddressMethod);
+ }
+
+ jobject remoteAddrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod);
- if(addrObject == NULL)
+ if(remoteAddrObject == NULL)
{
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
- jmethodID inetSock_getPort = cache.findMethod(
+ jmethodID inetSock_getPort = lookup.findMethod(
InetSocketAddressClass, "getPort", "()I");
if(env->ExceptionCheck() || inetSock_getPort == NULL)
{
LOGE("Couldn't find getPort method on InetSocketAddress");
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
// call InetSocketAddress.getPort()
- int port = env->CallIntMethod(in_remoteAddress, inetSock_getPort);
+ int remotePort = env->CallIntMethod(in_remoteAddress, inetSock_getPort);
if(env->ExceptionCheck())
{
LOGE("Exception calling InetSocketAddress.getPort()");
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
// Call InetAddress.getAddress()
- jbyteArray addressArray = (jbyteArray)env->CallObjectMethod(addrObject, getAddressMethod);
- if(addressArray == NULL)
+ jbyteArray remoteAddressArray = (jbyteArray)env->CallObjectMethod(remoteAddrObject, getAddressMethod);
+ if(remoteAddressArray == NULL)
{
+ LOGE("Unable to call getAddress()");
// unable to call getAddress()
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
- unsigned int addrSize = env->GetArrayLength(addressArray);
- // get the address bytes
- jbyte *addr = env->GetByteArrayElements(addressArray, NULL);
+ unsigned int addrSize = env->GetArrayLength(remoteAddressArray);
+
+
+ sockaddr_storage localAddress = {};
+
+ if(localAddrObj == NULL)
+ {
+ localAddress = ZT_SOCKADDR_NULL;
+ }
+ else
+ {
+ int localPort = env->CallIntMethod(in_localAddress, inetSock_getPort);
+ jbyteArray localAddressArray = (jbyteArray)env->CallObjectMethod(localAddrObj, getAddressMethod);
+ if(localAddressArray != NULL)
+ {
+ unsigned int localAddrSize = env->GetArrayLength(localAddressArray);
+ jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(localAddressArray, NULL);
+ if(localAddrSize == 16)
+ {
+ sockaddr_in6 ipv6 = {};
+ ipv6.sin6_family = AF_INET6;
+ ipv6.sin6_port = htons(localPort);
+ memcpy(ipv6.sin6_addr.s6_addr, addr, 16);
+ memcpy(&localAddress, &ipv6, sizeof(sockaddr_in6));
+ }
+ else if(localAddrSize)
+ {
+ // IPV4 address
+ sockaddr_in ipv4 = {};
+ ipv4.sin_family = AF_INET;
+ ipv4.sin_port = htons(localPort);
+ memcpy(&ipv4.sin_addr, addr, 4);
+ memcpy(&localAddress, &ipv4, sizeof(sockaddr_in));
+ }
+ else
+ {
+ localAddress = ZT_SOCKADDR_NULL;
+ }
+ env->ReleasePrimitiveArrayCritical(localAddressArray, addr, 0);
+ }
+ }
+
+ // get the address bytes
+ jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(remoteAddressArray, NULL);
sockaddr_storage remoteAddress = {};
if(addrSize == 16)
@@ -816,7 +883,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
// IPV6 address
sockaddr_in6 ipv6 = {};
ipv6.sin6_family = AF_INET6;
- ipv6.sin6_port = htons(port);
+ ipv6.sin6_port = htons(remotePort);
memcpy(ipv6.sin6_addr.s6_addr, addr, 16);
memcpy(&remoteAddress, &ipv6, sizeof(sockaddr_in6));
}
@@ -825,37 +892,50 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
// IPV4 address
sockaddr_in ipv4 = {};
ipv4.sin_family = AF_INET;
- ipv4.sin_port = htons(port);
+ ipv4.sin_port = htons(remotePort);
memcpy(&ipv4.sin_addr, addr, 4);
memcpy(&remoteAddress, &ipv4, sizeof(sockaddr_in));
}
else
{
+ LOGE("Unknown IP version");
// unknown address type
- env->ReleaseByteArrayElements(addressArray, addr, 0);
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
-
+ env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0);
unsigned int packetLength = env->GetArrayLength(in_packetData);
- jbyte *packetData = env->GetByteArrayElements(in_packetData, NULL);
+ if(packetLength == 0)
+ {
+ LOGE("Empty packet?!?");
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
+ }
+ void *packetData = env->GetPrimitiveArrayCritical(in_packetData, NULL);
+ void *localData = malloc(packetLength);
+ memcpy(localData, packetData, packetLength);
+ env->ReleasePrimitiveArrayCritical(in_packetData, packetData, 0);
uint64_t nextBackgroundTaskDeadline = 0;
- ZT1_ResultCode rc = ZT1_Node_processWirePacket(
+ ZT_ResultCode rc = ZT_Node_processWirePacket(
node,
now,
+ &localAddress,
&remoteAddress,
- packetData,
+ localData,
packetLength,
&nextBackgroundTaskDeadline);
+ if(rc != ZT_RESULT_OK)
+ {
+ LOGE("ZT_Node_processWirePacket returned: %d", rc);
+ }
- jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
- outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
- env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
+ free(localData);
- env->ReleaseByteArrayElements(addressArray, addr, 0);
- env->ReleaseByteArrayElements(in_packetData, packetData, 0);
+ jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
+ outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
+ env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
return createResultObject(env, rc);
}
@@ -872,27 +952,27 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks(
jlongArray out_nextBackgroundTaskDeadline)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
if(nbtd_len < 1)
{
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t now = (uint64_t)in_now;
uint64_t nextBackgroundTaskDeadline = 0;
- ZT1_ResultCode rc = ZT1_Node_processBackgroundTasks(node, now, &nextBackgroundTaskDeadline);
+ ZT_ResultCode rc = ZT_Node_processBackgroundTasks(node, now, &nextBackgroundTaskDeadline);
- jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
+ jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL);
outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
- env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
+ env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0);
return createResultObject(env, rc);
}
@@ -906,16 +986,16 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join(
JNIEnv *env, jobject obj, jlong id, jlong in_nwid)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t nwid = (uint64_t)in_nwid;
- ZT1_ResultCode rc = ZT1_Node_join(node, nwid);
+ ZT_ResultCode rc = ZT_Node_join(node, nwid);
return createResultObject(env, rc);
}
@@ -929,16 +1009,16 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave(
JNIEnv *env, jobject obj, jlong id, jlong in_nwid)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t nwid = (uint64_t)in_nwid;
- ZT1_ResultCode rc = ZT1_Node_leave(node, nwid);
+ ZT_ResultCode rc = ZT_Node_leave(node, nwid);
return createResultObject(env, rc);
}
@@ -956,18 +1036,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe(
jlong in_multicastAdi)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t nwid = (uint64_t)in_nwid;
uint64_t multicastGroup = (uint64_t)in_multicastGroup;
unsigned long multicastAdi = (unsigned long)in_multicastAdi;
- ZT1_ResultCode rc = ZT1_Node_multicastSubscribe(
+ ZT_ResultCode rc = ZT_Node_multicastSubscribe(
node, nwid, multicastGroup, multicastAdi);
return createResultObject(env, rc);
@@ -986,18 +1066,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe(
jlong in_multicastAdi)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
- return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+ return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
uint64_t nwid = (uint64_t)in_nwid;
uint64_t multicastGroup = (uint64_t)in_multicastGroup;
unsigned long multicastAdi = (unsigned long)in_multicastAdi;
- ZT1_ResultCode rc = ZT1_Node_multicastUnsubscribe(
+ ZT_ResultCode rc = ZT_Node_multicastUnsubscribe(
node, nwid, multicastGroup, multicastAdi);
return createResultObject(env, rc);
@@ -1012,14 +1092,14 @@ JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address(
JNIEnv *env , jobject obj, jlong id)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
return 0;
}
- uint64_t address = ZT1_Node_address(node);
+ uint64_t address = ZT_Node_address(node);
return (jlong)address;
}
@@ -1032,7 +1112,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
(JNIEnv *env, jobject obj, jlong id)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
@@ -1043,13 +1123,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)
{
@@ -1062,33 +1142,33 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
return NULL;
}
- ZT1_NodeStatus nodeStatus;
- ZT1_Node_status(node, &nodeStatus);
+ ZT_NodeStatus nodeStatus;
+ ZT_Node_status(node, &nodeStatus);
jfieldID addressField = NULL;
jfieldID publicIdentityField = NULL;
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;
@@ -1124,18 +1204,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig(
JNIEnv *env, jobject obj, jlong id, jlong nwid)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
return 0;
}
- ZT1_VirtualNetworkConfig *vnetConfig = ZT1_Node_networkConfig(node, nwid);
+ ZT_VirtualNetworkConfig *vnetConfig = ZT_Node_networkConfig(node, nwid);
jobject vnetConfigObject = newNetworkConfig(env, *vnetConfig);
- ZT1_Node_freeQueryResult(node, vnetConfig);
+ ZT_Node_freeQueryResult(node, vnetConfig);
return vnetConfigObject;
}
@@ -1153,7 +1233,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version(
int revision = 0;
unsigned long featureFlags = 0;
- ZT1_version(&major, &minor, &revision, &featureFlags);
+ ZT_version(&major, &minor, &revision, &featureFlags);
return newVersion(env, major, minor, revision, featureFlags);
}
@@ -1167,18 +1247,18 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers(
JNIEnv *env, jobject obj, jlong id)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
return 0;
}
- ZT1_PeerList *peerList = ZT1_Node_peers(node);
+ ZT_PeerList *peerList = ZT_Node_peers(node);
if(peerList == NULL)
{
- LOGE("ZT1_Node_peers returned NULL");
+ LOGE("ZT_Node_peers returned NULL");
return NULL;
}
@@ -1187,15 +1267,15 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers(
if(env->EnsureLocalCapacity(peerCount))
{
LOGE("EnsureLocalCapacity failed!!");
- ZT1_Node_freeQueryResult(node, peerList);
+ ZT_Node_freeQueryResult(node, peerList);
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");
- ZT1_Node_freeQueryResult(node, peerList);
+ ZT_Node_freeQueryResult(node, peerList);
return NULL;
}
@@ -1205,7 +1285,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers(
if(env->ExceptionCheck() || peerArrayObj == NULL)
{
LOGE("Error creating Peer[] array");
- ZT1_Node_freeQueryResult(node, peerList);
+ ZT_Node_freeQueryResult(node, peerList);
return NULL;
}
@@ -1221,7 +1301,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers(
}
}
- ZT1_Node_freeQueryResult(node, peerList);
+ ZT_Node_freeQueryResult(node, peerList);
peerList = NULL;
return peerArrayObj;
@@ -1236,24 +1316,24 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks(
JNIEnv *env, jobject obj, jlong id)
{
uint64_t nodeId = (uint64_t) id;
- ZT1_Node *node = findNode(nodeId);
+ ZT_Node *node = findNode(nodeId);
if(node == NULL)
{
// cannot find valid node. We should never get here.
return 0;
}
- ZT1_VirtualNetworkList *networkList = ZT1_Node_networks(node);
+ ZT_VirtualNetworkList *networkList = ZT_Node_networks(node);
if(networkList == NULL)
{
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");
- ZT1_Node_freeQueryResult(node, networkList);
+ ZT_Node_freeQueryResult(node, networkList);
return NULL;
}
@@ -1262,7 +1342,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks(
if(env->ExceptionCheck() || networkListObject == NULL)
{
LOGE("Error creating VirtualNetworkConfig[] array");
- ZT1_Node_freeQueryResult(node, networkList);
+ ZT_Node_freeQueryResult(node, networkList);
return NULL;
}
@@ -1277,7 +1357,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks(
}
}
- ZT1_Node_freeQueryResult(node, networkList);
+ ZT_Node_freeQueryResult(node, networkList);
return networkListObject;
}