From 58e3b8c5addbb8688b8c25a9ec308b2249dcb510 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 24 Jan 2023 11:50:00 -0500 Subject: [PATCH 01/68] add StringUtils --- .../zerotier/sdk/VirtualNetworkConfig.java | 8 +- .../com/zerotier/sdk/util/StringUtils.java | 52 +++++++++++++ .../zerotier/sdk/util/StringUtilsTest.java | 73 +++++++++++++++++++ 3 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 java/src/com/zerotier/sdk/util/StringUtils.java create mode 100644 java/test/com/zerotier/sdk/util/StringUtilsTest.java diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index c7b48d5c5..0236f813c 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -29,6 +29,8 @@ package com.zerotier.sdk; import android.util.Log; +import com.zerotier.sdk.util.StringUtils; + import java.lang.Comparable; import java.lang.Override; import java.lang.String; @@ -88,11 +90,11 @@ public final class VirtualNetworkConfig implements Comparable>= 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); + } +} diff --git a/java/test/com/zerotier/sdk/util/StringUtilsTest.java b/java/test/com/zerotier/sdk/util/StringUtilsTest.java new file mode 100644 index 000000000..257b14a99 --- /dev/null +++ b/java/test/com/zerotier/sdk/util/StringUtilsTest.java @@ -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"); + } +} From 216ed8c8ea932b2e03a1efb4431bae8363a8b3e3 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 08:05:24 -0500 Subject: [PATCH 02/68] fix headers use recommended headers and remove unused headers --- java/jni/ZT_jniutils.cpp | 2 +- java/jni/ZT_jniutils.h | 2 +- java/jni/com_zerotierone_sdk_Node.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index c479f87e2..f58154d16 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -21,7 +21,7 @@ #include "ZT_jniarray.h" #include -#include +#include #include #include diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index 3e81b934d..02c2e20f1 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -18,7 +18,7 @@ #ifndef ZT_jniutils_h_ #define ZT_jniutils_h_ -#include + #include #include diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 75af18bc8..877865828 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -34,8 +34,8 @@ #include #include -#include -#include +#include +#include // global static JNI Lookup Object JniLookup lookup; From 0733af523985491892763093f682d547795a3c55 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Mon, 30 Jan 2023 16:19:11 -0500 Subject: [PATCH 03/68] move extern "C" only JNI functions need to be exported --- java/jni/ZT_jniutils.cpp | 8 -------- java/jni/ZT_jniutils.h | 8 -------- java/jni/com_zerotierone_sdk_Node.cpp | 8 ++++---- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index f58154d16..f3d528183 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -30,10 +30,6 @@ extern JniLookup lookup; -#ifdef __cplusplus -extern "C" { -#endif - jobject createResultObject(JNIEnv *env, ZT_ResultCode code) { jclass resultClass = NULL; @@ -1028,7 +1024,3 @@ jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) } return NULL; } - -#ifdef __cplusplus -} -#endif diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index 02c2e20f1..a9dc40e48 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -22,10 +22,6 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - #define LOG_TAG "ZeroTierOneJNI" #if defined(__ANDROID__) @@ -78,8 +74,4 @@ jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route) jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns); -#ifdef __cplusplus -} #endif - -#endif \ No newline at end of file diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 877865828..9b5a6fbd6 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -40,10 +40,6 @@ // global static JNI Lookup Object JniLookup lookup; -#ifdef __cplusplus -extern "C" { -#endif - namespace { struct JniRef { @@ -732,6 +728,10 @@ namespace { } } +#ifdef __cplusplus +extern "C" { +#endif + JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { lookup.setJavaVM(vm); From 5be92a96df84d449286282e3a2a2fc90571da13e Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:09:16 -0500 Subject: [PATCH 04/68] cleanup --- java/jni/ZT_jniutils.h | 6 ++---- java/jni/com_zerotierone_sdk_Node.cpp | 2 +- java/src/com/zerotier/sdk/DataStoreGetListener.java | 1 + java/src/com/zerotier/sdk/DataStorePutListener.java | 1 + java/src/com/zerotier/sdk/Event.java | 1 + java/src/com/zerotier/sdk/EventListener.java | 4 +--- java/src/com/zerotier/sdk/Node.java | 2 +- java/src/com/zerotier/sdk/NodeException.java | 2 +- java/src/com/zerotier/sdk/PacketSender.java | 2 ++ java/src/com/zerotier/sdk/PathChecker.java | 1 + java/src/com/zerotier/sdk/Peer.java | 2 +- java/src/com/zerotier/sdk/PeerPhysicalPath.java | 2 +- java/src/com/zerotier/sdk/PeerRole.java | 1 + java/src/com/zerotier/sdk/ResultCode.java | 3 ++- java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java | 4 ++-- .../src/com/zerotier/sdk/VirtualNetworkConfigOperation.java | 2 ++ java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java | 1 + java/src/com/zerotier/sdk/VirtualNetworkStatus.java | 2 ++ java/src/com/zerotier/sdk/VirtualNetworkType.java | 2 ++ 19 files changed, 26 insertions(+), 15 deletions(-) diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index a9dc40e48..6b911c5ef 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #ifndef ZT_jniutils_h_ #define ZT_jniutils_h_ @@ -61,8 +61,6 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfig jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr); jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr); -jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc); - jobject newPeer(JNIEnv *env, const ZT_Peer &peer); jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp); @@ -74,4 +72,4 @@ jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route) jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns); -#endif +#endif // ZT_jniutils_h_ diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 9b5a6fbd6..4fcb939ef 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -1631,4 +1631,4 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( #ifdef __cplusplus } // extern "C" -#endif \ No newline at end of file +#endif diff --git a/java/src/com/zerotier/sdk/DataStoreGetListener.java b/java/src/com/zerotier/sdk/DataStoreGetListener.java index 317511e0c..273c94363 100644 --- a/java/src/com/zerotier/sdk/DataStoreGetListener.java +++ b/java/src/com/zerotier/sdk/DataStoreGetListener.java @@ -24,6 +24,7 @@ * 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 { diff --git a/java/src/com/zerotier/sdk/DataStorePutListener.java b/java/src/com/zerotier/sdk/DataStorePutListener.java index 77e55027e..bb9e089fa 100644 --- a/java/src/com/zerotier/sdk/DataStorePutListener.java +++ b/java/src/com/zerotier/sdk/DataStorePutListener.java @@ -24,6 +24,7 @@ * 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 { diff --git a/java/src/com/zerotier/sdk/Event.java b/java/src/com/zerotier/sdk/Event.java index 22d350e1e..d0f314e9a 100644 --- a/java/src/com/zerotier/sdk/Event.java +++ b/java/src/com/zerotier/sdk/Event.java @@ -28,6 +28,7 @@ package com.zerotier.sdk; public enum Event { + /** * Node has been initialized * diff --git a/java/src/com/zerotier/sdk/EventListener.java b/java/src/com/zerotier/sdk/EventListener.java index 91050aaa9..5dbe3da71 100644 --- a/java/src/com/zerotier/sdk/EventListener.java +++ b/java/src/com/zerotier/sdk/EventListener.java @@ -27,13 +27,11 @@ package com.zerotier.sdk; -import java.net.InetSocketAddress; -import java.lang.String; - /** * Interface to handle callbacks for ZeroTier One events. */ public interface EventListener { + /** * Callback for events with no other associated metadata * diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index 1b3a4901f..0e9c4ee83 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -472,4 +472,4 @@ public class Node { private native Peer[] peers(long nodeId); private native VirtualNetworkConfig[] networks(long nodeId); -} \ No newline at end of file +} diff --git a/java/src/com/zerotier/sdk/NodeException.java b/java/src/com/zerotier/sdk/NodeException.java index 1fdef72f8..75baf9d30 100644 --- a/java/src/com/zerotier/sdk/NodeException.java +++ b/java/src/com/zerotier/sdk/NodeException.java @@ -33,4 +33,4 @@ public class NodeException extends RuntimeException { public NodeException(String message) { super(message); } -} \ No newline at end of file +} diff --git a/java/src/com/zerotier/sdk/PacketSender.java b/java/src/com/zerotier/sdk/PacketSender.java index 06ec01bcc..1a4d4524e 100644 --- a/java/src/com/zerotier/sdk/PacketSender.java +++ b/java/src/com/zerotier/sdk/PacketSender.java @@ -24,12 +24,14 @@ * 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 * diff --git a/java/src/com/zerotier/sdk/PathChecker.java b/java/src/com/zerotier/sdk/PathChecker.java index 6bf31df2b..459dde122 100644 --- a/java/src/com/zerotier/sdk/PathChecker.java +++ b/java/src/com/zerotier/sdk/PathChecker.java @@ -8,6 +8,7 @@ package com.zerotier.sdk; import java.net.InetSocketAddress; public interface PathChecker { + /** * Callback to check whether a path should be used for ZeroTier traffic * diff --git a/java/src/com/zerotier/sdk/Peer.java b/java/src/com/zerotier/sdk/Peer.java index eb3d71300..63ef689b1 100644 --- a/java/src/com/zerotier/sdk/Peer.java +++ b/java/src/com/zerotier/sdk/Peer.java @@ -91,4 +91,4 @@ public final class Peer { public final PeerPhysicalPath[] paths() { return paths; } -} \ No newline at end of file +} diff --git a/java/src/com/zerotier/sdk/PeerPhysicalPath.java b/java/src/com/zerotier/sdk/PeerPhysicalPath.java index 3f9a86128..4aee98776 100644 --- a/java/src/com/zerotier/sdk/PeerPhysicalPath.java +++ b/java/src/com/zerotier/sdk/PeerPhysicalPath.java @@ -75,4 +75,4 @@ public final class PeerPhysicalPath { public final boolean isPreferred() { return preferred; } -} \ No newline at end of file +} diff --git a/java/src/com/zerotier/sdk/PeerRole.java b/java/src/com/zerotier/sdk/PeerRole.java index fce183d9c..83cc7d1e6 100644 --- a/java/src/com/zerotier/sdk/PeerRole.java +++ b/java/src/com/zerotier/sdk/PeerRole.java @@ -28,6 +28,7 @@ package com.zerotier.sdk; public enum PeerRole { + /** * An ordinary node */ diff --git a/java/src/com/zerotier/sdk/ResultCode.java b/java/src/com/zerotier/sdk/ResultCode.java index 09e7d3b13..7c80e5844 100644 --- a/java/src/com/zerotier/sdk/ResultCode.java +++ b/java/src/com/zerotier/sdk/ResultCode.java @@ -36,6 +36,7 @@ package com.zerotier.sdk; * problem.

*/ public enum ResultCode { + /** * Operation completed normally */ @@ -76,4 +77,4 @@ public enum ResultCode { public boolean isFatal(int id) { return (id > 100 && id < 1000); } -} \ No newline at end of file +} diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java b/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java index 15ae301cd..24229039e 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java @@ -25,11 +25,11 @@ * LLC. Start here: http://www.zerotier.com/ */ - package com.zerotier.sdk; public interface VirtualNetworkConfigListener { + /** * Callback called to update virtual network port configuration * @@ -57,4 +57,4 @@ public interface VirtualNetworkConfigListener { long nwid, VirtualNetworkConfigOperation op, VirtualNetworkConfig config); -} \ No newline at end of file +} diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java b/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java index b70eb4786..6abf2755f 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java @@ -24,9 +24,11 @@ * redistribute it in a modified binary form, please contact ZeroTier Networks * LLC. Start here: http://www.zerotier.com/ */ + package com.zerotier.sdk; public enum VirtualNetworkConfigOperation { + /** * Network is coming up (either for the first time or after service restart) */ diff --git a/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java b/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java index 9ad322825..a1c676172 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java @@ -28,6 +28,7 @@ package com.zerotier.sdk; public interface VirtualNetworkFrameListener { + /** * Function to send a frame out to a virtual network port * diff --git a/java/src/com/zerotier/sdk/VirtualNetworkStatus.java b/java/src/com/zerotier/sdk/VirtualNetworkStatus.java index 68e01bd61..f98aec4a5 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkStatus.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkStatus.java @@ -24,9 +24,11 @@ * redistribute it in a modified binary form, please contact ZeroTier Networks * LLC. Start here: http://www.zerotier.com/ */ + package com.zerotier.sdk; public enum VirtualNetworkStatus { + /** * Waiting for network configuration (also means revision == 0) */ diff --git a/java/src/com/zerotier/sdk/VirtualNetworkType.java b/java/src/com/zerotier/sdk/VirtualNetworkType.java index ab1f4e087..0b55828eb 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkType.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkType.java @@ -24,9 +24,11 @@ * redistribute it in a modified binary form, please contact ZeroTier Networks * LLC. Start here: http://www.zerotier.com/ */ + package com.zerotier.sdk; public enum VirtualNetworkType { + /** * Private networks are authorized via certificates of membership */ From 87edbb2d3aae2e6549f0f6024d4d0e7a6e0c1a1d Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 09:53:49 -0500 Subject: [PATCH 05/68] fix ANDROID-50: RESULT_ERROR_BAD_PARAMETER typo --- java/jni/ZT_jniutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index f3d528183..82772b979 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -69,7 +69,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) break; case ZT_RESULT_ERROR_BAD_PARAMETER: LOGV("ZT_RESULT_ERROR_BAD_PARAMETER"); - fieldName = "ZT_RESULT_ERROR_BAD_PARAMETER"; + fieldName = "RESULT_ERROR_BAD_PARAMETER"; break; case ZT_RESULT_FATAL_ERROR_INTERNAL: default: From 0027e6bdab920b1c22b1068deba2e34f4cf66521 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 11:31:52 -0500 Subject: [PATCH 06/68] fix typo in log message --- java/jni/ZT_jniutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 82772b979..34df2781f 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -56,7 +56,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) fieldName = "RESULT_FATAL_ERROR_OUT_OF_MEMORY"; break; case ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED: - LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED"); + LOGV("ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED"); fieldName = "RESULT_FATAL_ERROR_DATA_STORE_FAILED"; break; case ZT_RESULT_ERROR_NETWORK_NOT_FOUND: From 1c88037ea07c0e3a206c47482b1de7728eda6459 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 16:52:52 -0500 Subject: [PATCH 07/68] fix typos in JNI method signatures --- java/jni/com_zerotierone_sdk_Node.cpp | 6 +++--- java/jni/com_zerotierone_sdk_Node.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 4fcb939ef..90895dbe3 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -1002,7 +1002,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( /* * Class: com_zerotier_sdk_Node * Method: processWirePacket - * Signature: (JJJLjava/net/InetSocketAddress;I[B[J)Lcom/zerotier/sdk/ResultCode; + * Signature: (JJJLjava/net/InetSocketAddress;[B[J)Lcom/zerotier/sdk/ResultCode; */ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( JNIEnv *env, jobject obj, @@ -1466,7 +1466,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status /* * Class: com_zerotier_sdk_Node * Method: networkConfig - * Signature: (J)Lcom/zerotier/sdk/VirtualNetworkConfig; + * Signature: (JJ)Lcom/zerotier/sdk/VirtualNetworkConfig; */ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig( JNIEnv *env, jobject obj, jlong id, jlong nwid) @@ -1491,7 +1491,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig( /* * Class: com_zerotier_sdk_Node * Method: version - * Signature: (J)Lcom/zerotier/sdk/Version; + * Signature: ()Lcom/zerotier/sdk/Version; */ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version( JNIEnv *env, jobject obj) diff --git a/java/jni/com_zerotierone_sdk_Node.h b/java/jni/com_zerotierone_sdk_Node.h index 8487d8af2..a5c9668a6 100644 --- a/java/jni/com_zerotierone_sdk_Node.h +++ b/java/jni/com_zerotierone_sdk_Node.h @@ -34,7 +34,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame /* * Class: com_zerotier_sdk_Node * Method: processWirePacket - * Signature: (JJLjava/net/InetSockAddress;Ljava/net/InetSockAddress;[B[J)Lcom/zerotier/sdk/ResultCode; + * 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); From bfe4bc2894c2b83c2b0881a1bbd78097be0e8753 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Sat, 4 Feb 2023 09:16:39 -0500 Subject: [PATCH 08/68] fix typo --- java/src/com/zerotier/sdk/VirtualNetworkConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index 0236f813c..d1caee07d 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -191,7 +191,7 @@ public final class VirtualNetworkConfig implements Comparable Date: Tue, 31 Jan 2023 11:33:34 -0500 Subject: [PATCH 09/68] fix ANDROID-51: fieldName is uninitialized --- java/jni/ZT_jniutils.cpp | 3 +++ java/src/com/zerotier/sdk/Event.java | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 34df2781f..8c1fed768 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -170,8 +170,11 @@ jobject createEvent(JNIEnv *env, ZT_Event event) fieldName = "EVENT_TRACE"; break; case ZT_EVENT_USER_MESSAGE: + fieldName = "EVENT_USER_MESSAGE"; break; case ZT_EVENT_REMOTE_TRACE: + fieldName = "EVENT_REMOTE_TRACE"; + break; default: break; } diff --git a/java/src/com/zerotier/sdk/Event.java b/java/src/com/zerotier/sdk/Event.java index d0f314e9a..1f33cea5c 100644 --- a/java/src/com/zerotier/sdk/Event.java +++ b/java/src/com/zerotier/sdk/Event.java @@ -95,5 +95,25 @@ public enum Event { * *

Meta-data: {@link String}, TRACE message

