Browse Source

added implementation for processWirePacket

Signed-off-by: Grant Limberg <[email protected]>
Grant Limberg 10 years ago
parent
commit
3c499777c8
1 changed files with 111 additions and 0 deletions
  1. 111 0
      java/jni/com_zerotierone_sdk_Node.cpp

+ 111 - 0
java/jni/com_zerotierone_sdk_Node.cpp

@@ -31,6 +31,7 @@
 
 
 #include <map>
 #include <map>
 #include <assert.h>
 #include <assert.h>
+#include <string.h>
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
@@ -371,6 +372,116 @@ JNIEXPORT jobject JNICALL Java_com_zerotierone_sdk_Node_processVirtualNetworkFra
     return createResultObject(env, rc);
     return createResultObject(env, rc);
 }
 }
 
 
+/*
+ * Class:     com_zerotierone_sdk_Node
+ * Method:    processWirePacket
+ * Signature: (JJLjava/net/InetAddress;I[B[J)Lcom/zerotierone/sdk/ResultCode;
+ */
+JNIEXPORT jobject JNICALL Java_com_zerotierone_sdk_Node_processWirePacket
+   (JNIEnv *env, jobject obj, 
+    jlong id,
+    jlong in_now, 
+    jobject in_remoteAddress,
+    jint in_linkDesparation,
+    jbyteArray in_packetData,
+    jlongArray out_nextBackgroundTaskDeadline)
+{
+    uint64_t nodeId = (uint64_t) id;
+    ZT1_Node *node = findNode(nodeId);
+    if(node == NULL)
+    {
+        // cannot find valid node.  We should  never get here.
+        return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+    }
+
+    unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline);
+    if(nbtd_len < 1)
+    {
+        return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+    }
+
+    uint64_t now = (uint64_t)in_now;
+    unsigned int linkDesparation = (unsigned int)in_linkDesparation;
+
+    // get the java.net.InetAddress class and getAddress() method
+    jclass inetAddressClass = env->FindClass("java/net/InetAddress");
+    if(inetAddressClass == NULL)
+    {
+        // can't find java.net.InetAddress
+        return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+    }
+
+    jmethodID getAddressMethod = env->GetMethodID(
+        inetAddressClass, "getAddress", "()[B");
+    if(getAddressMethod == NULL)
+    {
+        // cant find InetAddress.getAddres()
+        return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+    }
+
+    // Call InetAddress.getAddress()
+    jbyteArray addressArray = (jbyteArray)env->CallObjectMethod(in_remoteAddress, getAddressMethod);
+    if(addressArray == NULL)
+    {
+        // 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);
+
+
+    sockaddr_storage remoteAddress = {};
+
+    if(addrSize == 16)
+    {
+        // IPV6 address
+        sockaddr_in6 ipv6 = {};
+        ipv6.sin6_family = AF_INET6;
+        memcpy(ipv6.sin6_addr.s6_addr, addr, 16);
+        memcpy(&remoteAddress, &ipv6, sizeof(sockaddr_in6));
+    }
+    else if(addrSize = 4)
+    {
+        // IPV4 address
+        sockaddr_in ipv4 = {};
+        ipv4.sin_family = AF_INET;
+        memcpy(&ipv4.sin_addr, addr, 4);
+        memcpy(&remoteAddress, &ipv4, sizeof(sockaddr_in));
+    }
+    else
+    {
+        // unknown address type
+        env->ReleaseByteArrayElements(addressArray, addr, 0);
+        return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL);
+    }
+
+
+    unsigned int packetLength = env->GetArrayLength(in_packetData);
+    jbyte *packetData = env->GetByteArrayElements(in_packetData, NULL);
+
+    uint64_t nextBackgroundTaskDeadline = 0;
+
+    ZT1_ResultCode rc = ZT1_Node_processWirePacket(
+        node,
+        now,
+        &remoteAddress,
+        linkDesparation,
+        packetData,
+        packetLength,
+        &nextBackgroundTaskDeadline);
+
+    jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL);
+    outDeadline[0] = (jlong)nextBackgroundTaskDeadline;
+    env->ReleaseLongArrayElements(out_nextBackgroundTaskDeadline, outDeadline, 0);
+
+    env->ReleaseByteArrayElements(addressArray, addr, 0);
+    env->ReleaseByteArrayElements(in_packetData, packetData, 0);
+
+    return createResultObject(env, ZT1_RESULT_OK);
+}
+
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 } // extern "C"
 } // extern "C"