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(