mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-25 11:12:23 +00:00
Merge branch 'dev' of http://10.6.6.2/zerotier/ZeroTierOne into dev
This commit is contained in:
commit
b3298a8f57
java
@ -56,6 +56,7 @@ namespace {
|
|||||||
, eventListener(NULL)
|
, eventListener(NULL)
|
||||||
, frameListener(NULL)
|
, frameListener(NULL)
|
||||||
, configListener(NULL)
|
, configListener(NULL)
|
||||||
|
, pathChecker(NULL)
|
||||||
, callbacks(NULL)
|
, callbacks(NULL)
|
||||||
{
|
{
|
||||||
callbacks = (ZT_Node_Callbacks*)malloc(sizeof(ZT_Node_Callbacks));
|
callbacks = (ZT_Node_Callbacks*)malloc(sizeof(ZT_Node_Callbacks));
|
||||||
@ -73,6 +74,7 @@ namespace {
|
|||||||
env->DeleteGlobalRef(eventListener);
|
env->DeleteGlobalRef(eventListener);
|
||||||
env->DeleteGlobalRef(frameListener);
|
env->DeleteGlobalRef(frameListener);
|
||||||
env->DeleteGlobalRef(configListener);
|
env->DeleteGlobalRef(configListener);
|
||||||
|
env->DeleteGlobalRef(pathChecker);
|
||||||
|
|
||||||
free(callbacks);
|
free(callbacks);
|
||||||
callbacks = NULL;
|
callbacks = NULL;
|
||||||
@ -90,6 +92,7 @@ namespace {
|
|||||||
jobject eventListener;
|
jobject eventListener;
|
||||||
jobject frameListener;
|
jobject frameListener;
|
||||||
jobject configListener;
|
jobject configListener;
|
||||||
|
jobject pathChecker;
|
||||||
|
|
||||||
ZT_Node_Callbacks *callbacks;
|
ZT_Node_Callbacks *callbacks;
|
||||||
};
|
};
|
||||||
@ -487,6 +490,165 @@ namespace {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PathCheckFunction(ZT_Node *node,
|
||||||
|
void *userPtr,
|
||||||
|
void *threadPtr,
|
||||||
|
uint64_t address,
|
||||||
|
const struct sockaddr_storage *localAddress,
|
||||||
|
const struct sockaddr_storage *remoteAddress)
|
||||||
|
{
|
||||||
|
JniRef *ref = (JniRef*)userPtr;
|
||||||
|
assert(ref->node == node);
|
||||||
|
|
||||||
|
if(ref->pathChecker == NULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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", "(JLjava/net/InetSocketAddress;Ljava/net/InetSocketAddress;)Z");
|
||||||
|
if(pathCheckCallbackMethod == NULL)
|
||||||
|
{
|
||||||
|
LOGE("Couldn't find onPathCheck method implementation");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject localAddressObj = NULL;
|
||||||
|
jobject remoteAddressObj = NULL;
|
||||||
|
|
||||||
|
if(memcmp(localAddress, &ZT_SOCKADDR_NULL, sizeof(sockaddr_storage)) != 0)
|
||||||
|
{
|
||||||
|
localAddressObj = newInetSocketAddress(env, *localAddress);
|
||||||
|
}
|
||||||
|
if(memcmp(remoteAddress, &ZT_SOCKADDR_NULL, sizeof(sockaddr_storage)) != 0)
|
||||||
|
{
|
||||||
|
remoteAddressObj = newInetSocketAddress(env, *remoteAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
return env->CallBooleanMethod(ref->pathChecker, pathCheckCallbackMethod, address, localAddressObj, remoteAddressObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PathLookupFunction(ZT_Node *node,
|
||||||
|
void *userPtr,
|
||||||
|
void *threadPtr,
|
||||||
|
uint64_t address,
|
||||||
|
int ss_family,
|
||||||
|
struct sockaddr_storage *result)
|
||||||
|
{
|
||||||
|
JniRef *ref = (JniRef*)userPtr;
|
||||||
|
assert(ref->node == node);
|
||||||
|
|
||||||
|
if(ref->pathChecker == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::map<uint64_t, JniRef*> NodeMap;
|
typedef std::map<uint64_t, JniRef*> NodeMap;
|
||||||
static NodeMap nodeMap;
|
static NodeMap nodeMap;
|
||||||
ZeroTier::Mutex nodeMapMutex;
|
ZeroTier::Mutex nodeMapMutex;
|
||||||
@ -619,12 +781,28 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init(
|
|||||||
}
|
}
|
||||||
ref->eventListener = env->NewGlobalRef(tmp);
|
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->callbacks->dataStoreGetFunction = &DataStoreGetFunction;
|
ref->callbacks->dataStoreGetFunction = &DataStoreGetFunction;
|
||||||
ref->callbacks->dataStorePutFunction = &DataStorePutFunction;
|
ref->callbacks->dataStorePutFunction = &DataStorePutFunction;
|
||||||
ref->callbacks->wirePacketSendFunction = &WirePacketSendFunction;
|
ref->callbacks->wirePacketSendFunction = &WirePacketSendFunction;
|
||||||
ref->callbacks->virtualNetworkFrameFunction = &VirtualNetworkFrameFunctionCallback;
|
ref->callbacks->virtualNetworkFrameFunction = &VirtualNetworkFrameFunctionCallback;
|
||||||
ref->callbacks->virtualNetworkConfigFunction = &VirtualNetworkConfigFunctionCallback;
|
ref->callbacks->virtualNetworkConfigFunction = &VirtualNetworkConfigFunctionCallback;
|
||||||
ref->callbacks->eventCallback = &EventCallback;
|
ref->callbacks->eventCallback = &EventCallback;
|
||||||
|
ref->callbacks->pathCheckFunction = &PathCheckFunction;
|
||||||
|
ref->callbacks->pathLookupFunction = &PathLookupFunction;
|
||||||
|
|
||||||
ZT_ResultCode rc = ZT_Node_new(
|
ZT_ResultCode rc = ZT_Node_new(
|
||||||
&node,
|
&node,
|
||||||
@ -1107,6 +1285,54 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe(
|
|||||||
return createResultObject(env, rc);
|
return createResultObject(env, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_zerotier_sdk_Node
|
||||||
|
* Method: orbit
|
||||||
|
* Signature: (JJJ)Lcom/zerotier/sdk/ResultCode;
|
||||||
|
*/
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_orbit(
|
||||||
|
JNIEnv *env, jobject obj,
|
||||||
|
jlong id,
|
||||||
|
jlong in_moonWorldId,
|
||||||
|
jlong in_moonSeed)
|
||||||
|
{
|
||||||
|
uint64_t nodeId = (uint64_t)id;
|
||||||
|
ZT_Node *node = findNode(nodeId);
|
||||||
|
if(node == NULL)
|
||||||
|
{
|
||||||
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t moonWorldId = (uint64_t)in_moonWorldId;
|
||||||
|
uint64_t moonSeed = (uint64_t)in_moonSeed;
|
||||||
|
|
||||||
|
ZT_ResultCode rc = ZT_Node_orbit(node, NULL, moonWorldId, moonSeed);
|
||||||
|
return createResultObject(env, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_zerotier_sdk_Node
|
||||||
|
* Method: deorbit
|
||||||
|
* Signature: (JJ)L/com/zerotier/sdk/ResultCode;
|
||||||
|
*/
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_deorbit(
|
||||||
|
JNIEnv *env, jobject obj,
|
||||||
|
jlong id,
|
||||||
|
jlong in_moonWorldId)
|
||||||
|
{
|
||||||
|
uint64_t nodeId = (uint64_t)id;
|
||||||
|
ZT_Node *node = findNode(nodeId);
|
||||||
|
if(node == NULL)
|
||||||
|
{
|
||||||
|
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t moonWorldId = (uint64_t)in_moonWorldId;
|
||||||
|
|
||||||
|
ZT_ResultCode rc = ZT_Node_deorbit(node, NULL, moonWorldId);
|
||||||
|
return createResultObject(env, rc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_zerotier_sdk_Node
|
* Class: com_zerotier_sdk_Node
|
||||||
* Method: address
|
* Method: address
|
||||||
|
@ -74,6 +74,7 @@ public class Node {
|
|||||||
private final EventListener eventListener;
|
private final EventListener eventListener;
|
||||||
private final VirtualNetworkFrameListener frameListener;
|
private final VirtualNetworkFrameListener frameListener;
|
||||||
private final VirtualNetworkConfigListener configListener;
|
private final VirtualNetworkConfigListener configListener;
|
||||||
|
private final PathChecker pathChecker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ZeroTier One node
|
* Create a new ZeroTier One node
|
||||||
@ -88,6 +89,7 @@ public class Node {
|
|||||||
* @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 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
|
||||||
* @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 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,
|
public Node(long now,
|
||||||
DataStoreGetListener getListener,
|
DataStoreGetListener getListener,
|
||||||
@ -95,7 +97,8 @@ public class Node {
|
|||||||
PacketSender sender,
|
PacketSender sender,
|
||||||
EventListener eventListener,
|
EventListener eventListener,
|
||||||
VirtualNetworkFrameListener frameListener,
|
VirtualNetworkFrameListener frameListener,
|
||||||
VirtualNetworkConfigListener configListener) throws NodeException
|
VirtualNetworkConfigListener configListener,
|
||||||
|
PathChecker pathChecker) throws NodeException
|
||||||
{
|
{
|
||||||
this.nodeId = now;
|
this.nodeId = now;
|
||||||
|
|
||||||
@ -105,6 +108,7 @@ public class Node {
|
|||||||
this.eventListener = eventListener;
|
this.eventListener = eventListener;
|
||||||
this.frameListener = frameListener;
|
this.frameListener = frameListener;
|
||||||
this.configListener = configListener;
|
this.configListener = configListener;
|
||||||
|
this.pathChecker = pathChecker;
|
||||||
|
|
||||||
ResultCode rc = node_init(now);
|
ResultCode rc = node_init(now);
|
||||||
if(rc != ResultCode.RESULT_OK)
|
if(rc != ResultCode.RESULT_OK)
|
||||||
@ -318,6 +322,34 @@ public class Node {
|
|||||||
return multicastUnsubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
return multicastUnsubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add or update a moon
|
||||||
|
*
|
||||||
|
* Moons are persisted in the data store in moons.d/, so this can persist
|
||||||
|
* across invocations if the contents of moon.d are scanned and orbit is
|
||||||
|
* called for each on startup.
|
||||||
|
*
|
||||||
|
* @param moonWorldId Moon's world ID
|
||||||
|
* @param moonSeed If non-zero, the ZeroTier address of any member of the moon to query for moon definition
|
||||||
|
* @return Error if moon was invalid or failed to be added
|
||||||
|
*/
|
||||||
|
public ResultCode orbit(
|
||||||
|
long moonWorldId,
|
||||||
|
long moonSeed) {
|
||||||
|
return orbit(nodeId, moonWorldId, moonSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a moon (does nothing if not present)
|
||||||
|
*
|
||||||
|
* @param moonWorldId World ID of moon to remove
|
||||||
|
* @return Error if anything bad happened
|
||||||
|
*/
|
||||||
|
public ResultCode deorbit(
|
||||||
|
long moonWorldId) {
|
||||||
|
return deorbit(nodeId, moonWorldId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this node's 40-bit ZeroTier address
|
* Get this node's 40-bit ZeroTier address
|
||||||
*
|
*
|
||||||
@ -420,6 +452,15 @@ public class Node {
|
|||||||
long multicastGroup,
|
long multicastGroup,
|
||||||
long multicastAdi);
|
long multicastAdi);
|
||||||
|
|
||||||
|
private native ResultCode orbit(
|
||||||
|
long nodeId,
|
||||||
|
long moonWorldId,
|
||||||
|
long moonSeed);
|
||||||
|
|
||||||
|
private native ResultCode deorbit(
|
||||||
|
long nodeId,
|
||||||
|
long moonWorldId);
|
||||||
|
|
||||||
private native long address(long nodeId);
|
private native long address(long nodeId);
|
||||||
|
|
||||||
private native NodeStatus status(long nodeId);
|
private native NodeStatus status(long nodeId);
|
||||||
|
45
java/src/com/zerotier/sdk/PathChecker.java
Normal file
45
java/src/com/zerotier/sdk/PathChecker.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* ZeroTier One - Network Virtualization Everywhere
|
||||||
|
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.zerotier.sdk;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
public interface PathChecker {
|
||||||
|
/**
|
||||||
|
* Callback to check whether a path should be used for ZeroTier traffic
|
||||||
|
*
|
||||||
|
* This function must return true if the path should be used.
|
||||||
|
*
|
||||||
|
* If no path check function is specified, ZeroTier will still exclude paths
|
||||||
|
* that overlap with ZeroTier-assigned and managed IP address blocks. But the
|
||||||
|
* use of a path check function is recommended to ensure that recursion does
|
||||||
|
* not occur in cases where addresses are assigned by the OS or managed by
|
||||||
|
* an out of band mechanism like DHCP. The path check function should examine
|
||||||
|
* all configured ZeroTier interfaces and check to ensure that the supplied
|
||||||
|
* addresses will not result in ZeroTier traffic being sent over a ZeroTier
|
||||||
|
* interface (recursion).
|
||||||
|
*
|
||||||
|
* Obviously this is not required in configurations where this can't happen,
|
||||||
|
* such as network containers or embedded.
|
||||||
|
*
|
||||||
|
* @param ztAddress ZeroTier address or 0 for none/any
|
||||||
|
* @param localAddress Local interface address
|
||||||
|
* @param remoteAddress remote address
|
||||||
|
*/
|
||||||
|
boolean onPathCheck(long ztAddress, InetSocketAddress localAddress, InetSocketAddress remoteAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to get physical addresses for ZeroTier peers
|
||||||
|
*
|
||||||
|
* If provided this function will be occasionally called to get physical
|
||||||
|
* addresses that might be tried to reach a ZeroTier address.
|
||||||
|
*
|
||||||
|
* @param ztAddress ZeroTier address (least significant 40 bits)
|
||||||
|
* @param ss_family desired address family or -1 for any
|
||||||
|
* @return address and port of ztAddress or null
|
||||||
|
*/
|
||||||
|
InetSocketAddress onPathLookup(long ztAddress, int ss_family);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user