*/ - EVENT_TRACE + EVENT_TRACE, + + /** + * VERB_USER_MESSAGE received + * + * These are generated when a VERB_USER_MESSAGE packet is received via + * ZeroTier VL1. + */ + EVENT_USER_MESSAGE, + + /** + * Remote trace received + * + * 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; } \ No newline at end of file From dd1b52c7d914303ebcbcc4a68ac3c6833b82242c Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 17:06:02 -0500 Subject: [PATCH 10/68] fix ANDROID-35: memory leak --- java/jni/com_zerotierone_sdk_Node.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 90895dbe3..7fe2b2cc0 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -992,6 +992,8 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( frameLength, &nextBackgroundTaskDeadline); + free(localData); + jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL); outDeadline[0] = (jlong)nextBackgroundTaskDeadline; env->ReleasePrimitiveArrayCritical(out_nextBackgroundTaskDeadline, outDeadline, 0); From 703f9290c993423d81f67fd433ceca144c55e206 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 17:44:51 -0500 Subject: [PATCH 11/68] fix missing DeleteLocalRef in loops --- java/jni/ZT_jniutils.cpp | 6 ++++++ java/jni/com_zerotierone_sdk_Node.cpp | 13 ++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 8c1fed768..fe5408491 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -608,6 +608,8 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) LOGE("exception assigning PeerPhysicalPath to array"); break; } + + env->DeleteLocalRef(path); } env->SetObjectField(peerObject, pathsField, arrayObject); @@ -809,6 +811,8 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) LOGE("Error assigning InetSocketAddress to array"); return NULL; } + + env->DeleteLocalRef(inetAddrObj); } env->SetObjectField(vnetConfigObj, assignedAddressesField, assignedAddrArrayObj); @@ -837,6 +841,8 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) LOGE("Error assigning VirtualNetworkRoute to array"); return NULL; } + + env->DeleteLocalRef(routeObj); } env->SetObjectField(vnetConfigObj, routesField, routesArrayObj); diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 7fe2b2cc0..b05ad1954 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -1531,15 +1531,6 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( return NULL; } - int peerCount = peerList->peerCount * 100; - LOGV("Ensure Local Capacity: %d", peerCount); - if(env->EnsureLocalCapacity(peerCount)) - { - LOGE("EnsureLocalCapacity failed!!"); - ZT_Node_freeQueryResult(node, peerList); - return NULL; - } - jclass peerClass = lookup.findClass("com/zerotier/sdk/Peer"); if(env->ExceptionCheck() || peerClass == NULL) { @@ -1568,6 +1559,8 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( LOGE("Error assigning Peer object to array"); break; } + + env->DeleteLocalRef(peerObj); } ZT_Node_freeQueryResult(node, peerList); @@ -1624,6 +1617,8 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( LOGE("Error assigning VirtualNetworkConfig object to array"); break; } + + env->DeleteLocalRef(networkObject); } ZT_Node_freeQueryResult(node, networkList); From 21264baaae34ab05d3e88254f3a2eb9c910fe093 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Sat, 4 Feb 2023 08:12:17 -0500 Subject: [PATCH 12/68] update to use unique error codes --- java/jni/com_zerotierone_sdk_Node.cpp | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index b05ad1954..8c44e7456 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -110,14 +110,14 @@ namespace { if (ref->configListener == NULL) { LOGE("configListener is NULL"); - return -1; + return -100; } jclass configListenerClass = env->GetObjectClass(ref->configListener); if(configListenerClass == NULL) { LOGE("Couldn't find class for VirtualNetworkConfigListener instance"); - return -1; + return -101; } jmethodID configListenerCallbackMethod = lookup.findMethod(configListenerClass, @@ -126,21 +126,21 @@ namespace { if(configListenerCallbackMethod == NULL) { LOGE("Couldn't find onVirtualNetworkFrame() method"); - return -2; + return -102; } jobject operationObject = createVirtualNetworkConfigOperation(env, operation); if(operationObject == NULL) { LOGE("Error creating VirtualNetworkConfigOperation object"); - return -3; + return -103; } jobject networkConfigObject = newNetworkConfig(env, *config); if(networkConfigObject == NULL) { LOGE("Error creating VirtualNetworkConfig object"); - return -4; + return -104; } return env->CallIntMethod( @@ -425,11 +425,11 @@ namespace { snprintf(p, sizeof(p), "peers.d/%.10llx", (unsigned long long)id[0]); break; default: - return -1; + return -100; } if (strlen(p) < 1) { - return -1; + return -101; } JniRef *ref = (JniRef*)userData; @@ -438,14 +438,14 @@ namespace { if (ref->dataStoreGetListener == NULL) { LOGE("dataStoreGetListener is NULL"); - return -2; + return -102; } jclass dataStoreGetClass = env->GetObjectClass(ref->dataStoreGetListener); if(dataStoreGetClass == NULL) { LOGE("Couldn't find class for DataStoreGetListener instance"); - return -2; + return -103; } jmethodID dataStoreGetCallbackMethod = lookup.findMethod( @@ -455,21 +455,21 @@ namespace { if(dataStoreGetCallbackMethod == NULL) { LOGE("Couldn't find onDataStoreGet method"); - return -2; + return -104; } jstring nameStr = env->NewStringUTF(p); if(nameStr == NULL) { LOGE("Error creating name string object"); - return -2; // out of memory + return -105; // out of memory } jbyteArray bufferObj = env->NewByteArray(bufferLength); if(bufferObj == NULL) { LOGE("Error creating byte[] buffer of size: %u", bufferLength); - return -2; + return -106; } LOGV("Calling onDataStoreGet(%s, %p)", p, buffer); @@ -510,14 +510,14 @@ namespace { if (ref->packetSender == NULL) { LOGE("packetSender is NULL"); - return -1; + return -100; } jclass packetSenderClass = env->GetObjectClass(ref->packetSender); if(packetSenderClass == NULL) { LOGE("Couldn't find class for PacketSender instance"); - return -1; + return -101; } jmethodID packetSenderCallbackMethod = lookup.findMethod(packetSenderClass, @@ -525,7 +525,7 @@ namespace { if(packetSenderCallbackMethod == NULL) { LOGE("Couldn't find onSendPacketRequested method"); - return -2; + return -102; } jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress); From 8373a0fa6063507e55b12167e53b63a2217d5b1e Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 14:00:39 -0500 Subject: [PATCH 13/68] add GETENV macro --- java/jni/ZT_jniutils.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index 6b911c5ef..a948d61c7 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -51,6 +51,32 @@ #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(&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) + + jobject createResultObject(JNIEnv *env, ZT_ResultCode code); jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status); jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type); From 71fc0dd097b62d4398470be999272e12b58c3308 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:13:02 -0500 Subject: [PATCH 14/68] add LOG_TAG defines --- java/jni/ZT_jnilookup.cpp | 2 ++ java/jni/ZT_jniutils.cpp | 2 ++ java/jni/ZT_jniutils.h | 2 -- java/jni/com_zerotierone_sdk_Node.cpp | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/java/jni/ZT_jnilookup.cpp b/java/jni/ZT_jnilookup.cpp index 4d867a35c..fc76f6762 100644 --- a/java/jni/ZT_jnilookup.cpp +++ b/java/jni/ZT_jnilookup.cpp @@ -28,6 +28,8 @@ #include "ZT_jnilookup.h" #include "ZT_jniutils.h" +#define LOG_TAG "Lookup" + JniLookup::JniLookup() : m_jvm(NULL) { diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index fe5408491..efc4b7289 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -28,6 +28,8 @@ #include #include +#define LOG_TAG "Utils" + extern JniLookup lookup; jobject createResultObject(JNIEnv *env, ZT_ResultCode code) diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index a948d61c7..3a9b227f1 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -22,8 +22,6 @@ #include #include -#define LOG_TAG "ZeroTierOneJNI" - #if defined(__ANDROID__) #include diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 8c44e7456..3df3fd285 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -37,6 +37,8 @@ #include #include +#define LOG_TAG "Node" + // global static JNI Lookup Object JniLookup lookup; From 7890185e81641b4faadd21894fe8e639950c5791 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Mon, 30 Jan 2023 16:28:45 -0500 Subject: [PATCH 15/68] ANDROID-48: add ZT_jnicache.cpp --- java/jni/ZT_jnicache.cpp | 396 ++++++++++++++++++++++++++ java/jni/ZT_jnicache.h | 172 +++++++++++ java/jni/com_zerotierone_sdk_Node.cpp | 7 +- 3 files changed, 574 insertions(+), 1 deletion(-) create mode 100644 java/jni/ZT_jnicache.cpp create mode 100644 java/jni/ZT_jnicache.h diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp new file mode 100644 index 000000000..ab5344b79 --- /dev/null +++ b/java/jni/ZT_jnicache.cpp @@ -0,0 +1,396 @@ +// +// Created by Brenton Bostick on 1/18/23. +// + +#include "ZT_jnicache.h" + +#include "ZT_jniutils.h" + +#include + +#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(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 InetAddress_getByAddress_method; + +// +// Instance fields +// + +jfieldID NodeStatus_address_field; +jfieldID NodeStatus_online_field; +jfieldID NodeStatus_publicIdentity_field; +jfieldID NodeStatus_secretIdentity_field; +jfieldID Node_configListener_field; +jfieldID Node_eventListener_field; +jfieldID Node_frameListener_field; +jfieldID Node_getListener_field; +jfieldID Node_pathChecker_field; +jfieldID Node_putListener_field; +jfieldID Node_sender_field; +jfieldID PeerPhysicalPath_address_field; +jfieldID PeerPhysicalPath_lastReceive_field; +jfieldID PeerPhysicalPath_lastSend_field; +jfieldID PeerPhysicalPath_preferred_field; +jfieldID Peer_address_field; +jfieldID Peer_latency_field; +jfieldID Peer_paths_field; +jfieldID Peer_role_field; +jfieldID Peer_versionMajor_field; +jfieldID Peer_versionMinor_field; +jfieldID Peer_versionRev_field; +jfieldID Version_major_field; +jfieldID Version_minor_field; +jfieldID Version_revision_field; +jfieldID VirtualNetworkConfig_assignedAddresses_field; +jfieldID VirtualNetworkConfig_bridge_field; +jfieldID VirtualNetworkConfig_broadcastEnabled_field; +jfieldID VirtualNetworkConfig_dhcp_field; +jfieldID VirtualNetworkConfig_dns_field; +jfieldID VirtualNetworkConfig_enabled_field; +jfieldID VirtualNetworkConfig_mac_field; +jfieldID VirtualNetworkConfig_mtu_field; +jfieldID VirtualNetworkConfig_name_field; +jfieldID VirtualNetworkConfig_nwid_field; +jfieldID VirtualNetworkConfig_portError_field; +jfieldID VirtualNetworkConfig_routes_field; +jfieldID VirtualNetworkConfig_status_field; +jfieldID VirtualNetworkConfig_type_field; +jfieldID VirtualNetworkDNS_domain_field; +jfieldID VirtualNetworkDNS_servers_field; +jfieldID VirtualNetworkRoute_flags_field; +jfieldID VirtualNetworkRoute_metric_field; +jfieldID VirtualNetworkRoute_target_field; +jfieldID VirtualNetworkRoute_via_field; + +// +// Static fields +// + +jfieldID Event_EVENT_DOWN_field; +jfieldID Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field; +jfieldID Event_EVENT_OFFLINE_field; +jfieldID Event_EVENT_ONLINE_field; +jfieldID Event_EVENT_REMOTE_TRACE_field; +jfieldID Event_EVENT_TRACE_field; +jfieldID Event_EVENT_UP_field; +jfieldID Event_EVENT_USER_MESSAGE_field; +jfieldID PeerRole_PEER_ROLE_LEAF_field; +jfieldID PeerRole_PEER_ROLE_MOON_field; +jfieldID PeerRole_PEER_ROLE_PLANET_field; +jfieldID ResultCode_RESULT_ERROR_BAD_PARAMETER_field; +jfieldID ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; +jfieldID ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; +jfieldID ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field; +jfieldID ResultCode_RESULT_FATAL_ERROR_INTERNAL_field; +jfieldID ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field; +jfieldID ResultCode_RESULT_OK_field; +jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; +jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; +jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; +jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field; +jfieldID VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; +jfieldID VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; +jfieldID VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; +jfieldID VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field; +jfieldID VirtualNetworkStatus_NETWORK_STATUS_OK_field; +jfieldID VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field; +jfieldID VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field; +jfieldID VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; +jfieldID VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; + +// +// 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, "", "(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, "", "(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, "", "()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, "", "()V")); + EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "()V")); + EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "()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, "", "()V")); + EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_ctor = env->GetMethodID(VirtualNetworkDNS_class, "", "()V")); + EXCEPTIONANDNULLCHECK(VirtualNetworkFrameListener_onVirtualNetworkFrame_method = env->GetMethodID(VirtualNetworkFrameListener_class, "onVirtualNetworkFrame", "(JJJJJ[B)V")); + EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_ctor = env->GetMethodID(VirtualNetworkRoute_class, "", "()V")); + + // + // Static methods + // + + EXCEPTIONANDNULLCHECK(InetAddress_getByAddress_method = env->GetStaticMethodID(InetAddress_class, "getByAddress", "([B)Ljava/net/InetAddress;")); + + // + // Instance fields + // + + EXCEPTIONANDNULLCHECK(NodeStatus_address_field = env->GetFieldID(NodeStatus_class, "address", "J")); + EXCEPTIONANDNULLCHECK(NodeStatus_online_field = env->GetFieldID(NodeStatus_class, "online", "Z")); + EXCEPTIONANDNULLCHECK(NodeStatus_publicIdentity_field = env->GetFieldID(NodeStatus_class, "publicIdentity", "Ljava/lang/String;")); + EXCEPTIONANDNULLCHECK(NodeStatus_secretIdentity_field = env->GetFieldID(NodeStatus_class, "secretIdentity", "Ljava/lang/String;")); + EXCEPTIONANDNULLCHECK(Node_configListener_field = env->GetFieldID(Node_class, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;")); + EXCEPTIONANDNULLCHECK(Node_eventListener_field = env->GetFieldID(Node_class, "eventListener", "Lcom/zerotier/sdk/EventListener;")); + EXCEPTIONANDNULLCHECK(Node_frameListener_field = env->GetFieldID(Node_class, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;")); + EXCEPTIONANDNULLCHECK(Node_getListener_field = env->GetFieldID(Node_class, "getListener", "Lcom/zerotier/sdk/DataStoreGetListener;")); + EXCEPTIONANDNULLCHECK(Node_pathChecker_field = env->GetFieldID(Node_class, "pathChecker", "Lcom/zerotier/sdk/PathChecker;")); + EXCEPTIONANDNULLCHECK(Node_putListener_field = env->GetFieldID(Node_class, "putListener", "Lcom/zerotier/sdk/DataStorePutListener;")); + EXCEPTIONANDNULLCHECK(Node_sender_field = env->GetFieldID(Node_class, "sender", "Lcom/zerotier/sdk/PacketSender;")); + EXCEPTIONANDNULLCHECK(PeerPhysicalPath_address_field = env->GetFieldID(PeerPhysicalPath_class, "address", "Ljava/net/InetSocketAddress;")); + EXCEPTIONANDNULLCHECK(PeerPhysicalPath_lastReceive_field = env->GetFieldID(PeerPhysicalPath_class, "lastReceive", "J")); + EXCEPTIONANDNULLCHECK(PeerPhysicalPath_lastSend_field = env->GetFieldID(PeerPhysicalPath_class, "lastSend", "J")); + EXCEPTIONANDNULLCHECK(PeerPhysicalPath_preferred_field = env->GetFieldID(PeerPhysicalPath_class, "preferred", "Z")); + EXCEPTIONANDNULLCHECK(Peer_address_field = env->GetFieldID(Peer_class, "address", "J")); + EXCEPTIONANDNULLCHECK(Peer_latency_field = env->GetFieldID(Peer_class, "latency", "I")); + EXCEPTIONANDNULLCHECK(Peer_paths_field = env->GetFieldID(Peer_class, "paths", "[Lcom/zerotier/sdk/PeerPhysicalPath;")); + EXCEPTIONANDNULLCHECK(Peer_role_field = env->GetFieldID(Peer_class, "role", "Lcom/zerotier/sdk/PeerRole;")); + EXCEPTIONANDNULLCHECK(Peer_versionMajor_field = env->GetFieldID(Peer_class, "versionMajor", "I")); + EXCEPTIONANDNULLCHECK(Peer_versionMinor_field = env->GetFieldID(Peer_class, "versionMinor", "I")); + EXCEPTIONANDNULLCHECK(Peer_versionRev_field = env->GetFieldID(Peer_class, "versionRev", "I")); + EXCEPTIONANDNULLCHECK(Version_major_field = env->GetFieldID(Version_class, "major", "I")); + EXCEPTIONANDNULLCHECK(Version_minor_field = env->GetFieldID(Version_class, "minor", "I")); + EXCEPTIONANDNULLCHECK(Version_revision_field = env->GetFieldID(Version_class, "revision", "I")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_assignedAddresses_field = env->GetFieldID(VirtualNetworkConfig_class, "assignedAddresses", "[Ljava/net/InetSocketAddress;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_bridge_field = env->GetFieldID(VirtualNetworkConfig_class, "bridge", "Z")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_broadcastEnabled_field = env->GetFieldID(VirtualNetworkConfig_class, "broadcastEnabled", "Z")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_dhcp_field = env->GetFieldID(VirtualNetworkConfig_class, "dhcp", "Z")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_dns_field = env->GetFieldID(VirtualNetworkConfig_class, "dns", "Lcom/zerotier/sdk/VirtualNetworkDNS;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_enabled_field = env->GetFieldID(VirtualNetworkConfig_class, "enabled", "Z")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_mac_field = env->GetFieldID(VirtualNetworkConfig_class, "mac", "J")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_mtu_field = env->GetFieldID(VirtualNetworkConfig_class, "mtu", "I")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_name_field = env->GetFieldID(VirtualNetworkConfig_class, "name", "Ljava/lang/String;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_nwid_field = env->GetFieldID(VirtualNetworkConfig_class, "nwid", "J")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_portError_field = env->GetFieldID(VirtualNetworkConfig_class, "portError", "I")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_routes_field = env->GetFieldID(VirtualNetworkConfig_class, "routes", "[Lcom/zerotier/sdk/VirtualNetworkRoute;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_status_field = env->GetFieldID(VirtualNetworkConfig_class, "status", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_type_field = env->GetFieldID(VirtualNetworkConfig_class, "type", "Lcom/zerotier/sdk/VirtualNetworkType;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_domain_field = env->GetFieldID(VirtualNetworkDNS_class, "domain", "Ljava/lang/String;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_servers_field = env->GetFieldID(VirtualNetworkDNS_class, "servers", "Ljava/util/ArrayList;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_flags_field = env->GetFieldID(VirtualNetworkRoute_class, "flags", "I")); + EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_metric_field = env->GetFieldID(VirtualNetworkRoute_class, "metric", "I")); + EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_target_field = env->GetFieldID(VirtualNetworkRoute_class, "target", "Ljava/net/InetSocketAddress;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_via_field = env->GetFieldID(VirtualNetworkRoute_class, "via", "Ljava/net/InetSocketAddress;")); + + // + // Static fields + // + + EXCEPTIONANDNULLCHECK(Event_EVENT_DOWN_field = env->GetStaticFieldID(Event_class, "EVENT_DOWN", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field = env->GetStaticFieldID(Event_class, "EVENT_FATAL_ERROR_IDENTITY_COLLISION", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(Event_EVENT_OFFLINE_field = env->GetStaticFieldID(Event_class, "EVENT_OFFLINE", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(Event_EVENT_ONLINE_field = env->GetStaticFieldID(Event_class, "EVENT_ONLINE", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(Event_EVENT_REMOTE_TRACE_field = env->GetStaticFieldID(Event_class, "EVENT_REMOTE_TRACE", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(Event_EVENT_TRACE_field = env->GetStaticFieldID(Event_class, "EVENT_TRACE", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(Event_EVENT_UP_field = env->GetStaticFieldID(Event_class, "EVENT_UP", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(Event_EVENT_USER_MESSAGE_field = env->GetStaticFieldID(Event_class, "EVENT_USER_MESSAGE", "Lcom/zerotier/sdk/Event;")); + EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_LEAF_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_LEAF", "Lcom/zerotier/sdk/PeerRole;")); + EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_MOON_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_MOON", "Lcom/zerotier/sdk/PeerRole;")); + EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_PLANET_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_PLANET", "Lcom/zerotier/sdk/PeerRole;")); + EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_BAD_PARAMETER_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_BAD_PARAMETER", "Lcom/zerotier/sdk/ResultCode;")); + EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_NETWORK_NOT_FOUND", "Lcom/zerotier/sdk/ResultCode;")); + EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_UNSUPPORTED_OPERATION", "Lcom/zerotier/sdk/ResultCode;")); + EXCEPTIONANDNULLCHECK(ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field = env->GetStaticFieldID(ResultCode_class, "RESULT_FATAL_ERROR_DATA_STORE_FAILED", "Lcom/zerotier/sdk/ResultCode;")); + EXCEPTIONANDNULLCHECK(ResultCode_RESULT_FATAL_ERROR_INTERNAL_field = env->GetStaticFieldID(ResultCode_class, "RESULT_FATAL_ERROR_INTERNAL", "Lcom/zerotier/sdk/ResultCode;")); + EXCEPTIONANDNULLCHECK(ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field = env->GetStaticFieldID(ResultCode_class, "RESULT_FATAL_ERROR_OUT_OF_MEMORY", "Lcom/zerotier/sdk/ResultCode;")); + EXCEPTIONANDNULLCHECK(ResultCode_RESULT_OK_field = env->GetStaticFieldID(ResultCode_class, "RESULT_OK", "Lcom/zerotier/sdk/ResultCode;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_UP", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_ACCESS_DENIED", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_AUTHENTICATION_REQUIRED", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_CLIENT_TOO_OLD", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_NOT_FOUND", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_OK_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_OK", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_PORT_ERROR", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_REQUESTING_CONFIGURATION", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkType_NETWORK_TYPE_PRIVATE_field = env->GetStaticFieldID(VirtualNetworkType_class, "NETWORK_TYPE_PRIVATE", "Lcom/zerotier/sdk/VirtualNetworkType;")); + EXCEPTIONANDNULLCHECK(VirtualNetworkType_NETWORK_TYPE_PUBLIC_field = env->GetStaticFieldID(VirtualNetworkType_class, "NETWORK_TYPE_PUBLIC", "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); +} diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h new file mode 100644 index 000000000..fb9cf6442 --- /dev/null +++ b/java/jni/ZT_jnicache.h @@ -0,0 +1,172 @@ +// +// Created by Brenton Bostick on 1/18/23. +// + +#ifndef ZEROTIERANDROID_JNICACHE_H +#define ZEROTIERANDROID_JNICACHE_H + +#include + + +// +// 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 InetAddress_getByAddress_method; + +// +// Instance fields +// + +extern jfieldID NodeStatus_address_field; +extern jfieldID NodeStatus_online_field; +extern jfieldID NodeStatus_publicIdentity_field; +extern jfieldID NodeStatus_secretIdentity_field; +extern jfieldID Node_configListener_field; +extern jfieldID Node_eventListener_field; +extern jfieldID Node_frameListener_field; +extern jfieldID Node_getListener_field; +extern jfieldID Node_pathChecker_field; +extern jfieldID Node_putListener_field; +extern jfieldID Node_sender_field; +extern jfieldID PeerPhysicalPath_address_field; +extern jfieldID PeerPhysicalPath_lastReceive_field; +extern jfieldID PeerPhysicalPath_lastSend_field; +extern jfieldID PeerPhysicalPath_preferred_field; +extern jfieldID Peer_address_field; +extern jfieldID Peer_latency_field; +extern jfieldID Peer_paths_field; +extern jfieldID Peer_role_field; +extern jfieldID Peer_versionMajor_field; +extern jfieldID Peer_versionMinor_field; +extern jfieldID Peer_versionRev_field; +extern jfieldID Version_major_field; +extern jfieldID Version_minor_field; +extern jfieldID Version_revision_field; +extern jfieldID VirtualNetworkConfig_assignedAddresses_field; +extern jfieldID VirtualNetworkConfig_bridge_field; +extern jfieldID VirtualNetworkConfig_broadcastEnabled_field; +extern jfieldID VirtualNetworkConfig_dhcp_field; +extern jfieldID VirtualNetworkConfig_dns_field; +extern jfieldID VirtualNetworkConfig_enabled_field; +extern jfieldID VirtualNetworkConfig_mac_field; +extern jfieldID VirtualNetworkConfig_mtu_field; +extern jfieldID VirtualNetworkConfig_name_field; +extern jfieldID VirtualNetworkConfig_nwid_field; +extern jfieldID VirtualNetworkConfig_portError_field; +extern jfieldID VirtualNetworkConfig_routes_field; +extern jfieldID VirtualNetworkConfig_status_field; +extern jfieldID VirtualNetworkConfig_type_field; +extern jfieldID VirtualNetworkDNS_domain_field; +extern jfieldID VirtualNetworkDNS_servers_field; +extern jfieldID VirtualNetworkRoute_flags_field; +extern jfieldID VirtualNetworkRoute_metric_field; +extern jfieldID VirtualNetworkRoute_target_field; +extern jfieldID VirtualNetworkRoute_via_field; + +// +// Static fields +// + +extern jfieldID Event_EVENT_DOWN_field; +extern jfieldID Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field; +extern jfieldID Event_EVENT_OFFLINE_field; +extern jfieldID Event_EVENT_ONLINE_field; +extern jfieldID Event_EVENT_REMOTE_TRACE_field; +extern jfieldID Event_EVENT_TRACE_field; +extern jfieldID Event_EVENT_UP_field; +extern jfieldID Event_EVENT_USER_MESSAGE_field; +extern jfieldID PeerRole_PEER_ROLE_LEAF_field; +extern jfieldID PeerRole_PEER_ROLE_MOON_field; +extern jfieldID PeerRole_PEER_ROLE_PLANET_field; +extern jfieldID ResultCode_RESULT_ERROR_BAD_PARAMETER_field; +extern jfieldID ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; +extern jfieldID ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; +extern jfieldID ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field; +extern jfieldID ResultCode_RESULT_FATAL_ERROR_INTERNAL_field; +extern jfieldID ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field; +extern jfieldID ResultCode_RESULT_OK_field; +extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; +extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; +extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; +extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field; +extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; +extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; +extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; +extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field; +extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_OK_field; +extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field; +extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field; +extern jfieldID VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; +extern jfieldID VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; + +// +// 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 diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 3df3fd285..b649b9c61 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -26,6 +26,8 @@ */ #include "com_zerotierone_sdk_Node.h" + +#include "ZT_jnicache.h" #include "ZT_jniutils.h" #include "ZT_jnilookup.h" @@ -737,12 +739,15 @@ extern "C" { JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { lookup.setJavaVM(vm); + + setupJNICache(vm); + return JNI_VERSION_1_6; } JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { - + teardownJNICache(vm); } From 82749e44420a1b96c8ee0aff87a84fa10c3b1a35 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Mon, 30 Jan 2023 17:11:39 -0500 Subject: [PATCH 16/68] ANDROID-48: use ZT_jnicache.cpp and remove ZT_jnilookup.cpp and ZT_jniarray.cpp --- java/jni/ZT_jniarray.cpp | 112 ----- java/jni/ZT_jniarray.h | 60 --- java/jni/ZT_jnilookup.cpp | 160 ------ java/jni/ZT_jnilookup.h | 54 --- java/jni/ZT_jniutils.cpp | 672 ++++---------------------- java/jni/com_zerotierone_sdk_Node.cpp | 468 +++--------------- 6 files changed, 164 insertions(+), 1362 deletions(-) delete mode 100644 java/jni/ZT_jniarray.cpp delete mode 100644 java/jni/ZT_jniarray.h delete mode 100644 java/jni/ZT_jnilookup.cpp delete mode 100644 java/jni/ZT_jnilookup.h diff --git a/java/jni/ZT_jniarray.cpp b/java/jni/ZT_jniarray.cpp deleted file mode 100644 index a1cae76ed..000000000 --- a/java/jni/ZT_jniarray.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// -// Created by Grant Limberg on 10/21/20. -// - -#include "ZT_jniarray.h" -#include -#include -#include - -jclass java_util_ArrayList; -jmethodID java_util_ArrayList_; -jmethodID java_util_ArrayList_size; -jmethodID java_util_ArrayList_get; -jmethodID java_util_ArrayList_add; - -void InitListJNI(JNIEnv* env) { - java_util_ArrayList = static_cast(env->NewGlobalRef(env->FindClass("java/util/ArrayList"))); - java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "", "(I)V"); - java_util_ArrayList_size = env->GetMethodID (java_util_ArrayList, "size", "()I"); - java_util_ArrayList_get = env->GetMethodID(java_util_ArrayList, "get", "(I)Ljava/lang/Object;"); - java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z"); -} - -jclass ListJNI::getListClass(JNIEnv* env) { - jclass jclazz = env->FindClass("java/util/List"); - assert(jclazz != nullptr); - return jclazz; -} - -jclass ListJNI::getArrayListClass(JNIEnv* env) { - jclass jclazz = env->FindClass("java/util/ArrayList"); - assert(jclazz != nullptr); - return jclazz; -} - -jclass ListJNI::getIteratorClass(JNIEnv* env) { - jclass jclazz = env->FindClass("java/util/Iterator"); - assert(jclazz != nullptr); - return jclazz; -} - -jmethodID ListJNI::getIteratorMethod(JNIEnv* env) { - static jmethodID mid = env->GetMethodID( - getListClass(env), "iterator", "()Ljava/util/Iterator;"); - assert(mid != nullptr); - return mid; -} - -jmethodID ListJNI::getHasNextMethod(JNIEnv* env) { - static jmethodID mid = env->GetMethodID( - getIteratorClass(env), "hasNext", "()Z"); - assert(mid != nullptr); - return mid; -} - -jmethodID ListJNI::getNextMethod(JNIEnv* env) { - static jmethodID mid = env->GetMethodID( - getIteratorClass(env), "next", "()Ljava/lang/Object;"); - assert(mid != nullptr); - return mid; -} - -jmethodID ListJNI::getArrayListConstructorMethodId(JNIEnv* env, jclass jclazz) { - static jmethodID mid = env->GetMethodID( - jclazz, "", "(I)V"); - assert(mid != nullptr); - return mid; -} - -jmethodID ListJNI::getListAddMethodId(JNIEnv* env) { - static jmethodID mid = env->GetMethodID( - getListClass(env), "add", "(Ljava/lang/Object;)Z"); - assert(mid != nullptr); - return mid; -} - -jclass ByteJNI::getByteClass(JNIEnv* env) { - jclass jclazz = env->FindClass("java/lang/Byte"); - assert(jclazz != nullptr); - return jclazz; -} - -jmethodID ByteJNI::getByteValueMethod(JNIEnv* env) { - static jmethodID mid = env->GetMethodID( - getByteClass(env), "byteValue", "()B"); - assert(mid != nullptr); - return mid; -} - -jobject cppToJava(JNIEnv* env, std::vector vector) { - jobject result = env->NewObject(java_util_ArrayList, java_util_ArrayList_, vector.size()); - for (std::string s: vector) { - jstring element = env->NewStringUTF(s.c_str()); - env->CallBooleanMethod(result, java_util_ArrayList_add, element); - env->DeleteLocalRef(element); - } - return result; -} - -std::vector javaToCpp(JNIEnv* env, jobject arrayList) { - jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size); - std::vector result; - result.reserve(len); - for (jint i=0; i(env->CallObjectMethod(arrayList, java_util_ArrayList_get, i)); - const char* pchars = env->GetStringUTFChars(element, nullptr); - result.emplace_back(pchars); - env->ReleaseStringUTFChars(element, pchars); - env->DeleteLocalRef(element); - } - return result; -} diff --git a/java/jni/ZT_jniarray.h b/java/jni/ZT_jniarray.h deleted file mode 100644 index d93c87b9c..000000000 --- a/java/jni/ZT_jniarray.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// Created by Grant Limberg on 10/21/20. -// - -#ifndef ZEROTIERANDROID_ZT_JNIARRAY_H -#define ZEROTIERANDROID_ZT_JNIARRAY_H - -#include -#include -#include - -extern jclass java_util_ArrayList; -extern jmethodID java_util_ArrayList_; -extern jmethodID java_util_ArrayList_size; -extern jmethodID java_util_ArrayList_get; -extern jmethodID java_util_ArrayList_add; - -void InitListJNI(JNIEnv* env); - -class ListJNI { -public: - // Get the java class id of java.util.List. - static jclass getListClass(JNIEnv* env); - - // Get the java class id of java.util.ArrayList. - static jclass getArrayListClass(JNIEnv* env); - - // Get the java class id of java.util.Iterator. - static jclass getIteratorClass(JNIEnv* env); - - // Get the java method id of java.util.List.iterator(). - static jmethodID getIteratorMethod(JNIEnv* env); - - // Get the java method id of java.util.Iterator.hasNext(). - static jmethodID getHasNextMethod(JNIEnv* env); - - // Get the java method id of java.util.Iterator.next(). - static jmethodID getNextMethod(JNIEnv* env); - - // Get the java method id of arrayList constructor. - static jmethodID getArrayListConstructorMethodId(JNIEnv* env, jclass jclazz); - - // Get the java method id of java.util.List.add(). - static jmethodID getListAddMethodId(JNIEnv* env); -}; - -class ByteJNI { -public: - // Get the java class id of java.lang.Byte. - static jclass getByteClass(JNIEnv* env); - - // Get the java method id of java.lang.Byte.byteValue. - static jmethodID getByteValueMethod(JNIEnv* env); -}; - -jobject cppToJava(JNIEnv* env, std::vector vector); - -std::vector javaToCpp(JNIEnv* env, jobject arrayList); - -#endif //ZEROTIERANDROID_ZT_JNIARRAY_H diff --git a/java/jni/ZT_jnilookup.cpp b/java/jni/ZT_jnilookup.cpp deleted file mode 100644 index fc76f6762..000000000 --- a/java/jni/ZT_jnilookup.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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 . - * - * -- - * - * 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/ - */ - -#include "ZT_jnilookup.h" -#include "ZT_jniutils.h" - -#define LOG_TAG "Lookup" - -JniLookup::JniLookup() - : m_jvm(NULL) -{ - LOGV("JNI Cache Created"); -} - -JniLookup::JniLookup(JavaVM *jvm) - : m_jvm(jvm) -{ - LOGV("JNI Cache Created"); -} - -JniLookup::~JniLookup() -{ - LOGV("JNI Cache Destroyed"); -} - - -void JniLookup::setJavaVM(JavaVM *jvm) -{ - LOGV("Assigned JVM to object"); - m_jvm = jvm; -} - - -jclass JniLookup::findClass(const std::string &name) -{ - if(!m_jvm) - return NULL; - - // get the class from the JVM - JNIEnv *env = NULL; - if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) - { - LOGE("Error retrieving JNI Environment"); - return NULL; - } - const char *c = name.c_str(); - jclass cls = env->FindClass(c); - if(env->ExceptionCheck()) - { - LOGE("Error finding class: %s", name.c_str()); - return NULL; - } - - return cls; -} - - -jmethodID JniLookup::findMethod(jclass cls, const std::string &methodName, const std::string &methodSig) -{ - if(!m_jvm) - return NULL; - - JNIEnv *env = NULL; - if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) - { - return NULL; - } - - jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodSig.c_str()); - if(env->ExceptionCheck()) - { - return NULL; - } - - return mid; -} - -jmethodID JniLookup::findStaticMethod(jclass cls, const std::string &methodName, const std::string &methodSig) -{ - if(!m_jvm) - return NULL; - - JNIEnv *env = NULL; - if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) - { - return NULL; - } - - jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodSig.c_str()); - if(env->ExceptionCheck()) - { - return NULL; - } - - return mid; -} - -jfieldID JniLookup::findField(jclass cls, const std::string &fieldName, const std::string &typeStr) -{ - if(!m_jvm) - return NULL; - - JNIEnv *env = NULL; - if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) - { - return NULL; - } - - jfieldID fid = env->GetFieldID(cls, fieldName.c_str(), typeStr.c_str()); - if(env->ExceptionCheck()) - { - return NULL; - } - - return fid; -} - -jfieldID JniLookup::findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr) -{ - if(!m_jvm) - return NULL; - - JNIEnv *env = NULL; - if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) - { - return NULL; - } - - jfieldID fid = env->GetStaticFieldID(cls, fieldName.c_str(), typeStr.c_str()); - if(env->ExceptionCheck()) - { - return NULL; - } - - return fid; -} \ No newline at end of file diff --git a/java/jni/ZT_jnilookup.h b/java/jni/ZT_jnilookup.h deleted file mode 100644 index f5bd97d7d..000000000 --- a/java/jni/ZT_jnilookup.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 . - * - * -- - * - * 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/ - */ - -#ifndef ZT_JNILOOKUP_H_ -#define ZT_JNILOOKUP_H_ - -#include -#include -#include - - - -class JniLookup { -public: - JniLookup(); - JniLookup(JavaVM *jvm); - ~JniLookup(); - - void setJavaVM(JavaVM *jvm); - - jclass findClass(const std::string &name); - jmethodID findMethod(jclass cls, const std::string &methodName, const std::string &methodSig); - jmethodID findStaticMethod(jclass cls, const std::string &methodName, const std::string &methodSig); - jfieldID findField(jclass cls, const std::string &fieldName, const std::string &typeStr); - jfieldID findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr); -private: - JavaVM *m_jvm; -}; - -#endif \ No newline at end of file diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index efc4b7289..0ed59fab9 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -17,8 +17,8 @@ */ #include "ZT_jniutils.h" -#include "ZT_jnilookup.h" -#include "ZT_jniarray.h" + +#include "ZT_jnicache.h" #include #include @@ -30,64 +30,46 @@ #define LOG_TAG "Utils" -extern JniLookup lookup; - jobject createResultObject(JNIEnv *env, ZT_ResultCode code) { - jclass resultClass = NULL; - jobject resultObject = NULL; - resultClass = lookup.findClass("com/zerotier/sdk/ResultCode"); - if(resultClass == NULL) - { - LOGE("Couldn't find ResultCode class"); - return NULL; // exception thrown - } - - std::string fieldName; + jfieldID field; switch(code) { case ZT_RESULT_OK: case ZT_RESULT_OK_IGNORED: LOGV("ZT_RESULT_OK"); - fieldName = "RESULT_OK"; + field = ResultCode_RESULT_OK_field; break; case ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY: LOGV("ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY"); - fieldName = "RESULT_FATAL_ERROR_OUT_OF_MEMORY"; + field = ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field; break; case ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED: LOGV("ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED"); - fieldName = "RESULT_FATAL_ERROR_DATA_STORE_FAILED"; + field = ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field; break; case ZT_RESULT_ERROR_NETWORK_NOT_FOUND: LOGV("ZT_RESULT_ERROR_NETWORK_NOT_FOUND"); - fieldName = "RESULT_ERROR_NETWORK_NOT_FOUND"; + field = ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; break; case ZT_RESULT_ERROR_UNSUPPORTED_OPERATION: LOGV("ZT_RESULT_ERROR_UNSUPPORTED_OPERATION"); - fieldName = "RESULT_ERROR_UNSUPPORTED_OPERATION"; + field = ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; break; case ZT_RESULT_ERROR_BAD_PARAMETER: LOGV("ZT_RESULT_ERROR_BAD_PARAMETER"); - fieldName = "RESULT_ERROR_BAD_PARAMETER"; + field = ResultCode_RESULT_ERROR_BAD_PARAMETER_field; break; case ZT_RESULT_FATAL_ERROR_INTERNAL: default: LOGV("ZT_RESULT_FATAL_ERROR_INTERNAL"); - fieldName = "RESULT_FATAL_ERROR_INTERNAL"; + field = ResultCode_RESULT_FATAL_ERROR_INTERNAL_field; break; } - jfieldID enumField = lookup.findStaticField(resultClass, fieldName.c_str(), "Lcom/zerotier/sdk/ResultCode;"); - if(env->ExceptionCheck() || enumField == NULL) - { - LOGE("Error on FindStaticField"); - return NULL; - } - - resultObject = env->GetStaticObjectField(resultClass, enumField); + resultObject = env->GetStaticObjectField(ResultCode_class, field); if(env->ExceptionCheck() || resultObject == NULL) { LOGE("Error on GetStaticObjectField"); @@ -100,206 +82,147 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) { jobject statusObject = NULL; - jclass statusClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkStatus"); - if(statusClass == NULL) - { - return NULL; // exception thrown - } - - std::string fieldName; + jfieldID field; switch(status) { case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: - fieldName = "NETWORK_STATUS_REQUESTING_CONFIGURATION"; + field = VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field; break; case ZT_NETWORK_STATUS_OK: - fieldName = "NETWORK_STATUS_OK"; + field = VirtualNetworkStatus_NETWORK_STATUS_OK_field; break; case ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED: - fieldName = "NETWORK_STATUS_AUTHENTICATION_REQUIRED"; + field = VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; break; case ZT_NETWORK_STATUS_ACCESS_DENIED: - fieldName = "NETWORK_STATUS_ACCESS_DENIED"; + field = VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; break; case ZT_NETWORK_STATUS_NOT_FOUND: - fieldName = "NETWORK_STATUS_NOT_FOUND"; + field = VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field; break; case ZT_NETWORK_STATUS_PORT_ERROR: - fieldName = "NETWORK_STATUS_PORT_ERROR"; + field = VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field; break; case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: - fieldName = "NETWORK_STATUS_CLIENT_TOO_OLD"; + field = VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; break; } - jfieldID enumField = lookup.findStaticField(statusClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkStatus;"); - - statusObject = env->GetStaticObjectField(statusClass, enumField); + statusObject = env->GetStaticObjectField(VirtualNetworkStatus_class, field); return statusObject; } jobject createEvent(JNIEnv *env, ZT_Event event) { - jclass eventClass = NULL; jobject eventObject = NULL; - eventClass = lookup.findClass("com/zerotier/sdk/Event"); - if(eventClass == NULL) - { - return NULL; - } - - std::string fieldName; + jfieldID field; switch(event) { case ZT_EVENT_UP: - fieldName = "EVENT_UP"; + field = Event_EVENT_UP_field; break; case ZT_EVENT_OFFLINE: - fieldName = "EVENT_OFFLINE"; + field = Event_EVENT_OFFLINE_field; break; case ZT_EVENT_ONLINE: - fieldName = "EVENT_ONLINE"; + field = Event_EVENT_ONLINE_field; break; case ZT_EVENT_DOWN: - fieldName = "EVENT_DOWN"; + field = Event_EVENT_DOWN_field; break; case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: - fieldName = "EVENT_FATAL_ERROR_IDENTITY_COLLISION"; + field = Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field; break; case ZT_EVENT_TRACE: - fieldName = "EVENT_TRACE"; + field = Event_EVENT_TRACE_field; break; case ZT_EVENT_USER_MESSAGE: - fieldName = "EVENT_USER_MESSAGE"; + field = Event_EVENT_USER_MESSAGE_field; break; case ZT_EVENT_REMOTE_TRACE: - fieldName = "EVENT_REMOTE_TRACE"; + field = Event_EVENT_REMOTE_TRACE_field; break; default: break; } - jfieldID enumField = lookup.findStaticField(eventClass, fieldName.c_str(), "Lcom/zerotier/sdk/Event;"); - - eventObject = env->GetStaticObjectField(eventClass, enumField); + eventObject = env->GetStaticObjectField(Event_class, field); return eventObject; } jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) { - jclass peerRoleClass = NULL; jobject peerRoleObject = NULL; - peerRoleClass = lookup.findClass("com/zerotier/sdk/PeerRole"); - if(peerRoleClass == NULL) - { - return NULL; - } - - std::string fieldName; + jfieldID field; switch(role) { case ZT_PEER_ROLE_LEAF: - fieldName = "PEER_ROLE_LEAF"; + field = PeerRole_PEER_ROLE_LEAF_field; break; case ZT_PEER_ROLE_MOON: - fieldName = "PEER_ROLE_MOON"; + field = PeerRole_PEER_ROLE_MOON_field; break; case ZT_PEER_ROLE_PLANET: - fieldName = "PEER_ROLE_PLANET"; + field = PeerRole_PEER_ROLE_PLANET_field; break; } - jfieldID enumField = lookup.findStaticField(peerRoleClass, fieldName.c_str(), "Lcom/zerotier/sdk/PeerRole;"); - - peerRoleObject = env->GetStaticObjectField(peerRoleClass, enumField); + peerRoleObject = env->GetStaticObjectField(PeerRole_class, field); return peerRoleObject; } jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) { - jclass vntypeClass = NULL; jobject vntypeObject = NULL; - vntypeClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkType"); - if(env->ExceptionCheck() || vntypeClass == NULL) - { - return NULL; - } - - std::string fieldName; + jfieldID field; switch(type) { case ZT_NETWORK_TYPE_PRIVATE: - fieldName = "NETWORK_TYPE_PRIVATE"; + field = VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; break; case ZT_NETWORK_TYPE_PUBLIC: - fieldName = "NETWORK_TYPE_PUBLIC"; + field = VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; break; } - jfieldID enumField = lookup.findStaticField(vntypeClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkType;"); - vntypeObject = env->GetStaticObjectField(vntypeClass, enumField); + vntypeObject = env->GetStaticObjectField(VirtualNetworkType_class, field); return vntypeObject; } jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op) { - jclass vnetConfigOpClass = NULL; jobject vnetConfigOpObject = NULL; - vnetConfigOpClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfigOperation"); - if(env->ExceptionCheck() || vnetConfigOpClass == NULL) - { - return NULL; - } - - std::string fieldName; + jfieldID field; switch(op) { case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: - fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_UP"; + field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field; break; case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: - fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE"; + field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; break; case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: - fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN"; + field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; break; case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: - fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY"; + field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; break; } - jfieldID enumField = lookup.findStaticField(vnetConfigOpClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;"); - vnetConfigOpObject = env->GetStaticObjectField(vnetConfigOpClass, enumField); + vnetConfigOpObject = env->GetStaticObjectField(VirtualNetworkConfigOperation_class, field); return vnetConfigOpObject; } jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) { LOGV("newInetAddress"); - jclass inetAddressClass = NULL; - jmethodID inetAddress_getByAddress = NULL; - - inetAddressClass = lookup.findClass("java/net/InetAddress"); - if(env->ExceptionCheck() || inetAddressClass == NULL) - { - LOGE("Error finding InetAddress class"); - return NULL; - } - - inetAddress_getByAddress = lookup.findStaticMethod( - inetAddressClass, "getByAddress", "([B)Ljava/net/InetAddress;"); - if(env->ExceptionCheck() || inetAddress_getByAddress == NULL) - { - LOGE("Error finding getByAddress() static method"); - return NULL; - } jobject inetAddressObj = NULL; switch(addr.ss_family) @@ -316,7 +239,7 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) env->SetByteArrayRegion(buff, 0, 16, (jbyte*)ipv6->sin6_addr.s6_addr); inetAddressObj = env->CallStaticObjectMethod( - inetAddressClass, inetAddress_getByAddress, buff); + InetAddress_class, InetAddress_getByAddress_method, buff); } break; case AF_INET: @@ -331,7 +254,7 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) env->SetByteArrayRegion(buff, 0, 4, (jbyte*)&ipv4->sin_addr); inetAddressObj = env->CallStaticObjectMethod( - inetAddressClass, inetAddress_getByAddress, buff); + InetAddress_class, InetAddress_getByAddress_method, buff); } break; } @@ -346,15 +269,6 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) { LOGV("newInetSocketAddress Called"); - jclass inetSocketAddressClass = NULL; - jmethodID inetSocketAddress_constructor = NULL; - - inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress"); - if(env->ExceptionCheck() || inetSocketAddressClass == NULL) - { - LOGE("Error finding InetSocketAddress Class"); - return NULL; - } jobject inetAddressObject = NULL; @@ -373,14 +287,6 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) return NULL; } - inetSocketAddress_constructor = lookup.findMethod( - inetSocketAddressClass, "", "(Ljava/net/InetAddress;I)V"); - if(env->ExceptionCheck() || inetSocketAddress_constructor == NULL) - { - LOGE("Error finding InetSocketAddress constructor"); - return NULL; - } - int port = 0; switch(addr.ss_family) { @@ -407,7 +313,7 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) } - jobject inetSocketAddressObject = env->NewObject(inetSocketAddressClass, inetSocketAddress_constructor, inetAddressObject, port); + jobject inetSocketAddressObject = env->NewObject(InetSocketAddress_class, InetSocketAddress_ctor, inetAddressObject, port); if(env->ExceptionCheck() || inetSocketAddressObject == NULL) { LOGE("Error creating InetSocketAddress object"); } @@ -417,58 +323,8 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) { LOGV("newPeerPhysicalPath Called"); - jclass pppClass = NULL; - jfieldID addressField = NULL; - jfieldID lastSendField = NULL; - jfieldID lastReceiveField = NULL; - jfieldID preferredField = NULL; - - jmethodID ppp_constructor = NULL; - - pppClass = lookup.findClass("com/zerotier/sdk/PeerPhysicalPath"); - if(env->ExceptionCheck() || pppClass == NULL) - { - LOGE("Error finding PeerPhysicalPath class"); - return NULL; - } - - addressField = lookup.findField(pppClass, "address", "Ljava/net/InetSocketAddress;"); - if(env->ExceptionCheck() || addressField == NULL) - { - LOGE("Error finding address field"); - return NULL; - } - - lastSendField = lookup.findField(pppClass, "lastSend", "J"); - if(env->ExceptionCheck() || lastSendField == NULL) - { - LOGE("Error finding lastSend field"); - return NULL; - } - - lastReceiveField = lookup.findField(pppClass, "lastReceive", "J"); - if(env->ExceptionCheck() || lastReceiveField == NULL) - { - LOGE("Error finding lastReceive field"); - return NULL; - } - - preferredField = lookup.findField(pppClass, "preferred", "Z"); - if(env->ExceptionCheck() || preferredField == NULL) - { - LOGE("Error finding preferred field"); - return NULL; - } - - ppp_constructor = lookup.findMethod(pppClass, "", "()V"); - if(env->ExceptionCheck() || ppp_constructor == NULL) - { - LOGE("Error finding PeerPhysicalPath constructor"); - return NULL; - } - - jobject pppObject = env->NewObject(pppClass, ppp_constructor); + jobject pppObject = env->NewObject(PeerPhysicalPath_class, PeerPhysicalPath_ctor); if(env->ExceptionCheck() || pppObject == NULL) { LOGE("Error creating PPP object"); @@ -481,10 +337,10 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) return NULL; } - env->SetObjectField(pppObject, addressField, addressObject); - env->SetLongField(pppObject, lastSendField, ppp.lastSend); - env->SetLongField(pppObject, lastReceiveField, ppp.lastReceive); - env->SetBooleanField(pppObject, preferredField, ppp.preferred); + env->SetObjectField(pppObject, PeerPhysicalPath_address_field, addressObject); + env->SetLongField(pppObject, PeerPhysicalPath_lastSend_field, ppp.lastSend); + env->SetLongField(pppObject, PeerPhysicalPath_lastReceive_field, ppp.lastReceive); + env->SetBooleanField(pppObject, PeerPhysicalPath_preferred_field, ppp.preferred); if(env->ExceptionCheck()) { LOGE("Exception assigning fields to PeerPhysicalPath object"); @@ -497,104 +353,22 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) { LOGV("newPeer called"); - jclass peerClass = NULL; - - jfieldID addressField = NULL; - jfieldID versionMajorField = NULL; - jfieldID versionMinorField = NULL; - jfieldID versionRevField = NULL; - jfieldID latencyField = NULL; - jfieldID roleField = NULL; - jfieldID pathsField = NULL; - - jmethodID peer_constructor = NULL; - - peerClass = lookup.findClass("com/zerotier/sdk/Peer"); - if(env->ExceptionCheck() || peerClass == NULL) - { - LOGE("Error finding Peer class"); - return NULL; - } - - addressField = lookup.findField(peerClass, "address", "J"); - if(env->ExceptionCheck() || addressField == NULL) - { - LOGE("Error finding address field of Peer object"); - return NULL; - } - - versionMajorField = lookup.findField(peerClass, "versionMajor", "I"); - if(env->ExceptionCheck() || versionMajorField == NULL) - { - LOGE("Error finding versionMajor field of Peer object"); - return NULL; - } - - versionMinorField = lookup.findField(peerClass, "versionMinor", "I"); - if(env->ExceptionCheck() || versionMinorField == NULL) - { - LOGE("Error finding versionMinor field of Peer object"); - return NULL; - } - - versionRevField = lookup.findField(peerClass, "versionRev", "I"); - if(env->ExceptionCheck() || versionRevField == NULL) - { - LOGE("Error finding versionRev field of Peer object"); - return NULL; - } - - latencyField = lookup.findField(peerClass, "latency", "I"); - if(env->ExceptionCheck() || latencyField == NULL) - { - LOGE("Error finding latency field of Peer object"); - return NULL; - } - - roleField = lookup.findField(peerClass, "role", "Lcom/zerotier/sdk/PeerRole;"); - if(env->ExceptionCheck() || roleField == NULL) - { - LOGE("Error finding role field of Peer object"); - return NULL; - } - - pathsField = lookup.findField(peerClass, "paths", "[Lcom/zerotier/sdk/PeerPhysicalPath;"); - if(env->ExceptionCheck() || pathsField == NULL) - { - LOGE("Error finding paths field of Peer object"); - return NULL; - } - - peer_constructor = lookup.findMethod(peerClass, "", "()V"); - if(env->ExceptionCheck() || peer_constructor == NULL) - { - LOGE("Error finding Peer constructor"); - return NULL; - } - - jobject peerObject = env->NewObject(peerClass, peer_constructor); + jobject peerObject = env->NewObject(Peer_class, Peer_ctor); if(env->ExceptionCheck() || peerObject == NULL) { LOGE("Error creating Peer object"); return NULL; // out of memory } - env->SetLongField(peerObject, addressField, (jlong)peer.address); - env->SetIntField(peerObject, versionMajorField, peer.versionMajor); - env->SetIntField(peerObject, versionMinorField, peer.versionMinor); - env->SetIntField(peerObject, versionRevField, peer.versionRev); - env->SetIntField(peerObject, latencyField, peer.latency); - env->SetObjectField(peerObject, roleField, createPeerRole(env, peer.role)); - - jclass peerPhysicalPathClass = lookup.findClass("com/zerotier/sdk/PeerPhysicalPath"); - if(env->ExceptionCheck() || peerPhysicalPathClass == NULL) - { - LOGE("Error finding PeerPhysicalPath class"); - return NULL; - } + env->SetLongField(peerObject, Peer_address_field, (jlong)peer.address); + env->SetIntField(peerObject, Peer_versionMajor_field, peer.versionMajor); + env->SetIntField(peerObject, Peer_versionMinor_field, peer.versionMinor); + env->SetIntField(peerObject, Peer_versionRev_field, peer.versionRev); + env->SetIntField(peerObject, Peer_latency_field, peer.latency); + env->SetObjectField(peerObject, Peer_role_field, createPeerRole(env, peer.role)); jobjectArray arrayObject = env->NewObjectArray( - peer.pathCount, peerPhysicalPathClass, NULL); + peer.pathCount, PeerPhysicalPath_class, NULL); if(env->ExceptionCheck() || arrayObject == NULL) { LOGE("Error creating PeerPhysicalPath[] array"); @@ -614,190 +388,51 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) env->DeleteLocalRef(path); } - env->SetObjectField(peerObject, pathsField, arrayObject); + env->SetObjectField(peerObject, Peer_paths_field, arrayObject); return peerObject; } jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) { - jclass vnetConfigClass = NULL; - jmethodID vnetConfig_constructor = NULL; - jfieldID nwidField = NULL; - jfieldID macField = NULL; - jfieldID nameField = NULL; - jfieldID statusField = NULL; - jfieldID typeField = NULL; - jfieldID mtuField = NULL; - jfieldID dhcpField = NULL; - jfieldID bridgeField = NULL; - jfieldID broadcastEnabledField = NULL; - jfieldID portErrorField = NULL; - jfieldID netconfRevisionField = NULL; - jfieldID assignedAddressesField = NULL; - jfieldID routesField = NULL; - jfieldID dnsField = NULL; - - vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig"); - if(vnetConfigClass == NULL) - { - LOGE("Couldn't find com.zerotier.sdk.VirtualNetworkConfig"); - return NULL; - } - - vnetConfig_constructor = lookup.findMethod( - vnetConfigClass, "", "()V"); - if(env->ExceptionCheck() || vnetConfig_constructor == NULL) - { - LOGE("Couldn't find VirtualNetworkConfig Constructor"); - return NULL; - } - - jobject vnetConfigObj = env->NewObject(vnetConfigClass, vnetConfig_constructor); + jobject vnetConfigObj = env->NewObject(VirtualNetworkConfig_class, VirtualNetworkConfig_ctor); if(env->ExceptionCheck() || vnetConfigObj == NULL) { LOGE("Error creating new VirtualNetworkConfig object"); return NULL; } - nwidField = lookup.findField(vnetConfigClass, "nwid", "J"); - if(env->ExceptionCheck() || nwidField == NULL) - { - LOGE("Error getting nwid field"); - return NULL; - } - - macField = lookup.findField(vnetConfigClass, "mac", "J"); - if(env->ExceptionCheck() || macField == NULL) - { - LOGE("Error getting mac field"); - return NULL; - } - - nameField = lookup.findField(vnetConfigClass, "name", "Ljava/lang/String;"); - if(env->ExceptionCheck() || nameField == NULL) - { - LOGE("Error getting name field"); - return NULL; - } - - statusField = lookup.findField(vnetConfigClass, "status", "Lcom/zerotier/sdk/VirtualNetworkStatus;"); - if(env->ExceptionCheck() || statusField == NULL) - { - LOGE("Error getting status field"); - return NULL; - } - - typeField = lookup.findField(vnetConfigClass, "type", "Lcom/zerotier/sdk/VirtualNetworkType;"); - if(env->ExceptionCheck() || typeField == NULL) - { - LOGE("Error getting type field"); - return NULL; - } - - mtuField = lookup.findField(vnetConfigClass, "mtu", "I"); - if(env->ExceptionCheck() || mtuField == NULL) - { - LOGE("Error getting mtu field"); - return NULL; - } - - dhcpField = lookup.findField(vnetConfigClass, "dhcp", "Z"); - if(env->ExceptionCheck() || dhcpField == NULL) - { - LOGE("Error getting dhcp field"); - return NULL; - } - - bridgeField = lookup.findField(vnetConfigClass, "bridge", "Z"); - if(env->ExceptionCheck() || bridgeField == NULL) - { - LOGE("Error getting bridge field"); - return NULL; - } - - broadcastEnabledField = lookup.findField(vnetConfigClass, "broadcastEnabled", "Z"); - if(env->ExceptionCheck() || broadcastEnabledField == NULL) - { - LOGE("Error getting broadcastEnabled field"); - return NULL; - } - - portErrorField = lookup.findField(vnetConfigClass, "portError", "I"); - if(env->ExceptionCheck() || portErrorField == NULL) - { - LOGE("Error getting portError field"); - return NULL; - } - - netconfRevisionField = lookup.findField(vnetConfigClass, "netconfRevision", "J"); - if(env->ExceptionCheck() || netconfRevisionField == NULL) - { - LOGE("Error getting netconfRevision field"); - return NULL; - } - - assignedAddressesField = lookup.findField(vnetConfigClass, "assignedAddresses", - "[Ljava/net/InetSocketAddress;"); - if(env->ExceptionCheck() || assignedAddressesField == NULL) - { - LOGE("Error getting assignedAddresses field"); - return NULL; - } - - routesField = lookup.findField(vnetConfigClass, "routes", - "[Lcom/zerotier/sdk/VirtualNetworkRoute;"); - if(env->ExceptionCheck() || routesField == NULL) - { - LOGE("Error getting routes field"); - return NULL; - } - - dnsField = lookup.findField(vnetConfigClass, "dns", "Lcom/zerotier/sdk/VirtualNetworkDNS;"); - if(env->ExceptionCheck() || dnsField == NULL) - { - LOGE("Error getting DNS field"); - return NULL; - } - - env->SetLongField(vnetConfigObj, nwidField, vnetConfig.nwid); - env->SetLongField(vnetConfigObj, macField, vnetConfig.mac); + env->SetLongField(vnetConfigObj, VirtualNetworkConfig_nwid_field, vnetConfig.nwid); + env->SetLongField(vnetConfigObj, VirtualNetworkConfig_mac_field, vnetConfig.mac); jstring nameStr = env->NewStringUTF(vnetConfig.name); if(env->ExceptionCheck() || nameStr == NULL) { return NULL; // out of memory } - env->SetObjectField(vnetConfigObj, nameField, nameStr); + env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_name_field, nameStr); jobject statusObject = createVirtualNetworkStatus(env, vnetConfig.status); if(env->ExceptionCheck() || statusObject == NULL) { return NULL; } - env->SetObjectField(vnetConfigObj, statusField, statusObject); + env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_status_field, statusObject); jobject typeObject = createVirtualNetworkType(env, vnetConfig.type); if(env->ExceptionCheck() || typeObject == NULL) { return NULL; } - env->SetObjectField(vnetConfigObj, typeField, typeObject); + env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_type_field, typeObject); - env->SetIntField(vnetConfigObj, mtuField, (int)vnetConfig.mtu); - env->SetBooleanField(vnetConfigObj, dhcpField, vnetConfig.dhcp); - env->SetBooleanField(vnetConfigObj, bridgeField, vnetConfig.bridge); - env->SetBooleanField(vnetConfigObj, broadcastEnabledField, vnetConfig.broadcastEnabled); - env->SetIntField(vnetConfigObj, portErrorField, vnetConfig.portError); - - jclass inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress"); - if(env->ExceptionCheck() || inetSocketAddressClass == NULL) - { - LOGE("Error finding InetSocketAddress class"); - return NULL; - } + env->SetIntField(vnetConfigObj, VirtualNetworkConfig_mtu_field, (int)vnetConfig.mtu); + env->SetBooleanField(vnetConfigObj, VirtualNetworkConfig_dhcp_field, vnetConfig.dhcp); + env->SetBooleanField(vnetConfigObj, VirtualNetworkConfig_bridge_field, vnetConfig.bridge); + env->SetBooleanField(vnetConfigObj, VirtualNetworkConfig_broadcastEnabled_field, vnetConfig.broadcastEnabled); + env->SetIntField(vnetConfigObj, VirtualNetworkConfig_portError_field, vnetConfig.portError); jobjectArray assignedAddrArrayObj = env->NewObjectArray( - vnetConfig.assignedAddressCount, inetSocketAddressClass, NULL); + vnetConfig.assignedAddressCount, InetSocketAddress_class, NULL); if(env->ExceptionCheck() || assignedAddrArrayObj == NULL) { LOGE("Error creating InetSocketAddress[] array"); @@ -817,17 +452,10 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) env->DeleteLocalRef(inetAddrObj); } - env->SetObjectField(vnetConfigObj, assignedAddressesField, assignedAddrArrayObj); - - jclass virtualNetworkRouteClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkRoute"); - if(env->ExceptionCheck() || virtualNetworkRouteClass == NULL) - { - LOGE("Error finding VirtualNetworkRoute class"); - return NULL; - } + env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_assignedAddresses_field, assignedAddrArrayObj); jobjectArray routesArrayObj = env->NewObjectArray( - vnetConfig.routeCount, virtualNetworkRouteClass, NULL); + vnetConfig.routeCount, VirtualNetworkRoute_class, NULL); if(env->ExceptionCheck() || routesArrayObj == NULL) { LOGE("Error creating VirtualNetworkRoute[] array"); @@ -847,174 +475,62 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) env->DeleteLocalRef(routeObj); } - env->SetObjectField(vnetConfigObj, routesField, routesArrayObj); + env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_routes_field, routesArrayObj); jobject dnsObj = newVirtualNetworkDNS(env, vnetConfig.dns); if (dnsObj != NULL) { - env->SetObjectField(vnetConfigObj, dnsField, dnsObj); + env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_dns_field, dnsObj); } return vnetConfigObj; } jobject newVersion(JNIEnv *env, int major, int minor, int rev) { - // create a com.zerotier.sdk.Version object - jclass versionClass = NULL; - jmethodID versionConstructor = NULL; - - versionClass = lookup.findClass("com/zerotier/sdk/Version"); - if(env->ExceptionCheck() || versionClass == NULL) - { - return NULL; - } - - versionConstructor = lookup.findMethod( - versionClass, "", "()V"); - if(env->ExceptionCheck() || versionConstructor == NULL) - { - return NULL; - } - - jobject versionObj = env->NewObject(versionClass, versionConstructor); + // create a com.zerotier.sdk.Version object + jobject versionObj = env->NewObject(Version_class, Version_ctor); if(env->ExceptionCheck() || versionObj == NULL) { return NULL; } - // copy data to Version object - jfieldID majorField = NULL; - jfieldID minorField = NULL; - jfieldID revisionField = NULL; - - majorField = lookup.findField(versionClass, "major", "I"); - if(env->ExceptionCheck() || majorField == NULL) - { - return NULL; - } - - minorField = lookup.findField(versionClass, "minor", "I"); - if(env->ExceptionCheck() || minorField == NULL) - { - return NULL; - } - - revisionField = lookup.findField(versionClass, "revision", "I"); - if(env->ExceptionCheck() || revisionField == NULL) - { - return NULL; - } - - env->SetIntField(versionObj, majorField, (jint)major); - env->SetIntField(versionObj, minorField, (jint)minor); - env->SetIntField(versionObj, revisionField, (jint)rev); + env->SetIntField(versionObj, Version_major_field, (jint)major); + env->SetIntField(versionObj, Version_minor_field, (jint)minor); + env->SetIntField(versionObj, Version_revision_field, (jint)rev); return versionObj; } jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route) { - jclass virtualNetworkRouteClass = NULL; - jmethodID routeConstructor = NULL; - - virtualNetworkRouteClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkRoute"); - if(env->ExceptionCheck() || virtualNetworkRouteClass == NULL) - { - return NULL; - } - - routeConstructor = lookup.findMethod(virtualNetworkRouteClass, "", "()V"); - if(env->ExceptionCheck() || routeConstructor == NULL) - { - return NULL; - } - - jobject routeObj = env->NewObject(virtualNetworkRouteClass, routeConstructor); + jobject routeObj = env->NewObject(VirtualNetworkRoute_class, VirtualNetworkRoute_ctor); if(env->ExceptionCheck() || routeObj == NULL) { return NULL; } - jfieldID targetField = NULL; - jfieldID viaField = NULL; - jfieldID flagsField = NULL; - jfieldID metricField = NULL; - - targetField = lookup.findField(virtualNetworkRouteClass, "target", - "Ljava/net/InetSocketAddress;"); - if(env->ExceptionCheck() || targetField == NULL) - { - return NULL; - } - - viaField = lookup.findField(virtualNetworkRouteClass, "via", - "Ljava/net/InetSocketAddress;"); - if(env->ExceptionCheck() || targetField == NULL) - { - return NULL; - } - - flagsField = lookup.findField(virtualNetworkRouteClass, "flags", "I"); - if(env->ExceptionCheck() || flagsField == NULL) - { - return NULL; - } - - metricField = lookup.findField(virtualNetworkRouteClass, "metric", "I"); - if(env->ExceptionCheck() || metricField == NULL) - { - return NULL; - } - jobject targetObj = newInetSocketAddress(env, route.target); jobject viaObj = newInetSocketAddress(env, route.via); - env->SetObjectField(routeObj, targetField, targetObj); - env->SetObjectField(routeObj, viaField, viaObj); - env->SetIntField(routeObj, flagsField, (jint)route.flags); - env->SetIntField(routeObj, metricField, (jint)route.metric); + env->SetObjectField(routeObj, VirtualNetworkRoute_target_field, targetObj); + env->SetObjectField(routeObj, VirtualNetworkRoute_via_field, viaObj); + env->SetIntField(routeObj, VirtualNetworkRoute_flags_field, (jint)route.flags); + env->SetIntField(routeObj, VirtualNetworkRoute_metric_field, (jint)route.metric); return routeObj; } jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) { - jclass virtualNetworkDNSClass = NULL; - jmethodID dnsConstructor = NULL; - - virtualNetworkDNSClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkDNS"); - if (env->ExceptionCheck() || virtualNetworkDNSClass == NULL) { - return NULL; - } - - dnsConstructor = lookup.findMethod(virtualNetworkDNSClass, "", "()V"); - if(env->ExceptionCheck() || dnsConstructor == NULL) { - return NULL; - } - - jobject dnsObj = env->NewObject(virtualNetworkDNSClass, dnsConstructor); + jobject dnsObj = env->NewObject(VirtualNetworkDNS_class, VirtualNetworkDNS_ctor); if(env->ExceptionCheck() || dnsObj == NULL) { return NULL; } - jfieldID domainField = NULL; - jfieldID serversField = NULL; - - domainField = lookup.findField(virtualNetworkDNSClass, "domain", "Ljava/lang/String;"); - if(env->ExceptionCheck() || domainField == NULL) - { - return NULL; - } - - serversField = lookup.findField(virtualNetworkDNSClass, "servers", "Ljava/util/ArrayList;"); - if(env->ExceptionCheck() || serversField == NULL) { - return NULL; - } - if (strlen(dns.domain) > 0) { - InitListJNI(env); + jstring domain = env->NewStringUTF(dns.domain); - jobject addrArray = env->NewObject(java_util_ArrayList, java_util_ArrayList_, 0); + jobject addrArray = env->NewObject(ArrayList_class, ArrayList_ctor, 0); struct sockaddr_storage nullAddr; memset(&nullAddr, 0, sizeof(struct sockaddr_storage)); @@ -1023,13 +539,13 @@ jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) if (memcmp(&tmp, &nullAddr, sizeof(struct sockaddr_storage)) != 0) { jobject addr = newInetSocketAddress(env, tmp); - env->CallBooleanMethod(addrArray, java_util_ArrayList_add, addr); + env->CallBooleanMethod(addrArray, ArrayList_add_method, addr); env->DeleteLocalRef(addr); } } - env->SetObjectField(dnsObj, domainField, domain); - env->SetObjectField(dnsObj, serversField, addrArray); + env->SetObjectField(dnsObj, VirtualNetworkDNS_domain_field, domain); + env->SetObjectField(dnsObj, VirtualNetworkDNS_servers_field, addrArray); return dnsObj; } diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index b649b9c61..780feed02 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -29,7 +29,6 @@ #include "ZT_jnicache.h" #include "ZT_jniutils.h" -#include "ZT_jnilookup.h" #include #include "Mutex.hpp" @@ -41,9 +40,6 @@ #define LOG_TAG "Node" -// global static JNI Lookup Object -JniLookup lookup; - namespace { struct JniRef { @@ -117,39 +113,23 @@ namespace { return -100; } - jclass configListenerClass = env->GetObjectClass(ref->configListener); - if(configListenerClass == NULL) - { - LOGE("Couldn't find class for VirtualNetworkConfigListener instance"); - return -101; - } - - jmethodID configListenerCallbackMethod = lookup.findMethod(configListenerClass, - "onNetworkConfigurationUpdated", - "(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I"); - if(configListenerCallbackMethod == NULL) - { - LOGE("Couldn't find onVirtualNetworkFrame() method"); - return -102; - } - jobject operationObject = createVirtualNetworkConfigOperation(env, operation); if(operationObject == NULL) { LOGE("Error creating VirtualNetworkConfigOperation object"); - return -103; + return -101; } jobject networkConfigObject = newNetworkConfig(env, *config); if(networkConfigObject == NULL) { LOGE("Error creating VirtualNetworkConfig object"); - return -104; + return -102; } return env->CallIntMethod( ref->configListener, - configListenerCallbackMethod, + VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method, (jlong)nwid, operationObject, networkConfigObject); } @@ -180,22 +160,6 @@ namespace { return; } - jclass frameListenerClass = env->GetObjectClass(ref->frameListener); - if(env->ExceptionCheck() || frameListenerClass == NULL) - { - LOGE("Couldn't find class for VirtualNetworkFrameListener instance"); - return; - } - - jmethodID frameListenerCallbackMethod = lookup.findMethod( - frameListenerClass, - "onVirtualNetworkFrame", "(JJJJJ[B)V"); - if(env->ExceptionCheck() || frameListenerCallbackMethod == NULL) - { - LOGE("Couldn't find onVirtualNetworkFrame() method"); - return; - } - jbyteArray dataArray = env->NewByteArray(frameLength); if(env->ExceptionCheck() || dataArray == NULL) { @@ -213,7 +177,7 @@ namespace { return; } - env->CallVoidMethod(ref->frameListener, frameListenerCallbackMethod, (jlong)nwid, (jlong)sourceMac, (jlong)destMac, (jlong)etherType, (jlong)vlanid, dataArray); + env->CallVoidMethod(ref->frameListener, VirtualNetworkFrameListener_onVirtualNetworkFrame_method, (jlong)nwid, (jlong)sourceMac, (jlong)destMac, (jlong)etherType, (jlong)vlanid, dataArray); } @@ -236,26 +200,6 @@ namespace { return; } - jclass eventListenerClass = env->GetObjectClass(ref->eventListener); - 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) { - LOGE("Couldn't find onEvent method"); - return; - } - - jmethodID onTraceMethod = lookup.findMethod(eventListenerClass, - "onTrace", "(Ljava/lang/String;)V"); - if (onTraceMethod == NULL) { - LOGE("Couldn't find onTrace method"); - return; - } - jobject eventObject = createEvent(env, event); if (eventObject == NULL) { return; @@ -264,28 +208,28 @@ namespace { switch (event) { case ZT_EVENT_UP: { LOGD("Event Up"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); break; } case ZT_EVENT_OFFLINE: { LOGD("Event Offline"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); break; } case ZT_EVENT_ONLINE: { LOGD("Event Online"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); break; } case ZT_EVENT_DOWN: { LOGD("Event Down"); - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); break; } case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { LOGV("Identity Collision"); // call onEvent() - env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); } break; case ZT_EVENT_TRACE: { @@ -294,7 +238,7 @@ namespace { if (data != NULL) { const char *message = (const char *) data; jstring messageStr = env->NewStringUTF(message); - env->CallVoidMethod(ref->eventListener, onTraceMethod, messageStr); + env->CallVoidMethod(ref->eventListener, EventListener_onTrace_method, messageStr); } } break; @@ -352,31 +296,6 @@ namespace { return; } - jclass dataStorePutClass = env->GetObjectClass(ref->dataStorePutListener); - if (dataStorePutClass == NULL) - { - LOGE("Couldn't find class for DataStorePutListener instance"); - return; - } - - jmethodID dataStorePutCallbackMethod = lookup.findMethod( - dataStorePutClass, - "onDataStorePut", - "(Ljava/lang/String;[BZ)I"); - if(dataStorePutCallbackMethod == NULL) - { - LOGE("Couldn't find onDataStorePut method"); - return; - } - - jmethodID deleteMethod = lookup.findMethod(dataStorePutClass, - "onDelete", "(Ljava/lang/String;)I"); - if(deleteMethod == NULL) - { - LOGE("Couldn't find onDelete method"); - return; - } - jstring nameStr = env->NewStringUTF(p); if (bufferLength >= 0) { @@ -392,11 +311,11 @@ namespace { env->SetByteArrayRegion(bufferObj, 0, bufferLength, (jbyte*)buffer); env->CallIntMethod(ref->dataStorePutListener, - dataStorePutCallbackMethod, + DataStorePutListener_onDataStorePut_method, nameStr, bufferObj, secure); } else { LOGD("JNI: Delete file: %s", p); - env->CallIntMethod(ref->dataStorePutListener, deleteMethod, nameStr); + env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDelete_method, nameStr); } } @@ -445,42 +364,25 @@ namespace { return -102; } - jclass dataStoreGetClass = env->GetObjectClass(ref->dataStoreGetListener); - if(dataStoreGetClass == NULL) - { - LOGE("Couldn't find class for DataStoreGetListener instance"); - return -103; - } - - jmethodID dataStoreGetCallbackMethod = lookup.findMethod( - dataStoreGetClass, - "onDataStoreGet", - "(Ljava/lang/String;[B)J"); - if(dataStoreGetCallbackMethod == NULL) - { - LOGE("Couldn't find onDataStoreGet method"); - return -104; - } - jstring nameStr = env->NewStringUTF(p); if(nameStr == NULL) { LOGE("Error creating name string object"); - return -105; // out of memory + return -103; // out of memory } jbyteArray bufferObj = env->NewByteArray(bufferLength); if(bufferObj == NULL) { LOGE("Error creating byte[] buffer of size: %u", bufferLength); - return -106; + return -104; } LOGV("Calling onDataStoreGet(%s, %p)", p, buffer); int retval = (int)env->CallLongMethod( ref->dataStoreGetListener, - dataStoreGetCallbackMethod, + DataStoreGetListener_onDataStoreGet_method, nameStr, bufferObj); @@ -517,25 +419,10 @@ namespace { return -100; } - jclass packetSenderClass = env->GetObjectClass(ref->packetSender); - if(packetSenderClass == NULL) - { - LOGE("Couldn't find class for PacketSender instance"); - return -101; - } - - jmethodID packetSenderCallbackMethod = lookup.findMethod(packetSenderClass, - "onSendPacketRequested", "(JLjava/net/InetSocketAddress;[BI)I"); - if(packetSenderCallbackMethod == NULL) - { - LOGE("Couldn't find onSendPacketRequested method"); - return -102; - } - jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress); jbyteArray bufferObj = env->NewByteArray(bufferSize); env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer); - int retval = env->CallIntMethod(ref->packetSender, packetSenderCallbackMethod, localSocket, remoteAddressObj, bufferObj); + int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj); LOGV("JNI Packet Sender returned: %d", retval); return retval; @@ -558,21 +445,6 @@ namespace { JNIEnv *env = NULL; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); - jclass pathCheckerClass = env->GetObjectClass(ref->pathChecker); - if(pathCheckerClass == NULL) - { - LOGE("Couldn't find class for PathChecker instance"); - return true; - } - - jmethodID pathCheckCallbackMethod = lookup.findMethod(pathCheckerClass, - "onPathCheck", "(JJLjava/net/InetSocketAddress;)Z"); - if(pathCheckCallbackMethod == NULL) - { - LOGE("Couldn't find onPathCheck method implementation"); - return true; - } - // // was: // struct sockaddr_storage nullAddress = {0}; @@ -600,7 +472,7 @@ namespace { remoteAddressObj = newInetSocketAddress(env, *remoteAddress); } - return env->CallBooleanMethod(ref->pathChecker, pathCheckCallbackMethod, address, localSocket, remoteAddressObj); + return env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, address, localSocket, remoteAddressObj); } int PathLookupFunction(ZT_Node *node, @@ -620,65 +492,17 @@ namespace { JNIEnv *env = NULL; ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); - jclass pathCheckerClass = env->GetObjectClass(ref->pathChecker); - if(pathCheckerClass == NULL) - { - LOGE("Couldn't find class for PathChecker instance"); - return false; - } - - jmethodID pathLookupMethod = lookup.findMethod(pathCheckerClass, - "onPathLookup", "(JI)Ljava/net/InetSocketAddress;"); - if(pathLookupMethod == NULL) { - return false; - } - - jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, pathLookupMethod, address, ss_family); + jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, PathChecker_onPathLookup_method, address, ss_family); if(sockAddressObject == NULL) { LOGE("Unable to call onPathLookup implementation"); return false; } - jclass inetSockAddressClass = env->GetObjectClass(sockAddressObject); - if(inetSockAddressClass == NULL) - { - LOGE("Unable to find InetSocketAddress class"); - return false; - } + jint port = env->CallIntMethod(sockAddressObject, InetSocketAddress_getPort_method); + jobject addressObject = env->CallObjectMethod(sockAddressObject, InetSocketAddress_getAddress_method); - jmethodID getAddressMethod = lookup.findMethod(inetSockAddressClass, "getAddress", "()Ljava/net/InetAddress;"); - if(getAddressMethod == NULL) - { - LOGE("Unable to find InetSocketAddress.getAddress() method"); - return false; - } - - jmethodID getPortMethod = lookup.findMethod(inetSockAddressClass, "getPort", "()I"); - if(getPortMethod == NULL) - { - LOGE("Unable to find InetSocketAddress.getPort() method"); - return false; - } - - jint port = env->CallIntMethod(sockAddressObject, getPortMethod); - jobject addressObject = env->CallObjectMethod(sockAddressObject, getAddressMethod); - - jclass inetAddressClass = lookup.findClass("java/net/InetAddress"); - if(inetAddressClass == NULL) - { - LOGE("Unable to find InetAddress class"); - return false; - } - - getAddressMethod = lookup.findMethod(inetAddressClass, "getAddress", "()[B"); - if(getAddressMethod == NULL) - { - LOGE("Unable to find InetAddress.getAddress() method"); - return false; - } - - jbyteArray addressBytes = (jbyteArray)env->CallObjectMethod(addressObject, getAddressMethod); + jbyteArray addressBytes = (jbyteArray)env->CallObjectMethod(addressObject, InetAddress_getAddress_method); if(addressBytes == NULL) { LOGE("Unable to call InetAddress.getBytes()"); @@ -738,10 +562,7 @@ extern "C" { JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { - lookup.setJavaVM(vm); - setupJNICache(vm); - return JNI_VERSION_1_6; } @@ -760,112 +581,59 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( JNIEnv *env, jobject obj, jlong now) { LOGV("Creating ZT_Node struct"); - jobject resultObject = createResultObject(env, ZT_RESULT_OK); + jobject resultObject = ResultCode_RESULT_OK_enum; ZT_Node *node; JniRef *ref = new JniRef; ref->id = (int64_t)now; env->GetJavaVM(&ref->jvm); - jclass cls = env->GetObjectClass(obj); - jfieldID fid = lookup.findField( - cls, "getListener", "Lcom/zerotier/sdk/DataStoreGetListener;"); - - if(fid == NULL) - { - return NULL; // exception already thrown - } - - jobject tmp = env->GetObjectField(obj, fid); - if(tmp == NULL) + jobject dataStoreGetListener = env->GetObjectField(obj, Node_getListener_field); + if(dataStoreGetListener == NULL) { return NULL; } - ref->dataStoreGetListener = env->NewGlobalRef(tmp); + ref->dataStoreGetListener = env->NewGlobalRef(dataStoreGetListener); - fid = lookup.findField( - cls, "putListener", "Lcom/zerotier/sdk/DataStorePutListener;"); - - if(fid == NULL) - { - return NULL; // exception already thrown - } - - tmp = env->GetObjectField(obj, fid); - if(tmp == NULL) + jobject dataStorePutListener = env->GetObjectField(obj, Node_putListener_field); + if(dataStorePutListener == NULL) { return NULL; } - ref->dataStorePutListener = env->NewGlobalRef(tmp); + ref->dataStorePutListener = env->NewGlobalRef(dataStorePutListener); - fid = lookup.findField( - cls, "sender", "Lcom/zerotier/sdk/PacketSender;"); - if(fid == NULL) - { - return NULL; // exception already thrown - } - - tmp = env->GetObjectField(obj, fid); - if(tmp == NULL) + jobject packetSender = env->GetObjectField(obj, Node_sender_field); + if(packetSender == NULL) { return NULL; } - ref->packetSender = env->NewGlobalRef(tmp); + ref->packetSender = env->NewGlobalRef(packetSender); - fid = lookup.findField( - cls, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;"); - if(fid == NULL) - { - return NULL; // exception already thrown - } - - tmp = env->GetObjectField(obj, fid); - if(tmp == NULL) + jobject frameListener = env->GetObjectField(obj, Node_frameListener_field); + if(frameListener == NULL) { return NULL; } - ref->frameListener = env->NewGlobalRef(tmp); + ref->frameListener = env->NewGlobalRef(frameListener); - fid = lookup.findField( - cls, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;"); - if(fid == NULL) - { - return NULL; // exception already thrown - } - - tmp = env->GetObjectField(obj, fid); - if(tmp == NULL) + jobject configListener = env->GetObjectField(obj, Node_configListener_field); + if(configListener == NULL) { return NULL; } - ref->configListener = env->NewGlobalRef(tmp); + ref->configListener = env->NewGlobalRef(configListener); - fid = lookup.findField( - cls, "eventListener", "Lcom/zerotier/sdk/EventListener;"); - if(fid == NULL) + jobject eventListener = env->GetObjectField(obj, Node_eventListener_field); + if(eventListener == NULL) { return NULL; } + ref->eventListener = env->NewGlobalRef(eventListener); - tmp = env->GetObjectField(obj, fid); - if(tmp == NULL) + jobject pathChecker = env->GetObjectField(obj, Node_pathChecker_field); + if(pathChecker != NULL) { - return NULL; - } - ref->eventListener = env->NewGlobalRef(tmp); - - fid = lookup.findField( - cls, "pathChecker", "Lcom/zerotier/sdk/PathChecker;"); - if(fid == NULL) - { - LOGE("no path checker?"); - return NULL; - } - - tmp = env->GetObjectField(obj, fid); - if(tmp != NULL) - { - ref->pathChecker = env->NewGlobalRef(tmp); + ref->pathChecker = env->NewGlobalRef(pathChecker); } ref->callbacks->stateGetFunction = &StateGetFunction; @@ -961,14 +729,14 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) { // array for next background task length has 0 elements! - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } int64_t now = (int64_t)in_now; @@ -1028,75 +796,40 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( { // cannot find valid node. We should never get here. LOGE("Couldn't find a valid node!"); - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } 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); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } int64_t now = (int64_t)in_now; - // get the java.net.InetSocketAddress class and getAddress() method - 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, ZT_RESULT_FATAL_ERROR_INTERNAL); - } - - jmethodID getAddressMethod = lookup.findMethod( - inetAddressClass, "getAddress", "()[B"); - if(getAddressMethod == NULL) - { - // cant find InetAddress.getAddress() - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); - } - - jclass InetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress"); - if(InetSocketAddressClass == NULL) - { - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); - } - - jmethodID inetSockGetAddressMethod = lookup.findMethod( - InetSocketAddressClass, "getAddress", "()Ljava/net/InetAddress;"); - - jobject remoteAddrObject = env->CallObjectMethod(in_remoteAddress, inetSockGetAddressMethod); + jobject remoteAddrObject = env->CallObjectMethod(in_remoteAddress, InetSocketAddress_getAddress_method); if(remoteAddrObject == NULL) { - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); - } - - 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, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } // call InetSocketAddress.getPort() - int remotePort = env->CallIntMethod(in_remoteAddress, inetSock_getPort); + int remotePort = env->CallIntMethod(in_remoteAddress, InetSocketAddress_getPort_method); if(env->ExceptionCheck()) { LOGE("Exception calling InetSocketAddress.getPort()"); - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } // Call InetAddress.getAddress() - jbyteArray remoteAddressArray = (jbyteArray)env->CallObjectMethod(remoteAddrObject, getAddressMethod); + jbyteArray remoteAddressArray = (jbyteArray)env->CallObjectMethod(remoteAddrObject, InetAddress_getAddress_method); if(remoteAddressArray == NULL) { LOGE("Unable to call getAddress()"); // unable to call getAddress() - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } unsigned int addrSize = env->GetArrayLength(remoteAddressArray); @@ -1129,7 +862,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( LOGE("Unknown IP version"); // unknown address type env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0); - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0); @@ -1137,7 +870,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(packetLength == 0) { LOGE("Empty packet?!?"); - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } void *packetData = env->GetPrimitiveArrayCritical(in_packetData, NULL); void *localData = malloc(packetLength); @@ -1185,13 +918,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) { - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } int64_t now = (int64_t)in_now; @@ -1219,7 +952,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join( if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } uint64_t nwid = (uint64_t)in_nwid; @@ -1242,7 +975,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave( if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } uint64_t nwid = (uint64_t)in_nwid; @@ -1269,7 +1002,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe( if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } uint64_t nwid = (uint64_t)in_nwid; @@ -1299,7 +1032,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe( if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } uint64_t nwid = (uint64_t)in_nwid; @@ -1327,7 +1060,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_orbit( ZT_Node *node = findNode(nodeId); if(node == NULL) { - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } uint64_t moonWorldId = (uint64_t)in_moonWorldId; @@ -1351,7 +1084,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit( ZT_Node *node = findNode(nodeId); if(node == NULL) { - return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } uint64_t moonWorldId = (uint64_t)in_moonWorldId; @@ -1396,24 +1129,8 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status return 0; } - jclass nodeStatusClass = NULL; - jmethodID nodeStatusConstructor = NULL; - // create a com.zerotier.sdk.NodeStatus object - nodeStatusClass = lookup.findClass("com/zerotier/sdk/NodeStatus"); - if(nodeStatusClass == NULL) - { - return NULL; - } - - nodeStatusConstructor = lookup.findMethod( - nodeStatusClass, "", "()V"); - if(nodeStatusConstructor == NULL) - { - return NULL; - } - - jobject nodeStatusObj = env->NewObject(nodeStatusClass, nodeStatusConstructor); + jobject nodeStatusObj = env->NewObject(NodeStatus_class, NodeStatus_ctor); if(nodeStatusObj == NULL) { return NULL; @@ -1422,52 +1139,23 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status ZT_NodeStatus nodeStatus; ZT_Node_status(node, &nodeStatus); - jfieldID addressField = NULL; - jfieldID publicIdentityField = NULL; - jfieldID secretIdentityField = NULL; - jfieldID onlineField = NULL; - - addressField = lookup.findField(nodeStatusClass, "address", "J"); - if(addressField == NULL) - { - return NULL; - } - - publicIdentityField = lookup.findField(nodeStatusClass, "publicIdentity", "Ljava/lang/String;"); - if(publicIdentityField == NULL) - { - return NULL; - } - - secretIdentityField = lookup.findField(nodeStatusClass, "secretIdentity", "Ljava/lang/String;"); - if(secretIdentityField == NULL) - { - return NULL; - } - - onlineField = lookup.findField(nodeStatusClass, "online", "Z"); - if(onlineField == NULL) - { - return NULL; - } - - env->SetLongField(nodeStatusObj, addressField, nodeStatus.address); + env->SetLongField(nodeStatusObj, NodeStatus_address_field, nodeStatus.address); jstring pubIdentStr = env->NewStringUTF(nodeStatus.publicIdentity); if(pubIdentStr == NULL) { return NULL; // out of memory } - env->SetObjectField(nodeStatusObj, publicIdentityField, pubIdentStr); + env->SetObjectField(nodeStatusObj, NodeStatus_publicIdentity_field, pubIdentStr); jstring secIdentStr = env->NewStringUTF(nodeStatus.secretIdentity); if(secIdentStr == NULL) { return NULL; // out of memory } - env->SetObjectField(nodeStatusObj, secretIdentityField, secIdentStr); + env->SetObjectField(nodeStatusObj, NodeStatus_secretIdentity_field, secIdentStr); - env->SetBooleanField(nodeStatusObj, onlineField, nodeStatus.online); + env->SetBooleanField(nodeStatusObj, NodeStatus_online_field, nodeStatus.online); return nodeStatusObj; } @@ -1538,16 +1226,8 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( return NULL; } - jclass peerClass = lookup.findClass("com/zerotier/sdk/Peer"); - if(env->ExceptionCheck() || peerClass == NULL) - { - LOGE("Error finding Peer class"); - ZT_Node_freeQueryResult(node, peerList); - return NULL; - } - jobjectArray peerArrayObj = env->NewObjectArray( - peerList->peerCount, peerClass, NULL); + peerList->peerCount, Peer_class, NULL); if(env->ExceptionCheck() || peerArrayObj == NULL) { @@ -1598,16 +1278,8 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( return NULL; } - jclass vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig"); - if(env->ExceptionCheck() || vnetConfigClass == NULL) - { - LOGE("Error finding VirtualNetworkConfig class"); - ZT_Node_freeQueryResult(node, networkList); - return NULL; - } - jobjectArray networkListObject = env->NewObjectArray( - networkList->networkCount, vnetConfigClass, NULL); + networkList->networkCount, VirtualNetworkConfig_class, NULL); if(env->ExceptionCheck() || networkListObject == NULL) { LOGE("Error creating VirtualNetworkConfig[] array"); From 7c5f256d4a383280ac5becc8378f225f3b3d0314 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 12:04:21 -0500 Subject: [PATCH 17/68] add Event.fromInt --- java/jni/ZT_jnicache.cpp | 18 +-------- java/jni/ZT_jnicache.h | 9 +---- java/jni/ZT_jniutils.cpp | 37 ++----------------- java/jni/com_zerotierone_sdk_Node.cpp | 2 +- java/src/com/zerotier/sdk/Event.java | 53 ++++++++++++++++++++++----- 5 files changed, 52 insertions(+), 67 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index ab5344b79..aeb2471c1 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -102,6 +102,7 @@ jmethodID VirtualNetworkRoute_ctor; // Static methods // +jmethodID Event_fromInt_method; jmethodID InetAddress_getByAddress_method; // @@ -158,14 +159,6 @@ jfieldID VirtualNetworkRoute_via_field; // Static fields // -jfieldID Event_EVENT_DOWN_field; -jfieldID Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field; -jfieldID Event_EVENT_OFFLINE_field; -jfieldID Event_EVENT_ONLINE_field; -jfieldID Event_EVENT_REMOTE_TRACE_field; -jfieldID Event_EVENT_TRACE_field; -jfieldID Event_EVENT_UP_field; -jfieldID Event_EVENT_USER_MESSAGE_field; jfieldID PeerRole_PEER_ROLE_LEAF_field; jfieldID PeerRole_PEER_ROLE_MOON_field; jfieldID PeerRole_PEER_ROLE_PLANET_field; @@ -265,6 +258,7 @@ void setupJNICache(JavaVM *vm) { // 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;")); // @@ -321,14 +315,6 @@ void setupJNICache(JavaVM *vm) { // Static fields // - EXCEPTIONANDNULLCHECK(Event_EVENT_DOWN_field = env->GetStaticFieldID(Event_class, "EVENT_DOWN", "Lcom/zerotier/sdk/Event;")); - EXCEPTIONANDNULLCHECK(Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field = env->GetStaticFieldID(Event_class, "EVENT_FATAL_ERROR_IDENTITY_COLLISION", "Lcom/zerotier/sdk/Event;")); - EXCEPTIONANDNULLCHECK(Event_EVENT_OFFLINE_field = env->GetStaticFieldID(Event_class, "EVENT_OFFLINE", "Lcom/zerotier/sdk/Event;")); - EXCEPTIONANDNULLCHECK(Event_EVENT_ONLINE_field = env->GetStaticFieldID(Event_class, "EVENT_ONLINE", "Lcom/zerotier/sdk/Event;")); - EXCEPTIONANDNULLCHECK(Event_EVENT_REMOTE_TRACE_field = env->GetStaticFieldID(Event_class, "EVENT_REMOTE_TRACE", "Lcom/zerotier/sdk/Event;")); - EXCEPTIONANDNULLCHECK(Event_EVENT_TRACE_field = env->GetStaticFieldID(Event_class, "EVENT_TRACE", "Lcom/zerotier/sdk/Event;")); - EXCEPTIONANDNULLCHECK(Event_EVENT_UP_field = env->GetStaticFieldID(Event_class, "EVENT_UP", "Lcom/zerotier/sdk/Event;")); - EXCEPTIONANDNULLCHECK(Event_EVENT_USER_MESSAGE_field = env->GetStaticFieldID(Event_class, "EVENT_USER_MESSAGE", "Lcom/zerotier/sdk/Event;")); EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_LEAF_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_LEAF", "Lcom/zerotier/sdk/PeerRole;")); EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_MOON_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_MOON", "Lcom/zerotier/sdk/PeerRole;")); EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_PLANET_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_PLANET", "Lcom/zerotier/sdk/PeerRole;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index fb9cf6442..d315cd0e7 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -71,6 +71,7 @@ extern jmethodID VirtualNetworkRoute_ctor; // Static methods // +extern jmethodID Event_fromInt_method; extern jmethodID InetAddress_getByAddress_method; // @@ -127,14 +128,6 @@ extern jfieldID VirtualNetworkRoute_via_field; // Static fields // -extern jfieldID Event_EVENT_DOWN_field; -extern jfieldID Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field; -extern jfieldID Event_EVENT_OFFLINE_field; -extern jfieldID Event_EVENT_ONLINE_field; -extern jfieldID Event_EVENT_REMOTE_TRACE_field; -extern jfieldID Event_EVENT_TRACE_field; -extern jfieldID Event_EVENT_UP_field; -extern jfieldID Event_EVENT_USER_MESSAGE_field; extern jfieldID PeerRole_PEER_ROLE_LEAF_field; extern jfieldID PeerRole_PEER_ROLE_MOON_field; extern jfieldID PeerRole_PEER_ROLE_PLANET_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 0ed59fab9..62250de9f 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -115,41 +115,12 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) jobject createEvent(JNIEnv *env, ZT_Event event) { - jobject eventObject = NULL; - - jfieldID field; - switch(event) - { - case ZT_EVENT_UP: - field = Event_EVENT_UP_field; - break; - case ZT_EVENT_OFFLINE: - field = Event_EVENT_OFFLINE_field; - break; - case ZT_EVENT_ONLINE: - field = Event_EVENT_ONLINE_field; - break; - case ZT_EVENT_DOWN: - field = Event_EVENT_DOWN_field; - break; - case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: - field = Event_EVENT_FATAL_ERROR_IDENTITY_COLLISION_field; - break; - case ZT_EVENT_TRACE: - field = Event_EVENT_TRACE_field; - break; - case ZT_EVENT_USER_MESSAGE: - field = Event_EVENT_USER_MESSAGE_field; - break; - case ZT_EVENT_REMOTE_TRACE: - field = Event_EVENT_REMOTE_TRACE_field; - break; - default: - break; + jobject eventObject = env->CallStaticObjectMethod(Event_class, Event_fromInt_method, event); + if (env->ExceptionCheck() || eventObject == NULL) { + LOGE("Error creating Event object"); + return NULL; } - eventObject = env->GetStaticObjectField(Event_class, field); - return eventObject; } diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 780feed02..c70d121ad 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -201,7 +201,7 @@ namespace { } jobject eventObject = createEvent(env, event); - if (eventObject == NULL) { + if (env->ExceptionCheck() || eventObject == NULL) { return; } diff --git a/java/src/com/zerotier/sdk/Event.java b/java/src/com/zerotier/sdk/Event.java index 1f33cea5c..fbc016c66 100644 --- a/java/src/com/zerotier/sdk/Event.java +++ b/java/src/com/zerotier/sdk/Event.java @@ -27,6 +27,11 @@ package com.zerotier.sdk; +/** + * Status codes sent to status update callback when things happen + * + * Defined in ZeroTierOne.h as ZT_Event + */ public enum Event { /** @@ -35,19 +40,19 @@ public enum Event { * This is the first event generated, and is always sent. It may occur * before Node's constructor returns. */ - EVENT_UP, + EVENT_UP(0), /** * Node is offline -- network does not seem to be reachable by any available strategy */ - EVENT_OFFLINE, + EVENT_OFFLINE(1), /** * Node is online -- at least one upstream node appears reachable * * Meta-data: none */ - EVENT_ONLINE, + EVENT_ONLINE(2), /** * Node is shutting down @@ -56,7 +61,7 @@ public enum Event { * It's done for convenience, since cleaning up other state in the event * handler may appear more idiomatic.

*/ - EVENT_DOWN, + EVENT_DOWN(3), /** * Your identity has collided with another node's ZeroTier address @@ -86,7 +91,7 @@ public enum Event { * 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?

*/ - EVENT_FATAL_ERROR_IDENTITY_COLLISION, + EVENT_FATAL_ERROR_IDENTITY_COLLISION(4), /** * Trace (debugging) message @@ -95,7 +100,7 @@ public enum Event { * *

Meta-data: {@link String}, TRACE message

*/ - EVENT_TRACE, + EVENT_TRACE(5), /** * VERB_USER_MESSAGE received @@ -103,7 +108,7 @@ public enum Event { * These are generated when a VERB_USER_MESSAGE packet is received via * ZeroTier VL1. */ - EVENT_USER_MESSAGE, + EVENT_USER_MESSAGE(6), /** * Remote trace received @@ -115,5 +120,35 @@ public enum Event { * these, and controllers only save them if they pertain to networks * with remote tracing enabled. */ - EVENT_REMOTE_TRACE; -} \ No newline at end of file + 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); + } + } +} From 056cef729206514edfb027d45ddefd54c0d83750 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 12:29:38 -0500 Subject: [PATCH 18/68] add PeerRole.fromInt --- java/jni/ZT_jnicache.cpp | 8 ++---- java/jni/ZT_jnicache.h | 4 +-- java/jni/ZT_jniutils.cpp | 20 +++------------ java/src/com/zerotier/sdk/PeerRole.java | 33 ++++++++++++++++++++++--- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index aeb2471c1..daaf803e6 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -104,6 +104,7 @@ jmethodID VirtualNetworkRoute_ctor; jmethodID Event_fromInt_method; jmethodID InetAddress_getByAddress_method; +jmethodID PeerRole_fromInt_method; // // Instance fields @@ -159,9 +160,6 @@ jfieldID VirtualNetworkRoute_via_field; // Static fields // -jfieldID PeerRole_PEER_ROLE_LEAF_field; -jfieldID PeerRole_PEER_ROLE_MOON_field; -jfieldID PeerRole_PEER_ROLE_PLANET_field; jfieldID ResultCode_RESULT_ERROR_BAD_PARAMETER_field; jfieldID ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; jfieldID ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; @@ -260,6 +258,7 @@ void setupJNICache(JavaVM *vm) { 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;")); // // Instance fields @@ -315,9 +314,6 @@ void setupJNICache(JavaVM *vm) { // Static fields // - EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_LEAF_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_LEAF", "Lcom/zerotier/sdk/PeerRole;")); - EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_MOON_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_MOON", "Lcom/zerotier/sdk/PeerRole;")); - EXCEPTIONANDNULLCHECK(PeerRole_PEER_ROLE_PLANET_field = env->GetStaticFieldID(PeerRole_class, "PEER_ROLE_PLANET", "Lcom/zerotier/sdk/PeerRole;")); EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_BAD_PARAMETER_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_BAD_PARAMETER", "Lcom/zerotier/sdk/ResultCode;")); EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_NETWORK_NOT_FOUND", "Lcom/zerotier/sdk/ResultCode;")); EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_UNSUPPORTED_OPERATION", "Lcom/zerotier/sdk/ResultCode;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index d315cd0e7..c79fe1db5 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -73,6 +73,7 @@ extern jmethodID VirtualNetworkRoute_ctor; extern jmethodID Event_fromInt_method; extern jmethodID InetAddress_getByAddress_method; +extern jmethodID PeerRole_fromInt_method; // // Instance fields @@ -128,9 +129,6 @@ extern jfieldID VirtualNetworkRoute_via_field; // Static fields // -extern jfieldID PeerRole_PEER_ROLE_LEAF_field; -extern jfieldID PeerRole_PEER_ROLE_MOON_field; -extern jfieldID PeerRole_PEER_ROLE_PLANET_field; extern jfieldID ResultCode_RESULT_ERROR_BAD_PARAMETER_field; extern jfieldID ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; extern jfieldID ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 62250de9f..5544446b7 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -126,24 +126,12 @@ jobject createEvent(JNIEnv *env, ZT_Event event) jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) { - jobject peerRoleObject = NULL; - - jfieldID field; - switch(role) - { - case ZT_PEER_ROLE_LEAF: - field = PeerRole_PEER_ROLE_LEAF_field; - break; - case ZT_PEER_ROLE_MOON: - field = PeerRole_PEER_ROLE_MOON_field; - break; - case ZT_PEER_ROLE_PLANET: - field = PeerRole_PEER_ROLE_PLANET_field; - break; + jobject peerRoleObject = env->CallStaticObjectMethod(PeerRole_class, PeerRole_fromInt_method, role); + if (env->ExceptionCheck() || peerRoleObject == NULL) { + LOGE("Error creating PeerRole object"); + return NULL; } - peerRoleObject = env->GetStaticObjectField(PeerRole_class, field); - return peerRoleObject; } diff --git a/java/src/com/zerotier/sdk/PeerRole.java b/java/src/com/zerotier/sdk/PeerRole.java index 83cc7d1e6..d69a1f1bb 100644 --- a/java/src/com/zerotier/sdk/PeerRole.java +++ b/java/src/com/zerotier/sdk/PeerRole.java @@ -27,20 +27,45 @@ package com.zerotier.sdk; +/** + * What trust hierarchy role does this peer have? + * + * Defined in ZeroTierOne.h as ZT_PeerRole + */ public enum PeerRole { /** * An ordinary node */ - PEER_ROLE_LEAF, + PEER_ROLE_LEAF(0), /** * moon root */ - PEER_ROLE_MOON, + PEER_ROLE_MOON(1), /** * planetary root */ - PEER_ROLE_PLANET -} \ No newline at end of file + 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); + } + } +} From 34ff813e2a0bfbc26f1f40c482ea61fe0656901f Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 12:40:59 -0500 Subject: [PATCH 19/68] add ResultCode.fromInt --- java/jni/ZT_jnicache.cpp | 16 ++------- java/jni/ZT_jnicache.h | 8 +---- java/jni/ZT_jniutils.cpp | 44 +++-------------------- java/jni/com_zerotierone_sdk_Node.cpp | 4 +++ java/src/com/zerotier/sdk/ResultCode.java | 32 ++++++++++++++--- 5 files changed, 39 insertions(+), 65 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index daaf803e6..a29bd8e74 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -105,6 +105,7 @@ jmethodID VirtualNetworkRoute_ctor; jmethodID Event_fromInt_method; jmethodID InetAddress_getByAddress_method; jmethodID PeerRole_fromInt_method; +jmethodID ResultCode_fromInt_method; // // Instance fields @@ -160,13 +161,6 @@ jfieldID VirtualNetworkRoute_via_field; // Static fields // -jfieldID ResultCode_RESULT_ERROR_BAD_PARAMETER_field; -jfieldID ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; -jfieldID ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; -jfieldID ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field; -jfieldID ResultCode_RESULT_FATAL_ERROR_INTERNAL_field; -jfieldID ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field; -jfieldID ResultCode_RESULT_OK_field; jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; @@ -259,6 +253,7 @@ void setupJNICache(JavaVM *vm) { 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;")); // // Instance fields @@ -314,13 +309,6 @@ void setupJNICache(JavaVM *vm) { // Static fields // - EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_BAD_PARAMETER_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_BAD_PARAMETER", "Lcom/zerotier/sdk/ResultCode;")); - EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_NETWORK_NOT_FOUND", "Lcom/zerotier/sdk/ResultCode;")); - EXCEPTIONANDNULLCHECK(ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field = env->GetStaticFieldID(ResultCode_class, "RESULT_ERROR_UNSUPPORTED_OPERATION", "Lcom/zerotier/sdk/ResultCode;")); - EXCEPTIONANDNULLCHECK(ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field = env->GetStaticFieldID(ResultCode_class, "RESULT_FATAL_ERROR_DATA_STORE_FAILED", "Lcom/zerotier/sdk/ResultCode;")); - EXCEPTIONANDNULLCHECK(ResultCode_RESULT_FATAL_ERROR_INTERNAL_field = env->GetStaticFieldID(ResultCode_class, "RESULT_FATAL_ERROR_INTERNAL", "Lcom/zerotier/sdk/ResultCode;")); - EXCEPTIONANDNULLCHECK(ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field = env->GetStaticFieldID(ResultCode_class, "RESULT_FATAL_ERROR_OUT_OF_MEMORY", "Lcom/zerotier/sdk/ResultCode;")); - EXCEPTIONANDNULLCHECK(ResultCode_RESULT_OK_field = env->GetStaticFieldID(ResultCode_class, "RESULT_OK", "Lcom/zerotier/sdk/ResultCode;")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index c79fe1db5..ffee04d93 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -74,6 +74,7 @@ extern jmethodID VirtualNetworkRoute_ctor; extern jmethodID Event_fromInt_method; extern jmethodID InetAddress_getByAddress_method; extern jmethodID PeerRole_fromInt_method; +extern jmethodID ResultCode_fromInt_method; // // Instance fields @@ -129,13 +130,6 @@ extern jfieldID VirtualNetworkRoute_via_field; // Static fields // -extern jfieldID ResultCode_RESULT_ERROR_BAD_PARAMETER_field; -extern jfieldID ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; -extern jfieldID ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; -extern jfieldID ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field; -extern jfieldID ResultCode_RESULT_FATAL_ERROR_INTERNAL_field; -extern jfieldID ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field; -extern jfieldID ResultCode_RESULT_OK_field; extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 5544446b7..bda1014fc 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -32,48 +32,12 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) { - jobject resultObject = NULL; - - jfieldID field; - switch(code) - { - case ZT_RESULT_OK: - case ZT_RESULT_OK_IGNORED: - LOGV("ZT_RESULT_OK"); - field = ResultCode_RESULT_OK_field; - break; - case ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY: - LOGV("ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY"); - field = ResultCode_RESULT_FATAL_ERROR_OUT_OF_MEMORY_field; - break; - case ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED: - LOGV("ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED"); - field = ResultCode_RESULT_FATAL_ERROR_DATA_STORE_FAILED_field; - break; - case ZT_RESULT_ERROR_NETWORK_NOT_FOUND: - LOGV("ZT_RESULT_ERROR_NETWORK_NOT_FOUND"); - field = ResultCode_RESULT_ERROR_NETWORK_NOT_FOUND_field; - break; - case ZT_RESULT_ERROR_UNSUPPORTED_OPERATION: - LOGV("ZT_RESULT_ERROR_UNSUPPORTED_OPERATION"); - field = ResultCode_RESULT_ERROR_UNSUPPORTED_OPERATION_field; - break; - case ZT_RESULT_ERROR_BAD_PARAMETER: - LOGV("ZT_RESULT_ERROR_BAD_PARAMETER"); - field = ResultCode_RESULT_ERROR_BAD_PARAMETER_field; - break; - case ZT_RESULT_FATAL_ERROR_INTERNAL: - default: - LOGV("ZT_RESULT_FATAL_ERROR_INTERNAL"); - field = ResultCode_RESULT_FATAL_ERROR_INTERNAL_field; - break; + jobject resultObject = env->CallStaticObjectMethod(ResultCode_class, ResultCode_fromInt_method, code); + if(env->ExceptionCheck() || resultObject == NULL) { + LOGE("Error creating ResultCode object"); + return NULL; } - resultObject = env->GetStaticObjectField(ResultCode_class, field); - if(env->ExceptionCheck() || resultObject == NULL) - { - LOGE("Error on GetStaticObjectField"); - } return resultObject; } diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index c70d121ad..92cc896ac 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -656,6 +656,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( { LOGE("Error creating Node: %d", rc); resultObject = createResultObject(env, rc); + if (env->ExceptionCheck() || resultObject == NULL) { + return NULL; + } + if(node) { ZT_Node_delete(node); diff --git a/java/src/com/zerotier/sdk/ResultCode.java b/java/src/com/zerotier/sdk/ResultCode.java index 7c80e5844..21a7fae48 100644 --- a/java/src/com/zerotier/sdk/ResultCode.java +++ b/java/src/com/zerotier/sdk/ResultCode.java @@ -34,6 +34,8 @@ package com.zerotier.sdk; * occurs, the node should be considered to not be working correctly. These * indicate serious problems like an inaccessible data store or a compile * problem.

+ * + * Defined in ZeroTierOne.h as ZT_ResultCode */ public enum ResultCode { @@ -69,10 +71,32 @@ public enum ResultCode { RESULT_ERROR_BAD_PARAMETER(1002); - - private final int id; - ResultCode(int id) { this.id = id; } - public int getValue() { return id; } + private final int id; + + ResultCode(int id) { + this.id = id; + } + + public static ResultCode fromInt(int id) { + switch (id) { + case 0: + return RESULT_OK; + 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(int id) { return (id > 100 && id < 1000); From acd8b951144e82f1514bfbfc1682f732867360ea Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 12:48:49 -0500 Subject: [PATCH 20/68] fix ANDROID-36: issues with ResultCode --- java/src/com/zerotier/sdk/ResultCode.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/java/src/com/zerotier/sdk/ResultCode.java b/java/src/com/zerotier/sdk/ResultCode.java index 21a7fae48..dc8a901b5 100644 --- a/java/src/com/zerotier/sdk/ResultCode.java +++ b/java/src/com/zerotier/sdk/ResultCode.java @@ -42,7 +42,12 @@ public enum ResultCode { /** * Operation completed normally */ - RESULT_OK(0), + RESULT_OK(0), + + /** + * Call produced no error but no action was taken + */ + RESULT_OK_IGNORED(1), // Fatal errors (>=100, <1000) /** @@ -81,6 +86,8 @@ public enum ResultCode { switch (id) { case 0: return RESULT_OK; + case 1: + return RESULT_OK_IGNORED; case 100: return RESULT_FATAL_ERROR_OUT_OF_MEMORY; case 101: @@ -98,7 +105,7 @@ public enum ResultCode { } } - public boolean isFatal(int id) { - return (id > 100 && id < 1000); + public boolean isFatal() { + return (id >= 100 && id < 1000); } } From 7c2766096c53c4325d7a579ab68b98d860d4b88f Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 12:50:47 -0500 Subject: [PATCH 21/68] add VirtualNetworkConfigOperation.fromInt --- java/jni/ZT_jnicache.cpp | 10 ++---- java/jni/ZT_jnicache.h | 5 +-- java/jni/ZT_jniutils.cpp | 22 +++--------- java/jni/com_zerotierone_sdk_Node.cpp | 3 +- .../sdk/VirtualNetworkConfigOperation.java | 35 ++++++++++++++++--- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index a29bd8e74..f42ac7b29 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -106,6 +106,7 @@ jmethodID Event_fromInt_method; jmethodID InetAddress_getByAddress_method; jmethodID PeerRole_fromInt_method; jmethodID ResultCode_fromInt_method; +jmethodID VirtualNetworkConfigOperation_fromInt_method; // // Instance fields @@ -161,10 +162,6 @@ jfieldID VirtualNetworkRoute_via_field; // Static fields // -jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; -jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; -jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; -jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field; jfieldID VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; jfieldID VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; jfieldID VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; @@ -254,6 +251,7 @@ void setupJNICache(JavaVM *vm) { 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;")); // // Instance fields @@ -309,10 +307,6 @@ void setupJNICache(JavaVM *vm) { // Static fields // - EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field = env->GetStaticFieldID(VirtualNetworkConfigOperation_class, "VIRTUAL_NETWORK_CONFIG_OPERATION_UP", "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;")); EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_ACCESS_DENIED", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_AUTHENTICATION_REQUIRED", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_CLIENT_TOO_OLD", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index ffee04d93..61865403a 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -75,6 +75,7 @@ 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; // // Instance fields @@ -130,10 +131,6 @@ extern jfieldID VirtualNetworkRoute_via_field; // Static fields // -extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; -extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; -extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; -extern jfieldID VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field; extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index bda1014fc..5a69116d4 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -120,26 +120,12 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op) { - jobject vnetConfigOpObject = NULL; - - jfieldID field; - switch(op) - { - case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: - field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_UP_field; - break; - case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: - field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE_field; - break; - case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: - field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN_field; - break; - case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: - field = VirtualNetworkConfigOperation_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY_field; - break; + jobject vnetConfigOpObject = env->CallStaticObjectMethod(VirtualNetworkConfigOperation_class, VirtualNetworkConfigOperation_fromInt_method, op); + if (env->ExceptionCheck() || vnetConfigOpObject == NULL) { + LOGE("Error creating VirtualNetworkConfigOperation object"); + return NULL; } - vnetConfigOpObject = env->GetStaticObjectField(VirtualNetworkConfigOperation_class, field); return vnetConfigOpObject; } diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 92cc896ac..e9686c302 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -114,9 +114,8 @@ namespace { } jobject operationObject = createVirtualNetworkConfigOperation(env, operation); - if(operationObject == NULL) + if(env->ExceptionCheck() || operationObject == NULL) { - LOGE("Error creating VirtualNetworkConfigOperation object"); return -101; } diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java b/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java index 6abf2755f..93a4c5d9d 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java @@ -27,25 +27,52 @@ package com.zerotier.sdk; +/** + * Virtual network configuration update type + * + * 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, + VIRTUAL_NETWORK_CONFIG_OPERATION_UP(0), /** * Network configuration has been updated */ - VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE, + VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE(1), /** * Network is going down (not permanently) */ - VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, + VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN(2), /** * Network is going down permanently (leave/delete) */ - VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY + VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY(3); + + @SuppressWarnings({"FieldCanBeLocal", "unused"}) + private final int id; + + VirtualNetworkConfigOperation(int id) { + this.id = id; + } + + public static VirtualNetworkConfigOperation fromInt(int id) { + switch (id) { + case 0: + return VIRTUAL_NETWORK_CONFIG_OPERATION_UP; + case 1: + return VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE; + case 2: + return VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN; + case 3: + return VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY; + default: + throw new RuntimeException("Unhandled value: " + id); + } + } } From ed3918b50890b20d3e65ba5a04df4f54e422a7ca Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 12:55:36 -0500 Subject: [PATCH 22/68] fix ANDROID-40: VirtualNetworkConfigOperation out-of-sync with ZT_VirtualNetworkConfigOperation enum --- .../sdk/VirtualNetworkConfigOperation.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java b/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java index 93a4c5d9d..a1981bd15 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java @@ -37,22 +37,22 @@ public enum VirtualNetworkConfigOperation { /** * Network is coming up (either for the first time or after service restart) */ - VIRTUAL_NETWORK_CONFIG_OPERATION_UP(0), + VIRTUAL_NETWORK_CONFIG_OPERATION_UP(1), /** * Network configuration has been updated */ - VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE(1), + VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE(2), /** * Network is going down (not permanently) */ - VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN(2), + VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN(3), /** * Network is going down permanently (leave/delete) */ - VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY(3); + VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY(4); @SuppressWarnings({"FieldCanBeLocal", "unused"}) private final int id; @@ -63,13 +63,13 @@ public enum VirtualNetworkConfigOperation { public static VirtualNetworkConfigOperation fromInt(int id) { switch (id) { - case 0: - return VIRTUAL_NETWORK_CONFIG_OPERATION_UP; case 1: - return VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE; + return VIRTUAL_NETWORK_CONFIG_OPERATION_UP; case 2: - return VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN; + 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); From 85bd773c554ea34acd9e16bc3545a58b743e7f7c Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 12:58:10 -0500 Subject: [PATCH 23/68] add VirtualNetworkStatus.fromInt --- java/jni/ZT_jnicache.cpp | 16 +------ java/jni/ZT_jnicache.h | 8 +--- java/jni/ZT_jniutils.cpp | 32 ++----------- .../zerotier/sdk/VirtualNetworkStatus.java | 47 ++++++++++++++++--- 4 files changed, 47 insertions(+), 56 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index f42ac7b29..3dcf003e2 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -107,6 +107,7 @@ jmethodID InetAddress_getByAddress_method; jmethodID PeerRole_fromInt_method; jmethodID ResultCode_fromInt_method; jmethodID VirtualNetworkConfigOperation_fromInt_method; +jmethodID VirtualNetworkStatus_fromInt_method; // // Instance fields @@ -162,13 +163,6 @@ jfieldID VirtualNetworkRoute_via_field; // Static fields // -jfieldID VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; -jfieldID VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; -jfieldID VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; -jfieldID VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field; -jfieldID VirtualNetworkStatus_NETWORK_STATUS_OK_field; -jfieldID VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field; -jfieldID VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field; jfieldID VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; jfieldID VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; @@ -252,6 +246,7 @@ void setupJNICache(JavaVM *vm) { 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;")); // // Instance fields @@ -307,13 +302,6 @@ void setupJNICache(JavaVM *vm) { // Static fields // - EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_ACCESS_DENIED", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_AUTHENTICATION_REQUIRED", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_CLIENT_TOO_OLD", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_NOT_FOUND", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_OK_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_OK", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_PORT_ERROR", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field = env->GetStaticFieldID(VirtualNetworkStatus_class, "NETWORK_STATUS_REQUESTING_CONFIGURATION", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); EXCEPTIONANDNULLCHECK(VirtualNetworkType_NETWORK_TYPE_PRIVATE_field = env->GetStaticFieldID(VirtualNetworkType_class, "NETWORK_TYPE_PRIVATE", "Lcom/zerotier/sdk/VirtualNetworkType;")); EXCEPTIONANDNULLCHECK(VirtualNetworkType_NETWORK_TYPE_PUBLIC_field = env->GetStaticFieldID(VirtualNetworkType_class, "NETWORK_TYPE_PUBLIC", "Lcom/zerotier/sdk/VirtualNetworkType;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index 61865403a..bebb49565 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -76,6 +76,7 @@ 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; // // Instance fields @@ -131,13 +132,6 @@ extern jfieldID VirtualNetworkRoute_via_field; // Static fields // -extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; -extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; -extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; -extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field; -extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_OK_field; -extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field; -extern jfieldID VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field; extern jfieldID VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; extern jfieldID VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 5a69116d4..f56035e2f 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -44,36 +44,12 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) { - jobject statusObject = NULL; - - jfieldID field; - switch(status) - { - case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: - field = VirtualNetworkStatus_NETWORK_STATUS_REQUESTING_CONFIGURATION_field; - break; - case ZT_NETWORK_STATUS_OK: - field = VirtualNetworkStatus_NETWORK_STATUS_OK_field; - break; - case ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED: - field = VirtualNetworkStatus_NETWORK_STATUS_AUTHENTICATION_REQUIRED_field; - break; - case ZT_NETWORK_STATUS_ACCESS_DENIED: - field = VirtualNetworkStatus_NETWORK_STATUS_ACCESS_DENIED_field; - break; - case ZT_NETWORK_STATUS_NOT_FOUND: - field = VirtualNetworkStatus_NETWORK_STATUS_NOT_FOUND_field; - break; - case ZT_NETWORK_STATUS_PORT_ERROR: - field = VirtualNetworkStatus_NETWORK_STATUS_PORT_ERROR_field; - break; - case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: - field = VirtualNetworkStatus_NETWORK_STATUS_CLIENT_TOO_OLD_field; - break; + jobject statusObject = env->CallStaticObjectMethod(VirtualNetworkStatus_class, VirtualNetworkStatus_fromInt_method, status); + if (env->ExceptionCheck() || statusObject == NULL) { + LOGE("Error creating VirtualNetworkStatus object"); + return NULL; } - statusObject = env->GetStaticObjectField(VirtualNetworkStatus_class, field); - return statusObject; } diff --git a/java/src/com/zerotier/sdk/VirtualNetworkStatus.java b/java/src/com/zerotier/sdk/VirtualNetworkStatus.java index f98aec4a5..616e05846 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkStatus.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkStatus.java @@ -27,40 +27,73 @@ package com.zerotier.sdk; +/** + * Virtual network status codes + * + * Defined in ZeroTierOne.h as ZT_VirtualNetworkStatus + */ public enum VirtualNetworkStatus { /** * Waiting for network configuration (also means revision == 0) */ - NETWORK_STATUS_REQUESTING_CONFIGURATION, + NETWORK_STATUS_REQUESTING_CONFIGURATION(0), /** * Configuration received and we are authorized */ - NETWORK_STATUS_OK, + NETWORK_STATUS_OK(1), /** * Netconf master said SSO auth required. */ - NETWORK_STATUS_AUTHENTICATION_REQUIRED, + NETWORK_STATUS_AUTHENTICATION_REQUIRED(2), /** * Netconf master told us 'nope' */ - NETWORK_STATUS_ACCESS_DENIED, + NETWORK_STATUS_ACCESS_DENIED(3), /** * Netconf master exists, but this virtual network does not */ - NETWORK_STATUS_NOT_FOUND, + NETWORK_STATUS_NOT_FOUND(4), /** * Initialization of network failed or other internal error */ - NETWORK_STATUS_PORT_ERROR, + NETWORK_STATUS_PORT_ERROR(5), /** * ZeroTier One version too old */ - NETWORK_STATUS_CLIENT_TOO_OLD + NETWORK_STATUS_CLIENT_TOO_OLD(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_AUTHENTICATION_REQUIRED; + case 3: + return NETWORK_STATUS_ACCESS_DENIED; + case 4: + return NETWORK_STATUS_NOT_FOUND; + case 5: + return NETWORK_STATUS_PORT_ERROR; + case 6: + return NETWORK_STATUS_CLIENT_TOO_OLD; + default: + throw new RuntimeException("Unhandled value: " + id); + } + } } From d1460ab65b72ead8dd0ada0e3c5863d04580d45c Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 13:29:57 -0500 Subject: [PATCH 24/68] fix ANDROID-37: VirtualNetworkStatus out-of-sync with ZT_VirtualNetworkStatus enum --- .../zerotier/sdk/VirtualNetworkStatus.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkStatus.java b/java/src/com/zerotier/sdk/VirtualNetworkStatus.java index 616e05846..8a32ba6ad 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkStatus.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkStatus.java @@ -44,30 +44,30 @@ public enum VirtualNetworkStatus { */ NETWORK_STATUS_OK(1), - /** - * Netconf master said SSO auth required. - */ - NETWORK_STATUS_AUTHENTICATION_REQUIRED(2), - /** * Netconf master told us 'nope' */ - NETWORK_STATUS_ACCESS_DENIED(3), + NETWORK_STATUS_ACCESS_DENIED(2), /** * Netconf master exists, but this virtual network does not */ - NETWORK_STATUS_NOT_FOUND(4), + NETWORK_STATUS_NOT_FOUND(3), /** * Initialization of network failed or other internal error */ - NETWORK_STATUS_PORT_ERROR(5), + NETWORK_STATUS_PORT_ERROR(4), /** * ZeroTier One version too old */ - NETWORK_STATUS_CLIENT_TOO_OLD(6); + 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; @@ -83,15 +83,15 @@ public enum VirtualNetworkStatus { case 1: return NETWORK_STATUS_OK; case 2: - return NETWORK_STATUS_AUTHENTICATION_REQUIRED; - case 3: return NETWORK_STATUS_ACCESS_DENIED; - case 4: + case 3: return NETWORK_STATUS_NOT_FOUND; - case 5: + case 4: return NETWORK_STATUS_PORT_ERROR; - case 6: + case 5: return NETWORK_STATUS_CLIENT_TOO_OLD; + case 6: + return NETWORK_STATUS_AUTHENTICATION_REQUIRED; default: throw new RuntimeException("Unhandled value: " + id); } From acf5b3579b2ea12ee083a9e349abda853504007f Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 13:15:19 -0500 Subject: [PATCH 25/68] add VirtualNetworkType.fromInt --- java/jni/ZT_jnicache.cpp | 16 ++--------- java/jni/ZT_jnicache.h | 8 +----- java/jni/ZT_jniutils.cpp | 16 +++-------- .../com/zerotier/sdk/VirtualNetworkType.java | 27 +++++++++++++++++-- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 3dcf003e2..86f61e106 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -108,6 +108,7 @@ jmethodID PeerRole_fromInt_method; jmethodID ResultCode_fromInt_method; jmethodID VirtualNetworkConfigOperation_fromInt_method; jmethodID VirtualNetworkStatus_fromInt_method; +jmethodID VirtualNetworkType_fromInt_method; // // Instance fields @@ -159,13 +160,6 @@ jfieldID VirtualNetworkRoute_metric_field; jfieldID VirtualNetworkRoute_target_field; jfieldID VirtualNetworkRoute_via_field; -// -// Static fields -// - -jfieldID VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; -jfieldID VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; - // // Enums // @@ -247,6 +241,7 @@ void setupJNICache(JavaVM *vm) { 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;")); // // Instance fields @@ -298,13 +293,6 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_target_field = env->GetFieldID(VirtualNetworkRoute_class, "target", "Ljava/net/InetSocketAddress;")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_via_field = env->GetFieldID(VirtualNetworkRoute_class, "via", "Ljava/net/InetSocketAddress;")); - // - // Static fields - // - - EXCEPTIONANDNULLCHECK(VirtualNetworkType_NETWORK_TYPE_PRIVATE_field = env->GetStaticFieldID(VirtualNetworkType_class, "NETWORK_TYPE_PRIVATE", "Lcom/zerotier/sdk/VirtualNetworkType;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkType_NETWORK_TYPE_PUBLIC_field = env->GetStaticFieldID(VirtualNetworkType_class, "NETWORK_TYPE_PUBLIC", "Lcom/zerotier/sdk/VirtualNetworkType;")); - // // Enums // diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index bebb49565..e9d553f00 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -77,6 +77,7 @@ 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; // // Instance fields @@ -128,13 +129,6 @@ extern jfieldID VirtualNetworkRoute_metric_field; extern jfieldID VirtualNetworkRoute_target_field; extern jfieldID VirtualNetworkRoute_via_field; -// -// Static fields -// - -extern jfieldID VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; -extern jfieldID VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; - // // Enums // diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index f56035e2f..128b30097 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -77,20 +77,12 @@ jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) { - jobject vntypeObject = NULL; - - jfieldID field; - switch(type) - { - case ZT_NETWORK_TYPE_PRIVATE: - field = VirtualNetworkType_NETWORK_TYPE_PRIVATE_field; - break; - case ZT_NETWORK_TYPE_PUBLIC: - field = VirtualNetworkType_NETWORK_TYPE_PUBLIC_field; - break; + jobject vntypeObject = env->CallStaticObjectMethod(VirtualNetworkType_class, VirtualNetworkType_fromInt_method, type); + if (env->ExceptionCheck() || vntypeObject == NULL) { + LOGE("Error creating VirtualNetworkType object"); + return NULL; } - vntypeObject = env->GetStaticObjectField(VirtualNetworkType_class, field); return vntypeObject; } diff --git a/java/src/com/zerotier/sdk/VirtualNetworkType.java b/java/src/com/zerotier/sdk/VirtualNetworkType.java index 0b55828eb..44be8864b 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkType.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkType.java @@ -27,15 +27,38 @@ package com.zerotier.sdk; +/** + * Virtual network type codes + * + * Defined in ZeroTierOne.h as ZT_VirtualNetworkType + */ public enum VirtualNetworkType { /** * Private networks are authorized via certificates of membership */ - NETWORK_TYPE_PRIVATE, + NETWORK_TYPE_PRIVATE(0), /** * Public networks have no access control -- they'll always be AUTHORIZED */ - NETWORK_TYPE_PUBLIC + 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); + } + } } From 4861ec5a40aef22189f8bd00011da6924c4e50c7 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 13:40:17 -0500 Subject: [PATCH 26/68] make NodeStatus a plain data class --- java/jni/ZT_jnicache.cpp | 10 +--- java/jni/ZT_jnicache.h | 4 -- java/jni/ZT_jniutils.cpp | 31 ++++++++++++ java/jni/ZT_jniutils.h | 2 + java/jni/com_zerotierone_sdk_Node.cpp | 32 +----------- java/src/com/zerotier/sdk/NodeStatus.java | 59 +++++++++++++++-------- 6 files changed, 75 insertions(+), 63 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 86f61e106..16b2add65 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -114,10 +114,6 @@ jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -jfieldID NodeStatus_address_field; -jfieldID NodeStatus_online_field; -jfieldID NodeStatus_publicIdentity_field; -jfieldID NodeStatus_secretIdentity_field; jfieldID Node_configListener_field; jfieldID Node_eventListener_field; jfieldID Node_frameListener_field; @@ -218,7 +214,7 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(InetSocketAddress_ctor = env->GetMethodID(InetSocketAddress_class, "", "(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, "", "()V")); + EXCEPTIONANDNULLCHECK(NodeStatus_ctor = env->GetMethodID(NodeStatus_class, "", "(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;")); @@ -247,10 +243,6 @@ void setupJNICache(JavaVM *vm) { // Instance fields // - EXCEPTIONANDNULLCHECK(NodeStatus_address_field = env->GetFieldID(NodeStatus_class, "address", "J")); - EXCEPTIONANDNULLCHECK(NodeStatus_online_field = env->GetFieldID(NodeStatus_class, "online", "Z")); - EXCEPTIONANDNULLCHECK(NodeStatus_publicIdentity_field = env->GetFieldID(NodeStatus_class, "publicIdentity", "Ljava/lang/String;")); - EXCEPTIONANDNULLCHECK(NodeStatus_secretIdentity_field = env->GetFieldID(NodeStatus_class, "secretIdentity", "Ljava/lang/String;")); EXCEPTIONANDNULLCHECK(Node_configListener_field = env->GetFieldID(Node_class, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;")); EXCEPTIONANDNULLCHECK(Node_eventListener_field = env->GetFieldID(Node_class, "eventListener", "Lcom/zerotier/sdk/EventListener;")); EXCEPTIONANDNULLCHECK(Node_frameListener_field = env->GetFieldID(Node_class, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index e9d553f00..12f9f7301 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -83,10 +83,6 @@ extern jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -extern jfieldID NodeStatus_address_field; -extern jfieldID NodeStatus_online_field; -extern jfieldID NodeStatus_publicIdentity_field; -extern jfieldID NodeStatus_secretIdentity_field; extern jfieldID Node_configListener_field; extern jfieldID Node_eventListener_field; extern jfieldID Node_frameListener_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 128b30097..5f4b1f702 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -428,3 +428,34 @@ jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) } return NULL; } + +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, + status.address, + pubIdentStr, + secIdentStr, + status.online); + if(env->ExceptionCheck() || nodeStatusObj == NULL) { + LOGE("Exception creating new NodeStatus"); + return NULL; + } + + return nodeStatusObj; +} diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index 3a9b227f1..164030ee5 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -96,4 +96,6 @@ jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route) jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns); +jobject newNodeStatus(JNIEnv *env, const ZT_NodeStatus &status); + #endif // ZT_jniutils_h_ diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index e9686c302..6e524c48c 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -1126,41 +1126,11 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return 0; - } - - // create a com.zerotier.sdk.NodeStatus object - jobject nodeStatusObj = env->NewObject(NodeStatus_class, NodeStatus_ctor); - if(nodeStatusObj == NULL) - { - return NULL; - } ZT_NodeStatus nodeStatus; ZT_Node_status(node, &nodeStatus); - env->SetLongField(nodeStatusObj, NodeStatus_address_field, nodeStatus.address); - - jstring pubIdentStr = env->NewStringUTF(nodeStatus.publicIdentity); - if(pubIdentStr == NULL) - { - return NULL; // out of memory - } - env->SetObjectField(nodeStatusObj, NodeStatus_publicIdentity_field, pubIdentStr); - - jstring secIdentStr = env->NewStringUTF(nodeStatus.secretIdentity); - if(secIdentStr == NULL) - { - return NULL; // out of memory - } - env->SetObjectField(nodeStatusObj, NodeStatus_secretIdentity_field, secIdentStr); - - env->SetBooleanField(nodeStatusObj, NodeStatus_online_field, nodeStatus.online); - - return nodeStatusObj; + return newNodeStatus(env, nodeStatus); } /* diff --git a/java/src/com/zerotier/sdk/NodeStatus.java b/java/src/com/zerotier/sdk/NodeStatus.java index 11e49ade1..1172650b1 100644 --- a/java/src/com/zerotier/sdk/NodeStatus.java +++ b/java/src/com/zerotier/sdk/NodeStatus.java @@ -27,43 +27,64 @@ package com.zerotier.sdk; -public final class NodeStatus { - private long address; - private String publicIdentity; - private String secretIdentity; - private boolean online; +import com.zerotier.sdk.util.StringUtils; - private NodeStatus() {} +/** + * Current node status + * + * 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 final long getAddress() { - return address; - } + public long getAddress() { + return address; + } /** * Public identity in string-serialized form (safe to send to others) * *

This identity will remain valid as long as the node exists.

*/ - public final String getPublicIdentity() { - return publicIdentity; - } + public String getPublicIdentity() { + return publicIdentity; + } /** * Full identity including secret key in string-serialized form * *

This identity will remain valid as long as the node exists.

*/ - public final String getSecretIdentity() { - return secretIdentity; - } + public String getSecretIdentity() { + return secretIdentity; + } /** * True if some kind of connectivity appears available */ - public final boolean isOnline() { - return online; - } -} \ No newline at end of file + public boolean isOnline() { + return online; + } +} From f9528f124873a9fcaffffce7ae6a76f9eda4e71f Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Mon, 27 Feb 2023 10:32:06 -0500 Subject: [PATCH 27/68] fix ANDROID-52: synchronization bug with nodeMap --- java/jni/com_zerotierone_sdk_Node.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 6e524c48c..fe87d6373 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -688,10 +688,9 @@ JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete( int64_t nodeId = (int64_t)id; NodeMap::iterator found; - { - ZeroTier::Mutex::Lock lock(nodeMapMutex); - found = nodeMap.find(nodeId); - } + + ZeroTier::Mutex::Lock lock(nodeMapMutex); + found = nodeMap.find(nodeId); if(found != nodeMap.end()) { From 90bf300bd8436bd0e062ff0fc55c416b5b225a33 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:45:43 -0500 Subject: [PATCH 28/68] Node init work: separate Node construction and init --- java/jni/ZT_jnicache.cpp | 14 -- java/jni/ZT_jnicache.h | 7 - java/jni/com_zerotierone_sdk_Node.cpp | 202 +++++++++++++------------- java/jni/com_zerotierone_sdk_Node.h | 10 +- java/src/com/zerotier/sdk/Node.java | 91 ++++++------ 5 files changed, 160 insertions(+), 164 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 16b2add65..764f7f6c1 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -114,13 +114,6 @@ jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -jfieldID Node_configListener_field; -jfieldID Node_eventListener_field; -jfieldID Node_frameListener_field; -jfieldID Node_getListener_field; -jfieldID Node_pathChecker_field; -jfieldID Node_putListener_field; -jfieldID Node_sender_field; jfieldID PeerPhysicalPath_address_field; jfieldID PeerPhysicalPath_lastReceive_field; jfieldID PeerPhysicalPath_lastSend_field; @@ -243,13 +236,6 @@ void setupJNICache(JavaVM *vm) { // Instance fields // - EXCEPTIONANDNULLCHECK(Node_configListener_field = env->GetFieldID(Node_class, "configListener", "Lcom/zerotier/sdk/VirtualNetworkConfigListener;")); - EXCEPTIONANDNULLCHECK(Node_eventListener_field = env->GetFieldID(Node_class, "eventListener", "Lcom/zerotier/sdk/EventListener;")); - EXCEPTIONANDNULLCHECK(Node_frameListener_field = env->GetFieldID(Node_class, "frameListener", "Lcom/zerotier/sdk/VirtualNetworkFrameListener;")); - EXCEPTIONANDNULLCHECK(Node_getListener_field = env->GetFieldID(Node_class, "getListener", "Lcom/zerotier/sdk/DataStoreGetListener;")); - EXCEPTIONANDNULLCHECK(Node_pathChecker_field = env->GetFieldID(Node_class, "pathChecker", "Lcom/zerotier/sdk/PathChecker;")); - EXCEPTIONANDNULLCHECK(Node_putListener_field = env->GetFieldID(Node_class, "putListener", "Lcom/zerotier/sdk/DataStorePutListener;")); - EXCEPTIONANDNULLCHECK(Node_sender_field = env->GetFieldID(Node_class, "sender", "Lcom/zerotier/sdk/PacketSender;")); EXCEPTIONANDNULLCHECK(PeerPhysicalPath_address_field = env->GetFieldID(PeerPhysicalPath_class, "address", "Ljava/net/InetSocketAddress;")); EXCEPTIONANDNULLCHECK(PeerPhysicalPath_lastReceive_field = env->GetFieldID(PeerPhysicalPath_class, "lastReceive", "J")); EXCEPTIONANDNULLCHECK(PeerPhysicalPath_lastSend_field = env->GetFieldID(PeerPhysicalPath_class, "lastSend", "J")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index 12f9f7301..8dd176ab4 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -83,13 +83,6 @@ extern jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -extern jfieldID Node_configListener_field; -extern jfieldID Node_eventListener_field; -extern jfieldID Node_frameListener_field; -extern jfieldID Node_getListener_field; -extern jfieldID Node_pathChecker_field; -extern jfieldID Node_putListener_field; -extern jfieldID Node_sender_field; extern jfieldID PeerPhysicalPath_address_field; extern jfieldID PeerPhysicalPath_lastReceive_field; extern jfieldID PeerPhysicalPath_lastSend_field; diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index fe87d6373..4d52735e7 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -54,6 +54,7 @@ namespace { , configListener(NULL) , pathChecker(NULL) , callbacks(NULL) + , inited() { callbacks = (ZT_Node_Callbacks*)malloc(sizeof(ZT_Node_Callbacks)); memset(callbacks, 0, sizeof(ZT_Node_Callbacks)); @@ -91,6 +92,10 @@ namespace { jobject pathChecker; ZT_Node_Callbacks *callbacks; + + bool inited; + + bool finishInitializing(); }; @@ -539,19 +544,81 @@ namespace { } typedef std::map NodeMap; - static NodeMap nodeMap; + NodeMap nodeMap; ZeroTier::Mutex nodeMapMutex; + bool isInited(int64_t nodeId) { + + ZeroTier::Mutex::Lock lock(nodeMapMutex); + NodeMap::iterator found = nodeMap.find(nodeId); + + if (found == nodeMap.end()) { + + // + // not in map yet, or has been removed from map + // + return false; + } + + JniRef *ref = found->second; + + assert(ref); + + return ref->inited; + } + + bool JniRef::finishInitializing() { + + ZeroTier::Mutex::Lock lock(nodeMapMutex); + NodeMap::iterator found = nodeMap.find(id); + + if (found != nodeMap.end()) { + // + // already in map + // + LOGE("Cannot finish initializing; node is already in map"); + return false; + } + + nodeMap.insert(std::make_pair(id, this)); + + assert(!inited); + inited = true; + + return true; + } + ZT_Node* findNode(int64_t nodeId) { ZeroTier::Mutex::Lock lock(nodeMapMutex); NodeMap::iterator found = nodeMap.find(nodeId); - if(found != nodeMap.end()) - { - JniRef *ref = found->second; - return ref->node; + + assert(found != nodeMap.end()); + + JniRef *ref = found->second; + + assert(ref); + + return ref->node; + } + + JniRef *removeRef(int64_t nodeId) { + + ZeroTier::Mutex::Lock lock(nodeMapMutex); + + NodeMap::iterator found = nodeMap.find(nodeId); + + if (found == nodeMap.end()) { + return nullptr; } - return NULL; + + JniRef *ref = found->second; + + assert(ref); + + nodeMap.erase(nodeId); + + return ref; } } @@ -574,10 +641,13 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) /* * Class: com_zerotier_sdk_Node * Method: node_init - * Signature: (J)Lcom/zerotier/sdk/ResultCode; + * 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 *env, jobject obj, jlong now) + JNIEnv *env, jobject obj, jlong now, jobject dataStoreGetListener, + jobject dataStorePutListener, jobject packetSender, jobject eventListener, + jobject frameListener, jobject configListener, + jobject pathChecker) { LOGV("Creating ZT_Node struct"); jobject resultObject = ResultCode_RESULT_OK_enum; @@ -587,49 +657,42 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( ref->id = (int64_t)now; env->GetJavaVM(&ref->jvm); - jobject dataStoreGetListener = env->GetObjectField(obj, Node_getListener_field); if(dataStoreGetListener == NULL) { return NULL; } ref->dataStoreGetListener = env->NewGlobalRef(dataStoreGetListener); - jobject dataStorePutListener = env->GetObjectField(obj, Node_putListener_field); if(dataStorePutListener == NULL) { return NULL; } ref->dataStorePutListener = env->NewGlobalRef(dataStorePutListener); - jobject packetSender = env->GetObjectField(obj, Node_sender_field); if(packetSender == NULL) { return NULL; } ref->packetSender = env->NewGlobalRef(packetSender); - jobject frameListener = env->GetObjectField(obj, Node_frameListener_field); if(frameListener == NULL) { return NULL; } ref->frameListener = env->NewGlobalRef(frameListener); - jobject configListener = env->GetObjectField(obj, Node_configListener_field); if(configListener == NULL) { return NULL; } ref->configListener = env->NewGlobalRef(configListener); - jobject eventListener = env->GetObjectField(obj, Node_eventListener_field); if(eventListener == NULL) { return NULL; } ref->eventListener = env->NewGlobalRef(eventListener); - jobject pathChecker = env->GetObjectField(obj, Node_pathChecker_field); if(pathChecker != NULL) { ref->pathChecker = env->NewGlobalRef(pathChecker); @@ -669,13 +732,29 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( return resultObject; } - ZeroTier::Mutex::Lock lock(nodeMapMutex); + // + // node is now updated + // ref->node = node; - nodeMap.insert(std::make_pair(ref->id, ref)); + + if (!ref->finishInitializing()) { + LOGE("finishInitializing() failed"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } return resultObject; } +/* + * Class: com_zerotier_sdk_Node + * Method: node_isInited + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_zerotier_sdk_Node_node_1isInited + (JNIEnv *env, jobject obj, jlong nodeId) { + return isInited(nodeId); +} + /* * Class: com_zerotier_sdk_Node * Method: node_delete @@ -687,25 +766,15 @@ JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete( LOGV("Destroying ZT_Node struct"); int64_t nodeId = (int64_t)id; - NodeMap::iterator found; + JniRef *ref = removeRef(nodeId); - ZeroTier::Mutex::Lock lock(nodeMapMutex); - found = nodeMap.find(nodeId); - - if(found != nodeMap.end()) - { - JniRef *ref = found->second; - nodeMap.erase(found); - - ZT_Node_delete(ref->node); - - delete ref; - ref = NULL; - } - else - { - LOGE("Attempted to delete a node that doesn't exist!"); + if (!ref) { + return; } + + ZT_Node_delete(ref->node); + + delete ref; } /* @@ -728,11 +797,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) @@ -794,12 +858,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - LOGE("Couldn't find a valid node!"); - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } unsigned int nbtd_len = (unsigned int)env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) @@ -917,11 +975,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) @@ -951,12 +1004,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } - uint64_t nwid = (uint64_t)in_nwid; ZT_ResultCode rc = ZT_Node_join(node, nwid, NULL, NULL); @@ -974,11 +1021,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } uint64_t nwid = (uint64_t)in_nwid; @@ -1001,11 +1043,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } uint64_t nwid = (uint64_t)in_nwid; uint64_t multicastGroup = (uint64_t)in_multicastGroup; @@ -1031,11 +1068,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } uint64_t nwid = (uint64_t)in_nwid; uint64_t multicastGroup = (uint64_t)in_multicastGroup; @@ -1060,10 +1092,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_orbit( { int64_t nodeId = (int64_t)id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } uint64_t moonWorldId = (uint64_t)in_moonWorldId; uint64_t moonSeed = (uint64_t)in_moonSeed; @@ -1084,10 +1112,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit( { int64_t nodeId = (int64_t)id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } uint64_t moonWorldId = (uint64_t)in_moonWorldId; @@ -1105,11 +1129,6 @@ JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return 0; - } uint64_t address = ZT_Node_address(node); return (jlong)address; @@ -1142,11 +1161,6 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return 0; - } ZT_VirtualNetworkConfig *vnetConfig = ZT_Node_networkConfig(node, nwid); @@ -1184,11 +1198,6 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return 0; - } ZT_PeerList *peerList = ZT_Node_peers(node); @@ -1238,11 +1247,6 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( { int64_t nodeId = (int64_t) id; ZT_Node *node = findNode(nodeId); - if(node == NULL) - { - // cannot find valid node. We should never get here. - return 0; - } ZT_VirtualNetworkList *networkList = ZT_Node_networks(node); if(networkList == NULL) diff --git a/java/jni/com_zerotierone_sdk_Node.h b/java/jni/com_zerotierone_sdk_Node.h index a5c9668a6..5acf2ff34 100644 --- a/java/jni/com_zerotierone_sdk_Node.h +++ b/java/jni/com_zerotierone_sdk_Node.h @@ -10,9 +10,17 @@ extern "C" { /* * Class: com_zerotier_sdk_Node * Method: node_init - * Signature: (J)Lcom/zerotier/sdk/ResultCode; + * 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); /* diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index 0e9c4ee83..29b3aedf0 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -63,60 +63,58 @@ public class Node { /** * Node ID for JNI purposes. * Currently set to the now value passed in at the constructor - * - * -1 if the node has already been closed */ - private long nodeId; - - private final DataStoreGetListener getListener; - private final DataStorePutListener putListener; - private final PacketSender sender; - private final EventListener eventListener; - private final VirtualNetworkFrameListener frameListener; - private final VirtualNetworkConfigListener configListener; - private final PathChecker pathChecker; + 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 + * *

Note that this can take a few seconds the first time it's called, as it * will generate an identity.

* - * @param now Current clock in milliseconds * @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 + * @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 + * @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 Node(long now, - DataStoreGetListener getListener, - DataStorePutListener putListener, - PacketSender sender, - EventListener eventListener, - VirtualNetworkFrameListener frameListener, - VirtualNetworkConfigListener configListener, - PathChecker pathChecker) throws NodeException - { - this.nodeId = now; - - this.getListener = getListener; - this.putListener = putListener; - this.sender = sender; - this.eventListener = eventListener; - this.frameListener = frameListener; - this.configListener = configListener; - this.pathChecker = pathChecker; - - ResultCode rc = node_init(now); - if(rc != ResultCode.RESULT_OK) - { - // TODO: Throw Exception + public ResultCode init( + DataStoreGetListener getListener, + DataStorePutListener putListener, + PacketSender sender, + EventListener eventListener, + VirtualNetworkFrameListener frameListener, + VirtualNetworkConfigListener configListener, + PathChecker pathChecker) throws NodeException { + ResultCode rc = node_init( + nodeId, + getListener, + putListener, + sender, + eventListener, + frameListener, + configListener, + pathChecker); + if(rc != ResultCode.RESULT_OK) { throw new NodeException(rc.toString()); } - } + return rc; + } + + public boolean isInited() { + return node_isInited(nodeId); + } /** * Close this Node. @@ -124,10 +122,7 @@ public class Node { *

The Node object can no longer be used once this method is called.

*/ public void close() { - if(nodeId != -1) { - node_delete(nodeId); - nodeId = -1; - } + node_delete(nodeId); } @Override @@ -408,7 +403,17 @@ public class Node { // // function declarations for JNI // - private native ResultCode node_init(long now); + 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); From 7ef68a9d6a8a0df9588763b26707587185d67227 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 13:55:52 -0500 Subject: [PATCH 29/68] add Node.toString --- java/src/com/zerotier/sdk/Node.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index 29b3aedf0..6ae6aaa4e 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -130,6 +130,11 @@ public class Node { close(); } + @Override + public String toString() { + return "Node(" + nodeId + ")"; + } + /** * Process a frame from a virtual network port * From 63f70ba4659d61bac0d800a23b01b07b16c2f14c Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 18:05:08 -0500 Subject: [PATCH 30/68] make PeerPhysicalPath a plain data class --- java/jni/ZT_jnicache.cpp | 10 +--- java/jni/ZT_jnicache.h | 4 -- java/jni/ZT_jniutils.cpp | 25 +++++----- .../com/zerotier/sdk/PeerPhysicalPath.java | 48 ++++++++++++++----- 4 files changed, 48 insertions(+), 39 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 764f7f6c1..13087ae2e 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -114,10 +114,6 @@ jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -jfieldID PeerPhysicalPath_address_field; -jfieldID PeerPhysicalPath_lastReceive_field; -jfieldID PeerPhysicalPath_lastSend_field; -jfieldID PeerPhysicalPath_preferred_field; jfieldID Peer_address_field; jfieldID Peer_latency_field; jfieldID Peer_paths_field; @@ -211,7 +207,7 @@ void setupJNICache(JavaVM *vm) { 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, "", "()V")); + EXCEPTIONANDNULLCHECK(PeerPhysicalPath_ctor = env->GetMethodID(PeerPhysicalPath_class, "", "(Ljava/net/InetSocketAddress;JJZZ)V")); EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "()V")); EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "()V")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method = env->GetMethodID(VirtualNetworkConfigListener_class, "onNetworkConfigurationUpdated", "(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I")); @@ -236,10 +232,6 @@ void setupJNICache(JavaVM *vm) { // Instance fields // - EXCEPTIONANDNULLCHECK(PeerPhysicalPath_address_field = env->GetFieldID(PeerPhysicalPath_class, "address", "Ljava/net/InetSocketAddress;")); - EXCEPTIONANDNULLCHECK(PeerPhysicalPath_lastReceive_field = env->GetFieldID(PeerPhysicalPath_class, "lastReceive", "J")); - EXCEPTIONANDNULLCHECK(PeerPhysicalPath_lastSend_field = env->GetFieldID(PeerPhysicalPath_class, "lastSend", "J")); - EXCEPTIONANDNULLCHECK(PeerPhysicalPath_preferred_field = env->GetFieldID(PeerPhysicalPath_class, "preferred", "Z")); EXCEPTIONANDNULLCHECK(Peer_address_field = env->GetFieldID(Peer_class, "address", "J")); EXCEPTIONANDNULLCHECK(Peer_latency_field = env->GetFieldID(Peer_class, "latency", "I")); EXCEPTIONANDNULLCHECK(Peer_paths_field = env->GetFieldID(Peer_class, "paths", "[Lcom/zerotier/sdk/PeerPhysicalPath;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index 8dd176ab4..1c4ea210b 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -83,10 +83,6 @@ extern jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -extern jfieldID PeerPhysicalPath_address_field; -extern jfieldID PeerPhysicalPath_lastReceive_field; -extern jfieldID PeerPhysicalPath_lastSend_field; -extern jfieldID PeerPhysicalPath_preferred_field; extern jfieldID Peer_address_field; extern jfieldID Peer_latency_field; extern jfieldID Peer_paths_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 5f4b1f702..d6faafeb2 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -201,26 +201,23 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) { LOGV("newPeerPhysicalPath Called"); - jobject pppObject = env->NewObject(PeerPhysicalPath_class, PeerPhysicalPath_ctor); - if(env->ExceptionCheck() || pppObject == NULL) - { - LOGE("Error creating PPP object"); - return NULL; // out of memory - } - jobject addressObject = newInetSocketAddress(env, ppp.address); if(env->ExceptionCheck() || addressObject == NULL) { LOGE("Error creating InetSocketAddress object"); return NULL; } - env->SetObjectField(pppObject, PeerPhysicalPath_address_field, addressObject); - env->SetLongField(pppObject, PeerPhysicalPath_lastSend_field, ppp.lastSend); - env->SetLongField(pppObject, PeerPhysicalPath_lastReceive_field, ppp.lastReceive); - env->SetBooleanField(pppObject, PeerPhysicalPath_preferred_field, ppp.preferred); - - if(env->ExceptionCheck()) { - LOGE("Exception assigning fields to PeerPhysicalPath object"); + jobject pppObject = env->NewObject( + PeerPhysicalPath_class, + PeerPhysicalPath_ctor, + addressObject, + ppp.lastSend, + ppp.lastReceive, + ppp.preferred); + if(env->ExceptionCheck() || pppObject == NULL) + { + LOGE("Error creating PPP object"); + return NULL; } return pppObject; diff --git a/java/src/com/zerotier/sdk/PeerPhysicalPath.java b/java/src/com/zerotier/sdk/PeerPhysicalPath.java index 4aee98776..078d11509 100644 --- a/java/src/com/zerotier/sdk/PeerPhysicalPath.java +++ b/java/src/com/zerotier/sdk/PeerPhysicalPath.java @@ -31,48 +31,72 @@ import java.net.InetSocketAddress; /** * Physical network path to a peer + * + * Defined in ZeroTierOne.h as ZT_PeerPhysicalPath */ -public final class PeerPhysicalPath { - private InetSocketAddress address; - private long lastSend; - private long lastReceive; - private boolean fixed; - private boolean preferred; +public class PeerPhysicalPath { - private PeerPhysicalPath() {} + private final InetSocketAddress address; + + private final long lastSend; + + private final long lastReceive; + + private final boolean fixed; + + private final boolean preferred; + + public PeerPhysicalPath(InetSocketAddress address, long lastSend, long lastReceive, boolean fixed, 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.fixed = fixed; + this.preferred = preferred; + } + + @Override + public String toString() { + return "PeerPhysicalPath(" + address + ", " + lastSend + ", " + lastReceive + ", " + fixed + ", " + preferred + ")"; + } /** * Address of endpoint */ - public final InetSocketAddress address() { + public InetSocketAddress getAddress() { return address; } /** * Time of last send in milliseconds or 0 for never */ - public final long lastSend() { + public long getLastSend() { return lastSend; } /** * Time of last receive in milliseconds or 0 for never */ - public final long lastReceive() { + public long getLastReceive() { return lastReceive; } /** * Is path fixed? (i.e. not learned, static) */ - public final boolean isFixed() { + public boolean isFixed() { return fixed; } /** * Is path preferred? */ - public final boolean isPreferred() { + public boolean isPreferred() { return preferred; } } From 2de4c95446be03b952fd6261c530c811edd04aa4 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 18:18:00 -0500 Subject: [PATCH 31/68] remove unused PeerPhysicalPath.fixed --- java/jni/ZT_jnicache.cpp | 2 +- java/src/com/zerotier/sdk/PeerPhysicalPath.java | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 13087ae2e..ae1d6615d 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -207,7 +207,7 @@ void setupJNICache(JavaVM *vm) { 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, "", "(Ljava/net/InetSocketAddress;JJZZ)V")); + EXCEPTIONANDNULLCHECK(PeerPhysicalPath_ctor = env->GetMethodID(PeerPhysicalPath_class, "", "(Ljava/net/InetSocketAddress;JJZ)V")); EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "()V")); EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "()V")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method = env->GetMethodID(VirtualNetworkConfigListener_class, "onNetworkConfigurationUpdated", "(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I")); diff --git a/java/src/com/zerotier/sdk/PeerPhysicalPath.java b/java/src/com/zerotier/sdk/PeerPhysicalPath.java index 078d11509..f6d326425 100644 --- a/java/src/com/zerotier/sdk/PeerPhysicalPath.java +++ b/java/src/com/zerotier/sdk/PeerPhysicalPath.java @@ -42,11 +42,9 @@ public class PeerPhysicalPath { private final long lastReceive; - private final boolean fixed; - private final boolean preferred; - public PeerPhysicalPath(InetSocketAddress address, long lastSend, long lastReceive, boolean fixed, boolean preferred) { + public PeerPhysicalPath(InetSocketAddress address, long lastSend, long lastReceive, boolean preferred) { this.address = address; if (lastSend < 0) { throw new RuntimeException("lastSend < 0: " + lastSend); @@ -56,13 +54,12 @@ public class PeerPhysicalPath { throw new RuntimeException("lastReceive < 0: " + lastReceive); } this.lastReceive = lastReceive; - this.fixed = fixed; this.preferred = preferred; } @Override public String toString() { - return "PeerPhysicalPath(" + address + ", " + lastSend + ", " + lastReceive + ", " + fixed + ", " + preferred + ")"; + return "PeerPhysicalPath(" + address + ", " + lastSend + ", " + lastReceive + ", " + preferred + ")"; } /** @@ -86,13 +83,6 @@ public class PeerPhysicalPath { return lastReceive; } - /** - * Is path fixed? (i.e. not learned, static) - */ - public boolean isFixed() { - return fixed; - } - /** * Is path preferred? */ From f51ce077a3f99c87583bc442e90a3ad82d3c0a5a Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 18:32:19 -0500 Subject: [PATCH 32/68] add array functions --- java/jni/ZT_jniutils.cpp | 151 ++++++++++++++------------ java/jni/ZT_jniutils.h | 62 +++++++++++ java/jni/com_zerotierone_sdk_Node.cpp | 81 +++----------- 3 files changed, 160 insertions(+), 134 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index d6faafeb2..3f90c6f79 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -107,14 +107,14 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) case AF_INET6: { sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr; - jbyteArray buff = env->NewByteArray(16); - if(buff == NULL) + const unsigned char *bytes = reinterpret_cast(&ipv6->sin6_addr.s6_addr); + + jbyteArray buff = newByteArray(env, bytes, 16); + if(env->ExceptionCheck() || buff == NULL) { - LOGE("Error creating IPV6 byte array"); return NULL; } - env->SetByteArrayRegion(buff, 0, 16, (jbyte*)ipv6->sin6_addr.s6_addr); inetAddressObj = env->CallStaticObjectMethod( InetAddress_class, InetAddress_getByAddress_method, buff); } @@ -122,14 +122,13 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) case AF_INET: { sockaddr_in *ipv4 = (sockaddr_in*)&addr; - jbyteArray buff = env->NewByteArray(4); - if(buff == NULL) + const unsigned char *bytes = reinterpret_cast(&ipv4->sin_addr.s_addr); + jbyteArray buff = newByteArray(env, bytes, 4); + if(env->ExceptionCheck() || buff == NULL) { - LOGE("Error creating IPV4 byte array"); return NULL; } - env->SetByteArrayRegion(buff, 0, 4, (jbyte*)&ipv4->sin_addr); inetAddressObj = env->CallStaticObjectMethod( InetAddress_class, InetAddress_getByAddress_method, buff); } @@ -241,26 +240,7 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) env->SetIntField(peerObject, Peer_latency_field, peer.latency); env->SetObjectField(peerObject, Peer_role_field, createPeerRole(env, peer.role)); - jobjectArray arrayObject = env->NewObjectArray( - peer.pathCount, PeerPhysicalPath_class, NULL); - if(env->ExceptionCheck() || arrayObject == NULL) - { - LOGE("Error creating PeerPhysicalPath[] array"); - return NULL; - } - - for(unsigned int i = 0; i < peer.pathCount; ++i) - { - jobject path = newPeerPhysicalPath(env, peer.paths[i]); - - env->SetObjectArrayElement(arrayObject, i, path); - if(env->ExceptionCheck()) { - LOGE("exception assigning PeerPhysicalPath to array"); - break; - } - - env->DeleteLocalRef(path); - } + jobjectArray arrayObject = newPeerPhysicalPathArray(env, peer.paths, peer.pathCount); env->SetObjectField(peerObject, Peer_paths_field, arrayObject); @@ -305,49 +285,11 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) env->SetBooleanField(vnetConfigObj, VirtualNetworkConfig_broadcastEnabled_field, vnetConfig.broadcastEnabled); env->SetIntField(vnetConfigObj, VirtualNetworkConfig_portError_field, vnetConfig.portError); - jobjectArray assignedAddrArrayObj = env->NewObjectArray( - vnetConfig.assignedAddressCount, InetSocketAddress_class, NULL); - if(env->ExceptionCheck() || assignedAddrArrayObj == NULL) - { - LOGE("Error creating InetSocketAddress[] array"); - return NULL; - } - - for(unsigned int i = 0; i < vnetConfig.assignedAddressCount; ++i) - { - jobject inetAddrObj = newInetSocketAddress(env, vnetConfig.assignedAddresses[i]); - env->SetObjectArrayElement(assignedAddrArrayObj, i, inetAddrObj); - if(env->ExceptionCheck()) - { - LOGE("Error assigning InetSocketAddress to array"); - return NULL; - } - - env->DeleteLocalRef(inetAddrObj); - } + jobjectArray assignedAddrArrayObj = newInetSocketAddressArray(env, vnetConfig.assignedAddresses, vnetConfig.assignedAddressCount); env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_assignedAddresses_field, assignedAddrArrayObj); - jobjectArray routesArrayObj = env->NewObjectArray( - vnetConfig.routeCount, VirtualNetworkRoute_class, NULL); - if(env->ExceptionCheck() || routesArrayObj == NULL) - { - LOGE("Error creating VirtualNetworkRoute[] array"); - return NULL; - } - - for(unsigned int i = 0; i < vnetConfig.routeCount; ++i) - { - jobject routeObj = newVirtualNetworkRoute(env, vnetConfig.routes[i]); - env->SetObjectArrayElement(routesArrayObj, i, routeObj); - if(env->ExceptionCheck()) - { - LOGE("Error assigning VirtualNetworkRoute to array"); - return NULL; - } - - env->DeleteLocalRef(routeObj); - } + jobjectArray routesArrayObj = newVirtualNetworkRouteArray(env, vnetConfig.routes, vnetConfig.routeCount); env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_routes_field, routesArrayObj); @@ -456,3 +398,76 @@ jobject newNodeStatus(JNIEnv *env, const ZT_NodeStatus &status) { return nodeStatusObj; } + +jobjectArray newPeerArray(JNIEnv *env, const ZT_Peer *peers, size_t count) { + return newArrayObject(env, peers, count, Peer_class); +} + +jobjectArray newVirtualNetworkConfigArray(JNIEnv *env, const ZT_VirtualNetworkConfig *networks, size_t count) { + return newArrayObject(env, networks, count, VirtualNetworkConfig_class); +} + +jobjectArray newPeerPhysicalPathArray(JNIEnv *env, const ZT_PeerPhysicalPath *paths, size_t count) { + return newArrayObject(env, paths, count, PeerPhysicalPath_class); +} + +jobjectArray newInetSocketAddressArray(JNIEnv *env, const sockaddr_storage *addresses, size_t count) { + return newArrayObject(env, addresses, count, InetSocketAddress_class); +} + +jobjectArray newVirtualNetworkRouteArray(JNIEnv *env, const ZT_VirtualNetworkRoute *routes, size_t count) { + return newArrayObject(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(count); + const jbyte *jBytes = reinterpret_cast(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(count); + + jbyteArray byteArrayObj = env->NewByteArray(jCount); + if(byteArrayObj == NULL) + { + LOGE("NewByteArray returned NULL"); + return NULL; + } + + return byteArrayObj; +} diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index 164030ee5..bad093218 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -22,6 +22,8 @@ #include #include +#include // for numeric_limits + #if defined(__ANDROID__) #include @@ -75,6 +77,8 @@ } while (false) +const jsize JSIZE_MAX = std::numeric_limits::max(); + jobject createResultObject(JNIEnv *env, ZT_ResultCode code); jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status); jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type); @@ -98,4 +102,62 @@ 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 +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(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); + #endif // ZT_jniutils_h_ diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 4d52735e7..557a887be 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -164,20 +164,10 @@ namespace { return; } - jbyteArray dataArray = env->NewByteArray(frameLength); + const unsigned char *bytes = static_cast(frameData); + jbyteArray dataArray = newByteArray(env, bytes, frameLength); if(env->ExceptionCheck() || dataArray == NULL) { - LOGE("Couldn't create frame data array"); - return; - } - - void *data = env->GetPrimitiveArrayCritical(dataArray, NULL); - memcpy(data, frameData, frameLength); - env->ReleasePrimitiveArrayCritical(dataArray, data, 0); - - if(env->ExceptionCheck()) - { - LOGE("Error setting frame data to array"); return; } @@ -304,16 +294,13 @@ namespace { if (bufferLength >= 0) { LOGD("JNI: Write file: %s", p); - // set operation - jbyteArray bufferObj = env->NewByteArray(bufferLength); + const unsigned char *bytes = static_cast(buffer); + jbyteArray bufferObj = newByteArray(env, bytes, bufferLength); if(env->ExceptionCheck() || bufferObj == NULL) { - LOGE("Error creating byte array buffer!"); return; } - env->SetByteArrayRegion(bufferObj, 0, bufferLength, (jbyte*)buffer); - env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDataStorePut_method, nameStr, bufferObj, secure); @@ -375,10 +362,9 @@ namespace { return -103; // out of memory } - jbyteArray bufferObj = env->NewByteArray(bufferLength); - if(bufferObj == NULL) + jbyteArray bufferObj = newByteArray(env, bufferLength); + if(env->ExceptionCheck() || bufferObj == NULL) { - LOGE("Error creating byte[] buffer of size: %u", bufferLength); return -104; } @@ -424,8 +410,13 @@ namespace { } jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress); - jbyteArray bufferObj = env->NewByteArray(bufferSize); - env->SetByteArrayRegion(bufferObj, 0, bufferSize, (jbyte*)buffer); + const unsigned char *bytes = static_cast(buffer); + jbyteArray bufferObj = newByteArray(env, bytes, bufferSize); + if (env->ExceptionCheck() || bufferObj == NULL) + { + return -101; + } + int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj); LOGV("JNI Packet Sender returned: %d", retval); @@ -1207,29 +1198,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( return NULL; } - jobjectArray peerArrayObj = env->NewObjectArray( - peerList->peerCount, Peer_class, NULL); - - if(env->ExceptionCheck() || peerArrayObj == NULL) - { - LOGE("Error creating Peer[] array"); - ZT_Node_freeQueryResult(node, peerList); - return NULL; - } - - - for(unsigned int i = 0; i < peerList->peerCount; ++i) - { - jobject peerObj = newPeer(env, peerList->peers[i]); - env->SetObjectArrayElement(peerArrayObj, i, peerObj); - if(env->ExceptionCheck()) - { - LOGE("Error assigning Peer object to array"); - break; - } - - env->DeleteLocalRef(peerObj); - } + jobjectArray peerArrayObj = newPeerArray(env, peerList->peers, peerList->peerCount); ZT_Node_freeQueryResult(node, peerList); peerList = NULL; @@ -1254,27 +1223,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( return NULL; } - jobjectArray networkListObject = env->NewObjectArray( - networkList->networkCount, VirtualNetworkConfig_class, NULL); - if(env->ExceptionCheck() || networkListObject == NULL) - { - LOGE("Error creating VirtualNetworkConfig[] array"); - ZT_Node_freeQueryResult(node, networkList); - return NULL; - } - - for(unsigned int i = 0; i < networkList->networkCount; ++i) - { - jobject networkObject = newNetworkConfig(env, networkList->networks[i]); - env->SetObjectArrayElement(networkListObject, i, networkObject); - if(env->ExceptionCheck()) - { - LOGE("Error assigning VirtualNetworkConfig object to array"); - break; - } - - env->DeleteLocalRef(networkObject); - } + jobjectArray networkListObject = newVirtualNetworkConfigArray(env, networkList->networks, networkList->networkCount); ZT_Node_freeQueryResult(node, networkList); From 6cc055dbbab7e94094e062747b88af9968f1c8a9 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Tue, 31 Jan 2023 19:37:45 -0500 Subject: [PATCH 33/68] make Peer a plain data class --- java/jni/ZT_jnicache.cpp | 16 +------- java/jni/ZT_jnicache.h | 7 ---- java/jni/ZT_jniutils.cpp | 31 +++++++++------ java/src/com/zerotier/sdk/Peer.java | 60 ++++++++++++++++++++--------- 4 files changed, 63 insertions(+), 51 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index ae1d6615d..095b647ce 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -114,13 +114,6 @@ jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -jfieldID Peer_address_field; -jfieldID Peer_latency_field; -jfieldID Peer_paths_field; -jfieldID Peer_role_field; -jfieldID Peer_versionMajor_field; -jfieldID Peer_versionMinor_field; -jfieldID Peer_versionRev_field; jfieldID Version_major_field; jfieldID Version_minor_field; jfieldID Version_revision_field; @@ -208,7 +201,7 @@ void setupJNICache(JavaVM *vm) { 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, "", "(Ljava/net/InetSocketAddress;JJZ)V")); - EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "()V")); + EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "(JIIIILcom/zerotier/sdk/PeerRole;[Lcom/zerotier/sdk/PeerPhysicalPath;)V")); EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "()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, "", "()V")); @@ -232,13 +225,6 @@ void setupJNICache(JavaVM *vm) { // Instance fields // - EXCEPTIONANDNULLCHECK(Peer_address_field = env->GetFieldID(Peer_class, "address", "J")); - EXCEPTIONANDNULLCHECK(Peer_latency_field = env->GetFieldID(Peer_class, "latency", "I")); - EXCEPTIONANDNULLCHECK(Peer_paths_field = env->GetFieldID(Peer_class, "paths", "[Lcom/zerotier/sdk/PeerPhysicalPath;")); - EXCEPTIONANDNULLCHECK(Peer_role_field = env->GetFieldID(Peer_class, "role", "Lcom/zerotier/sdk/PeerRole;")); - EXCEPTIONANDNULLCHECK(Peer_versionMajor_field = env->GetFieldID(Peer_class, "versionMajor", "I")); - EXCEPTIONANDNULLCHECK(Peer_versionMinor_field = env->GetFieldID(Peer_class, "versionMinor", "I")); - EXCEPTIONANDNULLCHECK(Peer_versionRev_field = env->GetFieldID(Peer_class, "versionRev", "I")); EXCEPTIONANDNULLCHECK(Version_major_field = env->GetFieldID(Version_class, "major", "I")); EXCEPTIONANDNULLCHECK(Version_minor_field = env->GetFieldID(Version_class, "minor", "I")); EXCEPTIONANDNULLCHECK(Version_revision_field = env->GetFieldID(Version_class, "revision", "I")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index 1c4ea210b..0630d6355 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -83,13 +83,6 @@ extern jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -extern jfieldID Peer_address_field; -extern jfieldID Peer_latency_field; -extern jfieldID Peer_paths_field; -extern jfieldID Peer_role_field; -extern jfieldID Peer_versionMajor_field; -extern jfieldID Peer_versionMinor_field; -extern jfieldID Peer_versionRev_field; extern jfieldID Version_major_field; extern jfieldID Version_minor_field; extern jfieldID Version_revision_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 3f90c6f79..220f062d8 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -226,23 +226,32 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) { LOGV("newPeer called"); - jobject peerObject = env->NewObject(Peer_class, Peer_ctor); - if(env->ExceptionCheck() || peerObject == NULL) + jobject peerRoleObj = createPeerRole(env, peer.role); + if(env->ExceptionCheck() || peerRoleObj == NULL) { - LOGE("Error creating Peer object"); return NULL; // out of memory } - env->SetLongField(peerObject, Peer_address_field, (jlong)peer.address); - env->SetIntField(peerObject, Peer_versionMajor_field, peer.versionMajor); - env->SetIntField(peerObject, Peer_versionMinor_field, peer.versionMinor); - env->SetIntField(peerObject, Peer_versionRev_field, peer.versionRev); - env->SetIntField(peerObject, Peer_latency_field, peer.latency); - env->SetObjectField(peerObject, Peer_role_field, createPeerRole(env, peer.role)); - jobjectArray arrayObject = newPeerPhysicalPathArray(env, peer.paths, peer.pathCount); + if (env->ExceptionCheck() || arrayObject == NULL) { + return NULL; + } - env->SetObjectField(peerObject, Peer_paths_field, arrayObject); + jobject peerObject = env->NewObject( + Peer_class, + Peer_ctor, + peer.address, + peer.versionMajor, + peer.versionMinor, + peer.versionRev, + peer.latency, + peerRoleObj, + arrayObject); + if(env->ExceptionCheck() || peerObject == NULL) + { + LOGE("Error creating Peer object"); + return NULL; + } return peerObject; } diff --git a/java/src/com/zerotier/sdk/Peer.java b/java/src/com/zerotier/sdk/Peer.java index 63ef689b1..e3d544381 100644 --- a/java/src/com/zerotier/sdk/Peer.java +++ b/java/src/com/zerotier/sdk/Peer.java @@ -27,68 +27,92 @@ package com.zerotier.sdk; -import java.util.ArrayList; +import com.zerotier.sdk.util.StringUtils; + +import java.util.Arrays; /** - * Peer status result + * Peer status result buffer + * + * Defined in ZeroTierOne.h as ZT_Peer */ -public final class Peer { - private long address; - private int versionMajor; - private int versionMinor; - private int versionRev; - private int latency; - private PeerRole role; - private PeerPhysicalPath[] paths; +public class Peer { - private 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 final long address() { + public long getAddress() { return address; } /** * Remote major version or -1 if not known */ - public final int versionMajor() { + public int getVersionMajor() { return versionMajor; } /** * Remote minor version or -1 if not known */ - public final int versionMinor() { + public int getVersionMinor() { return versionMinor; } /** * Remote revision or -1 if not known */ - public final int versionRev() { + public int getVersionRev() { return versionRev; } /** * Last measured latency in milliseconds or zero if unknown */ - public final int latency() { + public int getLatency() { return latency; } /** * What trust hierarchy role does this device have? */ - public final PeerRole role() { + public PeerRole getRole() { return role; } /** * Known network paths to peer */ - public final PeerPhysicalPath[] paths() { + public PeerPhysicalPath[] getPaths() { return paths; } } From 6102c708555d8ca30dda9ed549e3a56791aec3b8 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 06:25:22 -0500 Subject: [PATCH 34/68] make Version a plain data class --- java/jni/ZT_jnicache.cpp | 8 +------ java/jni/ZT_jnicache.h | 3 --- java/jni/ZT_jniutils.cpp | 7 ++---- java/src/com/zerotier/sdk/Version.java | 31 ++++++++++++++++++++------ 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 095b647ce..2465d9c51 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -114,9 +114,6 @@ jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -jfieldID Version_major_field; -jfieldID Version_minor_field; -jfieldID Version_revision_field; jfieldID VirtualNetworkConfig_assignedAddresses_field; jfieldID VirtualNetworkConfig_bridge_field; jfieldID VirtualNetworkConfig_broadcastEnabled_field; @@ -202,7 +199,7 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(PathChecker_onPathLookup_method = env->GetMethodID(PathChecker_class, "onPathLookup", "(JI)Ljava/net/InetSocketAddress;")); EXCEPTIONANDNULLCHECK(PeerPhysicalPath_ctor = env->GetMethodID(PeerPhysicalPath_class, "", "(Ljava/net/InetSocketAddress;JJZ)V")); EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "(JIIIILcom/zerotier/sdk/PeerRole;[Lcom/zerotier/sdk/PeerPhysicalPath;)V")); - EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "()V")); + EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "(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, "", "()V")); EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_ctor = env->GetMethodID(VirtualNetworkDNS_class, "", "()V")); @@ -225,9 +222,6 @@ void setupJNICache(JavaVM *vm) { // Instance fields // - EXCEPTIONANDNULLCHECK(Version_major_field = env->GetFieldID(Version_class, "major", "I")); - EXCEPTIONANDNULLCHECK(Version_minor_field = env->GetFieldID(Version_class, "minor", "I")); - EXCEPTIONANDNULLCHECK(Version_revision_field = env->GetFieldID(Version_class, "revision", "I")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_assignedAddresses_field = env->GetFieldID(VirtualNetworkConfig_class, "assignedAddresses", "[Ljava/net/InetSocketAddress;")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_bridge_field = env->GetFieldID(VirtualNetworkConfig_class, "bridge", "Z")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_broadcastEnabled_field = env->GetFieldID(VirtualNetworkConfig_class, "broadcastEnabled", "Z")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index 0630d6355..730b8d89f 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -83,9 +83,6 @@ extern jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -extern jfieldID Version_major_field; -extern jfieldID Version_minor_field; -extern jfieldID Version_revision_field; extern jfieldID VirtualNetworkConfig_assignedAddresses_field; extern jfieldID VirtualNetworkConfig_bridge_field; extern jfieldID VirtualNetworkConfig_broadcastEnabled_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 220f062d8..2ef8a4b26 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -312,16 +312,13 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) 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); + jobject versionObj = env->NewObject(Version_class, Version_ctor, major, minor, rev); if(env->ExceptionCheck() || versionObj == NULL) { + LOGE("Error creating new Version object"); return NULL; } - env->SetIntField(versionObj, Version_major_field, (jint)major); - env->SetIntField(versionObj, Version_minor_field, (jint)minor); - env->SetIntField(versionObj, Version_revision_field, (jint)rev); - return versionObj; } diff --git a/java/src/com/zerotier/sdk/Version.java b/java/src/com/zerotier/sdk/Version.java index c93c25970..0dbe1d2a5 100644 --- a/java/src/com/zerotier/sdk/Version.java +++ b/java/src/com/zerotier/sdk/Version.java @@ -27,10 +27,27 @@ package com.zerotier.sdk; -public final class Version { - private Version() {} - - public int major = 0; - public int minor = 0; - public int revision = 0; -} \ No newline at end of file +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; + } +} From d5944ae69c80b983c0bbe378f0762d53df749c27 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Mon, 6 Feb 2023 07:27:44 -0500 Subject: [PATCH 35/68] fix ANDROID-42: copy/paste error --- java/src/com/zerotier/sdk/VirtualNetworkConfig.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index d1caee07d..ca25372e1 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -118,15 +118,15 @@ public final class VirtualNetworkConfig implements Comparable Date: Mon, 27 Feb 2023 10:20:43 -0500 Subject: [PATCH 36/68] fix ANDROID-49: VirtualNetworkConfig.equals is wrong --- java/src/com/zerotier/sdk/VirtualNetworkConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index ca25372e1..f8f3a02f3 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -154,7 +154,7 @@ public final class VirtualNetworkConfig implements Comparable Date: Thu, 2 Feb 2023 16:54:20 -0500 Subject: [PATCH 37/68] reimplement VirtualNetworkConfig.equals --- .../zerotier/sdk/VirtualNetworkConfig.java | 152 ++++++++++++------ 1 file changed, 100 insertions(+), 52 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index f8f3a02f3..1eff5a602 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -31,11 +31,9 @@ import android.util.Log; import com.zerotier.sdk.util.StringUtils; -import java.lang.Comparable; -import java.lang.Override; -import java.lang.String; -import java.util.ArrayList; import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; public final class VirtualNetworkConfig implements Comparable { @@ -64,115 +62,165 @@ public final class VirtualNetworkConfig implements Comparable aaCurrent = new ArrayList<>(); - ArrayList aaNew = new ArrayList<>(); - for (InetSocketAddress s : assignedAddresses) { - aaCurrent.add(s.toString()); - } - for (InetSocketAddress s : cfg.assignedAddresses) { - aaNew.add(s.toString()); - } - Collections.sort(aaCurrent); - Collections.sort(aaNew); - boolean aaEqual = aaCurrent.equals(aaNew); + @Override + public boolean equals(Object o) { - ArrayList rCurrent = new ArrayList<>(); - ArrayList rNew = new ArrayList<>(); - for (VirtualNetworkRoute r : routes) { - rCurrent.add(r.toString()); + if (!(o instanceof VirtualNetworkConfig)) { + return false; } - for (VirtualNetworkRoute r : cfg.routes) { - rNew.add(r.toString()); - } - Collections.sort(rCurrent); - Collections.sort(rNew); - boolean routesEqual = rCurrent.equals(rNew); + + VirtualNetworkConfig cfg = (VirtualNetworkConfig) o; if (this.nwid != cfg.nwid) { - Log.i(TAG, "nwid Changed. Old: " + StringUtils.networkIdToString(this.nwid) + " (" + this.nwid + "), " + + Log.i(TAG, "NetworkID Changed. Old: " + StringUtils.networkIdToString(this.nwid) + " (" + this.nwid + "), " + "New: " + StringUtils.networkIdToString(cfg.nwid) + " (" + cfg.nwid + ")"); + + return false; } + if (this.mac != cfg.mac) { Log.i(TAG, "MAC Changed. Old: " + StringUtils.macAddressToString(this.mac) + ", New: " + StringUtils.macAddressToString(cfg.mac)); + + return false; } if (!this.name.equals(cfg.name)) { - Log.i(TAG, "Name Changed. Old: " + this.name + " New: "+ cfg.name); + Log.i(TAG, "Name Changed. Old: " + this.name + ", New: " + cfg.name); + + return false; } - if (!this.type.equals(cfg.type)) { - Log.i(TAG, "TYPE changed. Old " + this.type + ", New: " + cfg.type); + if (this.status != cfg.status) { + Log.i(TAG, "Status Changed. Old: " + this.status + ", New: " + cfg.status); + + return false; + } + + if (this.type != cfg.type) { + Log.i(TAG, "Type changed. Old " + this.type + ", New: " + cfg.type); + + return false; } if (this.mtu != cfg.mtu) { - Log.i(TAG, "MTU Changed. Old: " + this.mtu + ", New: " + cfg.mtu); + Log.i(TAG, "MTU Changed. Old: " + this.mtu + ", New: " + cfg.mtu); + + return false; } if (this.dhcp != cfg.dhcp) { Log.i(TAG, "DHCP Flag Changed. Old: " + this.dhcp + ", New: " + cfg.dhcp); + + return false; } if (this.bridge != cfg.bridge) { Log.i(TAG, "Bridge Flag Changed. Old: " + this.bridge + ", New: " + cfg.bridge); + + return false; } if (this.broadcastEnabled != cfg.broadcastEnabled) { - Log.i(TAG, "Broadcast Flag Changed. Old: "+ this.broadcastEnabled +", New: " + cfg.broadcastEnabled); + Log.i(TAG, "Broadcast Flag Changed. Old: "+ this.broadcastEnabled + ", New: " + cfg.broadcastEnabled); + + return false; } if (this.portError != cfg.portError) { Log.i(TAG, "Port Error Changed. Old: " + this.portError + ", New: " + cfg.portError); + + return false; } if (this.enabled != cfg.enabled) { Log.i(TAG, "Enabled Changed. Old: " + this.enabled + ", New: " + cfg.enabled); + + return false; } - if (!aaEqual) { + if (this.netconfRevision != cfg.netconfRevision) { + Log.i(TAG, "NetConfRevision Changed. Old: " + this.netconfRevision + ", New: " + cfg.netconfRevision); + + return false; + } + + if (!Arrays.equals(assignedAddresses, cfg.assignedAddresses)) { + + ArrayList aaCurrent = new ArrayList<>(); + ArrayList aaNew = new ArrayList<>(); + for (InetSocketAddress s : assignedAddresses) { + aaCurrent.add(s.toString()); + } + for (InetSocketAddress s : cfg.assignedAddresses) { + aaNew.add(s.toString()); + } + Collections.sort(aaCurrent); + Collections.sort(aaNew); + Log.i(TAG, "Assigned Addresses Changed"); Log.i(TAG, "Old:"); for (String s : aaCurrent) { Log.i(TAG, " " + s); } + Log.i(TAG, ""); Log.i(TAG, "New:"); for (String s : aaNew) { Log.i(TAG, " " +s); } + Log.i(TAG, ""); + + return false; } - if (!routesEqual) { + if (!Arrays.equals(routes, cfg.routes)) { + + ArrayList rCurrent = new ArrayList<>(); + ArrayList rNew = new ArrayList<>(); + for (VirtualNetworkRoute r : routes) { + rCurrent.add(r.toString()); + } + for (VirtualNetworkRoute r : cfg.routes) { + rNew.add(r.toString()); + } + Collections.sort(rCurrent); + Collections.sort(rNew); + Log.i(TAG, "Managed Routes Changed"); Log.i(TAG, "Old:"); for (String s : rCurrent) { Log.i(TAG, " " + s); } + Log.i(TAG, ""); Log.i(TAG, "New:"); for (String s : rNew) { Log.i(TAG, " " + s); } + Log.i(TAG, ""); + + return false; } - boolean dnsEquals = false; - if (this.dns == null && cfg.dns == null) { - dnsEquals = true; - } else if (this.dns != null) { - dnsEquals = this.dns.equals(cfg.dns); + boolean dnsEquals; + if (this.dns == null) { + //noinspection RedundantIfStatement + if (cfg.dns == null) { + dnsEquals = true; + } else { + dnsEquals = false; + } + } else { + if (cfg.dns == null) { + dnsEquals = false; + } else { + dnsEquals = this.dns.equals(cfg.dns); + } } - return this.nwid == cfg.nwid && - this.mac == cfg.mac && - this.name.equals(cfg.name) && - this.status.equals(cfg.status) && - this.type.equals(cfg.type) && - this.mtu == cfg.mtu && - this.dhcp == cfg.dhcp && - this.bridge == cfg.bridge && - this.broadcastEnabled == cfg.broadcastEnabled && - this.portError == cfg.portError && - this.enabled == cfg.enabled && - dnsEquals && - aaEqual && routesEqual; + if (!dnsEquals) { + return false; + } + + return true; } public int compareTo(VirtualNetworkConfig cfg) { From 7392a32cd82fe0ae65a3d6e75dbe41291043a574 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:57:20 -0500 Subject: [PATCH 38/68] reimplement VirtualNetworkConfig.compareTo --- java/src/com/zerotier/sdk/VirtualNetworkConfig.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index 1eff5a602..bc41cfd41 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -223,12 +223,9 @@ public final class VirtualNetworkConfig implements Comparable cfg.nwid ? 1 : -1; - } + return Long.compare(this.nwid, cfg.nwid); } /** From e060ae3176fd95636abe859058b8f304f25e89cd Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:59:59 -0500 Subject: [PATCH 39/68] add VirtualNetworkConfig.hashCode --- .../zerotier/sdk/VirtualNetworkConfig.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index bc41cfd41..8793a9657 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -228,6 +228,29 @@ public final class VirtualNetworkConfig implements Comparable>> 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 + (enabled ? 1 : 0); + 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 */ From 54fd7c7e9ae0296fb90661df68a7dbfc35ae4492 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 06:36:34 -0500 Subject: [PATCH 40/68] make VirtualNetworkConfig a plain data class --- java/jni/ZT_jnicache.cpp | 30 +---- java/jni/ZT_jnicache.h | 14 --- java/jni/ZT_jniutils.cpp | 64 ++++++---- java/jni/com_zerotierone_sdk_Node.cpp | 12 +- .../zerotier/sdk/VirtualNetworkConfig.java | 114 +++++++++++++----- 5 files changed, 130 insertions(+), 104 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 2465d9c51..9c3b82456 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -114,20 +114,6 @@ jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -jfieldID VirtualNetworkConfig_assignedAddresses_field; -jfieldID VirtualNetworkConfig_bridge_field; -jfieldID VirtualNetworkConfig_broadcastEnabled_field; -jfieldID VirtualNetworkConfig_dhcp_field; -jfieldID VirtualNetworkConfig_dns_field; -jfieldID VirtualNetworkConfig_enabled_field; -jfieldID VirtualNetworkConfig_mac_field; -jfieldID VirtualNetworkConfig_mtu_field; -jfieldID VirtualNetworkConfig_name_field; -jfieldID VirtualNetworkConfig_nwid_field; -jfieldID VirtualNetworkConfig_portError_field; -jfieldID VirtualNetworkConfig_routes_field; -jfieldID VirtualNetworkConfig_status_field; -jfieldID VirtualNetworkConfig_type_field; jfieldID VirtualNetworkDNS_domain_field; jfieldID VirtualNetworkDNS_servers_field; jfieldID VirtualNetworkRoute_flags_field; @@ -201,7 +187,7 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "(JIIIILcom/zerotier/sdk/PeerRole;[Lcom/zerotier/sdk/PeerPhysicalPath;)V")); EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "(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, "", "()V")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_ctor = env->GetMethodID(VirtualNetworkConfig_class, "", "(JJLjava/lang/String;Lcom/zerotier/sdk/VirtualNetworkStatus;Lcom/zerotier/sdk/VirtualNetworkType;IZZZIZJ[Ljava/net/InetSocketAddress;[Lcom/zerotier/sdk/VirtualNetworkRoute;Lcom/zerotier/sdk/VirtualNetworkDNS;)V")); EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_ctor = env->GetMethodID(VirtualNetworkDNS_class, "", "()V")); EXCEPTIONANDNULLCHECK(VirtualNetworkFrameListener_onVirtualNetworkFrame_method = env->GetMethodID(VirtualNetworkFrameListener_class, "onVirtualNetworkFrame", "(JJJJJ[B)V")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_ctor = env->GetMethodID(VirtualNetworkRoute_class, "", "()V")); @@ -222,20 +208,6 @@ void setupJNICache(JavaVM *vm) { // Instance fields // - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_assignedAddresses_field = env->GetFieldID(VirtualNetworkConfig_class, "assignedAddresses", "[Ljava/net/InetSocketAddress;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_bridge_field = env->GetFieldID(VirtualNetworkConfig_class, "bridge", "Z")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_broadcastEnabled_field = env->GetFieldID(VirtualNetworkConfig_class, "broadcastEnabled", "Z")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_dhcp_field = env->GetFieldID(VirtualNetworkConfig_class, "dhcp", "Z")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_dns_field = env->GetFieldID(VirtualNetworkConfig_class, "dns", "Lcom/zerotier/sdk/VirtualNetworkDNS;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_enabled_field = env->GetFieldID(VirtualNetworkConfig_class, "enabled", "Z")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_mac_field = env->GetFieldID(VirtualNetworkConfig_class, "mac", "J")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_mtu_field = env->GetFieldID(VirtualNetworkConfig_class, "mtu", "I")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_name_field = env->GetFieldID(VirtualNetworkConfig_class, "name", "Ljava/lang/String;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_nwid_field = env->GetFieldID(VirtualNetworkConfig_class, "nwid", "J")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_portError_field = env->GetFieldID(VirtualNetworkConfig_class, "portError", "I")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_routes_field = env->GetFieldID(VirtualNetworkConfig_class, "routes", "[Lcom/zerotier/sdk/VirtualNetworkRoute;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_status_field = env->GetFieldID(VirtualNetworkConfig_class, "status", "Lcom/zerotier/sdk/VirtualNetworkStatus;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_type_field = env->GetFieldID(VirtualNetworkConfig_class, "type", "Lcom/zerotier/sdk/VirtualNetworkType;")); EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_domain_field = env->GetFieldID(VirtualNetworkDNS_class, "domain", "Ljava/lang/String;")); EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_servers_field = env->GetFieldID(VirtualNetworkDNS_class, "servers", "Ljava/util/ArrayList;")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_flags_field = env->GetFieldID(VirtualNetworkRoute_class, "flags", "I")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index 730b8d89f..d230ad6cd 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -83,20 +83,6 @@ extern jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -extern jfieldID VirtualNetworkConfig_assignedAddresses_field; -extern jfieldID VirtualNetworkConfig_bridge_field; -extern jfieldID VirtualNetworkConfig_broadcastEnabled_field; -extern jfieldID VirtualNetworkConfig_dhcp_field; -extern jfieldID VirtualNetworkConfig_dns_field; -extern jfieldID VirtualNetworkConfig_enabled_field; -extern jfieldID VirtualNetworkConfig_mac_field; -extern jfieldID VirtualNetworkConfig_mtu_field; -extern jfieldID VirtualNetworkConfig_name_field; -extern jfieldID VirtualNetworkConfig_nwid_field; -extern jfieldID VirtualNetworkConfig_portError_field; -extern jfieldID VirtualNetworkConfig_routes_field; -extern jfieldID VirtualNetworkConfig_status_field; -extern jfieldID VirtualNetworkConfig_type_field; extern jfieldID VirtualNetworkDNS_domain_field; extern jfieldID VirtualNetworkDNS_servers_field; extern jfieldID VirtualNetworkRoute_flags_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 2ef8a4b26..a7ca7e10b 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -258,54 +258,66 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) { - jobject vnetConfigObj = env->NewObject(VirtualNetworkConfig_class, VirtualNetworkConfig_ctor); - if(env->ExceptionCheck() || vnetConfigObj == NULL) - { - LOGE("Error creating new VirtualNetworkConfig object"); - return NULL; - } - - env->SetLongField(vnetConfigObj, VirtualNetworkConfig_nwid_field, vnetConfig.nwid); - env->SetLongField(vnetConfigObj, VirtualNetworkConfig_mac_field, vnetConfig.mac); jstring nameStr = env->NewStringUTF(vnetConfig.name); if(env->ExceptionCheck() || nameStr == NULL) { + LOGE("Exception creating new string"); return NULL; // out of memory } - env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_name_field, nameStr); jobject statusObject = createVirtualNetworkStatus(env, vnetConfig.status); if(env->ExceptionCheck() || statusObject == NULL) { return NULL; } - env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_status_field, statusObject); jobject typeObject = createVirtualNetworkType(env, vnetConfig.type); if(env->ExceptionCheck() || typeObject == NULL) { return NULL; } - env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_type_field, typeObject); - - env->SetIntField(vnetConfigObj, VirtualNetworkConfig_mtu_field, (int)vnetConfig.mtu); - env->SetBooleanField(vnetConfigObj, VirtualNetworkConfig_dhcp_field, vnetConfig.dhcp); - env->SetBooleanField(vnetConfigObj, VirtualNetworkConfig_bridge_field, vnetConfig.bridge); - env->SetBooleanField(vnetConfigObj, VirtualNetworkConfig_broadcastEnabled_field, vnetConfig.broadcastEnabled); - env->SetIntField(vnetConfigObj, VirtualNetworkConfig_portError_field, vnetConfig.portError); jobjectArray assignedAddrArrayObj = newInetSocketAddressArray(env, vnetConfig.assignedAddresses, vnetConfig.assignedAddressCount); - - env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_assignedAddresses_field, assignedAddrArrayObj); + if (env->ExceptionCheck() || assignedAddrArrayObj == NULL) { + return NULL; + } jobjectArray routesArrayObj = newVirtualNetworkRouteArray(env, vnetConfig.routes, vnetConfig.routeCount); - - env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_routes_field, routesArrayObj); - - jobject dnsObj = newVirtualNetworkDNS(env, vnetConfig.dns); - if (dnsObj != NULL) { - env->SetObjectField(vnetConfigObj, VirtualNetworkConfig_dns_field, dnsObj); + 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, + vnetConfig.nwid, + vnetConfig.mac, + nameStr, + statusObject, + typeObject, + vnetConfig.mtu, + vnetConfig.dhcp, + vnetConfig.bridge, + vnetConfig.broadcastEnabled, + vnetConfig.portError, + vnetConfig.netconfRevision, + assignedAddrArrayObj, + routesArrayObj, + dnsObj); + if(env->ExceptionCheck() || vnetConfigObj == NULL) + { + LOGE("Error creating new VirtualNetworkConfig object"); + return NULL; + } + return vnetConfigObj; } diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 557a887be..a143d9210 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -124,13 +124,17 @@ namespace { return -101; } - jobject networkConfigObject = newNetworkConfig(env, *config); - if(networkConfigObject == NULL) - { - LOGE("Error creating VirtualNetworkConfig object"); + if (config == NULL) { + LOGE("Config is NULL"); return -102; } + jobject networkConfigObject = newNetworkConfig(env, *config); + if(env->ExceptionCheck() || networkConfigObject == NULL) + { + return -103; + } + return env->CallIntMethod( ref->configListener, VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method, diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index 8793a9657..51e8e8555 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -36,30 +36,75 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -public final class VirtualNetworkConfig implements Comparable { +/** + * Virtual network configuration + * + * Defined in ZeroTierOne.h as ZT_VirtualNetworkConfig + */ +public class VirtualNetworkConfig implements Comparable { + 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 long nwid; - private long mac; - private String name; - private VirtualNetworkStatus status; - private VirtualNetworkType type; - private int mtu; - private boolean dhcp; - private boolean bridge; - private boolean broadcastEnabled; - private int portError; - private boolean enabled; - private long netconfRevision; - private InetSocketAddress[] assignedAddresses; - private VirtualNetworkRoute[] routes; - private VirtualNetworkDNS dns; + private final long nwid; - private VirtualNetworkConfig() { + 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 boolean enabled; + + 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, boolean enabled, 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.enabled = enabled; + 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 + ", " + enabled + ", " + netconfRevision + ", " + Arrays.toString(assignedAddresses) + ", " + Arrays.toString(routes) + ", " + dns + ")"; } @Override @@ -254,42 +299,42 @@ public final class VirtualNetworkConfig implements Comparable */ - public final boolean isDhcpAvailable() { + public boolean isDhcp() { return dhcp; } @@ -310,21 +355,21 @@ public final class VirtualNetworkConfig implements ComparableThis is informational. If this is false, bridged packets will simply * be dropped and bridging won't work.

*/ - public final boolean isBridgeEnabled() { + public boolean isBridge() { return bridge; } /** * If true, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic */ - public final boolean broadcastEnabled() { + 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 final int portError() { + public int getPortError() { return portError; } @@ -333,7 +378,7 @@ public final class VirtualNetworkConfig implements ComparableIf this is zero, it means we're still waiting for our netconf.

*/ - public final long netconfRevision() { + public long getNetconfRevision() { return netconfRevision; } @@ -347,7 +392,7 @@ public final class VirtualNetworkConfig implements Comparable Date: Wed, 1 Feb 2023 07:57:35 -0500 Subject: [PATCH 41/68] remove unused VirtualNetworkConfig.enabled --- java/jni/ZT_jnicache.cpp | 2 +- .../src/com/zerotier/sdk/VirtualNetworkConfig.java | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 9c3b82456..e7f27ce52 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -187,7 +187,7 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "(JIIIILcom/zerotier/sdk/PeerRole;[Lcom/zerotier/sdk/PeerPhysicalPath;)V")); EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "(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, "", "(JJLjava/lang/String;Lcom/zerotier/sdk/VirtualNetworkStatus;Lcom/zerotier/sdk/VirtualNetworkType;IZZZIZJ[Ljava/net/InetSocketAddress;[Lcom/zerotier/sdk/VirtualNetworkRoute;Lcom/zerotier/sdk/VirtualNetworkDNS;)V")); + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_ctor = env->GetMethodID(VirtualNetworkConfig_class, "", "(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, "", "()V")); EXCEPTIONANDNULLCHECK(VirtualNetworkFrameListener_onVirtualNetworkFrame_method = env->GetMethodID(VirtualNetworkFrameListener_class, "onVirtualNetworkFrame", "(JJJJJ[B)V")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_ctor = env->GetMethodID(VirtualNetworkRoute_class, "", "()V")); diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index 51e8e8555..0e7337893 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -68,8 +68,6 @@ public class VirtualNetworkConfig implements Comparable { private final int portError; - private final boolean enabled; - private final long netconfRevision; private final InetSocketAddress[] assignedAddresses; @@ -78,7 +76,7 @@ public class VirtualNetworkConfig implements Comparable { 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, boolean enabled, long netconfRevision, InetSocketAddress[] assignedAddresses, VirtualNetworkRoute[] routes, 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; @@ -95,7 +93,6 @@ public class VirtualNetworkConfig implements Comparable { if (netconfRevision < 0) { throw new RuntimeException("netconfRevision < 0: " + netconfRevision); } - this.enabled = enabled; this.netconfRevision = netconfRevision; this.assignedAddresses = assignedAddresses; this.routes = routes; @@ -104,7 +101,7 @@ public class VirtualNetworkConfig implements Comparable { @Override public String toString() { - return "VirtualNetworkConfig(" + StringUtils.networkIdToString(nwid) + ", " + StringUtils.macAddressToString(mac) + ", " + name + ", " + status + ", " + type + ", " + mtu + ", " + dhcp + ", " + bridge + ", " + broadcastEnabled + ", " + portError + ", " + enabled + ", " + netconfRevision + ", " + Arrays.toString(assignedAddresses) + ", " + Arrays.toString(routes) + ", " + dns + ")"; + 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 @@ -177,12 +174,6 @@ public class VirtualNetworkConfig implements Comparable { return false; } - if (this.enabled != cfg.enabled) { - Log.i(TAG, "Enabled Changed. Old: " + this.enabled + ", New: " + cfg.enabled); - - return false; - } - if (this.netconfRevision != cfg.netconfRevision) { Log.i(TAG, "NetConfRevision Changed. Old: " + this.netconfRevision + ", New: " + cfg.netconfRevision); @@ -287,7 +278,6 @@ public class VirtualNetworkConfig implements Comparable { result = 37 * result + (bridge ? 1 : 0); result = 37 * result + (broadcastEnabled ? 1 : 0); result = 37 * result + portError; - result = 37 * result + (enabled ? 1 : 0); result = 37 * result + (int) (netconfRevision ^ (netconfRevision >>> 32)); result = 37 * result + Arrays.hashCode(assignedAddresses); result = 37 * result + Arrays.hashCode(routes); From 686561dc5b5c905ce956b5f4ad5d3956793c7ee7 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 17:01:45 -0500 Subject: [PATCH 42/68] reimplement VirtualNetworkDNS.equals --- .../com/zerotier/sdk/VirtualNetworkDNS.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkDNS.java b/java/src/com/zerotier/sdk/VirtualNetworkDNS.java index 7046fd424..8b74cd179 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkDNS.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkDNS.java @@ -14,9 +14,28 @@ public class VirtualNetworkDNS implements Comparable { public VirtualNetworkDNS() {} - public boolean equals(VirtualNetworkDNS o) { - if (o == null) return false; - return domain.equals(o.domain) && servers.equals(o.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; + } + + if (!servers.equals(d.servers)) { + return false; + } + + return true; } @Override From 8b0be5c1fc1d40b48cf969b9a0b1b2c8867cbfb6 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 17:03:33 -0500 Subject: [PATCH 43/68] add VirtualNetworkDNS.hashCode --- java/src/com/zerotier/sdk/VirtualNetworkDNS.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkDNS.java b/java/src/com/zerotier/sdk/VirtualNetworkDNS.java index 8b74cd179..48b9ffcd0 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkDNS.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkDNS.java @@ -43,6 +43,16 @@ public class VirtualNetworkDNS implements Comparable { 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 getSearchDomain() { return domain; } public ArrayList getServers() { return servers; } From f9a27d677897e22e55cd509eca78381c204bb4d9 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 06:40:42 -0500 Subject: [PATCH 44/68] make VirtualNetworkDNS a plain data class --- java/jni/ZT_jnicache.cpp | 6 +- java/jni/ZT_jnicache.h | 2 - java/jni/ZT_jniutils.cpp | 63 +++++++++++++------ .../com/zerotier/sdk/VirtualNetworkDNS.java | 28 +++++++-- 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index e7f27ce52..f89a7d499 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -114,8 +114,6 @@ jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -jfieldID VirtualNetworkDNS_domain_field; -jfieldID VirtualNetworkDNS_servers_field; jfieldID VirtualNetworkRoute_flags_field; jfieldID VirtualNetworkRoute_metric_field; jfieldID VirtualNetworkRoute_target_field; @@ -188,7 +186,7 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "(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, "", "(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, "", "()V")); + EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_ctor = env->GetMethodID(VirtualNetworkDNS_class, "", "(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, "", "()V")); @@ -208,8 +206,6 @@ void setupJNICache(JavaVM *vm) { // Instance fields // - EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_domain_field = env->GetFieldID(VirtualNetworkDNS_class, "domain", "Ljava/lang/String;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_servers_field = env->GetFieldID(VirtualNetworkDNS_class, "servers", "Ljava/util/ArrayList;")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_flags_field = env->GetFieldID(VirtualNetworkRoute_class, "flags", "I")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_metric_field = env->GetFieldID(VirtualNetworkRoute_class, "metric", "I")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_target_field = env->GetFieldID(VirtualNetworkRoute_class, "target", "Ljava/net/InetSocketAddress;")); diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index d230ad6cd..4c6703d02 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -83,8 +83,6 @@ extern jmethodID VirtualNetworkType_fromInt_method; // Instance fields // -extern jfieldID VirtualNetworkDNS_domain_field; -extern jfieldID VirtualNetworkDNS_servers_field; extern jfieldID VirtualNetworkRoute_flags_field; extern jfieldID VirtualNetworkRoute_metric_field; extern jfieldID VirtualNetworkRoute_target_field; diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index a7ca7e10b..bd1968442 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -353,37 +353,64 @@ jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route) return routeObj; } +// +// may return NULL +// jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) { - jobject dnsObj = env->NewObject(VirtualNetworkDNS_class, VirtualNetworkDNS_ctor); - if(env->ExceptionCheck() || dnsObj == NULL) { + if (strlen(dns.domain) == 0) { + LOGD("dns.domain is empty; returning NULL"); return NULL; } - if (strlen(dns.domain) > 0) { + jstring domain = env->NewStringUTF(dns.domain); + if (env->ExceptionCheck() || domain == NULL) { + LOGE("Exception creating new string"); + return NULL; + } - jstring domain = env->NewStringUTF(dns.domain); + jobject addrList = env->NewObject(ArrayList_class, ArrayList_ctor, 0); + if (env->ExceptionCheck() || addrList == NULL) { + LOGE("Exception creating new ArrayList"); + return NULL; + } - jobject addrArray = env->NewObject(ArrayList_class, ArrayList_ctor, 0); + for (int i = 0; i < ZT_MAX_DNS_SERVERS; ++i) { //NOLINT - struct sockaddr_storage nullAddr; - memset(&nullAddr, 0, sizeof(struct sockaddr_storage)); - for(int i = 0; i < ZT_MAX_DNS_SERVERS; ++i) { - struct sockaddr_storage tmp = dns.server_addr[i]; + struct sockaddr_storage tmp = dns.server_addr[i]; - if (memcmp(&tmp, &nullAddr, sizeof(struct sockaddr_storage)) != 0) { - jobject addr = newInetSocketAddress(env, tmp); - env->CallBooleanMethod(addrArray, ArrayList_add_method, addr); - env->DeleteLocalRef(addr); - } + // + // may be NULL + // + jobject addr = newInetSocketAddress(env, tmp); + if (env->ExceptionCheck()) { + return NULL; } - env->SetObjectField(dnsObj, VirtualNetworkDNS_domain_field, domain); - env->SetObjectField(dnsObj, VirtualNetworkDNS_servers_field, addrArray); + if (addr == NULL) { + continue; + } - return dnsObj; + env->CallBooleanMethod(addrList, ArrayList_add_method, addr); + if(env->ExceptionCheck()) + { + LOGE("Exception calling add"); + return NULL; + } + + env->DeleteLocalRef(addr); } - return NULL; + + jobject dnsObj = env->NewObject( + VirtualNetworkDNS_class, + VirtualNetworkDNS_ctor, + domain, + addrList); + if (env->ExceptionCheck() || dnsObj == NULL) { + LOGE("Exception creating new VirtualNetworkDNS"); + return NULL; + } + return dnsObj; } jobject newNodeStatus(JNIEnv *env, const ZT_NodeStatus &status) { diff --git a/java/src/com/zerotier/sdk/VirtualNetworkDNS.java b/java/src/com/zerotier/sdk/VirtualNetworkDNS.java index 48b9ffcd0..6e4bb3d22 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkDNS.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkDNS.java @@ -8,11 +8,25 @@ package com.zerotier.sdk; import java.net.InetSocketAddress; import java.util.ArrayList; +/** + * DNS configuration to be pushed on a virtual network + * + * Defined in ZeroTierOne.h as ZT_VirtualNetworkDNS + */ public class VirtualNetworkDNS implements Comparable { - private String domain; - private ArrayList servers; - public VirtualNetworkDNS() {} + private final String domain; + private final ArrayList servers; + + public VirtualNetworkDNS(String domain, ArrayList servers) { + this.domain = domain; + this.servers = servers; + } + + @Override + public String toString() { + return "VirtualNetworkDNS(" + domain + ", " + servers + ")"; + } @Override public boolean equals(Object o) { @@ -53,7 +67,11 @@ public class VirtualNetworkDNS implements Comparable { return result; } - public String getSearchDomain() { return domain; } + public String getDomain() { + return domain; + } - public ArrayList getServers() { return servers; } + public ArrayList getServers() { + return servers; + } } From 86122e164651e59879af39f05b11f01671cb4dc9 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 17:05:52 -0500 Subject: [PATCH 45/68] reimplement VirtualNetworkRoute.equals --- .../com/zerotier/sdk/VirtualNetworkRoute.java | 77 +++++++++++++------ 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java index 8dd700c09..d8bc6fb72 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java @@ -73,36 +73,63 @@ public final class VirtualNetworkRoute implements Comparable Date: Thu, 2 Feb 2023 17:12:55 -0500 Subject: [PATCH 46/68] reimplement VirtualNetworkRoute.compareTo --- java/src/com/zerotier/sdk/VirtualNetworkRoute.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java index d8bc6fb72..6c23d8bad 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java @@ -69,9 +69,9 @@ public final class VirtualNetworkRoute implements Comparable Date: Thu, 2 Feb 2023 17:14:48 -0500 Subject: [PATCH 47/68] reimplement VirtualNetworkRoute.toString --- java/src/com/zerotier/sdk/VirtualNetworkRoute.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java index 6c23d8bad..1d24ce83b 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java @@ -58,14 +58,9 @@ public final class VirtualNetworkRoute implements Comparable Date: Thu, 2 Feb 2023 17:15:43 -0500 Subject: [PATCH 48/68] add VirtualNetworkRoute.hashCode --- java/src/com/zerotier/sdk/VirtualNetworkRoute.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java index 1d24ce83b..02f08210e 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java @@ -127,4 +127,16 @@ public final class VirtualNetworkRoute implements Comparable Date: Wed, 1 Feb 2023 06:43:32 -0500 Subject: [PATCH 49/68] make VirtualNetworkRoute a plain data class --- java/jni/ZT_jnicache.cpp | 20 +------- java/jni/ZT_jnicache.h | 9 ---- java/jni/ZT_jniutils.cpp | 31 ++++++++---- .../com/zerotier/sdk/VirtualNetworkRoute.java | 47 ++++++++++++++----- 4 files changed, 58 insertions(+), 49 deletions(-) diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index f89a7d499..c721a9ee1 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -110,15 +110,6 @@ jmethodID VirtualNetworkConfigOperation_fromInt_method; jmethodID VirtualNetworkStatus_fromInt_method; jmethodID VirtualNetworkType_fromInt_method; -// -// Instance fields -// - -jfieldID VirtualNetworkRoute_flags_field; -jfieldID VirtualNetworkRoute_metric_field; -jfieldID VirtualNetworkRoute_target_field; -jfieldID VirtualNetworkRoute_via_field; - // // Enums // @@ -188,7 +179,7 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_ctor = env->GetMethodID(VirtualNetworkConfig_class, "", "(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, "", "(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, "", "()V")); + EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_ctor = env->GetMethodID(VirtualNetworkRoute_class, "", "(Ljava/net/InetSocketAddress;Ljava/net/InetSocketAddress;II)V")); // // Static methods @@ -202,15 +193,6 @@ void setupJNICache(JavaVM *vm) { 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;")); - // - // Instance fields - // - - EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_flags_field = env->GetFieldID(VirtualNetworkRoute_class, "flags", "I")); - EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_metric_field = env->GetFieldID(VirtualNetworkRoute_class, "metric", "I")); - EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_target_field = env->GetFieldID(VirtualNetworkRoute_class, "target", "Ljava/net/InetSocketAddress;")); - EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_via_field = env->GetFieldID(VirtualNetworkRoute_class, "via", "Ljava/net/InetSocketAddress;")); - // // Enums // diff --git a/java/jni/ZT_jnicache.h b/java/jni/ZT_jnicache.h index 4c6703d02..c5cc9cb2f 100644 --- a/java/jni/ZT_jnicache.h +++ b/java/jni/ZT_jnicache.h @@ -79,15 +79,6 @@ extern jmethodID VirtualNetworkConfigOperation_fromInt_method; extern jmethodID VirtualNetworkStatus_fromInt_method; extern jmethodID VirtualNetworkType_fromInt_method; -// -// Instance fields -// - -extern jfieldID VirtualNetworkRoute_flags_field; -extern jfieldID VirtualNetworkRoute_metric_field; -extern jfieldID VirtualNetworkRoute_target_field; -extern jfieldID VirtualNetworkRoute_via_field; - // // Enums // diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index bd1968442..24bca794e 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -336,19 +336,34 @@ jobject newVersion(JNIEnv *env, int major, int minor, int rev) jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route) { - jobject routeObj = env->NewObject(VirtualNetworkRoute_class, VirtualNetworkRoute_ctor); - if(env->ExceptionCheck() || routeObj == NULL) - { + // + // may be NULL + // + jobject targetObj = newInetSocketAddress(env, route.target); + if (env->ExceptionCheck()) { return NULL; } - jobject targetObj = newInetSocketAddress(env, route.target); + // + // may be NULL + // jobject viaObj = newInetSocketAddress(env, route.via); + if (env->ExceptionCheck()) { + return NULL; + } - env->SetObjectField(routeObj, VirtualNetworkRoute_target_field, targetObj); - env->SetObjectField(routeObj, VirtualNetworkRoute_via_field, viaObj); - env->SetIntField(routeObj, VirtualNetworkRoute_flags_field, (jint)route.flags); - env->SetIntField(routeObj, VirtualNetworkRoute_metric_field, (jint)route.metric); + jobject routeObj = env->NewObject( + VirtualNetworkRoute_class, + VirtualNetworkRoute_ctor, + targetObj, + viaObj, + route.flags, + route.metric); + if(env->ExceptionCheck() || routeObj == NULL) + { + LOGE("Exception creating VirtualNetworkRoute"); + return NULL; + } return routeObj; } diff --git a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java index 02f08210e..afd9ee45a 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkRoute.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkRoute.java @@ -29,34 +29,39 @@ package com.zerotier.sdk; import java.net.InetSocketAddress; -public final class VirtualNetworkRoute implements Comparable +/** + * A route to be pushed on a virtual network + * + * Defined in ZeroTierOne.h as ZT_VirtualNetworkRoute + */ +public class VirtualNetworkRoute implements Comparable { - private VirtualNetworkRoute() { - target = null; - via = null; - flags = 0; - metric = 0; - } - /** * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default */ - public InetSocketAddress target; - + private final InetSocketAddress target; + /** * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) */ - public InetSocketAddress via; + private final InetSocketAddress via; /** * Route flags */ - public int flags; + private final int flags; /** * Route metric (not currently used) */ - public int metric; + 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() { @@ -139,4 +144,20 @@ public final class VirtualNetworkRoute implements Comparable Date: Thu, 2 Feb 2023 13:32:49 -0500 Subject: [PATCH 50/68] add isSocketAddressEmpty --- java/jni/ZT_jniutils.cpp | 25 +++++++++++++++++++++++++ java/jni/ZT_jniutils.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 24bca794e..e72771965 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -531,3 +531,28 @@ jbyteArray newByteArray(JNIEnv *env, size_t count) { 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 +} diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index bad093218..e33dbea66 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -160,4 +160,6 @@ jbyteArray newByteArray(JNIEnv *env, const unsigned char *bytes, size_t count); jbyteArray newByteArray(JNIEnv *env, size_t count); +bool isSocketAddressEmpty(const sockaddr_storage addr); + #endif // ZT_jniutils_h_ From 30cfe65b396709d0268ab625bb95d0f6ed8ccb50 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 13:38:19 -0500 Subject: [PATCH 51/68] add addressPort --- java/jni/ZT_jniutils.cpp | 30 ++++++++++++++++++++++++++++++ java/jni/ZT_jniutils.h | 1 + 2 files changed, 31 insertions(+) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index e72771965..8d4469366 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -142,6 +142,36 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) return inetAddressObj; } +int addressPort(const sockaddr_storage addr) { + + int port = 0; + switch(addr.ss_family) + { + case AF_INET6: + { + LOGV("IPV6 Address"); + sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr; + port = ntohs(ipv6->sin6_port); + LOGV("Port %d", port); + } + break; + case AF_INET: + { + LOGV("IPV4 Address"); + sockaddr_in *ipv4 = (sockaddr_in*)&addr; + port = ntohs(ipv4->sin_port); + LOGV("Port: %d", port); + } + break; + default: + { + assert(false && "addr.ss_family is neither AF_INET6 nor AF_INET"); + } + } + + return port; +} + jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) { LOGV("newInetSocketAddress Called"); diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index e33dbea66..2c57bfdb7 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -88,6 +88,7 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfig 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); From 4ee73fa272fe6ca33c5cf426202e0ef467b81c9b Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 08:08:17 -0500 Subject: [PATCH 52/68] add fromSocketAddressObject --- java/jni/ZT_jniutils.cpp | 68 ++++++++++++++++++- java/jni/ZT_jniutils.h | 3 + java/jni/com_zerotierone_sdk_Node.cpp | 95 ++------------------------- 3 files changed, 75 insertions(+), 91 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 8d4469366..86e4fdcb8 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #define LOG_TAG "Utils" @@ -586,3 +585,70 @@ bool isSocketAddressEmpty(const sockaddr_storage addr) { 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(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(&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(&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; +} diff --git a/java/jni/ZT_jniutils.h b/java/jni/ZT_jniutils.h index 2c57bfdb7..23664a732 100644 --- a/java/jni/ZT_jniutils.h +++ b/java/jni/ZT_jniutils.h @@ -23,6 +23,7 @@ #include #include // for numeric_limits +#include // for sockaddr_storage #if defined(__ANDROID__) @@ -163,4 +164,6 @@ jbyteArray newByteArray(JNIEnv *env, size_t count); bool isSocketAddressEmpty(const sockaddr_storage addr); +sockaddr_storage fromSocketAddressObject(JNIEnv *env, jobject sockAddressObject); + #endif // ZT_jniutils_h_ diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index a143d9210..28a5ed5b9 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -498,40 +498,8 @@ namespace { return false; } - jint port = env->CallIntMethod(sockAddressObject, InetSocketAddress_getPort_method); - jobject addressObject = env->CallObjectMethod(sockAddressObject, InetSocketAddress_getAddress_method); - - jbyteArray addressBytes = (jbyteArray)env->CallObjectMethod(addressObject, InetAddress_getAddress_method); - if(addressBytes == NULL) - { - LOGE("Unable to call InetAddress.getBytes()"); - return false; - } - - int addressSize = env->GetArrayLength(addressBytes); - if(addressSize == 4) - { - // IPV4 - sockaddr_in *addr = (sockaddr_in*)result; - addr->sin_family = AF_INET; - addr->sin_port = htons(port); - - void *data = env->GetPrimitiveArrayCritical(addressBytes, NULL); - memcpy(&addr->sin_addr, data, 4); - env->ReleasePrimitiveArrayCritical(addressBytes, data, 0); - } - else if (addressSize == 16) - { - // IPV6 - sockaddr_in6 *addr = (sockaddr_in6*)result; - addr->sin6_family = AF_INET6; - addr->sin6_port = htons(port); - void *data = env->GetPrimitiveArrayCritical(addressBytes, NULL); - memcpy(&addr->sin6_addr, data, 16); - env->ReleasePrimitiveArrayCritical(addressBytes, data, 0); - } - else - { + *result = fromSocketAddressObject(env, sockAddressObject); + if (env->ExceptionCheck() || isSocketAddressEmpty(*result)) { return false; } @@ -863,64 +831,11 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( int64_t now = (int64_t)in_now; - jobject remoteAddrObject = env->CallObjectMethod(in_remoteAddress, InetSocketAddress_getAddress_method); - - if(remoteAddrObject == NULL) - { - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + sockaddr_storage remoteAddress = fromSocketAddressObject(env, in_remoteAddress); + if (env->ExceptionCheck() || isSocketAddressEmpty(remoteAddress)) { + return NULL; } - // call InetSocketAddress.getPort() - int remotePort = env->CallIntMethod(in_remoteAddress, InetSocketAddress_getPort_method); - if(env->ExceptionCheck()) - { - LOGE("Exception calling InetSocketAddress.getPort()"); - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } - - // Call InetAddress.getAddress() - jbyteArray remoteAddressArray = (jbyteArray)env->CallObjectMethod(remoteAddrObject, InetAddress_getAddress_method); - if(remoteAddressArray == NULL) - { - LOGE("Unable to call getAddress()"); - // unable to call getAddress() - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } - - unsigned int addrSize = env->GetArrayLength(remoteAddressArray); - - - // get the address bytes - jbyte *addr = (jbyte*)env->GetPrimitiveArrayCritical(remoteAddressArray, NULL); - sockaddr_storage remoteAddress = {}; - - if(addrSize == 16) - { - // IPV6 address - sockaddr_in6 ipv6 = {}; - ipv6.sin6_family = AF_INET6; - ipv6.sin6_port = htons(remotePort); - 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; - 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->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0); - return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; - } - env->ReleasePrimitiveArrayCritical(remoteAddressArray, addr, 0); - unsigned int packetLength = (unsigned int)env->GetArrayLength(in_packetData); if(packetLength == 0) { From e1c16a8e68beddba7b57557e9350994a55a0e4a7 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 11:19:01 -0500 Subject: [PATCH 53/68] invert logic in a couple of places and return early --- java/jni/ZT_jniutils.cpp | 18 +++++++----------- java/jni/com_zerotierone_sdk_Node.cpp | 9 +++++---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 86e4fdcb8..44191b81e 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -175,20 +175,16 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) { LOGV("newInetSocketAddress Called"); - jobject inetAddressObject = NULL; - - if(addr.ss_family != 0) + if(addr.ss_family == 0) { - inetAddressObject = newInetAddress(env, addr); - - if(env->ExceptionCheck() || inetAddressObject == NULL) - { - LOGE("Error creating new inet address"); - return NULL; - } + return NULL; } - else + + jobject inetAddressObject = newInetAddress(env, addr); + + if(env->ExceptionCheck() || inetAddressObject == NULL) { + LOGE("Error creating new inet address"); return NULL; } diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 28a5ed5b9..9b0a309a0 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -233,11 +233,12 @@ namespace { 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, EventListener_onTrace_method, messageStr); + if (data == NULL) { + break; } + const char *message = (const char *) data; + jstring messageStr = env->NewStringUTF(message); + env->CallVoidMethod(ref->eventListener, EventListener_onTrace_method, messageStr); } break; case ZT_EVENT_USER_MESSAGE: From 132bff25dfd59d6354590722ad276dbe4d32b5ab Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Wed, 1 Feb 2023 16:01:16 -0500 Subject: [PATCH 54/68] newInetAddress and newInetSocketAddress work allow newInetSocketAddress to return NULL if given empty address --- java/jni/ZT_jniutils.cpp | 45 ++++++++++----------------- java/jni/com_zerotierone_sdk_Node.cpp | 35 +++++++-------------- 2 files changed, 27 insertions(+), 53 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 44191b81e..d4339b4cf 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -132,6 +132,10 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) InetAddress_class, InetAddress_getByAddress_method, 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"); @@ -171,11 +175,16 @@ int addressPort(const sockaddr_storage addr) { return port; } +// +// addr may be empty +// +// may return NULL +// jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) { LOGV("newInetSocketAddress Called"); - if(addr.ss_family == 0) + if(isSocketAddressEmpty(addr)) { return NULL; } @@ -184,39 +193,15 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) if(env->ExceptionCheck() || inetAddressObject == NULL) { - LOGE("Error creating new inet address"); return NULL; } - int port = 0; - switch(addr.ss_family) - { - case AF_INET6: - { - LOGV("IPV6 Address"); - sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr; - port = ntohs(ipv6->sin6_port); - LOGV("Port %d", port); - } - break; - case AF_INET: - { - LOGV("IPV4 Address"); - sockaddr_in *ipv4 = (sockaddr_in*)&addr; - port = ntohs(ipv4->sin_port); - LOGV("Port: %d", port); - } - break; - default: - { - break; - } - } - + int port = addressPort(addr); jobject inetSocketAddressObject = env->NewObject(InetSocketAddress_class, InetSocketAddress_ctor, inetAddressObject, port); if(env->ExceptionCheck() || inetSocketAddressObject == NULL) { LOGE("Error creating InetSocketAddress object"); + return NULL; } return inetSocketAddressObject; } @@ -225,9 +210,11 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) { LOGV("newPeerPhysicalPath Called"); + // + // may be NULL + // jobject addressObject = newInetSocketAddress(env, ppp.address); - if(env->ExceptionCheck() || addressObject == NULL) { - LOGE("Error creating InetSocketAddress object"); + if(env->ExceptionCheck()) { return NULL; } diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 9b0a309a0..27f137ef1 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -414,12 +414,18 @@ namespace { return -100; } + // + // may be NULL + // jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress); + if (env->ExceptionCheck()) { + return -101; + } const unsigned char *bytes = static_cast(buffer); jbyteArray bufferObj = newByteArray(env, bytes, bufferSize); if (env->ExceptionCheck() || bufferObj == NULL) { - return -101; + return -102; } int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj); @@ -446,30 +452,11 @@ namespace { ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); // - // was: - // struct sockaddr_storage nullAddress = {0}; + // may be NULL // - // but was getting this warning: - // warning: suggest braces around initialization of subobject - // - // when building ZeroTierOne - // - struct sockaddr_storage nullAddress; - - // - // 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(&nullAddress, 0, sizeof(sockaddr_storage)); - - jobject remoteAddressObj = NULL; - - if(memcmp(remoteAddress, &nullAddress, sizeof(sockaddr_storage)) != 0) - { - remoteAddressObj = newInetSocketAddress(env, *remoteAddress); + jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress); + if (env->ExceptionCheck()) { + return true; } return env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, address, localSocket, remoteAddressObj); From 0a925a6f216f2fe8bb83d0e8d0c5ff1b9e804c25 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 11:34:18 -0500 Subject: [PATCH 55/68] fix ANDROID-38: stack corruption in onSendPacketRequested --- java/jni/com_zerotierone_sdk_Node.cpp | 4 ++-- java/src/com/zerotier/sdk/PacketSender.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 27f137ef1..d25b6adb4 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -402,7 +402,7 @@ namespace { unsigned int bufferSize, unsigned int ttl) { - LOGV("WirePacketSendFunction(%lld, %p, %p, %d)", (long long)localSocket, remoteAddress, buffer, bufferSize); + LOGV("WirePacketSendFunction(%lld, %p, %p, %d, %u)", (long long)localSocket, remoteAddress, buffer, bufferSize, ttl); JniRef *ref = (JniRef*)userData; assert(ref->node == node); @@ -428,7 +428,7 @@ namespace { return -102; } - int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj); + int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj, 0); LOGV("JNI Packet Sender returned: %d", retval); return retval; diff --git a/java/src/com/zerotier/sdk/PacketSender.java b/java/src/com/zerotier/sdk/PacketSender.java index 1a4d4524e..a845ac4a3 100644 --- a/java/src/com/zerotier/sdk/PacketSender.java +++ b/java/src/com/zerotier/sdk/PacketSender.java @@ -42,6 +42,7 @@ public interface PacketSender { * @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. */ public int onSendPacketRequested( From d28f44335ab53667609c83b1d59f0c89f6e98fc4 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 13:44:43 -0500 Subject: [PATCH 56/68] use GETENV macro --- java/jni/com_zerotierone_sdk_Node.cpp | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index d25b6adb4..43c85ccf9 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -62,8 +62,8 @@ namespace { ~JniRef() { - JNIEnv *env = NULL; - jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, jvm); env->DeleteGlobalRef(dataStoreGetListener); env->DeleteGlobalRef(dataStorePutListener); @@ -110,8 +110,8 @@ namespace { { LOGV("VirtualNetworkConfigFunctionCallback"); JniRef *ref = (JniRef*)userData; - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, ref->jvm); if (ref->configListener == NULL) { LOGE("configListener is NULL"); @@ -160,8 +160,8 @@ namespace { #endif JniRef *ref = (JniRef*)userData; assert(ref->node == node); - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, ref->jvm); if (ref->frameListener == NULL) { LOGE("frameListener is NULL"); @@ -190,8 +190,8 @@ namespace { 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); + JNIEnv *env; + GETENV(env, ref->jvm); if (ref->eventListener == NULL) { LOGE("eventListener is NULL"); @@ -287,8 +287,8 @@ namespace { } JniRef *ref = (JniRef*)userData; - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, ref->jvm); if (ref->dataStorePutListener == NULL) { LOGE("dataStorePutListener is NULL"); @@ -352,8 +352,8 @@ namespace { } JniRef *ref = (JniRef*)userData; - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, ref->jvm); if (ref->dataStoreGetListener == NULL) { LOGE("dataStoreGetListener is NULL"); @@ -406,8 +406,8 @@ namespace { JniRef *ref = (JniRef*)userData; assert(ref->node == node); - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, ref->jvm); if (ref->packetSender == NULL) { LOGE("packetSender is NULL"); @@ -448,8 +448,8 @@ namespace { return true; } - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, ref->jvm); // // may be NULL @@ -476,8 +476,8 @@ namespace { return false; } - JNIEnv *env = NULL; - ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + JNIEnv *env; + GETENV(env, ref->jvm); jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, PathChecker_onPathLookup_method, address, ss_family); if(sockAddressObject == NULL) @@ -606,7 +606,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( ZT_Node *node; JniRef *ref = new JniRef; ref->id = (int64_t)now; - env->GetJavaVM(&ref->jvm); + GETJAVAVM(env, ref->jvm); if(dataStoreGetListener == NULL) { From a2f753986b2423637eddf83ac65bac36fad3c629 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 14:44:04 -0500 Subject: [PATCH 57/68] JniRef work JniRef does not use callbacks struct, so remove fix NewGlobalRef / DeleteGlobalRef mismatch --- java/jni/com_zerotierone_sdk_Node.cpp | 148 +++++++++++++------------- 1 file changed, 72 insertions(+), 76 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 43c85ccf9..0c666fe88 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -43,22 +43,39 @@ namespace { struct JniRef { - JniRef() - : jvm(NULL) - , node(NULL) - , dataStoreGetListener(NULL) - , dataStorePutListener(NULL) - , packetSender(NULL) - , eventListener(NULL) - , frameListener(NULL) - , configListener(NULL) - , pathChecker(NULL) - , callbacks(NULL) - , inited() - { - callbacks = (ZT_Node_Callbacks*)malloc(sizeof(ZT_Node_Callbacks)); - memset(callbacks, 0, sizeof(ZT_Node_Callbacks)); - } + JniRef( + int64_t id, + JavaVM *jvm, + jobject dataStoreGetListenerLocalIn, + jobject dataStorePutListenerLocalIn, + jobject packetSenderLocalIn, + jobject eventListenerLocalIn, + jobject frameListenerLocalIn, + jobject configListenerLocalIn, + jobject pathCheckerLocalIn) + : id(id) + , jvm(jvm) + , node() + , dataStoreGetListener() + , dataStorePutListener() + , packetSender() + , eventListener() + , frameListener() + , configListener() + , pathChecker() + , inited() { + + JNIEnv *env; + GETENV(env, jvm); + + dataStoreGetListener = env->NewGlobalRef(dataStoreGetListenerLocalIn); + dataStorePutListener = env->NewGlobalRef(dataStorePutListenerLocalIn); + packetSender = env->NewGlobalRef(packetSenderLocalIn); + eventListener = env->NewGlobalRef(eventListenerLocalIn); + frameListener = env->NewGlobalRef(frameListenerLocalIn); + configListener = env->NewGlobalRef(configListenerLocalIn); + pathChecker = env->NewGlobalRef(pathCheckerLocalIn); + }; ~JniRef() { @@ -72,9 +89,6 @@ namespace { env->DeleteGlobalRef(frameListener); env->DeleteGlobalRef(configListener); env->DeleteGlobalRef(pathChecker); - - free(callbacks); - callbacks = NULL; } int64_t id; @@ -91,8 +105,6 @@ namespace { jobject configListener; jobject pathChecker; - ZT_Node_Callbacks *callbacks; - bool inited; bool finishInitializing(); @@ -603,66 +615,50 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( LOGV("Creating ZT_Node struct"); jobject resultObject = ResultCode_RESULT_OK_enum; + JavaVM *vm; + GETJAVAVM(env, vm); + + assert(dataStoreGetListener != NULL); + assert(dataStorePutListener != NULL); + assert(packetSender != NULL); + assert(frameListener != NULL); + assert(configListener != NULL); + assert(eventListener != NULL); + // + // OPTIONAL, pathChecker may be NULL + // +// assert(pathChecker != NULL); + + ZT_Node_Callbacks callbacks{}; + callbacks.stateGetFunction = &StateGetFunction; + callbacks.statePutFunction = &StatePutFunction; + callbacks.wirePacketSendFunction = &WirePacketSendFunction; + callbacks.virtualNetworkFrameFunction = &VirtualNetworkFrameFunctionCallback; + callbacks.virtualNetworkConfigFunction = &VirtualNetworkConfigFunctionCallback; + callbacks.eventCallback = &EventCallback; + callbacks.pathCheckFunction = &PathCheckFunction; + callbacks.pathLookupFunction = &PathLookupFunction; + + // + // a bit of a confusing dance here where ref and node both know about each other + // + JniRef *ref = new JniRef( + now, + vm, + dataStoreGetListener, + dataStorePutListener, + packetSender, + eventListener, + frameListener, + configListener, + pathChecker); + ZT_Node *node; - JniRef *ref = new JniRef; - ref->id = (int64_t)now; - GETJAVAVM(env, ref->jvm); - - if(dataStoreGetListener == NULL) - { - return NULL; - } - ref->dataStoreGetListener = env->NewGlobalRef(dataStoreGetListener); - - if(dataStorePutListener == NULL) - { - return NULL; - } - ref->dataStorePutListener = env->NewGlobalRef(dataStorePutListener); - - if(packetSender == NULL) - { - return NULL; - } - ref->packetSender = env->NewGlobalRef(packetSender); - - if(frameListener == NULL) - { - return NULL; - } - ref->frameListener = env->NewGlobalRef(frameListener); - - if(configListener == NULL) - { - return NULL; - } - ref->configListener = env->NewGlobalRef(configListener); - - if(eventListener == NULL) - { - return NULL; - } - ref->eventListener = env->NewGlobalRef(eventListener); - - if(pathChecker != NULL) - { - ref->pathChecker = env->NewGlobalRef(pathChecker); - } - - ref->callbacks->stateGetFunction = &StateGetFunction; - ref->callbacks->statePutFunction = &StatePutFunction; - ref->callbacks->wirePacketSendFunction = &WirePacketSendFunction; - ref->callbacks->virtualNetworkFrameFunction = &VirtualNetworkFrameFunctionCallback; - ref->callbacks->virtualNetworkConfigFunction = &VirtualNetworkConfigFunctionCallback; - ref->callbacks->eventCallback = &EventCallback; - ref->callbacks->pathCheckFunction = &PathCheckFunction; - ref->callbacks->pathLookupFunction = &PathLookupFunction; - ZT_ResultCode rc = ZT_Node_new( &node, ref, NULL, - ref->callbacks, + &callbacks, (int64_t)now); if(rc != ZT_RESULT_OK) From a1bf1391888c32f8bcac3d71c7d46f2dcf97499c Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 14:47:17 -0500 Subject: [PATCH 58/68] use PRId64 macros --- java/jni/com_zerotierone_sdk_Node.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 0c666fe88..3c1eb9f77 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -37,6 +37,7 @@ #include #include #include +#include // for PRId64 #define LOG_TAG "Node" @@ -282,13 +283,13 @@ namespace { snprintf(p, sizeof(p), "planet"); break; case ZT_STATE_OBJECT_MOON: - snprintf(p, sizeof(p), "moons.d/%.16llx.moon", (unsigned long long)id[0]); + snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]); break; case ZT_STATE_OBJECT_NETWORK_CONFIG: - snprintf(p, sizeof(p), "networks.d/%.16llx.conf", (unsigned long long)id[0]); + snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]); break; case ZT_STATE_OBJECT_PEER: - snprintf(p, sizeof(p), "peers.d/%.10llx", (unsigned long long)id[0]); + snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); break; default: return; @@ -347,13 +348,13 @@ namespace { snprintf(p, sizeof(p), "planet"); break; case ZT_STATE_OBJECT_MOON: - snprintf(p, sizeof(p), "moons.d/%.16llx.moon", (unsigned long long)id[0]); + snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]); break; case ZT_STATE_OBJECT_NETWORK_CONFIG: - snprintf(p, sizeof(p), "networks.d/%.16llx.conf", (unsigned long long)id[0]); + snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]); break; case ZT_STATE_OBJECT_PEER: - snprintf(p, sizeof(p), "peers.d/%.10llx", (unsigned long long)id[0]); + snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); break; default: return -100; @@ -414,7 +415,7 @@ namespace { unsigned int bufferSize, unsigned int ttl) { - LOGV("WirePacketSendFunction(%lld, %p, %p, %d, %u)", (long long)localSocket, remoteAddress, buffer, bufferSize, ttl); + LOGV("WirePacketSendFunction(%" PRId64 ", %p, %p, %d, %u)", localSocket, remoteAddress, buffer, bufferSize, ttl); JniRef *ref = (JniRef*)userData; assert(ref->node == node); From 914b4fae7bfec99078ee80f07a4dedfb0f391b2e Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 14:52:16 -0500 Subject: [PATCH 59/68] switch statement work --- java/jni/com_zerotierone_sdk_Node.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 3c1eb9f77..f664ebc56 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -256,7 +256,6 @@ namespace { break; case ZT_EVENT_USER_MESSAGE: case ZT_EVENT_REMOTE_TRACE: - default: break; } } @@ -291,7 +290,7 @@ namespace { case ZT_STATE_OBJECT_PEER: snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); break; - default: + case ZT_STATE_OBJECT_NULL: return; } @@ -356,7 +355,7 @@ namespace { case ZT_STATE_OBJECT_PEER: snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); break; - default: + case ZT_STATE_OBJECT_NULL: return -100; } From fbd834716f2110b58d41fcbaf0d232ae91122a99 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 14:52:39 -0500 Subject: [PATCH 60/68] comments and logging --- java/jni/ZT_jniutils.cpp | 12 ----- java/jni/com_zerotierone_sdk_Node.cpp | 44 +++++++++++++++++-- java/src/com/zerotier/sdk/Node.java | 1 + java/src/com/zerotier/sdk/PathChecker.java | 1 + .../zerotier/sdk/VirtualNetworkConfig.java | 6 +-- .../sdk/VirtualNetworkConfigListener.java | 2 +- .../sdk/VirtualNetworkFrameListener.java | 4 +- 7 files changed, 48 insertions(+), 22 deletions(-) diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index d4339b4cf..053c5adb0 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -98,8 +98,6 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfig jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) { - LOGV("newInetAddress"); - jobject inetAddressObj = NULL; switch(addr.ss_family) { @@ -152,18 +150,14 @@ int addressPort(const sockaddr_storage addr) { { case AF_INET6: { - LOGV("IPV6 Address"); sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr; port = ntohs(ipv6->sin6_port); - LOGV("Port %d", port); } break; case AF_INET: { - LOGV("IPV4 Address"); sockaddr_in *ipv4 = (sockaddr_in*)&addr; port = ntohs(ipv4->sin_port); - LOGV("Port: %d", port); } break; default: @@ -182,8 +176,6 @@ int addressPort(const sockaddr_storage addr) { // jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) { - LOGV("newInetSocketAddress Called"); - if(isSocketAddressEmpty(addr)) { return NULL; @@ -208,8 +200,6 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) { - LOGV("newPeerPhysicalPath Called"); - // // may be NULL // @@ -236,8 +226,6 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) jobject newPeer(JNIEnv *env, const ZT_Peer &peer) { - LOGV("newPeer called"); - jobject peerRoleObj = createPeerRole(env, peer.role); if(env->ExceptionCheck() || peerRoleObj == NULL) { diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index f664ebc56..3243bfb07 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -112,12 +112,17 @@ namespace { }; + /* + * 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. + */ int VirtualNetworkConfigFunctionCallback( ZT_Node *node, void *userData, void *threadData, uint64_t nwid, - void **, + void **nuptr, enum ZT_VirtualNetworkConfigOperation operation, const ZT_VirtualNetworkConfig *config) { @@ -158,7 +163,7 @@ namespace { void *userData, void *threadData, uint64_t nwid, - void**, + void** nuptr, uint64_t sourceMac, uint64_t destMac, unsigned int etherType, @@ -268,6 +273,8 @@ namespace { const uint64_t id[2], const void *buffer, int bufferLength) { + LOGV("StatePutFunction"); + char p[4096] = {0}; bool secure = false; switch (type) { @@ -327,6 +334,11 @@ namespace { } } + /** + * This function should return the number of bytes actually stored to the + * buffer or -1 if the state object was not found or the buffer was too + * small to store it. + */ int StateGetFunction( ZT_Node *node, void *userData, @@ -335,6 +347,8 @@ namespace { const uint64_t id[2], void *buffer, unsigned int bufferLength) { + LOGV("StateGetFunction"); + char p[4096] = {0}; switch (type) { case ZT_STATE_OBJECT_IDENTITY_PUBLIC: @@ -405,6 +419,11 @@ namespace { return retval; } + /** + * 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. + */ int WirePacketSendFunction(ZT_Node *node, void *userData, void *threadData, @@ -414,7 +433,7 @@ namespace { unsigned int bufferSize, unsigned int ttl) { - LOGV("WirePacketSendFunction(%" PRId64 ", %p, %p, %d, %u)", localSocket, remoteAddress, buffer, bufferSize, ttl); + LOGV("WirePacketSendFunction(%" PRId64 ", %p, %p, %u, %u)", localSocket, remoteAddress, buffer, bufferSize, ttl); JniRef *ref = (JniRef*)userData; assert(ref->node == node); @@ -446,6 +465,9 @@ namespace { return retval; } + /** + * This function must return nonzero (true) if the path should be used. + */ int PathCheckFunction(ZT_Node *node, void *userPtr, void *threadPtr, @@ -453,6 +475,8 @@ namespace { int64_t localSocket, const struct sockaddr_storage *remoteAddress) { + LOGV("PathCheckFunction"); + JniRef *ref = (JniRef*)userPtr; assert(ref->node == node); @@ -474,6 +498,9 @@ namespace { return env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, address, localSocket, remoteAddressObj); } + /** + * It must return a nonzero (true) value if the result buffer has been filled with an address. + */ int PathLookupFunction(ZT_Node *node, void *userPtr, void *threadPtr, @@ -481,6 +508,8 @@ namespace { int ss_family, struct sockaddr_storage *result) { + LOGV("PathLookupFunction"); + JniRef *ref = (JniRef*)userPtr; assert(ref->node == node); @@ -491,6 +520,9 @@ namespace { JNIEnv *env; GETENV(env, ref->jvm); + // + // may be NULL + // jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, PathChecker_onPathLookup_method, address, ss_family); if(sockAddressObject == NULL) { @@ -761,6 +793,9 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( unsigned int frameLength = env->GetArrayLength(in_frameData); void *frameData = env->GetPrimitiveArrayCritical(in_frameData, NULL); + // + // need local copy of frameData because arbitrary code may run in ZT_Node_processVirtualNetworkFrame and no other JNI work may happen between GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical + // void *localData = malloc(frameLength); memcpy(localData, frameData, frameLength); env->ReleasePrimitiveArrayCritical(in_frameData, frameData, 0); @@ -827,6 +862,9 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; } void *packetData = env->GetPrimitiveArrayCritical(in_packetData, NULL); + // + // need local copy of packetData because arbitrary code may run in ZT_Node_processWirePacket and no other JNI work may happen between GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical + // void *localData = malloc(packetLength); memcpy(localData, packetData, packetLength); env->ReleasePrimitiveArrayCritical(in_packetData, packetData, 0); diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index 6ae6aaa4e..964c896c9 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -166,6 +166,7 @@ public class Node { * 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() diff --git a/java/src/com/zerotier/sdk/PathChecker.java b/java/src/com/zerotier/sdk/PathChecker.java index 459dde122..cfc97d60e 100644 --- a/java/src/com/zerotier/sdk/PathChecker.java +++ b/java/src/com/zerotier/sdk/PathChecker.java @@ -29,6 +29,7 @@ public interface PathChecker { * @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); diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index 0e7337893..bcf64854a 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -373,7 +373,7 @@ public class VirtualNetworkConfig implements Comparable { } /** - * ZeroTier-assigned addresses (in {@link java.net.InetSocketAddress} objects) + * ZeroTier-assigned addresses (in {@link InetSocketAddress} objects) * * 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. @@ -387,9 +387,7 @@ public class VirtualNetworkConfig implements Comparable { } /** - * ZeroTier-assigned routes (in {@link com.zerotier.sdk.VirtualNetworkRoute} objects) - * - * @return + * ZeroTier-assigned routes (in {@link VirtualNetworkRoute} objects) */ public VirtualNetworkRoute[] getRoutes() { return routes; diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java b/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java index 24229039e..abd170aec 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java @@ -40,7 +40,7 @@ public interface VirtualNetworkConfigListener { * This in turn should be used by the underlying implementation to create * and configure tap devices at the OS (or virtual network stack) layer.

* - * This should not call {@link Node#multicastSubscribe} or other network-modifying + * 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. * diff --git a/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java b/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java index a1c676172..c3dd2bbcc 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java @@ -35,8 +35,8 @@ public interface VirtualNetworkFrameListener { * @param nwid ZeroTier One network ID * @param srcMac source MAC address * @param destMac destination MAC address - * @param ethertype - * @param vlanId + * @param etherType EtherType + * @param vlanId VLAN ID * @param frameData data to send */ public void onVirtualNetworkFrame( From ca73651e12758b51cab41eb0b1e581d9505bd286 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 15:50:31 -0500 Subject: [PATCH 61/68] Modifier 'public' is redundant for interface members --- java/src/com/zerotier/sdk/DataStoreGetListener.java | 2 +- java/src/com/zerotier/sdk/DataStorePutListener.java | 4 ++-- java/src/com/zerotier/sdk/EventListener.java | 4 ++-- java/src/com/zerotier/sdk/PacketSender.java | 2 +- java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java | 2 +- java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/java/src/com/zerotier/sdk/DataStoreGetListener.java b/java/src/com/zerotier/sdk/DataStoreGetListener.java index 273c94363..105b14c55 100644 --- a/java/src/com/zerotier/sdk/DataStoreGetListener.java +++ b/java/src/com/zerotier/sdk/DataStoreGetListener.java @@ -49,7 +49,7 @@ public interface DataStoreGetListener { * @param out_buffer buffer to put the object in * @return size of the object */ - public long onDataStoreGet( + long onDataStoreGet( String name, byte[] out_buffer); } diff --git a/java/src/com/zerotier/sdk/DataStorePutListener.java b/java/src/com/zerotier/sdk/DataStorePutListener.java index bb9e089fa..0fa8e19c1 100644 --- a/java/src/com/zerotier/sdk/DataStorePutListener.java +++ b/java/src/com/zerotier/sdk/DataStorePutListener.java @@ -44,7 +44,7 @@ public interface DataStorePutListener { * @param secure set to user read/write only. * @return 0 on success. */ - public int onDataStorePut( + int onDataStorePut( String name, byte[] buffer, boolean secure); @@ -55,6 +55,6 @@ public interface DataStorePutListener { * @param name Object name * @return 0 on success. */ - public int onDelete( + int onDelete( String name); } diff --git a/java/src/com/zerotier/sdk/EventListener.java b/java/src/com/zerotier/sdk/EventListener.java index 5dbe3da71..88fb8afc3 100644 --- a/java/src/com/zerotier/sdk/EventListener.java +++ b/java/src/com/zerotier/sdk/EventListener.java @@ -37,7 +37,7 @@ public interface EventListener { * * @param event {@link Event} enum */ - public void onEvent(Event event); + void onEvent(Event event); /** * Trace messages @@ -46,5 +46,5 @@ public interface EventListener { * * @param message the trace message */ - public void onTrace(String message); + void onTrace(String message); } diff --git a/java/src/com/zerotier/sdk/PacketSender.java b/java/src/com/zerotier/sdk/PacketSender.java index a845ac4a3..893824a08 100644 --- a/java/src/com/zerotier/sdk/PacketSender.java +++ b/java/src/com/zerotier/sdk/PacketSender.java @@ -45,7 +45,7 @@ public interface PacketSender { * @param ttl TTL is ignored * @return 0 on success, any error code on failure. */ - public int onSendPacketRequested( + int onSendPacketRequested( long localSocket, InetSocketAddress remoteAddr, byte[] packetData, diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java b/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java index abd170aec..ce91e79d9 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java @@ -53,7 +53,7 @@ public interface VirtualNetworkConfigListener { * @param config {@link VirtualNetworkConfig} object with the new configuration * @return 0 on success */ - public int onNetworkConfigurationUpdated( + int onNetworkConfigurationUpdated( long nwid, VirtualNetworkConfigOperation op, VirtualNetworkConfig config); diff --git a/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java b/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java index c3dd2bbcc..650c9cedc 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java @@ -39,7 +39,7 @@ public interface VirtualNetworkFrameListener { * @param vlanId VLAN ID * @param frameData data to send */ - public void onVirtualNetworkFrame( + void onVirtualNetworkFrame( long nwid, long srcMac, long destMac, From 33a9cd02ba6b75be836a73384c3d5bb2bc8132b8 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 15:59:16 -0500 Subject: [PATCH 62/68] NodeException can be made a checked Exception --- java/src/com/zerotier/sdk/NodeException.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/src/com/zerotier/sdk/NodeException.java b/java/src/com/zerotier/sdk/NodeException.java index 75baf9d30..05d6a5efb 100644 --- a/java/src/com/zerotier/sdk/NodeException.java +++ b/java/src/com/zerotier/sdk/NodeException.java @@ -27,9 +27,7 @@ package com.zerotier.sdk; -import java.lang.RuntimeException; - -public class NodeException extends RuntimeException { +public class NodeException extends Exception { public NodeException(String message) { super(message); } From 5b5625a6f0cfc29f47739f3fdafee0e728c6baf4 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:00:04 -0500 Subject: [PATCH 63/68] 'NodeException' does not define a 'serialVersionUID' field --- java/src/com/zerotier/sdk/NodeException.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/src/com/zerotier/sdk/NodeException.java b/java/src/com/zerotier/sdk/NodeException.java index 05d6a5efb..beeb06063 100644 --- a/java/src/com/zerotier/sdk/NodeException.java +++ b/java/src/com/zerotier/sdk/NodeException.java @@ -28,6 +28,9 @@ package com.zerotier.sdk; public class NodeException extends Exception { + + private static final long serialVersionUID = 6268040509883125819L; + public NodeException(String message) { super(message); } From 1ab36d891c7508e3ef9893c414104f6b474c434b Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:02:07 -0500 Subject: [PATCH 64/68] 'finalize()' should not be overridden this is fine to do because ZeroTierOneService calls close() when it is done --- java/src/com/zerotier/sdk/Node.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index 964c896c9..ac20398e1 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -125,11 +125,6 @@ public class Node { node_delete(nodeId); } - @Override - protected void finalize() { - close(); - } - @Override public String toString() { return "Node(" + nodeId + ")"; From 0aa4a4ba7a7469edf7dd5558a88be2d72e5e65a7 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 2 Feb 2023 16:05:01 -0500 Subject: [PATCH 65/68] error handling, error reporting, asserts, logging --- java/jni/com_zerotierone_sdk_Node.cpp | 264 ++++++++++++++++++++++---- 1 file changed, 232 insertions(+), 32 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 3243bfb07..1a33e0123 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -128,35 +128,47 @@ namespace { { LOGV("VirtualNetworkConfigFunctionCallback"); JniRef *ref = (JniRef*)userData; + assert(ref); JNIEnv *env; GETENV(env, ref->jvm); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); + return -100; + } + if (ref->configListener == NULL) { LOGE("configListener is NULL"); - return -100; + return -101; } jobject operationObject = createVirtualNetworkConfigOperation(env, operation); if(env->ExceptionCheck() || operationObject == NULL) { - return -101; + return -102; } if (config == NULL) { LOGE("Config is NULL"); - return -102; + return -103; } jobject networkConfigObject = newNetworkConfig(env, *config); if(env->ExceptionCheck() || networkConfigObject == NULL) { - return -103; + return -104; } - return env->CallIntMethod( + jint ret = env->CallIntMethod( ref->configListener, VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method, (jlong)nwid, operationObject, networkConfigObject); + if (env->ExceptionCheck()) { + LOGE("Exception calling onNetworkConfigurationUpdated"); + return -105; + } + + return ret; } void VirtualNetworkFrameFunctionCallback(ZT_Node *node, @@ -173,14 +185,22 @@ namespace { { LOGV("VirtualNetworkFrameFunctionCallback"); #ifndef NDEBUG - unsigned char* local = (unsigned char*)frameData; - LOGV("Type Bytes: 0x%02x%02x", local[12], local[13]); + if (frameLength >= 14) { + unsigned char* local = (unsigned char*)frameData; + LOGV("Type Bytes: 0x%02x%02x", local[12], local[13]); + } #endif JniRef *ref = (JniRef*)userData; + assert(ref); assert(ref->node == node); JNIEnv *env; GETENV(env, ref->jvm); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); + return; + } + if (ref->frameListener == NULL) { LOGE("frameListener is NULL"); return; @@ -194,6 +214,10 @@ namespace { } env->CallVoidMethod(ref->frameListener, VirtualNetworkFrameListener_onVirtualNetworkFrame_method, (jlong)nwid, (jlong)sourceMac, (jlong)destMac, (jlong)etherType, (jlong)vlanid, dataArray); + if (env->ExceptionCheck()) { + LOGE("Exception calling onVirtualNetworkFrame"); + return; + } } @@ -204,6 +228,7 @@ namespace { const void *data) { LOGV("EventCallback"); JniRef *ref = (JniRef *) userData; + assert(ref); if (ref->node != node && event != ZT_EVENT_UP) { LOGE("Nodes not equal. ref->node %p, node %p. Event: %d", ref->node, node, event); return; @@ -211,6 +236,11 @@ namespace { JNIEnv *env; GETENV(env, ref->jvm); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); + return; + } + if (ref->eventListener == NULL) { LOGE("eventListener is NULL"); return; @@ -225,27 +255,47 @@ namespace { case ZT_EVENT_UP: { LOGD("Event Up"); env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + if (env->ExceptionCheck()) { + LOGE("Exception calling onEvent"); + return; + } break; } case ZT_EVENT_OFFLINE: { LOGD("Event Offline"); env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + if (env->ExceptionCheck()) { + LOGE("Exception calling onEvent"); + return; + } break; } case ZT_EVENT_ONLINE: { LOGD("Event Online"); env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + if (env->ExceptionCheck()) { + LOGE("Exception calling onEvent"); + return; + } break; } case ZT_EVENT_DOWN: { LOGD("Event Down"); env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + if (env->ExceptionCheck()) { + LOGE("Exception calling onEvent"); + return; + } break; } case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { LOGV("Identity Collision"); // call onEvent() env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + if (env->ExceptionCheck()) { + LOGE("Exception calling onEvent"); + return; + } } break; case ZT_EVENT_TRACE: { @@ -256,7 +306,16 @@ namespace { } const char *message = (const char *) data; jstring messageStr = env->NewStringUTF(message); + if (env->ExceptionCheck() || messageStr == NULL) { + LOGE("Exception creating new string"); + return; + } + env->CallVoidMethod(ref->eventListener, EventListener_onTrace_method, messageStr); + if (env->ExceptionCheck()) { + LOGE("Exception calling onTrace"); + return; + } } break; case ZT_EVENT_USER_MESSAGE: @@ -277,44 +336,56 @@ namespace { char p[4096] = {0}; bool secure = false; + int res = 0; switch (type) { case ZT_STATE_OBJECT_IDENTITY_PUBLIC: - snprintf(p, sizeof(p), "identity.public"); + res = snprintf(p, sizeof(p), "identity.public"); break; case ZT_STATE_OBJECT_IDENTITY_SECRET: - snprintf(p, sizeof(p), "identity.secret"); + res = snprintf(p, sizeof(p), "identity.secret"); secure = true; break; case ZT_STATE_OBJECT_PLANET: - snprintf(p, sizeof(p), "planet"); + res = snprintf(p, sizeof(p), "planet"); break; case ZT_STATE_OBJECT_MOON: - snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]); + res = snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]); break; case ZT_STATE_OBJECT_NETWORK_CONFIG: - snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]); + res = snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]); break; case ZT_STATE_OBJECT_PEER: - snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); + res = snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); break; case ZT_STATE_OBJECT_NULL: return; } - if (strlen(p) < 1) { + if (!(0 <= res && res < sizeof(p))) { + LOGE("snprintf error: %d", res); return; } JniRef *ref = (JniRef*)userData; + assert(ref); JNIEnv *env; GETENV(env, ref->jvm); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); + return; + } + if (ref->dataStorePutListener == NULL) { LOGE("dataStorePutListener is NULL"); return; } jstring nameStr = env->NewStringUTF(p); + if (env->ExceptionCheck() || nameStr == NULL) { + LOGE("Exception creating new string"); + return; + } if (bufferLength >= 0) { LOGD("JNI: Write file: %s", p); @@ -325,12 +396,29 @@ namespace { return; } - env->CallIntMethod(ref->dataStorePutListener, + int retval = env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDataStorePut_method, nameStr, bufferObj, secure); + if (env->ExceptionCheck()) { + LOGE("Exception calling onDataStorePut"); + return; + } + + if (retval != 0) { + LOGE("onDataStorePut error: %d", retval); + } + } else { LOGD("JNI: Delete file: %s", p); - env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDelete_method, nameStr); + int retval = env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDelete_method, nameStr); + if (env->ExceptionCheck()) { + LOGE("Exception calling onDelete"); + return; + } + + if (retval != 0) { + LOGE("onDelete error: %d", retval); + } } } @@ -350,53 +438,61 @@ namespace { LOGV("StateGetFunction"); char p[4096] = {0}; + int res = 0; switch (type) { case ZT_STATE_OBJECT_IDENTITY_PUBLIC: - snprintf(p, sizeof(p), "identity.public"); + res = snprintf(p, sizeof(p), "identity.public"); break; case ZT_STATE_OBJECT_IDENTITY_SECRET: - snprintf(p, sizeof(p), "identity.secret"); + res = snprintf(p, sizeof(p), "identity.secret"); break; case ZT_STATE_OBJECT_PLANET: - snprintf(p, sizeof(p), "planet"); + res = snprintf(p, sizeof(p), "planet"); break; case ZT_STATE_OBJECT_MOON: - snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]); + res = snprintf(p, sizeof(p), "moons.d/%.16" PRIx64 ".moon", id[0]); break; case ZT_STATE_OBJECT_NETWORK_CONFIG: - snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]); + res = snprintf(p, sizeof(p), "networks.d/%.16" PRIx64 ".conf", id[0]); break; case ZT_STATE_OBJECT_PEER: - snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); + res = snprintf(p, sizeof(p), "peers.d/%.10" PRIx64, id[0]); break; case ZT_STATE_OBJECT_NULL: return -100; } - if (strlen(p) < 1) { + if (!(0 <= res && res < sizeof(p))) { + LOGE("snprintf error: %d", res); return -101; } JniRef *ref = (JniRef*)userData; + assert(ref); JNIEnv *env; GETENV(env, ref->jvm); - if (ref->dataStoreGetListener == NULL) { - LOGE("dataStoreGetListener is NULL"); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); return -102; } + if (ref->dataStoreGetListener == NULL) { + LOGE("dataStoreGetListener is NULL"); + return -103; + } + jstring nameStr = env->NewStringUTF(p); - if(nameStr == NULL) + if(env->ExceptionCheck() || nameStr == NULL) { LOGE("Error creating name string object"); - return -103; // out of memory + return -104; // out of memory } jbyteArray bufferObj = newByteArray(env, bufferLength); if(env->ExceptionCheck() || bufferObj == NULL) { - return -104; + return -105; } LOGV("Calling onDataStoreGet(%s, %p)", p, buffer); @@ -406,11 +502,20 @@ namespace { DataStoreGetListener_onDataStoreGet_method, nameStr, bufferObj); + if (env->ExceptionCheck()) { + LOGE("Exception calling onDataStoreGet"); + return -106; + } LOGV("onDataStoreGet returned %d", retval); if(retval > 0) { + if (retval > bufferLength) { + LOGE("retval > bufferLength. retval: %d, bufferLength: %u", retval, bufferLength); + return -107; + } + void *data = env->GetPrimitiveArrayCritical(bufferObj, NULL); memcpy(buffer, data, retval); env->ReleasePrimitiveArrayCritical(bufferObj, data, 0); @@ -435,14 +540,20 @@ namespace { { LOGV("WirePacketSendFunction(%" PRId64 ", %p, %p, %u, %u)", localSocket, remoteAddress, buffer, bufferSize, ttl); JniRef *ref = (JniRef*)userData; + assert(ref); assert(ref->node == node); JNIEnv *env; GETENV(env, ref->jvm); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); + return -100; + } + if (ref->packetSender == NULL) { LOGE("packetSender is NULL"); - return -100; + return -101; } // @@ -450,16 +561,20 @@ namespace { // jobject remoteAddressObj = newInetSocketAddress(env, *remoteAddress); if (env->ExceptionCheck()) { - return -101; + return -102; } const unsigned char *bytes = static_cast(buffer); jbyteArray bufferObj = newByteArray(env, bytes, bufferSize); if (env->ExceptionCheck() || bufferObj == NULL) { - return -102; + return -103; } int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj, 0); + if (env->ExceptionCheck()) { + LOGE("Exception calling onSendPacketRequested"); + return -104; + } LOGV("JNI Packet Sender returned: %d", retval); return retval; @@ -478,6 +593,7 @@ namespace { LOGV("PathCheckFunction"); JniRef *ref = (JniRef*)userPtr; + assert(ref); assert(ref->node == node); if(ref->pathChecker == NULL) { @@ -487,6 +603,11 @@ namespace { JNIEnv *env; GETENV(env, ref->jvm); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); + return true; + } + // // may be NULL // @@ -495,7 +616,13 @@ namespace { return true; } - return env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, address, localSocket, remoteAddressObj); + jboolean ret = env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, address, localSocket, remoteAddressObj); + if (env->ExceptionCheck()) { + LOGE("Exception calling onPathCheck"); + return true; + } + + return ret; } /** @@ -511,6 +638,7 @@ namespace { LOGV("PathLookupFunction"); JniRef *ref = (JniRef*)userPtr; + assert(ref); assert(ref->node == node); if(ref->pathChecker == NULL) { @@ -520,10 +648,20 @@ namespace { JNIEnv *env; GETENV(env, ref->jvm); + if (env->ExceptionCheck()) { + LOGE("Unhandled pending exception"); + return false; + } + // // may be NULL // jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, PathChecker_onPathLookup_method, address, ss_family); + if (env->ExceptionCheck()) { + LOGE("Unable to call onPathLookup implementation"); + return false; + } + if(sockAddressObject == NULL) { LOGE("Unable to call onPathLookup implementation"); @@ -692,7 +830,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( NULL, &callbacks, (int64_t)now); + if (env->ExceptionCheck()) { + LOGE("Exception creating Node"); + if(node) + { + ZT_Node_delete(node); + node = NULL; + } + delete ref; + ref = NULL; + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } if(rc != ZT_RESULT_OK) { LOGE("Error creating Node: %d", rc); @@ -814,6 +963,14 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( (const void*)localData, frameLength, &nextBackgroundTaskDeadline); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_processVirtualNetworkFrame"); + free(localData); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } + if (rc != ZT_RESULT_OK) { + LOGE("ZT_Node_processVirtualNetworkFrame returned: %d", rc); + } free(localData); @@ -880,6 +1037,11 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( localData, packetLength, &nextBackgroundTaskDeadline); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_processWirePacket"); + free(localData); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } if(rc != ZT_RESULT_OK) { LOGE("ZT_Node_processWirePacket returned: %d", rc); @@ -918,6 +1080,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( int64_t nextBackgroundTaskDeadline = 0; ZT_ResultCode rc = ZT_Node_processBackgroundTasks(node, NULL, now, &nextBackgroundTaskDeadline); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_processBackgroundTasks"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } + if (rc != ZT_RESULT_OK) { + LOGE("ZT_Node_processBackgroundTasks returned: %d", rc); + } jlong *outDeadline = (jlong*)env->GetPrimitiveArrayCritical(out_nextBackgroundTaskDeadline, NULL); outDeadline[0] = (jlong)nextBackgroundTaskDeadline; @@ -939,6 +1108,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join( uint64_t nwid = (uint64_t)in_nwid; ZT_ResultCode rc = ZT_Node_join(node, nwid, NULL, NULL); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_join"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } return createResultObject(env, rc); } @@ -957,6 +1130,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave( uint64_t nwid = (uint64_t)in_nwid; ZT_ResultCode rc = ZT_Node_leave(node, nwid, NULL, NULL); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_leave"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } return createResultObject(env, rc); } @@ -982,6 +1159,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe( ZT_ResultCode rc = ZT_Node_multicastSubscribe( node, NULL, nwid, multicastGroup, multicastAdi); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_multicastSubscribe"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } return createResultObject(env, rc); } @@ -1007,6 +1188,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe( ZT_ResultCode rc = ZT_Node_multicastUnsubscribe( node, nwid, multicastGroup, multicastAdi); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_multicastUnsubscribe"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } return createResultObject(env, rc); } @@ -1029,6 +1214,11 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_orbit( uint64_t moonSeed = (uint64_t)in_moonSeed; ZT_ResultCode rc = ZT_Node_orbit(node, NULL, moonWorldId, moonSeed); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_orbit"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } + return createResultObject(env, rc); } @@ -1048,6 +1238,11 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit( uint64_t moonWorldId = (uint64_t)in_moonWorldId; ZT_ResultCode rc = ZT_Node_deorbit(node, NULL, moonWorldId); + if (env->ExceptionCheck()) { + LOGE("Exception calling ZT_Node_deorbit"); + return ResultCode_RESULT_FATAL_ERROR_INTERNAL_enum; + } + return createResultObject(env, rc); } @@ -1095,6 +1290,10 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig( ZT_Node *node = findNode(nodeId); ZT_VirtualNetworkConfig *vnetConfig = ZT_Node_networkConfig(node, nwid); + if (vnetConfig == NULL) { + LOGE("vnetConfig == NULL"); + return NULL; + } jobject vnetConfigObject = newNetworkConfig(env, *vnetConfig); @@ -1161,6 +1360,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( ZT_VirtualNetworkList *networkList = ZT_Node_networks(node); if(networkList == NULL) { + LOGE("ZT_Node_networks returned NULL"); return NULL; } From 7f996ea6d54d2f5fa08435b6cbd16dbfdd3de064 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Mon, 13 Feb 2023 10:46:55 -0500 Subject: [PATCH 66/68] simplify loadLibrary --- java/src/com/zerotier/sdk/NativeUtils.java | 93 ---------------------- java/src/com/zerotier/sdk/Node.java | 27 +------ 2 files changed, 3 insertions(+), 117 deletions(-) delete mode 100644 java/src/com/zerotier/sdk/NativeUtils.java diff --git a/java/src/com/zerotier/sdk/NativeUtils.java b/java/src/com/zerotier/sdk/NativeUtils.java deleted file mode 100644 index 4932a6c71..000000000 --- a/java/src/com/zerotier/sdk/NativeUtils.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.zerotier.sdk; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Simple library class for working with JNI (Java Native Interface) - * - * @see http://adamheinrich.com/2012/how-to-load-native-jni-library-from-jar - * - * @author Adam Heirnich , http://www.adamh.cz - */ -public class NativeUtils { - - /** - * Private constructor - this class will never be instanced - */ - private NativeUtils() { - } - - /** - * Loads library from current JAR archive - * - * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting. - * Method uses String as filename because the pathname is "abstract", not system-dependent. - * - * @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext - * @throws IOException If temporary file creation or read/write operation fails - * @throws IllegalArgumentException If source file (param path) does not exist - * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}). - */ - public static void loadLibraryFromJar(String path) throws IOException { - - if (!path.startsWith("/")) { - throw new IllegalArgumentException("The path has to be absolute (start with '/')."); - } - - // Obtain filename from path - String[] parts = path.split("/"); - String filename = (parts.length > 1) ? parts[parts.length - 1] : null; - - // Split filename to prefix and suffix (extension) - String prefix = ""; - String suffix = null; - if (filename != null) { - parts = filename.split("\\.", 2); - prefix = parts[0]; - suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-) - } - - // Check if the filename is okay - if (filename == null || prefix.length() < 3) { - throw new IllegalArgumentException("The filename has to be at least 3 characters long."); - } - - // Prepare temporary file - File temp = File.createTempFile(prefix, suffix); - temp.deleteOnExit(); - - if (!temp.exists()) { - throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist."); - } - - // Prepare buffer for data copying - byte[] buffer = new byte[1024]; - int readBytes; - - // Open and check input stream - InputStream is = NativeUtils.class.getResourceAsStream(path); - if (is == null) { - throw new FileNotFoundException("File " + path + " was not found inside JAR."); - } - - // Open output stream and copy data between source file in JAR and the temporary file - OutputStream os = new FileOutputStream(temp); - try { - while ((readBytes = is.read(buffer)) != -1) { - os.write(buffer, 0, readBytes); - } - } finally { - // If read/write fails, close streams safely before throwing an exception - os.close(); - is.close(); - } - - // Finally, load the library - System.load(temp.getAbsolutePath()); - } -} \ No newline at end of file diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index ac20398e1..46060b2bc 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -28,35 +28,14 @@ package com.zerotier.sdk; import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.io.IOException; /** * A ZeroTier One node */ public class Node { - static { - try { - System.loadLibrary("ZeroTierOneJNI"); - } catch (UnsatisfiedLinkError e) { - try { - if(System.getProperty("os.name").startsWith("Windows")) { - System.out.println("Arch: " + System.getProperty("sun.arch.data.model")); - if(System.getProperty("sun.arch.data.model").equals("64")) { - NativeUtils.loadLibraryFromJar("/lib/ZeroTierOneJNI_win64.dll"); - } else { - NativeUtils.loadLibraryFromJar("/lib/ZeroTierOneJNI_win32.dll"); - } - } else if(System.getProperty("os.name").startsWith("Mac")) { - NativeUtils.loadLibraryFromJar("/lib/libZeroTierOneJNI.jnilib"); - } else { - // TODO: Linux - } - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - } + static { + System.loadLibrary("ZeroTierOneJNI"); + } private static final String TAG = "NODE"; From 8d74d34f2a99ec627db979ffdba9ff06f2ad79ff Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Thu, 16 Feb 2023 12:41:27 -0500 Subject: [PATCH 67/68] rename Node.networks -> Node.networkConfigs --- java/jni/com_zerotierone_sdk_Node.cpp | 4 ++-- java/jni/com_zerotierone_sdk_Node.h | 4 ++-- java/src/com/zerotier/sdk/Node.java | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 1a33e0123..536c7cb6a 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -1348,10 +1348,10 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( /* * Class: com_zerotier_sdk_Node - * Method: networks + * Method: networkConfigs * Signature: (J)[Lcom/zerotier/sdk/VirtualNetworkConfig; */ -JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( +JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networkConfigs( JNIEnv *env, jobject obj, jlong id) { int64_t nodeId = (int64_t) id; diff --git a/java/jni/com_zerotierone_sdk_Node.h b/java/jni/com_zerotierone_sdk_Node.h index 5acf2ff34..a439f4129 100644 --- a/java/jni/com_zerotierone_sdk_Node.h +++ b/java/jni/com_zerotierone_sdk_Node.h @@ -129,10 +129,10 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers /* * Class: com_zerotier_sdk_Node - * Method: networks + * Method: networkConfigs * Signature: (J)[Lcom/zerotier/sdk/VirtualNetworkConfig; */ -JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks +JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networkConfigs (JNIEnv *, jobject, jlong); #ifdef __cplusplus diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java index 46060b2bc..a3f3ab470 100644 --- a/java/src/com/zerotier/sdk/Node.java +++ b/java/src/com/zerotier/sdk/Node.java @@ -367,8 +367,8 @@ public class Node { * * @return List of networks or NULL on failure */ - public VirtualNetworkConfig[] networks() { - return networks(nodeId); + public VirtualNetworkConfig[] networkConfigs() { + return networkConfigs(nodeId); } /** @@ -456,5 +456,5 @@ public class Node { private native Peer[] peers(long nodeId); - private native VirtualNetworkConfig[] networks(long nodeId); + private native VirtualNetworkConfig[] networkConfigs(long nodeId); } From cc4251c5b704ae65466b8e315841dbd650061a39 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Sat, 4 Mar 2023 00:43:00 -0800 Subject: [PATCH 68/68] Windows file permissions fix (#1887) --- one.cpp | 21 +++++++++++++++++++++ osdep/OSUtils.cpp | 10 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/one.cpp b/one.cpp index 46a23b1ee..ba5be9b18 100644 --- a/one.cpp +++ b/one.cpp @@ -2235,6 +2235,27 @@ int main(int argc,char **argv) } } + // Check and fix permissions on critical files at startup + try { + char p[4096]; + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "identity.secret", homeDir.c_str()); + if (OSUtils::fileExists(p)) { + OSUtils::lockDownFile(p, false); + } + } + catch (...) { + } + + try { + char p[4096]; + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "authtoken.secret", homeDir.c_str()); + if (OSUtils::fileExists(p)) { + OSUtils::lockDownFile(p, false); + } + } + catch (...) { + } + // This can be removed once the new controller code has been around for many versions if (OSUtils::fileExists((homeDir + ZT_PATH_SEPARATOR_S + "controller.db").c_str(),true)) { fprintf(stderr,"%s: FATAL: an old controller.db exists in %s -- see instructions in controller/README.md for how to migrate!" ZT_EOL_S,argv[0],homeDir.c_str()); diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp index 36814523a..e237325c4 100644 --- a/osdep/OSUtils.cpp +++ b/osdep/OSUtils.cpp @@ -257,6 +257,16 @@ void OSUtils::lockDownFile(const char *path,bool isDir) CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } + + // Remove 'Everyone' group from R/RX access + startupInfo.cb = sizeof(startupInfo); + memset(&startupInfo, 0, sizeof(STARTUPINFOA)); + memset(&processInfo, 0, sizeof(PROCESS_INFORMATION)); + if (CreateProcessA(NULL, (LPSTR)(std::string("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /remove:g Everyone /t /c /Q").c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) { + WaitForSingleObject(processInfo.hProcess, INFINITE); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + } } #endif #endif