android_jni NDK build patch, also removed old unrelated SDK files
This commit is contained in:
@@ -12,6 +12,7 @@ LOCAL_C_INCLUDES := $(LWIP)/include
|
|||||||
LOCAL_C_INCLUDES += $(LWIP)/include/lwip
|
LOCAL_C_INCLUDES += $(LWIP)/include/lwip
|
||||||
LOCAL_C_INCLUDES += $(LWIP)/include/lwip/priv
|
LOCAL_C_INCLUDES += $(LWIP)/include/lwip/priv
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES += $(ZTSDK)
|
||||||
LOCAL_C_INCLUDES += $(ZTSDK)/src
|
LOCAL_C_INCLUDES += $(ZTSDK)/src
|
||||||
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers/lwip
|
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers/lwip
|
||||||
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers
|
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers
|
||||||
@@ -100,7 +101,6 @@ LOCAL_SRC_FILES += $(LWIP)/core/ipv4/autoip.c \
|
|||||||
# $(LWIP)/core/ipv6/mld6.c \
|
# $(LWIP)/core/ipv6/mld6.c \
|
||||||
# $(LWIP)/core/ipv6/nd6.c
|
# $(LWIP)/core/ipv6/nd6.c
|
||||||
|
|
||||||
|
|
||||||
# lwIP netif files
|
# lwIP netif files
|
||||||
LOCAL_SRC_FILES += \
|
LOCAL_SRC_FILES += \
|
||||||
$(LWIP)/netif/ethernetif.c \
|
$(LWIP)/netif/ethernetif.c \
|
||||||
@@ -115,10 +115,4 @@ LOCAL_SRC_FILES += \
|
|||||||
$(ZTSDK)/src/tap.cpp \
|
$(ZTSDK)/src/tap.cpp \
|
||||||
$(ZTSDK)/src/stack_drivers/lwip/lwip.cpp
|
$(ZTSDK)/src/stack_drivers/lwip/lwip.cpp
|
||||||
|
|
||||||
# JNI Files
|
|
||||||
#LOCAL_SRC_FILES += \
|
|
||||||
# com_zerotierone_sdk_Node.cpp \
|
|
||||||
# ZT_jniutils.cpp \
|
|
||||||
# ZT_jnilookup.cpp
|
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
@@ -1,158 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
|
|
||||||
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 retreiving JNI Environment");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jclass cls = env->FindClass(name.c_str());
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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 <jni.h>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,931 +0,0 @@
|
|||||||
#include "ZT_jniutils.h"
|
|
||||||
#include "ZT_jnilookup.h"
|
|
||||||
#include <string>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
extern JniLookup lookup;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jobject createResultObject(JNIEnv *env, ZT_ResultCode code)
|
|
||||||
{
|
|
||||||
jclass resultClass = NULL;
|
|
||||||
|
|
||||||
jobject resultObject = NULL;
|
|
||||||
|
|
||||||
resultClass = lookup.findClass("com/zerotier/sdk/ResultCode");
|
|
||||||
if(resultClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Couldnt find ResultCode class");
|
|
||||||
return NULL; // exception thrown
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fieldName;
|
|
||||||
switch(code)
|
|
||||||
{
|
|
||||||
case ZT_RESULT_OK:
|
|
||||||
LOGV("ZT_RESULT_OK");
|
|
||||||
fieldName = "RESULT_OK";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY:
|
|
||||||
LOGV("ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY");
|
|
||||||
fieldName = "RESULT_FATAL_ERROR_OUT_OF_MEMORY";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED:
|
|
||||||
LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED");
|
|
||||||
fieldName = "RESULT_FATAL_ERROR_DATA_STORE_FAILED";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_ERROR_NETWORK_NOT_FOUND:
|
|
||||||
LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED");
|
|
||||||
fieldName = "RESULT_ERROR_NETWORK_NOT_FOUND";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_FATAL_ERROR_INTERNAL:
|
|
||||||
default:
|
|
||||||
LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED");
|
|
||||||
fieldName = "RESULT_FATAL_ERROR_INTERNAL";
|
|
||||||
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);
|
|
||||||
if(env->ExceptionCheck() || resultObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error on GetStaticObjectField");
|
|
||||||
}
|
|
||||||
return resultObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
switch(status)
|
|
||||||
{
|
|
||||||
case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION:
|
|
||||||
fieldName = "NETWORK_STATUS_REQUESTING_CONFIGURATION";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_OK:
|
|
||||||
fieldName = "NETWORK_STATUS_OK";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_ACCESS_DENIED:
|
|
||||||
fieldName = "NETWORK_STATUS_ACCESS_DENIED";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_NOT_FOUND:
|
|
||||||
fieldName = "NETWORK_STATUS_NOT_FOUND";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_PORT_ERROR:
|
|
||||||
fieldName = "NETWORK_STATUS_PORT_ERROR";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_CLIENT_TOO_OLD:
|
|
||||||
fieldName = "NETWORK_STATUS_CLIENT_TOO_OLD";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(statusClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkStatus;");
|
|
||||||
|
|
||||||
statusObject = env->GetStaticObjectField(statusClass, enumField);
|
|
||||||
|
|
||||||
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;
|
|
||||||
switch(event)
|
|
||||||
{
|
|
||||||
case ZT_EVENT_UP:
|
|
||||||
fieldName = "EVENT_UP";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_OFFLINE:
|
|
||||||
fieldName = "EVENT_OFFLINE";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_ONLINE:
|
|
||||||
fieldName = "EVENT_ONLINE";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_DOWN:
|
|
||||||
fieldName = "EVENT_DOWN";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION:
|
|
||||||
fieldName = "EVENT_FATAL_ERROR_IDENTITY_COLLISION";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_TRACE:
|
|
||||||
fieldName = "EVENT_TRACE";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(eventClass, fieldName.c_str(), "Lcom/zerotier/sdk/Event;");
|
|
||||||
|
|
||||||
eventObject = env->GetStaticObjectField(eventClass, enumField);
|
|
||||||
|
|
||||||
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;
|
|
||||||
switch(role)
|
|
||||||
{
|
|
||||||
case ZT_PEER_ROLE_LEAF:
|
|
||||||
fieldName = "PEER_ROLE_LEAF";
|
|
||||||
break;
|
|
||||||
case ZT_PEER_ROLE_RELAY:
|
|
||||||
fieldName = "PEER_ROLE_RELAY";
|
|
||||||
break;
|
|
||||||
case ZT_PEER_ROLE_ROOT:
|
|
||||||
fieldName = "PEER_ROLE_ROOTS";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(peerRoleClass, fieldName.c_str(), "Lcom/zerotier/sdk/PeerRole;");
|
|
||||||
|
|
||||||
peerRoleObject = env->GetStaticObjectField(peerRoleClass, enumField);
|
|
||||||
|
|
||||||
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;
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case ZT_NETWORK_TYPE_PRIVATE:
|
|
||||||
fieldName = "NETWORK_TYPE_PRIVATE";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_TYPE_PUBLIC:
|
|
||||||
fieldName = "NETWORK_TYPE_PUBLIC";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(vntypeClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkType;");
|
|
||||||
vntypeObject = env->GetStaticObjectField(vntypeClass, enumField);
|
|
||||||
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;
|
|
||||||
switch(op)
|
|
||||||
{
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_UP";
|
|
||||||
break;
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE";
|
|
||||||
break;
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN";
|
|
||||||
break;
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(vnetConfigOpClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;");
|
|
||||||
vnetConfigOpObject = env->GetStaticObjectField(vnetConfigOpClass, enumField);
|
|
||||||
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("Erorr finding getByAddress() static method");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject inetAddressObj = NULL;
|
|
||||||
switch(addr.ss_family)
|
|
||||||
{
|
|
||||||
case AF_INET6:
|
|
||||||
{
|
|
||||||
sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr;
|
|
||||||
jbyteArray buff = env->NewByteArray(16);
|
|
||||||
if(buff == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating IPV6 byte array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetByteArrayRegion(buff, 0, 16, (jbyte*)ipv6->sin6_addr.s6_addr);
|
|
||||||
inetAddressObj = env->CallStaticObjectMethod(
|
|
||||||
inetAddressClass, inetAddress_getByAddress, buff);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AF_INET:
|
|
||||||
{
|
|
||||||
sockaddr_in *ipv4 = (sockaddr_in*)&addr;
|
|
||||||
jbyteArray buff = env->NewByteArray(4);
|
|
||||||
if(buff == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating IPV4 byte array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetByteArrayRegion(buff, 0, 4, (jbyte*)&ipv4->sin_addr);
|
|
||||||
inetAddressObj = env->CallStaticObjectMethod(
|
|
||||||
inetAddressClass, inetAddress_getByAddress, buff);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(env->ExceptionCheck() || inetAddressObj == NULL) {
|
|
||||||
LOGE("Error creating InetAddress object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return inetAddressObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = newInetAddress(env, addr);
|
|
||||||
|
|
||||||
if(env->ExceptionCheck() || inetAddressObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating new inet address");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inetSocketAddress_constructor = lookup.findMethod(
|
|
||||||
inetSocketAddressClass, "<init>", "(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)
|
|
||||||
{
|
|
||||||
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:
|
|
||||||
{
|
|
||||||
LOGE("ERROR: addr.ss_family is not set or unknown");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
jobject inetSocketAddressObject = env->NewObject(inetSocketAddressClass, inetSocketAddress_constructor, inetAddressObject, port);
|
|
||||||
if(env->ExceptionCheck() || inetSocketAddressObject == NULL) {
|
|
||||||
LOGE("Error creating InetSocketAddress object");
|
|
||||||
}
|
|
||||||
return inetSocketAddressObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc)
|
|
||||||
{
|
|
||||||
jclass multicastGroupClass = NULL;
|
|
||||||
jmethodID multicastGroup_constructor = NULL;
|
|
||||||
|
|
||||||
jfieldID macField = NULL;
|
|
||||||
jfieldID adiField = NULL;
|
|
||||||
|
|
||||||
multicastGroupClass = lookup.findClass("com/zerotier/sdk/MulticastGroup");
|
|
||||||
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
multicastGroup_constructor = lookup.findMethod(
|
|
||||||
multicastGroupClass, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || multicastGroup_constructor == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject multicastGroupObj = env->NewObject(multicastGroupClass, multicastGroup_constructor);
|
|
||||||
if(env->ExceptionCheck() || multicastGroupObj == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
macField = lookup.findField(multicastGroupClass, "mac", "J");
|
|
||||||
if(env->ExceptionCheck() || macField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
adiField = lookup.findField(multicastGroupClass, "adi", "J");
|
|
||||||
if(env->ExceptionCheck() || adiField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetLongField(multicastGroupObj, macField, mc.mac);
|
|
||||||
env->SetLongField(multicastGroupObj, adiField, mc.adi);
|
|
||||||
|
|
||||||
return multicastGroupObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp)
|
|
||||||
{
|
|
||||||
LOGV("newPeerPhysicalPath Called");
|
|
||||||
jclass pppClass = NULL;
|
|
||||||
|
|
||||||
jfieldID addressField = NULL;
|
|
||||||
jfieldID lastSendField = NULL;
|
|
||||||
jfieldID lastReceiveField = NULL;
|
|
||||||
jfieldID activeField = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
activeField = lookup.findField(pppClass, "active", "Z");
|
|
||||||
if(env->ExceptionCheck() || activeField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding active 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, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || ppp_constructor == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding PeerPhysicalPath constructor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject pppObject = env->NewObject(pppClass, ppp_constructor);
|
|
||||||
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, addressField, addressObject);
|
|
||||||
env->SetLongField(pppObject, lastSendField, ppp.lastSend);
|
|
||||||
env->SetLongField(pppObject, lastReceiveField, ppp.lastReceive);
|
|
||||||
env->SetBooleanField(pppObject, activeField, ppp.active);
|
|
||||||
env->SetBooleanField(pppObject, preferredField, ppp.preferred);
|
|
||||||
|
|
||||||
if(env->ExceptionCheck()) {
|
|
||||||
LOGE("Exception assigning fields to PeerPhysicalPath object");
|
|
||||||
}
|
|
||||||
|
|
||||||
return pppObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newPeer(JNIEnv *env, const ZT_Peer &peer)
|
|
||||||
{
|
|
||||||
LOGV("newPeer called");
|
|
||||||
|
|
||||||
jclass peerClass = NULL;
|
|
||||||
|
|
||||||
jfieldID addressField = NULL;
|
|
||||||
jfieldID lastUnicastFrameField = NULL;
|
|
||||||
jfieldID lastMulticastFrameField = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastUnicastFrameField = lookup.findField(peerClass, "lastUnicastFrame", "J");
|
|
||||||
if(env->ExceptionCheck() || lastUnicastFrameField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding lastUnicastFrame field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastMulticastFrameField = lookup.findField(peerClass, "lastMulticastFrame", "J");
|
|
||||||
if(env->ExceptionCheck() || lastMulticastFrameField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding lastMulticastFrame 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, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || peer_constructor == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding Peer constructor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject peerObject = env->NewObject(peerClass, peer_constructor);
|
|
||||||
if(env->ExceptionCheck() || peerObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating Peer object");
|
|
||||||
return NULL; // out of memory
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetLongField(peerObject, addressField, (jlong)peer.address);
|
|
||||||
env->SetLongField(peerObject, lastUnicastFrameField, (jlong)peer.lastUnicastFrame);
|
|
||||||
env->SetLongField(peerObject, lastMulticastFrameField, (jlong)peer.lastMulticastFrame);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobjectArray arrayObject = env->NewObjectArray(
|
|
||||||
peer.pathCount, peerPhysicalPathClass, 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->SetObjectField(peerObject, pathsField, 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 enabledField = NULL;
|
|
||||||
jfieldID netconfRevisionField = NULL;
|
|
||||||
jfieldID multicastSubscriptionsField = NULL;
|
|
||||||
jfieldID assignedAddressesField = 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, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || vnetConfig_constructor == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Couldn't find VirtualNetworkConfig Constructor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject vnetConfigObj = env->NewObject(vnetConfigClass, vnetConfig_constructor);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
enabledField = lookup.findField(vnetConfigClass, "enabled", "Z");
|
|
||||||
if(env->ExceptionCheck() || enabledField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting enabled field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
netconfRevisionField = lookup.findField(vnetConfigClass, "netconfRevision", "J");
|
|
||||||
if(env->ExceptionCheck() || netconfRevisionField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting netconfRevision field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
multicastSubscriptionsField = lookup.findField(vnetConfigClass, "multicastSubscriptions", "[Lcom/zerotier/sdk/MulticastGroup;");
|
|
||||||
if(env->ExceptionCheck() || multicastSubscriptionsField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting multicastSubscriptions field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
assignedAddressesField = lookup.findField(vnetConfigClass, "assignedAddresses", "[Ljava/net/InetSocketAddress;");
|
|
||||||
if(env->ExceptionCheck() || assignedAddressesField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting assignedAddresses field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetLongField(vnetConfigObj, nwidField, vnetConfig.nwid);
|
|
||||||
env->SetLongField(vnetConfigObj, macField, vnetConfig.mac);
|
|
||||||
jstring nameStr = env->NewStringUTF(vnetConfig.name);
|
|
||||||
if(env->ExceptionCheck() || nameStr == NULL)
|
|
||||||
{
|
|
||||||
return NULL; // out of memory
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, nameField, nameStr);
|
|
||||||
|
|
||||||
jobject statusObject = createVirtualNetworkStatus(env, vnetConfig.status);
|
|
||||||
if(env->ExceptionCheck() || statusObject == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, statusField, statusObject);
|
|
||||||
|
|
||||||
jobject typeObject = createVirtualNetworkType(env, vnetConfig.type);
|
|
||||||
if(env->ExceptionCheck() || typeObject == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, typeField, 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->SetBooleanField(vnetConfigObj, enabledField, vnetConfig.enabled);
|
|
||||||
env->SetIntField(vnetConfigObj, portErrorField, vnetConfig.portError);
|
|
||||||
|
|
||||||
jclass multicastGroupClass = lookup.findClass("com/zerotier/sdk/MulticastGroup");
|
|
||||||
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding MulticastGroup class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobjectArray mcastSubsArrayObj = env->NewObjectArray(
|
|
||||||
vnetConfig.multicastSubscriptionCount, multicastGroupClass, NULL);
|
|
||||||
if(env->ExceptionCheck() || mcastSubsArrayObj == NULL) {
|
|
||||||
LOGE("Error creating MulticastGroup[] array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < vnetConfig.multicastSubscriptionCount; ++i)
|
|
||||||
{
|
|
||||||
jobject mcastObj = newMulticastGroup(env, vnetConfig.multicastSubscriptions[i]);
|
|
||||||
env->SetObjectArrayElement(mcastSubsArrayObj, i, mcastObj);
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
LOGE("Error assigning MulticastGroup to array");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, multicastSubscriptionsField, mcastSubsArrayObj);
|
|
||||||
|
|
||||||
jclass inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
|
|
||||||
if(env->ExceptionCheck() || inetSocketAddressClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding InetSocketAddress class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobjectArray assignedAddrArrayObj = env->NewObjectArray(
|
|
||||||
vnetConfig.assignedAddressCount, inetSocketAddressClass, 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->SetObjectField(vnetConfigObj, assignedAddressesField, assignedAddrArrayObj);
|
|
||||||
|
|
||||||
return vnetConfigObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags)
|
|
||||||
{
|
|
||||||
// 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, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || versionConstructor == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject versionObj = env->NewObject(versionClass, versionConstructor);
|
|
||||||
if(env->ExceptionCheck() || versionObj == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy data to Version object
|
|
||||||
jfieldID majorField = NULL;
|
|
||||||
jfieldID minorField = NULL;
|
|
||||||
jfieldID revisionField = NULL;
|
|
||||||
jfieldID featureFlagsField = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
featureFlagsField = lookup.findField(versionClass, "featureFlags", "J");
|
|
||||||
if(env->ExceptionCheck() || featureFlagsField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetIntField(versionObj, majorField, (jint)major);
|
|
||||||
env->SetIntField(versionObj, minorField, (jint)minor);
|
|
||||||
env->SetIntField(versionObj, revisionField, (jint)rev);
|
|
||||||
env->SetLongField(versionObj, featureFlagsField, (jlong)featureFlags);
|
|
||||||
|
|
||||||
return versionObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#ifndef ZT_jniutils_h_
|
|
||||||
#define ZT_jniutils_h_
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <jni.h>
|
|
||||||
#include <ZeroTierOne.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LOG_TAG "ZeroTierOneJNI"
|
|
||||||
|
|
||||||
#if __ANDROID__
|
|
||||||
#include <android/log.h>
|
|
||||||
#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
|
||||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
|
|
||||||
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
|
||||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
|
||||||
#else
|
|
||||||
#define LOGV(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#define LOGI(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#define LOGD(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#define LOGE(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jobject createResultObject(JNIEnv *env, ZT_ResultCode code);
|
|
||||||
jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status);
|
|
||||||
jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type);
|
|
||||||
jobject createEvent(JNIEnv *env, ZT_Event event);
|
|
||||||
jobject createPeerRole(JNIEnv *env, ZT_PeerRole role);
|
|
||||||
jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &config);
|
|
||||||
|
|
||||||
jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,133 +0,0 @@
|
|||||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
|
||||||
#include <jni.h>
|
|
||||||
/* Header for class com_zerotier_sdk_Node */
|
|
||||||
|
|
||||||
#ifndef _Included_com_zerotierone_sdk_Node
|
|
||||||
#define _Included_com_zerotierone_sdk_Node
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: node_init
|
|
||||||
* Signature: (J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: node_delete
|
|
||||||
* Signature: (J)V
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: processVirtualNetworkFrame
|
|
||||||
* Signature: (JJJJJII[B[J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong, jlong, jint, jint, jbyteArray, jlongArray);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: processWirePacket
|
|
||||||
* Signature: (JJLjava/net/InetSockAddress;Ljava/net/InetSockAddress;[B[J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jobject, jobject, jbyteArray, jlongArray);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: processBackgroundTasks
|
|
||||||
* Signature: (JJ[J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlongArray);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: join
|
|
||||||
* Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join
|
|
||||||
(JNIEnv *, jobject, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: leave
|
|
||||||
* Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave
|
|
||||||
(JNIEnv *, jobject, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: multicastSubscribe
|
|
||||||
* Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: multicastUnsubscribe
|
|
||||||
* Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: address
|
|
||||||
* Signature: (J)J
|
|
||||||
*/
|
|
||||||
JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: status
|
|
||||||
* Signature: (J)Lcom/zerotier/sdk/NodeStatus;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: networkConfig
|
|
||||||
* Signature: (JJ)Lcom/zerotier/sdk/VirtualNetworkConfig;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig
|
|
||||||
(JNIEnv *, jobject, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: version
|
|
||||||
* Signature: ()Lcom/zerotier/sdk/Version;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version
|
|
||||||
(JNIEnv *, jobject);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: peers
|
|
||||||
* Signature: (J)[Lcom/zerotier/sdk/Peer;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: networks
|
|
||||||
* Signature: (J)[Lcom/zerotier/sdk/VirtualNetworkConfig;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,58 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public interface DataStoreGetListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to get an object from the data store
|
|
||||||
*
|
|
||||||
* <p>Object names can contain forward slash (/) path separators. They will
|
|
||||||
* never contain .. or backslash (\), so this is safe to map as a Unix-style
|
|
||||||
* path if the underlying storage permits. For security reasons we recommend
|
|
||||||
* returning errors if .. or \ are used.</p>
|
|
||||||
*
|
|
||||||
* <p>The function must return the actual number of bytes read. If the object
|
|
||||||
* doesn't exist, it should return -1. -2 should be returned on other errors
|
|
||||||
* such as errors accessing underlying storage.</p>
|
|
||||||
*
|
|
||||||
* <p>If the read doesn't fit in the buffer, the max number of bytes should be
|
|
||||||
* read. The caller may call the function multiple times to read the whole
|
|
||||||
* object.</p>
|
|
||||||
*
|
|
||||||
* @param name Name of the object in the data store
|
|
||||||
* @param out_buffer buffer to put the object in
|
|
||||||
* @param bufferIndex index in the object to start reading
|
|
||||||
* @param out_objectSize long[1] to be set to the actual size of the object if it exists.
|
|
||||||
* @return the actual number of bytes read.
|
|
||||||
*/
|
|
||||||
public long onDataStoreGet(
|
|
||||||
String name,
|
|
||||||
byte[] out_buffer,
|
|
||||||
long bufferIndex,
|
|
||||||
long[] out_objectSize);
|
|
||||||
}
|
|
||||||
@@ -1,59 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public interface DataStorePutListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to store an object in the data store
|
|
||||||
*
|
|
||||||
* <p>If secure is true, the file should be set readable and writable only
|
|
||||||
* to the user running ZeroTier One. What this means is platform-specific.</p>
|
|
||||||
*
|
|
||||||
* <p>Name semantics are the same as {@link DataStoreGetListener}. This must return
|
|
||||||
* zero on success. You can return any OS-specific error code on failure, as these
|
|
||||||
* may be visible in logs or error messages and might aid in debugging.</p>
|
|
||||||
*
|
|
||||||
* @param name Object name
|
|
||||||
* @param buffer data to store
|
|
||||||
* @param secure set to user read/write only.
|
|
||||||
* @return 0 on success.
|
|
||||||
*/
|
|
||||||
public int onDataStorePut(
|
|
||||||
String name,
|
|
||||||
byte[] buffer,
|
|
||||||
boolean secure);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to delete an object from the data store
|
|
||||||
*
|
|
||||||
* @param name Object name
|
|
||||||
* @return 0 on success.
|
|
||||||
*/
|
|
||||||
public int onDelete(
|
|
||||||
String name);
|
|
||||||
}
|
|
||||||
@@ -1,98 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum Event {
|
|
||||||
/**
|
|
||||||
* Node has been initialized
|
|
||||||
*
|
|
||||||
* This is the first event generated, and is always sent. It may occur
|
|
||||||
* before Node's constructor returns.
|
|
||||||
*/
|
|
||||||
EVENT_UP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node is offline -- network does not seem to be reachable by any available strategy
|
|
||||||
*/
|
|
||||||
EVENT_OFFLINE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node is online -- at least one upstream node appears reachable
|
|
||||||
*
|
|
||||||
* Meta-data: none
|
|
||||||
*/
|
|
||||||
EVENT_ONLINE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node is shutting down
|
|
||||||
*
|
|
||||||
* <p>This is generated within Node's destructor when it is being shut down.
|
|
||||||
* It's done for convenience, since cleaning up other state in the event
|
|
||||||
* handler may appear more idiomatic.</p>
|
|
||||||
*/
|
|
||||||
EVENT_DOWN,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Your identity has collided with another node's ZeroTier address
|
|
||||||
*
|
|
||||||
* <p>This happens if two different public keys both hash (via the algorithm
|
|
||||||
* in Identity::generate()) to the same 40-bit ZeroTier address.</p>
|
|
||||||
*
|
|
||||||
* <p>This is something you should "never" see, where "never" is defined as
|
|
||||||
* once per 2^39 new node initializations / identity creations. If you do
|
|
||||||
* see it, you're going to see it very soon after a node is first
|
|
||||||
* initialized.</p>
|
|
||||||
*
|
|
||||||
* <p>This is reported as an event rather than a return code since it's
|
|
||||||
* detected asynchronously via error messages from authoritative nodes.</p>
|
|
||||||
*
|
|
||||||
* <p>If this occurs, you must shut down and delete the node, delete the
|
|
||||||
* identity.secret record/file from the data store, and restart to generate
|
|
||||||
* a new identity. If you don't do this, you will not be able to communicate
|
|
||||||
* with other nodes.</p>
|
|
||||||
*
|
|
||||||
* <p>We'd automate this process, but we don't think silently deleting
|
|
||||||
* private keys or changing our address without telling the calling code
|
|
||||||
* is good form. It violates the principle of least surprise.</p>
|
|
||||||
*
|
|
||||||
* <p>You can technically get away with not handling this, but we recommend
|
|
||||||
* doing so in a mature reliable application. Besides, handling this
|
|
||||||
* 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?</p>
|
|
||||||
*/
|
|
||||||
EVENT_FATAL_ERROR_IDENTITY_COLLISION,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trace (debugging) message
|
|
||||||
*
|
|
||||||
* <p>These events are only generated if this is a TRACE-enabled build.</p>
|
|
||||||
*
|
|
||||||
* <p>Meta-data: {@link String}, TRACE message</p>
|
|
||||||
*/
|
|
||||||
EVENT_TRACE
|
|
||||||
}
|
|
||||||
@@ -1,52 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
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
|
|
||||||
*
|
|
||||||
* @param event {@link Event} enum
|
|
||||||
*/
|
|
||||||
public void onEvent(Event event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trace messages
|
|
||||||
*
|
|
||||||
* <p>These events are only generated if the underlying ZeroTierOne SDK is a TRACE-enabled build.</p>
|
|
||||||
*
|
|
||||||
* @param message the trace message
|
|
||||||
*/
|
|
||||||
public void onTrace(String message);
|
|
||||||
}
|
|
||||||
@@ -1,53 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
|
|
||||||
public final class MulticastGroup {
|
|
||||||
private MulticastGroup() {}
|
|
||||||
|
|
||||||
private long mac;
|
|
||||||
private long adi;
|
|
||||||
|
|
||||||
public boolean equals(MulticastGroup other) {
|
|
||||||
return mac == other.mac && adi == other.adi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MAC address (least significant 48 bits)
|
|
||||||
*/
|
|
||||||
public final long getMacAddress() {
|
|
||||||
return mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Additional distinguishing information (usually zero)
|
|
||||||
*/
|
|
||||||
public final long getAdi() {
|
|
||||||
return adi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <adam@adamh.cz>, 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 prexif 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,442 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ZeroTier One node
|
|
||||||
*/
|
|
||||||
public class Node {
|
|
||||||
|
|
||||||
//public static native int load_symbols();
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
//System.loadLibrary("ZeroTierOneJNI");
|
|
||||||
|
|
||||||
// test call
|
|
||||||
//System.out.println("load_symbols() = " + load_symbols());
|
|
||||||
|
|
||||||
|
|
||||||
} 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String TAG = "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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new ZeroTier One node
|
|
||||||
*
|
|
||||||
* <p>Note that this can take a few seconds the first time it's called, as it
|
|
||||||
* will generate an identity.</p>
|
|
||||||
*
|
|
||||||
* @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 intstance of the {@link DataStorePutListener} interface called to put objects in persistent storage. This instance must be unique per Node object.
|
|
||||||
* @param sender
|
|
||||||
* @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 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.
|
|
||||||
*/
|
|
||||||
public Node(long now,
|
|
||||||
DataStoreGetListener getListener,
|
|
||||||
DataStorePutListener putListener,
|
|
||||||
PacketSender sender,
|
|
||||||
EventListener eventListener,
|
|
||||||
VirtualNetworkFrameListener frameListener,
|
|
||||||
VirtualNetworkConfigListener configListener) throws NodeException
|
|
||||||
{
|
|
||||||
this.nodeId = now;
|
|
||||||
|
|
||||||
this.getListener = getListener;
|
|
||||||
this.putListener = putListener;
|
|
||||||
this.sender = sender;
|
|
||||||
this.eventListener = eventListener;
|
|
||||||
this.frameListener = frameListener;
|
|
||||||
this.configListener = configListener;
|
|
||||||
|
|
||||||
ResultCode rc = node_init(now);
|
|
||||||
if(rc != ResultCode.RESULT_OK)
|
|
||||||
{
|
|
||||||
// TODO: Throw Exception
|
|
||||||
throw new NodeException(rc.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close this Node.
|
|
||||||
*
|
|
||||||
* <p>The Node object can no longer be used once this method is called.</p>
|
|
||||||
*/
|
|
||||||
public void close() {
|
|
||||||
if(nodeId != -1) {
|
|
||||||
node_delete(nodeId);
|
|
||||||
nodeId = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a frame from a virtual network port
|
|
||||||
*
|
|
||||||
* @param now Current clock in milliseconds
|
|
||||||
* @param nwid ZeroTier 64-bit virtual network ID
|
|
||||||
* @param sourceMac Source MAC address (least significant 48 bits)
|
|
||||||
* @param destMac Destination MAC address (least significant 48 bits)
|
|
||||||
* @param etherType 16-bit Ethernet frame type
|
|
||||||
* @param vlanId 10-bit VLAN ID or 0 if none
|
|
||||||
* @param frameData Frame payload data
|
|
||||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode processVirtualNetworkFrame(
|
|
||||||
long now,
|
|
||||||
long nwid,
|
|
||||||
long sourceMac,
|
|
||||||
long destMac,
|
|
||||||
int etherType,
|
|
||||||
int vlanId,
|
|
||||||
byte[] frameData,
|
|
||||||
long[] nextBackgroundTaskDeadline) {
|
|
||||||
return processVirtualNetworkFrame(
|
|
||||||
nodeId, now, nwid, sourceMac, destMac, etherType, vlanId,
|
|
||||||
frameData, nextBackgroundTaskDeadline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a packet received from the physical wire
|
|
||||||
*
|
|
||||||
* @param now Current clock in milliseconds
|
|
||||||
* @param remoteAddress Origin of packet
|
|
||||||
* @param packetData Packet data
|
|
||||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode processWirePacket(
|
|
||||||
long now,
|
|
||||||
InetSocketAddress localAddress,
|
|
||||||
InetSocketAddress remoteAddress,
|
|
||||||
byte[] packetData,
|
|
||||||
long[] nextBackgroundTaskDeadline) {
|
|
||||||
return processWirePacket(
|
|
||||||
nodeId, now, localAddress, remoteAddress, packetData,
|
|
||||||
nextBackgroundTaskDeadline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform periodic background operations
|
|
||||||
*
|
|
||||||
* @param now Current clock in milliseconds
|
|
||||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode processBackgroundTasks(long now, long[] nextBackgroundTaskDeadline) {
|
|
||||||
return processBackgroundTasks(nodeId, now, nextBackgroundTaskDeadline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Join a network
|
|
||||||
*
|
|
||||||
* <p>This may generate calls to the port config callback before it returns,
|
|
||||||
* or these may be deffered if a netconf is not available yet.</p>
|
|
||||||
*
|
|
||||||
* <p>If we are already a member of the network, nothing is done and OK is
|
|
||||||
* returned.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit ZeroTier network ID
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode join(long nwid) {
|
|
||||||
return join(nodeId, nwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Leave a network
|
|
||||||
*
|
|
||||||
* <p>If a port has been configured for this network this will generate a call
|
|
||||||
* to the port config callback with a NULL second parameter to indicate that
|
|
||||||
* the port is now deleted.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode leave(long nwid) {
|
|
||||||
return leave(nodeId, nwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to an Ethernet multicast group
|
|
||||||
*
|
|
||||||
* <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
|
|
||||||
* broadcast address) but with an ADI equal to each IPv4 address in host
|
|
||||||
* byte order. This converts ARP from a non-scalable broadcast protocol to
|
|
||||||
* a scalable multicast protocol with perfect address specificity.</p>
|
|
||||||
*
|
|
||||||
* <p>If this is not done, ARP will not work reliably.</p>
|
|
||||||
*
|
|
||||||
* <p>Multiple calls to subscribe to the same multicast address will have no
|
|
||||||
* effect. It is perfectly safe to do this.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastSubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup) {
|
|
||||||
return multicastSubscribe(nodeId, nwid, multicastGroup, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to an Ethernet multicast group
|
|
||||||
*
|
|
||||||
* <p>ADI stands for additional distinguishing information. This defaults to zero
|
|
||||||
* and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
|
|
||||||
* and this must be done.</p>
|
|
||||||
*
|
|
||||||
* <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
|
|
||||||
* broadcast address) but with an ADI equal to each IPv4 address in host
|
|
||||||
* byte order. This converts ARP from a non-scalable broadcast protocol to
|
|
||||||
* a scalable multicast protocol with perfect address specificity.</p>
|
|
||||||
*
|
|
||||||
* <p>If this is not done, ARP will not work reliably.</p>
|
|
||||||
*
|
|
||||||
* <p>Multiple calls to subscribe to the same multicast address will have no
|
|
||||||
* effect. It is perfectly safe to do this.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastSubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi) {
|
|
||||||
return multicastSubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe from an Ethernet multicast group (or all groups)
|
|
||||||
*
|
|
||||||
* <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
|
|
||||||
* you are not subscribed to a group this has no effect.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastUnsubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup) {
|
|
||||||
return multicastUnsubscribe(nodeId, nwid, multicastGroup, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe from an Ethernet multicast group (or all groups)
|
|
||||||
*
|
|
||||||
* <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
|
|
||||||
* you are not subscribed to a group this has no effect.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* <p>ADI stands for additional distinguishing information. This defaults to zero
|
|
||||||
* and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
|
|
||||||
* and this must be done.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastUnsubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi) {
|
|
||||||
return multicastUnsubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get this node's 40-bit ZeroTier address
|
|
||||||
*
|
|
||||||
* @return ZeroTier address (least significant 40 bits of 64-bit int)
|
|
||||||
*/
|
|
||||||
public long address() {
|
|
||||||
return address(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of this node
|
|
||||||
*
|
|
||||||
* @return @{link NodeStatus} struct with the current node status.
|
|
||||||
*/
|
|
||||||
public NodeStatus status() {
|
|
||||||
return status(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of known peer nodes
|
|
||||||
*
|
|
||||||
* @return List of known peers or NULL on failure
|
|
||||||
*/
|
|
||||||
public Peer[] peers() {
|
|
||||||
return peers(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of a virtual network
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @return {@link VirtualNetworkConfig} or NULL if we are not a member of this network
|
|
||||||
*/
|
|
||||||
public VirtualNetworkConfig networkConfig(long nwid) {
|
|
||||||
return networkConfig(nodeId, nwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enumerate and get status of all networks
|
|
||||||
*
|
|
||||||
* @return List of networks or NULL on failure
|
|
||||||
*/
|
|
||||||
public VirtualNetworkConfig[] networks() {
|
|
||||||
return networks(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get ZeroTier One version
|
|
||||||
*
|
|
||||||
* @return {@link Version} object with ZeroTierOne version information.
|
|
||||||
*/
|
|
||||||
public Version getVersion() {
|
|
||||||
return version();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// function declarations for JNI
|
|
||||||
//
|
|
||||||
private native ResultCode node_init(long now);
|
|
||||||
|
|
||||||
private native void node_delete(long nodeId);
|
|
||||||
|
|
||||||
private native ResultCode processVirtualNetworkFrame(
|
|
||||||
long nodeId,
|
|
||||||
long now,
|
|
||||||
long nwid,
|
|
||||||
long sourceMac,
|
|
||||||
long destMac,
|
|
||||||
int etherType,
|
|
||||||
int vlanId,
|
|
||||||
byte[] frameData,
|
|
||||||
long[] nextBackgroundTaskDeadline);
|
|
||||||
|
|
||||||
private native ResultCode processWirePacket(
|
|
||||||
long nodeId,
|
|
||||||
long now,
|
|
||||||
InetSocketAddress localAddress,
|
|
||||||
InetSocketAddress remoteAddress,
|
|
||||||
byte[] packetData,
|
|
||||||
long[] nextBackgroundTaskDeadline);
|
|
||||||
|
|
||||||
private native ResultCode processBackgroundTasks(
|
|
||||||
long nodeId,
|
|
||||||
long now,
|
|
||||||
long[] nextBackgroundTaskDeadline);
|
|
||||||
|
|
||||||
private native ResultCode join(long nodeId, long nwid);
|
|
||||||
|
|
||||||
private native ResultCode leave(long nodeId, long nwid);
|
|
||||||
|
|
||||||
private native ResultCode multicastSubscribe(
|
|
||||||
long nodeId,
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi);
|
|
||||||
|
|
||||||
private native ResultCode multicastUnsubscribe(
|
|
||||||
long nodeId,
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi);
|
|
||||||
|
|
||||||
private native long address(long nodeId);
|
|
||||||
|
|
||||||
private native NodeStatus status(long nodeId);
|
|
||||||
|
|
||||||
private native VirtualNetworkConfig networkConfig(long nodeId, long nwid);
|
|
||||||
|
|
||||||
private native Version version();
|
|
||||||
|
|
||||||
private native Peer[] peers(long nodeId);
|
|
||||||
|
|
||||||
private native VirtualNetworkConfig[] networks(long nodeId);
|
|
||||||
}
|
|
||||||
@@ -1,36 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.lang.RuntimeException;
|
|
||||||
|
|
||||||
public class NodeException extends RuntimeException {
|
|
||||||
public NodeException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public final class NodeStatus {
|
|
||||||
private long address;
|
|
||||||
private String publicIdentity;
|
|
||||||
private String secretIdentity;
|
|
||||||
private boolean online;
|
|
||||||
|
|
||||||
private NodeStatus() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 40-bit ZeroTier address of this node
|
|
||||||
*/
|
|
||||||
public final long getAddres() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public identity in string-serialized form (safe to send to others)
|
|
||||||
*
|
|
||||||
* <p>This identity will remain valid as long as the node exists.</p>
|
|
||||||
*/
|
|
||||||
public final String getPublicIdentity() {
|
|
||||||
return publicIdentity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Full identity including secret key in string-serialized form
|
|
||||||
*
|
|
||||||
* <p>This identity will remain valid as long as the node exists.</p>
|
|
||||||
*/
|
|
||||||
public final String getSecretIdentity() {
|
|
||||||
return secretIdentity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if some kind of connectivity appears available
|
|
||||||
*/
|
|
||||||
public final boolean isOnline() {
|
|
||||||
return online;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
|
|
||||||
public interface PacketSender {
|
|
||||||
/**
|
|
||||||
* Function to send a ZeroTier packet out over the wire
|
|
||||||
*
|
|
||||||
* <p>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.</p>
|
|
||||||
*
|
|
||||||
* @param localAddr {@link InetSocketAddress} to send from. Set to null if not specified.
|
|
||||||
* @param remoteAddr {@link InetSocketAddress} to send to
|
|
||||||
* @param packetData data to send
|
|
||||||
* @return 0 on success, any error code on failure.
|
|
||||||
*/
|
|
||||||
public int onSendPacketRequested(
|
|
||||||
InetSocketAddress localAddr,
|
|
||||||
InetSocketAddress remoteAddr,
|
|
||||||
byte[] packetData,
|
|
||||||
int ttl);
|
|
||||||
}
|
|
||||||
@@ -1,110 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Peer status result
|
|
||||||
*/
|
|
||||||
public final class Peer {
|
|
||||||
private long address;
|
|
||||||
private long lastUnicastFrame;
|
|
||||||
private long lastMulticastFrame;
|
|
||||||
private int versionMajor;
|
|
||||||
private int versionMinor;
|
|
||||||
private int versionRev;
|
|
||||||
private int latency;
|
|
||||||
private PeerRole role;
|
|
||||||
private PeerPhysicalPath[] paths;
|
|
||||||
|
|
||||||
private Peer() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZeroTier address (40 bits)
|
|
||||||
*/
|
|
||||||
public final long address() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time we last received a unicast frame from this peer
|
|
||||||
*/
|
|
||||||
public final long lastUnicastFrame() {
|
|
||||||
return lastUnicastFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time we last received a multicast rame from this peer
|
|
||||||
*/
|
|
||||||
public final long lastMulticastFrame() {
|
|
||||||
return lastMulticastFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote major version or -1 if not known
|
|
||||||
*/
|
|
||||||
public final int versionMajor() {
|
|
||||||
return versionMajor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote minor version or -1 if not known
|
|
||||||
*/
|
|
||||||
public final int versionMinor() {
|
|
||||||
return versionMinor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote revision or -1 if not known
|
|
||||||
*/
|
|
||||||
public final int versionRev() {
|
|
||||||
return versionRev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Last measured latency in milliseconds or zero if unknown
|
|
||||||
*/
|
|
||||||
public final int latency() {
|
|
||||||
return latency;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* What trust hierarchy role does this device have?
|
|
||||||
*/
|
|
||||||
public final PeerRole role() {
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Known network paths to peer
|
|
||||||
*/
|
|
||||||
public final PeerPhysicalPath[] paths() {
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Physical network path to a peer
|
|
||||||
*/
|
|
||||||
public final class PeerPhysicalPath {
|
|
||||||
private InetSocketAddress address;
|
|
||||||
private long lastSend;
|
|
||||||
private long lastReceive;
|
|
||||||
private boolean fixed;
|
|
||||||
private boolean active;
|
|
||||||
private boolean preferred;
|
|
||||||
|
|
||||||
private PeerPhysicalPath() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address of endpoint
|
|
||||||
*/
|
|
||||||
public final InetSocketAddress address() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time of last send in milliseconds or 0 for never
|
|
||||||
*/
|
|
||||||
public final long lastSend() {
|
|
||||||
return lastSend;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time of last receive in milliseconds or 0 for never
|
|
||||||
*/
|
|
||||||
public final long lastReceive() {
|
|
||||||
return lastReceive;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is path fixed? (i.e. not learned, static)
|
|
||||||
*/
|
|
||||||
public final boolean isFixed() {
|
|
||||||
return fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is path active?
|
|
||||||
*/
|
|
||||||
public final boolean isActive() {
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is path preferred?
|
|
||||||
*/
|
|
||||||
public final boolean isPreferred() {
|
|
||||||
return preferred;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum PeerRole {
|
|
||||||
/**
|
|
||||||
* An ordinary node
|
|
||||||
*/
|
|
||||||
PEER_ROLE_LEAF,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* relay node
|
|
||||||
*/
|
|
||||||
PEER_ROLE_RELAY,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* root server
|
|
||||||
*/
|
|
||||||
PEER_ROLE_ROOT
|
|
||||||
}
|
|
||||||
@@ -1,74 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function return code: OK (0) or error results
|
|
||||||
*
|
|
||||||
* <p>Use {@link ResultCode#isFatal) to check for a fatal error. If a fatal error
|
|
||||||
* occurs, the node should be considered to not be working correctly. These
|
|
||||||
* indicate serious problems like an inaccessible data store or a compile
|
|
||||||
* problem.</p>
|
|
||||||
*/
|
|
||||||
public enum ResultCode {
|
|
||||||
/**
|
|
||||||
* Operation completed normally
|
|
||||||
*/
|
|
||||||
RESULT_OK(0),
|
|
||||||
|
|
||||||
// Fatal errors (> 0, < 1000)
|
|
||||||
/**
|
|
||||||
* Ran out of memory
|
|
||||||
*/
|
|
||||||
RESULT_FATAL_ERROR_OUT_OF_MEMORY(1),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data store is not writable or has failed
|
|
||||||
*/
|
|
||||||
RESULT_FATAL_ERROR_DATA_STORE_FAILED(2),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal error (e.g. unexpected exception indicating bug or build problem)
|
|
||||||
*/
|
|
||||||
RESULT_FATAL_ERROR_INTERNAL(3),
|
|
||||||
|
|
||||||
// non-fatal errors
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network ID not valid
|
|
||||||
*/
|
|
||||||
RESULT_ERROR_NETWORK_NOT_FOUND(1000);
|
|
||||||
|
|
||||||
private final int id;
|
|
||||||
ResultCode(int id) { this.id = id; }
|
|
||||||
public int getValue() { return id; }
|
|
||||||
|
|
||||||
public boolean isFatal(int id) {
|
|
||||||
return (id > 0 && id < 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public final class Version {
|
|
||||||
private Version() {}
|
|
||||||
|
|
||||||
public int major = 0;
|
|
||||||
public int minor = 0;
|
|
||||||
public int revision = 0;
|
|
||||||
public long featureFlags = 0;
|
|
||||||
}
|
|
||||||
@@ -1,206 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.lang.Comparable;
|
|
||||||
import java.lang.Override;
|
|
||||||
import java.lang.String;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
public final class VirtualNetworkConfig implements Comparable<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 MulticastGroup[] multicastSubscriptions;
|
|
||||||
private InetSocketAddress[] assignedAddresses;
|
|
||||||
|
|
||||||
private VirtualNetworkConfig() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(VirtualNetworkConfig cfg) {
|
|
||||||
boolean aaEqual = true;
|
|
||||||
if(assignedAddresses.length == cfg.assignedAddresses.length) {
|
|
||||||
for(int i = 0; i < assignedAddresses.length; ++i) {
|
|
||||||
if(!assignedAddresses[i].equals(cfg.assignedAddresses[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
aaEqual = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nwid == cfg.nwid &&
|
|
||||||
mac == cfg.mac &&
|
|
||||||
name.equals(cfg.name) &&
|
|
||||||
status.equals(cfg.status) &&
|
|
||||||
type.equals(cfg.type) &&
|
|
||||||
mtu == cfg.mtu &&
|
|
||||||
dhcp == cfg.dhcp &&
|
|
||||||
bridge == cfg.bridge &&
|
|
||||||
broadcastEnabled == cfg.broadcastEnabled &&
|
|
||||||
portError == cfg.portError &&
|
|
||||||
enabled == cfg.enabled &&
|
|
||||||
aaEqual;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(VirtualNetworkConfig cfg) {
|
|
||||||
if(cfg.nwid == this.nwid) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return this.nwid > cfg.nwid ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 64-bit ZeroTier network ID
|
|
||||||
*/
|
|
||||||
public final long networkId() {
|
|
||||||
return nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ethernet MAC (40 bits) that should be assigned to port
|
|
||||||
*/
|
|
||||||
public final long macAddress() {
|
|
||||||
return mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network name (from network configuration master)
|
|
||||||
*/
|
|
||||||
public final String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network configuration request status
|
|
||||||
*/
|
|
||||||
public final VirtualNetworkStatus networkStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network type
|
|
||||||
*/
|
|
||||||
public final VirtualNetworkType networkType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum interface MTU
|
|
||||||
*/
|
|
||||||
public final int mtu() {
|
|
||||||
return mtu;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the network this port belongs to indicates DHCP availability
|
|
||||||
*
|
|
||||||
* <p>This is a suggestion. The underlying implementation is free to ignore it
|
|
||||||
* for security or other reasons. This is simply a netconf parameter that
|
|
||||||
* means 'DHCP is available on this network.'</p>
|
|
||||||
*/
|
|
||||||
public final boolean isDhcpAvailable() {
|
|
||||||
return dhcp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this port is allowed to bridge to other networks
|
|
||||||
*
|
|
||||||
* <p>This is informational. If this is false, bridged packets will simply
|
|
||||||
* be dropped and bridging won't work.</p>
|
|
||||||
*/
|
|
||||||
public final boolean isBridgeEnabled() {
|
|
||||||
return bridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic
|
|
||||||
*/
|
|
||||||
public final boolean broadcastEnabled() {
|
|
||||||
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() {
|
|
||||||
return portError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this network enabled? If not, all frames to/from are dropped.
|
|
||||||
*/
|
|
||||||
public final boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network config revision as reported by netconf master
|
|
||||||
*
|
|
||||||
* <p>If this is zero, it means we're still waiting for our netconf.</p>
|
|
||||||
*/
|
|
||||||
public final long netconfRevision() {
|
|
||||||
return netconfRevision;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multicast group subscriptions
|
|
||||||
*/
|
|
||||||
public final MulticastGroup[] multicastSubscriptions() {
|
|
||||||
return multicastSubscriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZeroTier-assigned addresses (in {@link java.net.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.
|
|
||||||
* Other fields like interface number can be ignored.
|
|
||||||
*
|
|
||||||
* This is only used for ZeroTier-managed address assignments sent by the
|
|
||||||
* virtual network's configuration master.
|
|
||||||
*/
|
|
||||||
public final InetSocketAddress[] assignedAddresses() {
|
|
||||||
return assignedAddresses;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
|
|
||||||
public interface VirtualNetworkConfigListener {
|
|
||||||
/**
|
|
||||||
* Callback called to update virtual network port configuration
|
|
||||||
*
|
|
||||||
* <p>This can be called at any time to update the configuration of a virtual
|
|
||||||
* network port. The parameter after the network ID specifies whether this
|
|
||||||
* port is being brought up, updated, brought down, or permanently deleted.
|
|
||||||
*
|
|
||||||
* This in turn should be used by the underlying implementation to create
|
|
||||||
* and configure tap devices at the OS (or virtual network stack) layer.</P>
|
|
||||||
*
|
|
||||||
* This should not call {@link Node#multicastSubscribe} or other network-modifying
|
|
||||||
* methods, as this could cause a deadlock in multithreaded or interrupt
|
|
||||||
* driven environments.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @param nwid network id
|
|
||||||
* @param op {@link VirtualNetworkConfigOperation} enum describing the configuration operation
|
|
||||||
* @param config {@link VirtualNetworkConfig} object with the new configuration
|
|
||||||
* @return 0 on success
|
|
||||||
*/
|
|
||||||
public int onNetworkConfigurationUpdated(
|
|
||||||
long nwid,
|
|
||||||
VirtualNetworkConfigOperation op,
|
|
||||||
VirtualNetworkConfig config);
|
|
||||||
}
|
|
||||||
@@ -1,49 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum VirtualNetworkConfigOperation {
|
|
||||||
/**
|
|
||||||
* Network is coming up (either for the first time or after service restart)
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_UP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network configuration has been updated
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network is going down (not permanently)
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network is going down permanently (leave/delete)
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY
|
|
||||||
}
|
|
||||||
@@ -1,48 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public interface VirtualNetworkFrameListener {
|
|
||||||
/**
|
|
||||||
* Function to send a frame out to a virtual network port
|
|
||||||
*
|
|
||||||
* @param nwid ZeroTier One network ID
|
|
||||||
* @param srcMac source MAC address
|
|
||||||
* @param destMac destination MAC address
|
|
||||||
* @param ethertype
|
|
||||||
* @param vlanId
|
|
||||||
* @param frameData data to send
|
|
||||||
*/
|
|
||||||
public void onVirtualNetworkFrame(
|
|
||||||
long nwid,
|
|
||||||
long srcMac,
|
|
||||||
long destMac,
|
|
||||||
long etherType,
|
|
||||||
long vlanId,
|
|
||||||
byte[] frameData);
|
|
||||||
}
|
|
||||||
@@ -1,59 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum VirtualNetworkStatus {
|
|
||||||
/**
|
|
||||||
* Waiting for network configuration (also means revision == 0)
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_REQUESTING_CONFIGURATION,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration received and we are authorized
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_OK,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Netconf master told us 'nope'
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_ACCESS_DENIED,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Netconf master exists, but this virtual network does not
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_NOT_FOUND,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization of network failed or other internal error
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_PORT_ERROR,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZeroTier One version too old
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_CLIENT_TOO_OLD
|
|
||||||
}
|
|
||||||
@@ -1,39 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* 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/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum VirtualNetworkType {
|
|
||||||
/**
|
|
||||||
* Private networks are authorized via certificates of membership
|
|
||||||
*/
|
|
||||||
NETWORK_TYPE_PRIVATE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public networks have no access control -- they'll always be AUTHORIZED
|
|
||||||
*/
|
|
||||||
NETWORK_TYPE_PUBLIC
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.GoogleAnalytics;
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 8/25/2015.
|
|
||||||
*/
|
|
||||||
public class AnalyticsApplication extends Application {
|
|
||||||
private Tracker mTracker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the default {@link Tracker} for this {@link Application}.
|
|
||||||
* @return tracker
|
|
||||||
*/
|
|
||||||
synchronized public Tracker getDefaultTracker() {
|
|
||||||
if (mTracker == null) {
|
|
||||||
SharedPreferences prefs = getSharedPreferences("user", MODE_PRIVATE);
|
|
||||||
|
|
||||||
String uuid = UUID.randomUUID().toString();
|
|
||||||
String savedUUID = prefs.getString("uuid", UUID.randomUUID().toString());
|
|
||||||
|
|
||||||
if(savedUUID.equals(uuid)) {
|
|
||||||
// this is a newly generated UUID. Save it
|
|
||||||
SharedPreferences.Editor e = prefs.edit();
|
|
||||||
e.putString("uuid", savedUUID);
|
|
||||||
e.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
|
|
||||||
// To enable debug logging use: adb shell setprop log.tag.GAv4 DEBUG
|
|
||||||
mTracker = analytics.newTracker(R.xml.app_tracker);
|
|
||||||
|
|
||||||
mTracker.set("&uid", savedUUID);
|
|
||||||
|
|
||||||
mTracker.send(new HitBuilders.ScreenViewBuilder()
|
|
||||||
.setNewSession()
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
return mTracker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.GoogleAnalytics;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of Google Analytics trackers. Fetch the tracker you need using
|
|
||||||
* {@code AnalyticsTrackers.getInstance().get(...)}
|
|
||||||
* <p/>
|
|
||||||
* This code was generated by Android Studio but can be safely modified by
|
|
||||||
* hand at this point.
|
|
||||||
* <p/>
|
|
||||||
* TODO: Call {@link #initialize(Context)} from an entry point in your app
|
|
||||||
* before using this!
|
|
||||||
*/
|
|
||||||
public final class AnalyticsTrackers {
|
|
||||||
|
|
||||||
public enum Target {
|
|
||||||
APP,
|
|
||||||
// Add more trackers here if you need, and update the code in #get(Target) below
|
|
||||||
}
|
|
||||||
|
|
||||||
private static AnalyticsTrackers sInstance;
|
|
||||||
|
|
||||||
public static synchronized void initialize(Context context) {
|
|
||||||
if (sInstance != null) {
|
|
||||||
throw new IllegalStateException("Extra call to initialize analytics trackers");
|
|
||||||
}
|
|
||||||
|
|
||||||
sInstance = new AnalyticsTrackers(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized AnalyticsTrackers getInstance() {
|
|
||||||
if (sInstance == null) {
|
|
||||||
throw new IllegalStateException("Call initialize() before getInstance()");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Map<Target, Tracker> mTrackers = new HashMap<Target, Tracker>();
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't instantiate directly - use {@link #getInstance()} instead.
|
|
||||||
*/
|
|
||||||
private AnalyticsTrackers(Context context) {
|
|
||||||
mContext = context.getApplicationContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Tracker get(Target target) {
|
|
||||||
if (!mTrackers.containsKey(target)) {
|
|
||||||
Tracker tracker;
|
|
||||||
switch (target) {
|
|
||||||
case APP:
|
|
||||||
tracker = GoogleAnalytics.getInstance(mContext).newTracker(R.xml.app_tracker);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unhandled analytics target " + target);
|
|
||||||
}
|
|
||||||
mTrackers.put(target, tracker);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mTrackers.get(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class ErrorEvent {
|
|
||||||
ResultCode result;
|
|
||||||
|
|
||||||
public ErrorEvent(ResultCode rc) {
|
|
||||||
result = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getError() {
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.one.ui.JoinNetworkFragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class JoinNetworkEvent {
|
|
||||||
private long networkId;
|
|
||||||
|
|
||||||
public JoinNetworkEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class LeaveNetworkEvent {
|
|
||||||
long networkId;
|
|
||||||
|
|
||||||
public LeaveNetworkEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 8/4/2015.
|
|
||||||
*/
|
|
||||||
public class ManualDisconnectEvent {
|
|
||||||
public ManualDisconnectEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkInfoReplyEvent {
|
|
||||||
private VirtualNetworkConfig vnc;
|
|
||||||
|
|
||||||
public NetworkInfoReplyEvent(VirtualNetworkConfig vnc) {
|
|
||||||
this.vnc = vnc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VirtualNetworkConfig getNetworkInfo() {
|
|
||||||
return vnc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkListReplyEvent {
|
|
||||||
private VirtualNetworkConfig[] networks;
|
|
||||||
|
|
||||||
public NetworkListReplyEvent(VirtualNetworkConfig[] networks) {
|
|
||||||
this.networks = networks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VirtualNetworkConfig[] getNetworkList() {
|
|
||||||
return networks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import android.net.Network;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/24/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkReconfigureEvent {
|
|
||||||
public NetworkReconfigureEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkRemovedEvent {
|
|
||||||
private long networkId;
|
|
||||||
|
|
||||||
public NetworkRemovedEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/28/2015.
|
|
||||||
*/
|
|
||||||
public class NodeDestroyedEvent {
|
|
||||||
public NodeDestroyedEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/9/2015.
|
|
||||||
*/
|
|
||||||
public class NodeIDEvent {
|
|
||||||
private long nodeId;
|
|
||||||
|
|
||||||
public NodeIDEvent(long nodeId) {
|
|
||||||
this.nodeId = nodeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNodeId() {
|
|
||||||
return nodeId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.NodeStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/9/2015.
|
|
||||||
*/
|
|
||||||
public class NodeStatusEvent {
|
|
||||||
private NodeStatus status;
|
|
||||||
|
|
||||||
public NodeStatusEvent(NodeStatus status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeStatus getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class RequestNetworkInfoEvent {
|
|
||||||
private long networkId;
|
|
||||||
|
|
||||||
public RequestNetworkInfoEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class RequestNetworkListEvent {
|
|
||||||
public RequestNetworkListEvent() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 8/1/2015.
|
|
||||||
*/
|
|
||||||
public class RequestNodeStatusEvent {
|
|
||||||
public RequestNodeStatusEvent() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/9/2015.
|
|
||||||
*/
|
|
||||||
public class StopEvent {
|
|
||||||
public StopEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class ARPTable {
|
|
||||||
public static final String TAG = "ARPTable";
|
|
||||||
|
|
||||||
private static final int REQUEST = 1;
|
|
||||||
private static final int REPLY = 2;
|
|
||||||
|
|
||||||
private final HashMap<InetAddress, Long> inetAddressToMacAddress;
|
|
||||||
private final HashMap<Long, InetAddress> macAddressToInetAdddress;
|
|
||||||
|
|
||||||
private static final long ENTRY_TIMEOUT = 120000L; // 2 minutes
|
|
||||||
|
|
||||||
private final ArrayList<ArpEntry> entries;
|
|
||||||
|
|
||||||
public ARPTable() {
|
|
||||||
entries = new ArrayList<ArpEntry>();
|
|
||||||
inetAddressToMacAddress = new HashMap<InetAddress, Long>();
|
|
||||||
macAddressToInetAdddress = new HashMap<Long, InetAddress>();
|
|
||||||
timeoutThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
timeoutThread.interrupt();
|
|
||||||
super.finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAddress(InetAddress addr, long mac) {
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
inetAddressToMacAddress.put(addr, mac);
|
|
||||||
}
|
|
||||||
synchronized (macAddressToInetAdddress) {
|
|
||||||
macAddressToInetAdddress.put(mac, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (entries) {
|
|
||||||
ArpEntry entry = new ArpEntry(mac, addr);
|
|
||||||
if(entries.contains(entry)) {
|
|
||||||
// update the entry time
|
|
||||||
int index = entries.indexOf(entry);
|
|
||||||
entries.get(index).updateTime();
|
|
||||||
} else {
|
|
||||||
entries.add(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateArpEntryTime(long mac) {
|
|
||||||
synchronized (entries) {
|
|
||||||
for(ArpEntry e : entries) {
|
|
||||||
if(mac == e.getMac()) {
|
|
||||||
e.updateTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateArpEntryTime(InetAddress addr) {
|
|
||||||
synchronized (entries) {
|
|
||||||
for(ArpEntry e : entries) {
|
|
||||||
if(addr.equals(e.getAddress())) {
|
|
||||||
e.updateTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MAC address for a given InetAddress
|
|
||||||
*
|
|
||||||
* @param addr address to get the MAC for
|
|
||||||
* @return MAC address as long. -1 if the address isn't known
|
|
||||||
*/
|
|
||||||
long getMacForAddress(InetAddress addr) {
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
if(inetAddressToMacAddress.containsKey(addr)) {
|
|
||||||
long mac = inetAddressToMacAddress.get(addr);
|
|
||||||
updateArpEntryTime(mac);
|
|
||||||
return mac;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the InetAddress for a given MAC address
|
|
||||||
*
|
|
||||||
* @param mac mac address to lookup.
|
|
||||||
* @return InetAddress if it's in the map. Otherwise null.
|
|
||||||
*/
|
|
||||||
InetAddress getAddressForMac(long mac) {
|
|
||||||
synchronized (macAddressToInetAdddress) {
|
|
||||||
if (macAddressToInetAdddress.containsKey(mac)) {
|
|
||||||
InetAddress addr = macAddressToInetAdddress.get(mac);
|
|
||||||
updateArpEntryTime(addr);
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasMacForAddress(InetAddress addr) {
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
return inetAddressToMacAddress.containsKey(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAddressForMac(long mac) {
|
|
||||||
synchronized (macAddressToInetAdddress) {
|
|
||||||
return macAddressToInetAdddress.containsKey(mac);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] longToBytes(long l) {
|
|
||||||
// allocate an 8 byte buffer. Long.SIZE returns number of bits so divide by 8
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE/8);
|
|
||||||
buffer.putLong(l);
|
|
||||||
return buffer.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getRequestPacket(long senderMac, InetAddress senderAddress, InetAddress destinationAddress) {
|
|
||||||
return getARPPacket(REQUEST, senderMac, 0, senderAddress, destinationAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getReplyPacket(long senderMac, InetAddress senderAddress, long destMac, InetAddress destAddress) {
|
|
||||||
return getARPPacket(REPLY, senderMac, destMac, senderAddress, destAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getARPPacket(int packetType, long senderMac, long destMac, InetAddress senderAddress, InetAddress destinationAddress) {
|
|
||||||
byte[] packet = new byte[28];
|
|
||||||
|
|
||||||
// Ethernet packet type
|
|
||||||
packet[0] = 0;
|
|
||||||
packet[1] = 1;
|
|
||||||
|
|
||||||
// IPV4 Protocol. 0x0800
|
|
||||||
packet[2] = 0x08;
|
|
||||||
packet[3] = 0;
|
|
||||||
|
|
||||||
// Hardware MAC address length
|
|
||||||
packet[4] = 6;
|
|
||||||
|
|
||||||
// IP address length
|
|
||||||
packet[5] = 4;
|
|
||||||
|
|
||||||
packet[6] = 0;
|
|
||||||
packet[7] = (byte)packetType;
|
|
||||||
|
|
||||||
byte[] senderMacBuffer = longToBytes(senderMac);
|
|
||||||
System.arraycopy(senderMacBuffer, 2, packet, 8, 6);
|
|
||||||
|
|
||||||
byte[] addrBuffer = senderAddress.getAddress();
|
|
||||||
System.arraycopy(addrBuffer, 0, packet, 14, 4);
|
|
||||||
|
|
||||||
byte[] destMacBuffer = longToBytes(destMac);
|
|
||||||
System.arraycopy(destMacBuffer, 2, packet, 18, 6);
|
|
||||||
|
|
||||||
byte[] destAddrBuffer = destinationAddress.getAddress();
|
|
||||||
System.arraycopy(destAddrBuffer, 0, packet, 24, 4);
|
|
||||||
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a reply is needed
|
|
||||||
*
|
|
||||||
* @param replyBuffer
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public ARPReplyData processARPPacket(byte[] replyBuffer) {
|
|
||||||
Log.d(TAG, "Processing ARP packet");
|
|
||||||
|
|
||||||
byte[] srcMacBuffer = new byte[8];
|
|
||||||
System.arraycopy(replyBuffer, 8, srcMacBuffer, 2, 6);
|
|
||||||
|
|
||||||
byte[] senderAddressBuffer = new byte[4];
|
|
||||||
System.arraycopy(replyBuffer, 14, senderAddressBuffer, 0, 4);
|
|
||||||
|
|
||||||
byte[] destMacBuffer = new byte[8];
|
|
||||||
System.arraycopy(replyBuffer, 18, destMacBuffer, 2, 6);
|
|
||||||
|
|
||||||
byte[] destAddressBuffer = new byte[4];
|
|
||||||
System.arraycopy(replyBuffer, 24, destAddressBuffer, 0, 4);
|
|
||||||
|
|
||||||
InetAddress senderAddress = null;
|
|
||||||
try {
|
|
||||||
senderAddress = InetAddress.getByAddress(senderAddressBuffer);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
InetAddress destAddress = null;
|
|
||||||
try {
|
|
||||||
destAddress = InetAddress.getByAddress(destAddressBuffer);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
long sourceMac = ByteBuffer.wrap(srcMacBuffer).getLong();
|
|
||||||
long destMac = ByteBuffer.wrap(destMacBuffer).getLong();
|
|
||||||
|
|
||||||
if(sourceMac != 0 && senderAddress != null) {
|
|
||||||
setAddress(senderAddress,sourceMac);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destMac != 0 && destAddress != null) {
|
|
||||||
setAddress(destAddress, destMac);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(replyBuffer[7] == 1) {
|
|
||||||
Log.d(TAG, "Reply needed");
|
|
||||||
|
|
||||||
ARPReplyData data = new ARPReplyData();
|
|
||||||
data.destMac = sourceMac;
|
|
||||||
data.destAddress = senderAddress;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ARPReplyData {
|
|
||||||
public long senderMac;
|
|
||||||
public InetAddress senderAddress;
|
|
||||||
public long destMac;
|
|
||||||
public InetAddress destAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ArpEntry {
|
|
||||||
private long mac;
|
|
||||||
private InetAddress address;
|
|
||||||
private long time;
|
|
||||||
|
|
||||||
ArpEntry(long mac, InetAddress address) {
|
|
||||||
this.mac = mac;
|
|
||||||
this.address = address;
|
|
||||||
updateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getMac() { return this.mac; }
|
|
||||||
public InetAddress getAddress() { return this.address; }
|
|
||||||
|
|
||||||
public void updateTime() {
|
|
||||||
this.time = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(ArpEntry e) {
|
|
||||||
// purposely do not check time
|
|
||||||
// mac & address alone determine equality
|
|
||||||
return (mac == e.mac) &&
|
|
||||||
(address.equals(e.address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Thread timeoutThread = new Thread("ARP Timeout Thread") {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
synchronized (entries) {
|
|
||||||
for (ArpEntry e : entries) {
|
|
||||||
if(e.time < (System.currentTimeMillis() + ENTRY_TIMEOUT) ) {
|
|
||||||
synchronized(macAddressToInetAdddress) {
|
|
||||||
macAddressToInetAdddress.remove(e.mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
inetAddressToMacAddress.remove(e.address);
|
|
||||||
}
|
|
||||||
|
|
||||||
entries.remove(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.DataStoreGetListener;
|
|
||||||
import com.zerotier.sdk.DataStorePutListener;
|
|
||||||
|
|
||||||
public class DataStore implements DataStoreGetListener, DataStorePutListener {
|
|
||||||
private static final String TAG = "DataStore";
|
|
||||||
private Context _ctx;
|
|
||||||
|
|
||||||
public DataStore(Context ctx) {
|
|
||||||
this._ctx = ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onDataStorePut(String name, byte[] buffer, boolean secure) {
|
|
||||||
Log.d(TAG, "Writing File: " + name);
|
|
||||||
try {
|
|
||||||
if(name.contains("/")) {
|
|
||||||
// filename has a directory separator.
|
|
||||||
int ix = name.lastIndexOf('/');
|
|
||||||
String path = name.substring(0, ix);
|
|
||||||
|
|
||||||
File f = new File(_ctx.getFilesDir(), path);
|
|
||||||
if(!f.exists()) {
|
|
||||||
f.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
File outputFile = new File(f, name.substring(name.lastIndexOf("/")+1));
|
|
||||||
FileOutputStream fos = new FileOutputStream(outputFile);
|
|
||||||
fos.write(buffer);
|
|
||||||
fos.flush();
|
|
||||||
fos.close();
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
FileOutputStream fos = _ctx.openFileOutput(name, Context.MODE_PRIVATE);
|
|
||||||
fos.write(buffer);
|
|
||||||
fos.flush();
|
|
||||||
fos.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException fnf) {
|
|
||||||
fnf.printStackTrace();
|
|
||||||
return -1;
|
|
||||||
} catch (IOException io) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
io.printStackTrace(pw);
|
|
||||||
Log.e(TAG, sw.toString());
|
|
||||||
return -2;
|
|
||||||
} catch(IllegalArgumentException ie) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
ie.printStackTrace(pw);
|
|
||||||
Log.e(TAG, sw.toString());
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onDelete(String name) {
|
|
||||||
Log.d(TAG, "Deleting File: " + name);
|
|
||||||
boolean deleted = false;
|
|
||||||
if(name.contains("/")) {
|
|
||||||
// filename has a directory separator.
|
|
||||||
|
|
||||||
File f = new File(_ctx.getFilesDir(), name);
|
|
||||||
if (!f.exists()) {
|
|
||||||
deleted = true;
|
|
||||||
} else {
|
|
||||||
deleted = f.delete();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deleted = _ctx.deleteFile(name);
|
|
||||||
}
|
|
||||||
return deleted ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long onDataStoreGet(String name, byte[] out_buffer,
|
|
||||||
long bufferIndex, long[] out_objectSize) {
|
|
||||||
Log.d(TAG, "Reading File: " + name);
|
|
||||||
try {
|
|
||||||
if(name.contains("/")) {
|
|
||||||
// filename has a directory separator.
|
|
||||||
int ix = name.lastIndexOf('/');
|
|
||||||
String path = name.substring(0, ix);
|
|
||||||
|
|
||||||
File f = new File(_ctx.getFilesDir(), path);
|
|
||||||
if(!f.exists()) {
|
|
||||||
f.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
File inputFile = new File(f, name.substring(name.lastIndexOf('/')+1));
|
|
||||||
if(!inputFile.exists()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInputStream fin = new FileInputStream(inputFile);
|
|
||||||
if(bufferIndex > 0) {
|
|
||||||
fin.skip(bufferIndex);
|
|
||||||
}
|
|
||||||
int read = fin.read(out_buffer);
|
|
||||||
fin.close();
|
|
||||||
return read;
|
|
||||||
} else {
|
|
||||||
FileInputStream fin = _ctx.openFileInput(name);
|
|
||||||
out_objectSize[0] = fin.getChannel().size();
|
|
||||||
if (bufferIndex > 0) {
|
|
||||||
fin.skip(bufferIndex);
|
|
||||||
}
|
|
||||||
int read = fin.read(out_buffer);
|
|
||||||
fin.close();
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException fnf) {
|
|
||||||
// Can't read a file that doesn't exist!
|
|
||||||
out_objectSize[0] = 0;
|
|
||||||
return -1;
|
|
||||||
} catch (IOException io) {
|
|
||||||
io.printStackTrace();
|
|
||||||
return -2;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/7/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkStateReceiver extends BroadcastReceiver {
|
|
||||||
private static String TAG = "NetworkStateReceiver";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context ctx, Intent intent) {
|
|
||||||
ConnectivityManager cm =
|
|
||||||
(ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
|
|
||||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
|
||||||
boolean isConnected = (activeNetwork != null &&
|
|
||||||
activeNetwork.isConnectedOrConnecting());
|
|
||||||
|
|
||||||
Intent i = new Intent(ctx, RuntimeService.class);
|
|
||||||
if(isConnected) {
|
|
||||||
Log.d(TAG, "Network State: Connected");
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.START_NETWORK_CHANGE);
|
|
||||||
ctx.startService(i);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Network State: Disconnected");
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.STOP_NETWORK_CHANGE);
|
|
||||||
ctx.startService(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import com.zerotier.one.util.InetAddressUtils;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/13/2015.
|
|
||||||
*/
|
|
||||||
public class Route {
|
|
||||||
InetAddress address;
|
|
||||||
int prefix;
|
|
||||||
|
|
||||||
public Route(InetAddress address, int prefix) {
|
|
||||||
this.address = address;
|
|
||||||
this.prefix = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean belongsToRoute(InetAddress otherAddr) {
|
|
||||||
InetAddress route = InetAddressUtils.addressToRoute(otherAddr, prefix);
|
|
||||||
|
|
||||||
return address.equals(route);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Route r) {
|
|
||||||
return address.equals(r.address) && prefix == r.prefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.one.events.ManualDisconnectEvent;
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
public class RuntimeService extends Service {
|
|
||||||
public static final String START_TYPE = "com.zerotier.one.service.RuntimeService.start_type";
|
|
||||||
public static final int START_NETWORK_CHANGE = 1;
|
|
||||||
public static final int START_BOOT = 2;
|
|
||||||
public static final int START_USER_INTERFACE = 3;
|
|
||||||
public static final int STOP_NETWORK_CHANGE = 4;
|
|
||||||
public static final int STOP_USER_INTERFACE = 5;
|
|
||||||
|
|
||||||
private static final String TAG = "RuntimeService";
|
|
||||||
private EventBus eventBus = EventBus.getDefault();
|
|
||||||
|
|
||||||
private boolean serviceStarted = false;
|
|
||||||
|
|
||||||
private NetworkStateReceiver nsReceiver = null;
|
|
||||||
|
|
||||||
public RuntimeService() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder onBind(Intent intent) {
|
|
||||||
// TODO: Return the communication channel to the service.
|
|
||||||
throw new UnsupportedOperationException("Not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
Log.d(TAG, "RuntimeService started");
|
|
||||||
|
|
||||||
if(nsReceiver == null) {
|
|
||||||
IntentFilter filter = new IntentFilter();
|
|
||||||
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
|
|
||||||
nsReceiver = new NetworkStateReceiver();
|
|
||||||
registerReceiver(nsReceiver, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(intent == null) {
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
|
|
||||||
int startMode = intent.getIntExtra(START_TYPE, 0);
|
|
||||||
// in each of the following cases, Prepare should always return null as the prepare call
|
|
||||||
// is called the first time the UI is started granting permission for ZeroTier to use
|
|
||||||
// the VPN API
|
|
||||||
switch (startMode) {
|
|
||||||
case START_NETWORK_CHANGE: {
|
|
||||||
Log.d(TAG, "Start Network change");
|
|
||||||
if(serviceStarted) {
|
|
||||||
// start ZeroTierOne service.
|
|
||||||
Log.d(TAG, "Start Network Change");
|
|
||||||
Intent i = ZeroTierOneService.prepare(this);
|
|
||||||
if(i == null) {
|
|
||||||
i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
startService(i);
|
|
||||||
serviceStarted = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Ignore Start Network Change: Service has not been manually started.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case START_BOOT: {
|
|
||||||
// if start on boot, start service
|
|
||||||
Log.d(TAG, "Start Boot");
|
|
||||||
Intent i = ZeroTierOneService.prepare(this);
|
|
||||||
if(i == null) {
|
|
||||||
i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
startService(i);
|
|
||||||
serviceStarted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case START_USER_INTERFACE: {
|
|
||||||
Log.d(TAG, "Start User Interface");
|
|
||||||
Intent i = ZeroTierOneService.prepare(this);
|
|
||||||
if(i == null) {
|
|
||||||
i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
startService(i);
|
|
||||||
serviceStarted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case STOP_NETWORK_CHANGE: {
|
|
||||||
Log.d(TAG, "Stop Network Change. Ignored.");
|
|
||||||
// Intent i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
// stopService(i);
|
|
||||||
// EventBus.getDefault().post(new StopEvent());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case STOP_USER_INTERFACE: {
|
|
||||||
Log.d(TAG, "Stop User Interface");
|
|
||||||
Intent i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
stopService(i);
|
|
||||||
EventBus.getDefault().post(new ManualDisconnectEvent());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
Log.e(TAG, "Unknown start ID: " + startId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Broadcast receiver that listens for system bootup and starts
|
|
||||||
* the ZeroTier service
|
|
||||||
*/
|
|
||||||
public class StartupReceiver extends BroadcastReceiver {
|
|
||||||
private static final String TAG = "StartupReceiver";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context ctx, Intent intent) {
|
|
||||||
Log.i(TAG, "Received: " + intent.getAction()+ ". Starting ZeroTier One service.");
|
|
||||||
|
|
||||||
// TODO: Start service
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
|
||||||
|
|
||||||
boolean shouldStart = prefs.getBoolean("general_start_zerotier_on_boot", true);
|
|
||||||
if(shouldStart) {
|
|
||||||
Log.i(TAG, "Preferences set to start ZeroTier on boot");
|
|
||||||
Intent i = new Intent(ctx, RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.START_BOOT);
|
|
||||||
ctx.startService(i);
|
|
||||||
} else {
|
|
||||||
Log.i(TAG, "Preferences set to not start ZeroTier on boot");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,272 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.one.util.IPPacketUtils;
|
|
||||||
import com.zerotier.sdk.Node;
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkFrameListener;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/3/2015.
|
|
||||||
*/
|
|
||||||
public class TunTapAdapter implements VirtualNetworkFrameListener {
|
|
||||||
public static final String TAG = "TunTapAdapter";
|
|
||||||
|
|
||||||
private static final int ARP_PACKET = 0x0806;
|
|
||||||
private static final int IPV4_PACKET = 0x0800;
|
|
||||||
private static final int IPV6_PACKET = 0x86dd;
|
|
||||||
|
|
||||||
public static final long BROADCAST_MAC = 0xffffffffffffL;
|
|
||||||
|
|
||||||
private ARPTable arpTable;
|
|
||||||
private Node node;
|
|
||||||
private ZeroTierOneService ztService;
|
|
||||||
private ParcelFileDescriptor vpnSocket;
|
|
||||||
private FileInputStream in;
|
|
||||||
private FileOutputStream out;
|
|
||||||
|
|
||||||
private final HashMap<Route, Long> routeMap;
|
|
||||||
|
|
||||||
private Thread receiveThread;
|
|
||||||
|
|
||||||
public TunTapAdapter(ZeroTierOneService ztService) {
|
|
||||||
this.ztService = ztService;
|
|
||||||
arpTable = new ARPTable();
|
|
||||||
routeMap = new HashMap<Route, Long>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNode(Node node) {
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVpnSocket(ParcelFileDescriptor vpnSocket) {
|
|
||||||
this.vpnSocket = vpnSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileStreams(FileInputStream in, FileOutputStream out) {
|
|
||||||
this.in = in;
|
|
||||||
this.out = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addRouteAndNetwork(Route route, long networkId) {
|
|
||||||
synchronized (routeMap) {
|
|
||||||
routeMap.put(route, networkId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearRouteMap() {
|
|
||||||
synchronized (routeMap) {
|
|
||||||
routeMap.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startThreads() {
|
|
||||||
receiveThread = new Thread("Tunnel Receive Thread") {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, "TUN Receive Thread Started");
|
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(32767);
|
|
||||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
try {
|
|
||||||
while (!isInterrupted()) {
|
|
||||||
boolean idle = true;
|
|
||||||
int length = in.read(buffer.array());
|
|
||||||
if (length > 0) {
|
|
||||||
Log.d(TAG, "Sending packet to ZeroTier. " + length + " bytes.");
|
|
||||||
idle = false;
|
|
||||||
|
|
||||||
byte packet[] = new byte[length];
|
|
||||||
System.arraycopy(buffer.array(), 0, packet, 0, length);
|
|
||||||
|
|
||||||
InetAddress destAddress = IPPacketUtils.getDestIP(packet);
|
|
||||||
InetAddress sourceAddress = IPPacketUtils.getSourceIP(packet);
|
|
||||||
|
|
||||||
long nwid = networkIdForDestination(destAddress);
|
|
||||||
if (nwid == 0) {
|
|
||||||
Log.e(TAG, "Unable to find network ID for destination address: " + destAddress);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualNetworkConfig cfg = node.networkConfig(nwid);
|
|
||||||
InetAddress myAddress = cfg.assignedAddresses()[0].getAddress();
|
|
||||||
|
|
||||||
long srcMac = cfg.macAddress();
|
|
||||||
long bgt_dl[] = new long[1];
|
|
||||||
|
|
||||||
if (arpTable.hasMacForAddress(destAddress)) {
|
|
||||||
long destMac = arpTable.getMacForAddress(destAddress);
|
|
||||||
|
|
||||||
ResultCode rc = node.processVirtualNetworkFrame(
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
nwid,
|
|
||||||
srcMac,
|
|
||||||
destMac,
|
|
||||||
IPV4_PACKET,
|
|
||||||
0,
|
|
||||||
packet,
|
|
||||||
bgt_dl);
|
|
||||||
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error calling processVirtualNetworkFrame: " + rc.toString());
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Packet sent to ZT");
|
|
||||||
ztService.setNextBackgroundTaskDeadline(bgt_dl[0]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Unknown dest MAC address. Need to look it up. " + destAddress);
|
|
||||||
byte[] arpRequest = arpTable.getRequestPacket(srcMac, myAddress, destAddress);
|
|
||||||
|
|
||||||
ResultCode rc = node.processVirtualNetworkFrame(
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
nwid,
|
|
||||||
srcMac,
|
|
||||||
BROADCAST_MAC,
|
|
||||||
ARP_PACKET,
|
|
||||||
0,
|
|
||||||
arpRequest,
|
|
||||||
bgt_dl);
|
|
||||||
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error sending ARP packet: " + rc.toString());
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "ARP Request Sent!");
|
|
||||||
ztService.setNextBackgroundTaskDeadline(bgt_dl[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer.clear();
|
|
||||||
} else {
|
|
||||||
//Log.d(TAG, "No bytes read: " + length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idle) {
|
|
||||||
Thread.sleep(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error in TUN Receive: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// swallow InterruptedException
|
|
||||||
}
|
|
||||||
Log.d(TAG, "TUN Receive Thread ended");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
receiveThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void interrupt() {
|
|
||||||
if (receiveThread != null) {
|
|
||||||
receiveThread.interrupt();
|
|
||||||
try {
|
|
||||||
receiveThread.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// swallow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRunning() {
|
|
||||||
if (receiveThread == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return receiveThread.isAlive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onVirtualNetworkFrame(
|
|
||||||
long nwid,
|
|
||||||
long srcMac,
|
|
||||||
long destMac,
|
|
||||||
long etherType,
|
|
||||||
long vlanId,
|
|
||||||
byte[] frameData) {
|
|
||||||
Log.d(TAG, "Got Virtual Network Frame. Network ID: " + Long.toHexString(nwid) + " Source MAC: " + Long.toHexString(srcMac) +
|
|
||||||
" Dest MAC: " + Long.toHexString(destMac) + " Ether type: " + etherType + " VLAN ID: " + vlanId + " Frame Length: " + frameData.length);
|
|
||||||
|
|
||||||
if (vpnSocket == null) {
|
|
||||||
Log.e(TAG, "vpnSocket is null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in == null || out == null) {
|
|
||||||
Log.e(TAG, "no in/out streams");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (etherType == ARP_PACKET) {
|
|
||||||
Log.d(TAG, "Got ARP Packet");
|
|
||||||
|
|
||||||
ARPTable.ARPReplyData data = arpTable.processARPPacket(frameData);
|
|
||||||
|
|
||||||
if (data != null && data.destMac != 0 && data.destAddress != null) {
|
|
||||||
// We need to reply here.
|
|
||||||
long deadline[] = new long[1];
|
|
||||||
|
|
||||||
VirtualNetworkConfig cfg = node.networkConfig(nwid);
|
|
||||||
|
|
||||||
InetAddress myAddress = cfg.assignedAddresses()[0].getAddress();
|
|
||||||
|
|
||||||
byte[] replyPacket = arpTable.getReplyPacket(cfg.macAddress(), myAddress, data.destMac, data.destAddress);
|
|
||||||
ResultCode rc = node.processVirtualNetworkFrame(
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
nwid,
|
|
||||||
cfg.macAddress(),
|
|
||||||
srcMac,
|
|
||||||
ARP_PACKET,
|
|
||||||
0,
|
|
||||||
replyPacket,
|
|
||||||
deadline);
|
|
||||||
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error sending ARP packet: " + rc.toString());
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "ARP Reply Sent!");
|
|
||||||
ztService.setNextBackgroundTaskDeadline(deadline[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ((etherType == IPV4_PACKET) ||
|
|
||||||
(etherType == IPV6_PACKET)) {
|
|
||||||
// Got IPv4 or IPv6 packet!
|
|
||||||
Log.d(TAG, "Got IP packet. Length: " + frameData.length + " Bytes");
|
|
||||||
|
|
||||||
try {
|
|
||||||
InetAddress sourceAddress = IPPacketUtils.getSourceIP(frameData);
|
|
||||||
if (sourceAddress != null) {
|
|
||||||
arpTable.setAddress(sourceAddress, srcMac);
|
|
||||||
}
|
|
||||||
out.write(frameData);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error writing data to vpn socket: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Unknown Packet Type Received: 0x" + String.format("%02X%02X", frameData[12], frameData[13]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private long networkIdForDestination(InetAddress destination) {
|
|
||||||
synchronized (routeMap) {
|
|
||||||
for (Route r : routeMap.keySet()) {
|
|
||||||
if (r.belongsToRoute(destination)) {
|
|
||||||
return routeMap.get(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.Node;
|
|
||||||
import com.zerotier.sdk.PacketSender;
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
|
|
||||||
import java.net.DatagramPacket;
|
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/3/2015.
|
|
||||||
*/
|
|
||||||
public class UdpCom implements PacketSender, Runnable {
|
|
||||||
private final static String TAG = "UdpCom";
|
|
||||||
|
|
||||||
Node node;
|
|
||||||
ZeroTierOneService ztService;
|
|
||||||
DatagramSocket svrSocket;
|
|
||||||
|
|
||||||
UdpCom(ZeroTierOneService service, DatagramSocket socket) {
|
|
||||||
svrSocket = socket;
|
|
||||||
this.ztService = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNode(Node node) {
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int onSendPacketRequested(
|
|
||||||
InetSocketAddress localAddress,
|
|
||||||
InetSocketAddress remoteAddress,
|
|
||||||
byte[] packetData,
|
|
||||||
int ttl) {
|
|
||||||
// TTL is ignored. No way to set it on a UDP packet in Java
|
|
||||||
if(svrSocket == null) {
|
|
||||||
Log.e(TAG, "Attempted to send packet on a null socket");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
DatagramPacket p = new DatagramPacket(packetData, packetData.length, remoteAddress);
|
|
||||||
Log.d(TAG, "onSendPacketRequested: Sent "+ p.getLength() + " bytes to " + remoteAddress.toString());
|
|
||||||
svrSocket.send(p);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
Log.d(TAG, "UDP Listen Thread Started.");
|
|
||||||
try {
|
|
||||||
long[] bgtask = new long[1];
|
|
||||||
byte[] buffer = new byte[16384];
|
|
||||||
while(!Thread.interrupted()) {
|
|
||||||
|
|
||||||
bgtask[0] = 0;
|
|
||||||
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
|
|
||||||
|
|
||||||
try {
|
|
||||||
svrSocket.receive(p);
|
|
||||||
if(p.getLength() > 0)
|
|
||||||
{
|
|
||||||
byte[] received = new byte[p.getLength()];
|
|
||||||
System.arraycopy(p.getData(), 0, received, 0, p.getLength());
|
|
||||||
Log.d(TAG, "Got " + p.getLength() + " Bytes From: " + p.getAddress().toString() +":" + p.getPort());
|
|
||||||
|
|
||||||
ResultCode rc = node.processWirePacket(System.currentTimeMillis(), null, new InetSocketAddress(p.getAddress(), p.getPort()), received, bgtask);
|
|
||||||
|
|
||||||
if(rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "procesWirePacket returned: " + rc.toString());
|
|
||||||
ztService.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
ztService.setNextBackgroundTaskDeadline( bgtask[0] );
|
|
||||||
}
|
|
||||||
} catch (SocketTimeoutException e) {
|
|
||||||
Log.d(TAG, "Socket Timeout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
Log.d(TAG, "UDP Listen Thread Ended.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,537 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.net.VpnService;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.zerotier.one.events.ErrorEvent;
|
|
||||||
import com.zerotier.one.events.JoinNetworkEvent;
|
|
||||||
import com.zerotier.one.events.LeaveNetworkEvent;
|
|
||||||
import com.zerotier.one.events.ManualDisconnectEvent;
|
|
||||||
import com.zerotier.one.events.NetworkInfoReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkListReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkReconfigureEvent;
|
|
||||||
import com.zerotier.one.events.NetworkRemovedEvent;
|
|
||||||
import com.zerotier.one.events.NodeDestroyedEvent;
|
|
||||||
import com.zerotier.one.events.NodeIDEvent;
|
|
||||||
import com.zerotier.one.events.NodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.RequestNetworkInfoEvent;
|
|
||||||
import com.zerotier.one.events.RequestNetworkListEvent;
|
|
||||||
import com.zerotier.one.events.RequestNodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
import com.zerotier.one.util.InetAddressUtils;
|
|
||||||
import com.zerotier.one.util.NetworkIdUtils;
|
|
||||||
import com.zerotier.sdk.Event;
|
|
||||||
import com.zerotier.sdk.EventListener;
|
|
||||||
import com.zerotier.sdk.Node;
|
|
||||||
import com.zerotier.sdk.NodeException;
|
|
||||||
import com.zerotier.sdk.NodeStatus;
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfigListener;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfigOperation;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
public class ZeroTierOneService extends VpnService implements Runnable, EventListener, VirtualNetworkConfigListener {
|
|
||||||
|
|
||||||
private static final String TAG = "ZT1_Service";
|
|
||||||
|
|
||||||
public static final String ZT1_NETWORK_ID = "com.zerotier.one.network_id";
|
|
||||||
|
|
||||||
public static final int MSG_JOIN_NETWORK = 1;
|
|
||||||
public static final int MSG_LEAVE_NETWORK = 2;
|
|
||||||
|
|
||||||
private Thread vpnThread;
|
|
||||||
private UdpCom udpCom;
|
|
||||||
private Thread udpThread;
|
|
||||||
|
|
||||||
private TunTapAdapter tunTapAdapter;
|
|
||||||
|
|
||||||
private Node node;
|
|
||||||
private DataStore dataStore;
|
|
||||||
|
|
||||||
DatagramSocket svrSocket;
|
|
||||||
ParcelFileDescriptor vpnSocket;
|
|
||||||
FileInputStream in;
|
|
||||||
FileOutputStream out;
|
|
||||||
|
|
||||||
private final HashMap<Long, VirtualNetworkConfig> networkConfigs;
|
|
||||||
|
|
||||||
private EventBus eventBus = EventBus.getDefault();
|
|
||||||
|
|
||||||
private long nextBackgroundTaskDeadline = 0;
|
|
||||||
private long lastMulticastGroupCheck = 0;
|
|
||||||
|
|
||||||
protected void setNextBackgroundTaskDeadline(long deadline) {
|
|
||||||
synchronized (this) {
|
|
||||||
nextBackgroundTaskDeadline = deadline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZeroTierOneService() {
|
|
||||||
super();
|
|
||||||
dataStore = new DataStore(this);
|
|
||||||
networkConfigs = new HashMap<>();
|
|
||||||
eventBus.register(this);
|
|
||||||
|
|
||||||
Netcon.ZT_SDK_Wrapper wrapper = new Netcon.ZT_SDK_Wrapper();
|
|
||||||
|
|
||||||
|
|
||||||
wrapper.startOneService();
|
|
||||||
/*
|
|
||||||
if(wrapper.loadsymbols() == 4)
|
|
||||||
{
|
|
||||||
Log.e(TAG,"loadsymbols(): Symbol found");
|
|
||||||
//Toast t = Toast.makeText(this, "WORKED", Toast.LENGTH_SHORT);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log.e(TAG,"loadsymbols(): Symbol NOT found");
|
|
||||||
//Toast t = Toast.makeText(this, "DIDNT WORK", Toast.LENGTH_SHORT);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopZeroTier() {
|
|
||||||
if(udpThread != null && udpThread.isAlive()) {
|
|
||||||
udpThread.interrupt();
|
|
||||||
udpThread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(vpnThread != null && vpnThread.isAlive()) {
|
|
||||||
vpnThread.interrupt();
|
|
||||||
vpnThread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(svrSocket != null) {
|
|
||||||
svrSocket.close();
|
|
||||||
svrSocket = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node != null) {
|
|
||||||
eventBus.post(new NodeDestroyedEvent());
|
|
||||||
node.close();
|
|
||||||
node = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
stopZeroTier();
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRevoke() {
|
|
||||||
Intent i = new Intent(this, RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.STOP_USER_INTERFACE);
|
|
||||||
this.startService(i);
|
|
||||||
|
|
||||||
stopZeroTier();
|
|
||||||
try {
|
|
||||||
vpnSocket.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// swallow it
|
|
||||||
}
|
|
||||||
vpnSocket = null;
|
|
||||||
|
|
||||||
stopSelf();
|
|
||||||
|
|
||||||
Intent stopIntent = new Intent(this, RuntimeService.class);
|
|
||||||
stopService(stopIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "ZeroTierOne Service Started");
|
|
||||||
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
boolean autoRejoin = prefs.getBoolean("network_auto_rejoin_networks", true);
|
|
||||||
|
|
||||||
if(autoRejoin) {
|
|
||||||
// find all local network configs and join them
|
|
||||||
File networksFolder = new File(getFilesDir(), "networks.d");
|
|
||||||
if (networksFolder.exists()) {
|
|
||||||
File[] networks = networksFolder.listFiles();
|
|
||||||
for (File f : networks) {
|
|
||||||
if (f.getName().endsWith(".conf")) {
|
|
||||||
String filename = f.getName();
|
|
||||||
filename = filename.substring(0, filename.lastIndexOf('.'));
|
|
||||||
Log.d(TAG, "Loading network: " + filename);
|
|
||||||
ResultCode rc = node.join(NetworkIdUtils.hexStringToLong(filename));
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.d(TAG, "Error joining network: " + rc.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "This Node Address: " + Long.toHexString(node.address()));
|
|
||||||
|
|
||||||
while(!Thread.interrupted()) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
long dl = nextBackgroundTaskDeadline;
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
if (dl <= now) {
|
|
||||||
long[] returnDeadline = {0};
|
|
||||||
ResultCode rc = node.processBackgroundTasks(now, returnDeadline);
|
|
||||||
|
|
||||||
synchronized(this) {
|
|
||||||
nextBackgroundTaskDeadline = returnDeadline[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error on processBackgroundTasks: " + rc.toString());
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
long delay = (dl > now) ? (dl - now) : 100;
|
|
||||||
Thread.sleep(delay);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
break;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.e(TAG, ex.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.d(TAG, "ZeroTierOne Service Ended");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// EventBus events
|
|
||||||
//
|
|
||||||
|
|
||||||
public void onEvent(StopEvent e) {
|
|
||||||
stopZeroTier();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEvent(ManualDisconnectEvent e) {
|
|
||||||
stopZeroTier();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(JoinNetworkEvent e) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Join Network Event");
|
|
||||||
if(node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Remove this once multi-network support is in place
|
|
||||||
for(long nwid : networkConfigs.keySet()) {
|
|
||||||
onEventBackgroundThread(new LeaveNetworkEvent(nwid));
|
|
||||||
}
|
|
||||||
|
|
||||||
networkConfigs.clear();
|
|
||||||
|
|
||||||
ResultCode rc = node.join(e.getNetworkId());
|
|
||||||
if(rc != ResultCode.RESULT_OK) {
|
|
||||||
eventBus.post(new ErrorEvent(rc));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(LeaveNetworkEvent e) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Leave Network Event");
|
|
||||||
|
|
||||||
if(node != null) {
|
|
||||||
ResultCode rc = node.leave(e.getNetworkId());
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
eventBus.post(new ErrorEvent(rc));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String certsFile = "networks.d/" + Long.toHexString(e.getNetworkId()) + ".mcerts";
|
|
||||||
String confFile = "networks.d/" + Long.toHexString(e.getNetworkId()) + ".conf";
|
|
||||||
dataStore.onDelete(confFile);
|
|
||||||
dataStore.onDelete(certsFile);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(RequestNetworkInfoEvent e) {
|
|
||||||
/*
|
|
||||||
if(node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualNetworkConfig vnc = node.networkConfig(e.getNetworkId());
|
|
||||||
if(vnc != null) {
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(vnc));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(RequestNetworkListEvent e) {
|
|
||||||
/*
|
|
||||||
if(node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VirtualNetworkConfig[] networks = node.networks();
|
|
||||||
if(networks != null && networks.length > 0) {
|
|
||||||
eventBus.post(new NetworkListReplyEvent(networks));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(RequestNodeStatusEvent e) {
|
|
||||||
/*
|
|
||||||
if (node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeStatus ns = node.status();
|
|
||||||
|
|
||||||
eventBus.post(new NodeStatusEvent(ns));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventAsync(NetworkReconfigureEvent e) {
|
|
||||||
updateTunnelConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Event Listener Overrides
|
|
||||||
//
|
|
||||||
public void onEvent(Event e) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Event: " + e.toString());
|
|
||||||
|
|
||||||
if(node != null) {
|
|
||||||
NodeStatus status = node.status();
|
|
||||||
NodeStatusEvent nse = new NodeStatusEvent(status);
|
|
||||||
eventBus.post(nse);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTrace(String msg) {
|
|
||||||
Log.d(TAG, "Trace: " + msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Virtual Network Config Listener overrides
|
|
||||||
//
|
|
||||||
|
|
||||||
public int onNetworkConfigurationUpdated(
|
|
||||||
long nwid,
|
|
||||||
VirtualNetworkConfigOperation op,
|
|
||||||
VirtualNetworkConfig config) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Virtual Network Config Operation: " + op.toString());
|
|
||||||
switch(op) {
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_UP: {
|
|
||||||
Log.d(TAG, "Network Type:" + config.networkType().toString() + " " +
|
|
||||||
"Network Status: " + config.networkStatus().toString() + " " +
|
|
||||||
"Network Name: " + config.name() + " ");
|
|
||||||
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(config));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: {
|
|
||||||
Log.d(TAG, "Network Config Update!");
|
|
||||||
|
|
||||||
|
|
||||||
VirtualNetworkConfig cfg = null;
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
if (networkConfigs.containsKey(nwid)) {
|
|
||||||
cfg = networkConfigs.get(nwid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cfg == null) {
|
|
||||||
// we don't already have this network config
|
|
||||||
Log.d(TAG, "Adding new network.");
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
networkConfigs.put(nwid, config);
|
|
||||||
}
|
|
||||||
eventBus.post(new NetworkReconfigureEvent());
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(config));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!cfg.equals(config)) {
|
|
||||||
Log.d(TAG, "Updating network config");
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
networkConfigs.remove(nwid);
|
|
||||||
networkConfigs.put(nwid, config);
|
|
||||||
}
|
|
||||||
eventBus.post(new NetworkReconfigureEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(config));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN:
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY:
|
|
||||||
Log.d(TAG, "Network Down!");
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
if (networkConfigs.containsKey(nwid)) {
|
|
||||||
networkConfigs.remove(nwid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eventBus.post(new NetworkReconfigureEvent());
|
|
||||||
eventBus.post(new NetworkRemovedEvent(nwid));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Log.e(TAG, "Unknown Network Config Operation!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void shutdown() {
|
|
||||||
stopZeroTier();
|
|
||||||
this.stopSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This should ONLY be called from onEventAsync(NetworkReconfigureEvent)
|
|
||||||
*/
|
|
||||||
private void updateTunnelConfig() {
|
|
||||||
|
|
||||||
/*
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
if (networkConfigs.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tunTapAdapter.isRunning()) {
|
|
||||||
tunTapAdapter.interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
tunTapAdapter.clearRouteMap();
|
|
||||||
|
|
||||||
if (vpnSocket != null) {
|
|
||||||
try {
|
|
||||||
vpnSocket.close();
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
vpnSocket = null;
|
|
||||||
in = null;
|
|
||||||
out = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Builder builder = new Builder();
|
|
||||||
|
|
||||||
int highestMtu = 0;
|
|
||||||
|
|
||||||
for (VirtualNetworkConfig config : networkConfigs.values()) {
|
|
||||||
if (config.isEnabled()) {
|
|
||||||
long nwid = config.networkId();
|
|
||||||
|
|
||||||
InetSocketAddress addresses[] = config.assignedAddresses();
|
|
||||||
|
|
||||||
int adi = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < addresses.length; ++i) {
|
|
||||||
Log.d(TAG, "Adding VPN Address: " + addresses[i].getAddress() + " Mac: " + Long.toHexString(config.macAddress()));
|
|
||||||
|
|
||||||
byte[] addrBytes = addresses[i].getAddress().getAddress();
|
|
||||||
|
|
||||||
try {
|
|
||||||
adi = ByteBuffer.wrap(addrBytes).getInt();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Exception calculating multicast ADI: " + e.getMessage());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int routeSub = addresses[i].getPort();
|
|
||||||
InetAddress address = addresses[i].getAddress();
|
|
||||||
|
|
||||||
// TODO: Support IPv6
|
|
||||||
if(address instanceof Inet6Address) {
|
|
||||||
Log.d(TAG, "Got an IPV6 Address. Not adding it to the adapter");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
InetAddress route = InetAddressUtils.addressToRoute(address, routeSub);
|
|
||||||
if(route == null) {
|
|
||||||
Log.e(TAG, "NULL route calculated!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode rc = node.multicastSubscribe(nwid, TunTapAdapter.BROADCAST_MAC, adi);
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error joining multicast group");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Joined multicast group");
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.addAddress(address, routeSub);
|
|
||||||
builder.addRoute(route, routeSub);
|
|
||||||
|
|
||||||
Route r = new Route(route, routeSub);
|
|
||||||
tunTapAdapter.addRouteAndNetwork(r, nwid);
|
|
||||||
|
|
||||||
|
|
||||||
int mtu = config.mtu();
|
|
||||||
if (mtu > highestMtu) {
|
|
||||||
highestMtu = mtu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.setMtu(highestMtu);
|
|
||||||
builder.setSession("ZeroTier One");
|
|
||||||
|
|
||||||
|
|
||||||
vpnSocket = builder.establish();
|
|
||||||
if(vpnSocket == null) {
|
|
||||||
Log.e(TAG, "vpnSocket is NULL after builder.establish()!!!!");
|
|
||||||
stopZeroTier();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
in = new FileInputStream(vpnSocket.getFileDescriptor());
|
|
||||||
out = new FileOutputStream(vpnSocket.getFileDescriptor());
|
|
||||||
|
|
||||||
tunTapAdapter.setVpnSocket(vpnSocket);
|
|
||||||
tunTapAdapter.setFileStreams(in, out);
|
|
||||||
tunTapAdapter.startThreads();
|
|
||||||
Log.i(TAG, "ZeroTier One Connected");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013 Maarten Pennings
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* If you use this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.inputmethodservice.Keyboard;
|
|
||||||
import android.inputmethodservice.KeyboardView;
|
|
||||||
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.InputType;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.View.OnFocusChangeListener;
|
|
||||||
import android.view.View.OnTouchListener;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When an activity hosts a keyboardView, this class allows several EditText's to register for it.
|
|
||||||
*
|
|
||||||
* @author Maarten Pennings
|
|
||||||
* @date 2012 December 23
|
|
||||||
*/
|
|
||||||
class HexKeyboard {
|
|
||||||
private final static String TAG = "HexKeyboard";
|
|
||||||
|
|
||||||
/** A link to the KeyboardView that is used to render this CustomKeyboard. */
|
|
||||||
private KeyboardView mKeyboardView;
|
|
||||||
/** A link to the activity that hosts the {@link #mKeyboardView}. */
|
|
||||||
private Activity mHostActivity;
|
|
||||||
|
|
||||||
/** The key (code) handler. */
|
|
||||||
private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
|
|
||||||
|
|
||||||
public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
|
|
||||||
public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL
|
|
||||||
public final static int CodePrev = 55000;
|
|
||||||
public final static int CodeAllLeft = 55001;
|
|
||||||
public final static int CodeLeft = 55002;
|
|
||||||
public final static int CodeRight = 55003;
|
|
||||||
public final static int CodeAllRight = 55004;
|
|
||||||
public final static int CodeNext = 55005;
|
|
||||||
public final static int CodeClear = 55006;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onKey(int primaryCode, int[] keyCodes) {
|
|
||||||
// NOTE We can say '<Key android:codes="49,50" ... >' in the xml file; all codes come in keyCodes, the first in this list in primaryCode
|
|
||||||
// Get the EditText and its Editable
|
|
||||||
View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
|
|
||||||
|
|
||||||
if( focusCurrent==null) return;
|
|
||||||
|
|
||||||
EditText edittext = (EditText) focusCurrent;
|
|
||||||
Editable editable = edittext.getText();
|
|
||||||
int start = edittext.getSelectionStart();
|
|
||||||
// Apply the key to the edittext
|
|
||||||
if( primaryCode==CodeCancel ) {
|
|
||||||
hideCustomKeyboard();
|
|
||||||
} else if( primaryCode==CodeDelete ) {
|
|
||||||
if( editable!=null && start>0 ) editable.delete(start - 1, start);
|
|
||||||
} else if( primaryCode==CodeClear ) {
|
|
||||||
if( editable!=null ) editable.clear();
|
|
||||||
} else if( primaryCode==CodeLeft ) {
|
|
||||||
if( start>0 ) edittext.setSelection(start - 1);
|
|
||||||
} else if( primaryCode==CodeRight ) {
|
|
||||||
if (start < edittext.length()) edittext.setSelection(start + 1);
|
|
||||||
} else if( primaryCode==CodeAllLeft ) {
|
|
||||||
edittext.setSelection(0);
|
|
||||||
} else if( primaryCode==CodeAllRight ) {
|
|
||||||
edittext.setSelection(edittext.length());
|
|
||||||
} else if( primaryCode==CodePrev ) {
|
|
||||||
View focusNew= edittext.focusSearch(View.FOCUS_LEFT);
|
|
||||||
if( focusNew!=null ) focusNew.requestFocus();
|
|
||||||
} else if( primaryCode==CodeNext ) {
|
|
||||||
View focusNew= edittext.focusSearch(View.FOCUS_RIGHT);
|
|
||||||
if( focusNew!=null ) focusNew.requestFocus();
|
|
||||||
} else { // insert character
|
|
||||||
editable.insert(start, Character.toString((char) primaryCode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPress(int arg0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRelease(int primaryCode) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onText(CharSequence text) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeDown() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeLeft() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeRight() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeUp() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a custom keyboard, that uses the KeyboardView (with resource id <var>viewid</var>) of the <var>host</var> activity,
|
|
||||||
* and load the keyboard layout from xml file <var>layoutid</var> (see {@link Keyboard} for description).
|
|
||||||
* Note that the <var>host</var> activity must have a <var>KeyboardView</var> in its layout (typically aligned with the bottom of the activity).
|
|
||||||
* Note that the keyboard layout xml file may include key codes for navigation; see the constants in this class for their values.
|
|
||||||
* Note that to enable EditText's to use this custom keyboard, call the {@link #registerEditText(int)}.
|
|
||||||
*
|
|
||||||
* @param host The hosting activity.
|
|
||||||
* @param viewid The id of the KeyboardView.
|
|
||||||
* @param layoutid The id of the xml file containing the keyboard layout.
|
|
||||||
*/
|
|
||||||
public HexKeyboard(Activity host, int viewid, int layoutid) {
|
|
||||||
mHostActivity= host;
|
|
||||||
mKeyboardView= (KeyboardView)mHostActivity.findViewById(viewid);
|
|
||||||
mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
|
|
||||||
mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview balloons
|
|
||||||
mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
|
|
||||||
// Hide the standard keyboard initially
|
|
||||||
mHostActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether the CustomKeyboard is visible. */
|
|
||||||
public boolean isCustomKeyboardVisible() {
|
|
||||||
return mKeyboardView.getVisibility() == View.VISIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make the CustomKeyboard visible, and hide the system keyboard for view v. */
|
|
||||||
public void showCustomKeyboard( View v ) {
|
|
||||||
mKeyboardView.setVisibility(View.VISIBLE);
|
|
||||||
mKeyboardView.setEnabled(true);
|
|
||||||
if( v!=null ) ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make the CustomKeyboard invisible. */
|
|
||||||
public void hideCustomKeyboard() {
|
|
||||||
mKeyboardView.setVisibility(View.GONE);
|
|
||||||
mKeyboardView.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register <var>EditText<var> with resource id <var>resid</var> (on the hosting activity) for using this custom keyboard.
|
|
||||||
*
|
|
||||||
* @param resid The resource id of the EditText that registers to the custom keyboard.
|
|
||||||
*/
|
|
||||||
public void registerEditText(int resid) {
|
|
||||||
// Find the EditText 'resid'
|
|
||||||
EditText edittext= (EditText)mHostActivity.findViewById(resid);
|
|
||||||
// Make the custom keyboard appear
|
|
||||||
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
|
|
||||||
// NOTE By setting the on focus listener, we can show the custom keyboard when the edit box gets focus, but also hide it when the edit box loses focus
|
|
||||||
@Override
|
|
||||||
public void onFocusChange(View v, boolean hasFocus) {
|
|
||||||
if (hasFocus) showCustomKeyboard(v);
|
|
||||||
else hideCustomKeyboard();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
edittext.setOnClickListener(new OnClickListener() {
|
|
||||||
// NOTE By setting the on click listener, we can show the custom keyboard again, by tapping on an edit box that already had focus (but that had the keyboard hidden).
|
|
||||||
@Override public void onClick(View v) {
|
|
||||||
showCustomKeyboard(v);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Disable standard keyboard hard way
|
|
||||||
// NOTE There is also an easy way: 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
|
|
||||||
edittext.setOnTouchListener(new OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
|
||||||
EditText edittext = (EditText) v;
|
|
||||||
int inType = edittext.getInputType(); // Backup the input type
|
|
||||||
edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
|
|
||||||
edittext.onTouchEvent(event); // Call native handler
|
|
||||||
edittext.setInputType(inType); // Restore input type
|
|
||||||
return true; // Consume touch event
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Disable spell check (hex strings look like words to Android)
|
|
||||||
edittext.setInputType(edittext.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/20/2015.
|
|
||||||
*/
|
|
||||||
public class JoinNetworkActivity extends SingleFragmentActivity {
|
|
||||||
public Fragment createFragment() {
|
|
||||||
return new JoinNetworkFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
|
|
||||||
import com.zerotier.one.AnalyticsApplication;
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
import com.zerotier.one.events.JoinNetworkEvent;
|
|
||||||
import com.zerotier.one.util.NetworkIdUtils;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/20/2015.
|
|
||||||
*/
|
|
||||||
public class JoinNetworkFragment extends Fragment {
|
|
||||||
public final static String TAG = "JoinNetwork";
|
|
||||||
|
|
||||||
private Tracker tracker = null;
|
|
||||||
|
|
||||||
private Button mJoinButton;
|
|
||||||
private EditText mNetworkIdTextView;
|
|
||||||
private ListView mRecentNetworksList;
|
|
||||||
|
|
||||||
EventBus eventBus = EventBus.getDefault();
|
|
||||||
|
|
||||||
HexKeyboard mHexKeyboard;
|
|
||||||
|
|
||||||
public JoinNetworkFragment() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Join Network");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Join Network");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
|
|
||||||
mHexKeyboard = new HexKeyboard(getActivity(), R.id.join_network_keyboard, R.xml.hex_keyboard);
|
|
||||||
mHexKeyboard.registerEditText(R.id.join_network_edit_text);
|
|
||||||
mHexKeyboard.hideCustomKeyboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
|
|
||||||
super.onCreateView(inflater, parent, savedInstanceState);
|
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_join_network, parent, false);
|
|
||||||
|
|
||||||
mNetworkIdTextView = (EditText)v.findViewById(R.id.join_network_edit_text);
|
|
||||||
mNetworkIdTextView.addTextChangedListener(new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
if (s.toString().length() == 16) {
|
|
||||||
mJoinButton.setEnabled(true);
|
|
||||||
} else {
|
|
||||||
mJoinButton.setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mJoinButton = (Button)v.findViewById(R.id.button_join_network);
|
|
||||||
mJoinButton.setEnabled(false);
|
|
||||||
mJoinButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, "Joining network " + mNetworkIdTextView.getText().toString());
|
|
||||||
String netIdString = mNetworkIdTextView.getText().toString();
|
|
||||||
long networkId = NetworkIdUtils.hexStringToLong(netIdString);
|
|
||||||
|
|
||||||
SharedPreferences prefs = getActivity().getSharedPreferences("recent_networks", Context.MODE_PRIVATE);
|
|
||||||
try {
|
|
||||||
String nws = prefs.getString("recent_networks", (new JSONArray()).toString());
|
|
||||||
JSONArray jArray = new JSONArray(nws);
|
|
||||||
ArrayList<String> array = new ArrayList<>();
|
|
||||||
|
|
||||||
// convert the JSON array to an actual array for ease of modification
|
|
||||||
for(int i = 0; i < jArray.length(); ++i) {
|
|
||||||
array.add(jArray.getString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean containsValue = false;
|
|
||||||
|
|
||||||
for(String id : array) {
|
|
||||||
if(id.equals(netIdString)) {
|
|
||||||
containsValue = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(containsValue) {
|
|
||||||
// remove the item
|
|
||||||
array.remove(netIdString);
|
|
||||||
} else {
|
|
||||||
// pop off the last item
|
|
||||||
if (array.size() > 4) {
|
|
||||||
array.remove(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert ID at the beginning of the list
|
|
||||||
array.add(0, mNetworkIdTextView.getText().toString());
|
|
||||||
|
|
||||||
// convert the list back to a JSON array
|
|
||||||
jArray = new JSONArray();
|
|
||||||
for(String id : array) {
|
|
||||||
jArray.put(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write JSON array to preferences
|
|
||||||
SharedPreferences.Editor e = prefs.edit();
|
|
||||||
e.putString("recent_networks", jArray.toString());
|
|
||||||
e.apply();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Exception setting recent networks: " + e.getMessage());
|
|
||||||
}
|
|
||||||
eventBus.post(new JoinNetworkEvent(networkId));
|
|
||||||
} catch (Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
Log.d(TAG, "Join Network: Error parsing network ID");
|
|
||||||
} finally {
|
|
||||||
getActivity().onBackPressed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mRecentNetworksList = (ListView) v.findViewById(R.id.recent_networks_list);
|
|
||||||
|
|
||||||
SharedPreferences prefs = getActivity().getSharedPreferences("recent_networks", Context.MODE_PRIVATE);
|
|
||||||
try {
|
|
||||||
String nws = prefs.getString("recent_networks", new JSONArray().toString());
|
|
||||||
JSONArray networks = new JSONArray(nws);
|
|
||||||
|
|
||||||
|
|
||||||
TextView recentNetworksText = (TextView) v.findViewById(R.id.recent_networks);
|
|
||||||
|
|
||||||
if (networks.length() == 0) {
|
|
||||||
mRecentNetworksList.setVisibility(View.GONE);
|
|
||||||
recentNetworksText.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
mRecentNetworksList.setVisibility(View.VISIBLE);
|
|
||||||
recentNetworksText.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
ArrayList<String> recentNetworks = new ArrayList<>();
|
|
||||||
for(int i = 0; i < networks.length(); ++i) {
|
|
||||||
recentNetworks.add(networks.getString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
final NetworkIDAdapter adapter = new NetworkIDAdapter(recentNetworks);
|
|
||||||
mRecentNetworksList.setAdapter(adapter);
|
|
||||||
|
|
||||||
mRecentNetworksList.setOnItemClickListener(new ListView.OnItemClickListener() {
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
mNetworkIdTextView.setText(adapter.getItem(position));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "JSON Error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class NetworkIDAdapter extends ArrayAdapter<String> {
|
|
||||||
public NetworkIDAdapter(ArrayList<String> config) {
|
|
||||||
super(getActivity(), 0, config);
|
|
||||||
Log.d(TAG, "Created network list item adapter");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
if(convertView == null) {
|
|
||||||
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_recent_network, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
String networkId = getItem(position);
|
|
||||||
TextView network = (TextView) convertView.findViewById(R.id.list_recent_network_id);
|
|
||||||
network.setText(networkId);
|
|
||||||
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/20/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkListActivity extends SingleFragmentActivity {
|
|
||||||
@Override
|
|
||||||
public Fragment createFragment() {
|
|
||||||
return new NetworkListFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,487 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
import com.zerotier.one.AnalyticsApplication;
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
import com.zerotier.one.events.LeaveNetworkEvent;
|
|
||||||
import com.zerotier.one.events.ManualDisconnectEvent;
|
|
||||||
import com.zerotier.one.events.NetworkInfoReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkListReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkRemovedEvent;
|
|
||||||
import com.zerotier.one.events.NodeDestroyedEvent;
|
|
||||||
import com.zerotier.one.events.NodeIDEvent;
|
|
||||||
import com.zerotier.one.events.NodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.RequestNetworkListEvent;
|
|
||||||
import com.zerotier.one.events.RequestNodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
import com.zerotier.one.service.RuntimeService;
|
|
||||||
import com.zerotier.one.service.ZeroTierOneService;
|
|
||||||
import com.zerotier.sdk.NodeStatus;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
public class NetworkListFragment extends Fragment {
|
|
||||||
enum ConnectStatus {
|
|
||||||
CONNECTED,
|
|
||||||
DISCONNECTED
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tracker tracker = null;
|
|
||||||
|
|
||||||
public static final String TAG = "NetworkListFragment";
|
|
||||||
|
|
||||||
public static final int START_VPN = 2;
|
|
||||||
|
|
||||||
private ArrayList<VirtualNetworkConfig> mNetworkConfigs;
|
|
||||||
|
|
||||||
private EventBus eventBus;
|
|
||||||
private NetworkAdapter adapter;
|
|
||||||
private ListView listView;
|
|
||||||
private TextView nodeIdView;
|
|
||||||
private TextView nodeStatusView;
|
|
||||||
private Button connectButton;
|
|
||||||
private MenuItem joinNetworkMenu;
|
|
||||||
|
|
||||||
private ConnectStatus cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mandatory empty constructor for the fragment manager to instantiate the
|
|
||||||
* fragment (e.g. upon screen orientation changes).
|
|
||||||
*/
|
|
||||||
public NetworkListFragment() {
|
|
||||||
Log.d(TAG, "Network List Fragment created");
|
|
||||||
mNetworkConfigs = new ArrayList<VirtualNetworkConfig>();
|
|
||||||
eventBus = EventBus.getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
eventBus.register(this);
|
|
||||||
eventBus.post(new RequestNetworkListEvent());
|
|
||||||
eventBus.post(new RequestNodeStatusEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
eventBus.unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
|
|
||||||
super.onCreateView(inflater, parent, savedInstanceState);
|
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.network_list_fragment, parent, false);
|
|
||||||
|
|
||||||
listView = (ListView)v.findViewById(R.id.joined_networks_list);
|
|
||||||
|
|
||||||
adapter = new NetworkAdapter(mNetworkConfigs);
|
|
||||||
listView.setAdapter(adapter);
|
|
||||||
|
|
||||||
nodeIdView = (TextView) v.findViewById(R.id.node_id);
|
|
||||||
nodeStatusView = (TextView) v.findViewById(R.id.node_status);
|
|
||||||
connectButton = (Button) v.findViewById(R.id.connect_button);
|
|
||||||
|
|
||||||
if(cstatus == ConnectStatus.CONNECTED) {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_disconnect));
|
|
||||||
} else {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
}
|
|
||||||
|
|
||||||
connectButton.setOnClickListener(new Button.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (cstatus == ConnectStatus.CONNECTED) {
|
|
||||||
Intent i = new Intent(getActivity(), RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.STOP_USER_INTERFACE);
|
|
||||||
getActivity().startService(i);
|
|
||||||
cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
nodeStatusView.setText("OFFLINE");
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
sendStartServiceIntent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendStartServiceIntent() {
|
|
||||||
Intent i = ZeroTierOneService.prepare(getActivity());
|
|
||||||
if(i != null) {
|
|
||||||
startActivityForResult(i, START_VPN);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Intent is NULL. Already approved.");
|
|
||||||
startService();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
Log.d(TAG, "NetworkListFragment.onCreate");
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
|
|
||||||
|
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Network List");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
nodeStatusView.setText("OFFLINE");
|
|
||||||
mNetworkConfigs.clear();
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
|
|
||||||
eventBus.post(new RequestNetworkListEvent());
|
|
||||||
eventBus.post(new RequestNodeStatusEvent());
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
tracker.setScreenName("Network List");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
||||||
Log.d(TAG, "NetworkListFragment.onCreateOptionsMenu");
|
|
||||||
inflater.inflate(R.menu.menu_network_list, menu);
|
|
||||||
joinNetworkMenu = menu.findItem(R.id.menu_item_join_network);
|
|
||||||
joinNetworkMenu.setEnabled(false);
|
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
|
||||||
eventBus.post(new RequestNodeStatusEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.menu_item_join_network: {
|
|
||||||
Log.d(TAG, "Selected Join Network");
|
|
||||||
Intent i = new Intent(getActivity(), JoinNetworkActivity.class);
|
|
||||||
startActivity(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case R.id.menu_item_prefs: {
|
|
||||||
Log.d(TAG, "Selected Preferences");
|
|
||||||
Intent i = new Intent(getActivity(), PrefsActivity.class);
|
|
||||||
startActivity(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
|
|
||||||
switch(requestCode)
|
|
||||||
{
|
|
||||||
case START_VPN:
|
|
||||||
{
|
|
||||||
// Start ZeroTierOneService
|
|
||||||
startService();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity) {
|
|
||||||
super.onAttach(activity);
|
|
||||||
Log.d(TAG, "NetworkListFragment.onAttach");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetach() {
|
|
||||||
Log.d(TAG, "NetworkListFragment.onDetach");
|
|
||||||
super.onDetach();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NetworkListReplyEvent e) {
|
|
||||||
Log.d(TAG, "Got network list");
|
|
||||||
mNetworkConfigs.clear();
|
|
||||||
for(int i = 0; i < e.getNetworkList().length; ++i) {
|
|
||||||
mNetworkConfigs.add(e.getNetworkList()[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NetworkInfoReplyEvent e) {
|
|
||||||
Log.d(TAG, "Got Network Info");
|
|
||||||
VirtualNetworkConfig vnc = e.getNetworkInfo();
|
|
||||||
boolean hasNetworkWithId = false;
|
|
||||||
|
|
||||||
for(VirtualNetworkConfig c : mNetworkConfigs) {
|
|
||||||
if(c.networkId() == vnc.networkId()) {
|
|
||||||
hasNetworkWithId = true;
|
|
||||||
int index = mNetworkConfigs.indexOf(c);
|
|
||||||
mNetworkConfigs.set(index, vnc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!hasNetworkWithId) {
|
|
||||||
mNetworkConfigs.add(vnc);
|
|
||||||
}
|
|
||||||
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NetworkRemovedEvent e) {
|
|
||||||
Log.d(TAG, "Removing network: " + Long.toHexString(e.getNetworkId()));
|
|
||||||
for(VirtualNetworkConfig c : mNetworkConfigs) {
|
|
||||||
if(c.networkId() == e.getNetworkId()) {
|
|
||||||
mNetworkConfigs.remove(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NodeIDEvent e) {
|
|
||||||
long nodeId = e.getNodeId();
|
|
||||||
String nodeHex = Long.toHexString(nodeId);
|
|
||||||
while(nodeHex.length() < 10) {
|
|
||||||
nodeHex = "0" + nodeHex;
|
|
||||||
}
|
|
||||||
nodeIdView.setText(nodeHex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NodeStatusEvent e) {
|
|
||||||
NodeStatus status = e.getStatus();
|
|
||||||
if(status.isOnline()) {
|
|
||||||
nodeStatusView.setText("ONLINE");
|
|
||||||
if(joinNetworkMenu != null) {
|
|
||||||
joinNetworkMenu.setEnabled(true);
|
|
||||||
}
|
|
||||||
cstatus = ConnectStatus.CONNECTED;
|
|
||||||
if(connectButton != null) {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_disconnect));
|
|
||||||
}
|
|
||||||
if(nodeIdView != null) {
|
|
||||||
nodeIdView.setText(Long.toHexString(status.getAddres()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setOfflineState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NodeDestroyedEvent e) {
|
|
||||||
setOfflineState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setOfflineState() {
|
|
||||||
if(nodeStatusView != null) {
|
|
||||||
nodeStatusView.setText("OFFLINE");
|
|
||||||
}
|
|
||||||
if(joinNetworkMenu != null) {
|
|
||||||
joinNetworkMenu.setEnabled(false);
|
|
||||||
}
|
|
||||||
cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
if(connectButton != null) {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sortNetworkListAndNotify() {
|
|
||||||
Collections.sort(mNetworkConfigs);
|
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
listView.invalidateViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startService() {
|
|
||||||
Intent i = new Intent(getActivity(), RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.START_USER_INTERFACE);
|
|
||||||
getActivity().startService(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NetworkAdapter extends ArrayAdapter<VirtualNetworkConfig> {
|
|
||||||
|
|
||||||
public NetworkAdapter(ArrayList<VirtualNetworkConfig> config) {
|
|
||||||
super(getActivity(), 0, config);
|
|
||||||
Log.d(TAG, "Created network list item adapter");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
if(!listView.getItemsCanFocus()) {
|
|
||||||
listView.setItemsCanFocus(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(convertView == null) {
|
|
||||||
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_network, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualNetworkConfig vnc = getItem(position);
|
|
||||||
TextView networkId = (TextView)convertView.findViewById(R.id.network_list_network_id);
|
|
||||||
networkId.setText(Long.toHexString(vnc.networkId()));
|
|
||||||
|
|
||||||
TextView networkName = (TextView) convertView.findViewById(R.id.network_list_network_name);
|
|
||||||
networkName.setText(vnc.name());
|
|
||||||
|
|
||||||
|
|
||||||
TextView networkStatus = (TextView)convertView.findViewById(R.id.network_status_textview);
|
|
||||||
|
|
||||||
CharSequence statusText;
|
|
||||||
switch(vnc.networkStatus()) {
|
|
||||||
case NETWORK_STATUS_OK:
|
|
||||||
statusText = getResources().getText(R.string.network_status_ok);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_ACCESS_DENIED:
|
|
||||||
statusText = getResources().getText(R.string.network_status_access_denied);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_CLIENT_TOO_OLD:
|
|
||||||
statusText = getResources().getText(R.string.network_status_client_too_old);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_NOT_FOUND:
|
|
||||||
statusText = getResources().getText(R.string.network_status_not_found);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_PORT_ERROR:
|
|
||||||
statusText = getResources().getText(R.string.network_status_port_error);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_REQUESTING_CONFIGURATION:
|
|
||||||
statusText = getResources().getText(R.string.network_status_requesting_configuration);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
statusText = getResources().getText(R.string.network_status_unknown);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
networkStatus.setText(statusText);
|
|
||||||
|
|
||||||
TextView networkType = (TextView)convertView.findViewById(R.id.network_type_textview);
|
|
||||||
switch(vnc.networkType()) {
|
|
||||||
case NETWORK_TYPE_PUBLIC:
|
|
||||||
networkType.setText(getResources().getText(R.string.network_type_public));
|
|
||||||
break;
|
|
||||||
case NETWORK_TYPE_PRIVATE:
|
|
||||||
networkType.setText(getResources().getText(R.string.network_type_private));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
networkType.setText(getResources().getText(R.string.network_type_unknown));
|
|
||||||
}
|
|
||||||
|
|
||||||
String mac = Long.toHexString(vnc.macAddress());
|
|
||||||
while(mac.length() < 12) {
|
|
||||||
mac = "0" + mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder displayMac = new StringBuilder();
|
|
||||||
displayMac.append(mac.charAt(0));
|
|
||||||
displayMac.append(mac.charAt(1));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(2));
|
|
||||||
displayMac.append(mac.charAt(3));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(4));
|
|
||||||
displayMac.append(mac.charAt(5));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(6));
|
|
||||||
displayMac.append(mac.charAt(7));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(8));
|
|
||||||
displayMac.append(mac.charAt(9));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(10));
|
|
||||||
displayMac.append(mac.charAt(11));
|
|
||||||
|
|
||||||
TextView macView = (TextView)convertView.findViewById(R.id.network_mac_textview);
|
|
||||||
macView.setText(displayMac.toString());
|
|
||||||
|
|
||||||
TextView mtuView = (TextView) convertView.findViewById(R.id.network_mtu_textview);
|
|
||||||
mtuView.setText(Integer.toString(vnc.mtu()));
|
|
||||||
|
|
||||||
TextView broadcastEnabledView = (TextView) convertView.findViewById(R.id.network_broadcast_textview);
|
|
||||||
broadcastEnabledView.setText(vnc.broadcastEnabled() ? "Enabled" : "Disabled");
|
|
||||||
|
|
||||||
TextView bridgingEnabledView = (TextView) convertView.findViewById(R.id.network_bridging_textview);
|
|
||||||
bridgingEnabledView.setText(vnc.isBridgeEnabled() ? "Enabled" : "Disabled");
|
|
||||||
|
|
||||||
InetSocketAddress[] addresses = vnc.assignedAddresses();
|
|
||||||
StringBuilder addrText = new StringBuilder();
|
|
||||||
for(InetSocketAddress addr : addresses) {
|
|
||||||
InetAddress ipaddr = addr.getAddress();
|
|
||||||
if(ipaddr instanceof Inet6Address) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String address = addr.toString();
|
|
||||||
if(address.startsWith("/")) {
|
|
||||||
address = address.substring(1);
|
|
||||||
}
|
|
||||||
int lastSlashPosition = address.lastIndexOf(':');
|
|
||||||
address = address.substring(0, lastSlashPosition) + "/" + address.substring(lastSlashPosition+1, address.length());
|
|
||||||
addrText.append(address);
|
|
||||||
addrText.append('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView addressesView = (TextView) convertView.findViewById(R.id.network_ipaddresses_textview);
|
|
||||||
addressesView.setText(addrText.toString());
|
|
||||||
|
|
||||||
Button leaveButton = (Button) convertView.findViewById(R.id.network_leave_button);
|
|
||||||
leaveButton.setOnClickListener(new LeaveButtonClickListener(vnc.networkId()));
|
|
||||||
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LeaveButtonClickListener implements Button.OnClickListener {
|
|
||||||
|
|
||||||
private long nwid;
|
|
||||||
|
|
||||||
public LeaveButtonClickListener(long nwid) {
|
|
||||||
this.nwid = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Log.d(TAG, "Leave Button Pressed for network: " + Long.toHexString(nwid));
|
|
||||||
EventBus.getDefault().post(new LeaveNetworkEvent(nwid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/7/2015.
|
|
||||||
*/
|
|
||||||
public class PrefsActivity extends SingleFragmentActivity {
|
|
||||||
@Override
|
|
||||||
public Fragment createFragment() {
|
|
||||||
return new PrefsFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.PreferenceFragment;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
import com.zerotier.one.AnalyticsApplication;
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
import com.zerotier.one.service.ZeroTierOneService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/7/2015.
|
|
||||||
*/
|
|
||||||
public class PrefsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
|
||||||
private Tracker tracker = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Preferences");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Preferences");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
|
||||||
if(key.equals("network_use_cellular_data")) {
|
|
||||||
if(sharedPreferences.getBoolean("network_use_cellular_data", false)) {
|
|
||||||
Intent i = new Intent(getActivity(), ZeroTierOneService.class);
|
|
||||||
getActivity().startService(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.app.FragmentManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/16/2015.
|
|
||||||
*/
|
|
||||||
public abstract class SingleFragmentActivity extends AppCompatActivity {
|
|
||||||
protected abstract Fragment createFragment();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_fragment);
|
|
||||||
|
|
||||||
FragmentManager fm = getFragmentManager();
|
|
||||||
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
|
|
||||||
|
|
||||||
if(fragment == null) {
|
|
||||||
fragment = createFragment();
|
|
||||||
fm.beginTransaction()
|
|
||||||
.add(R.id.fragmentContainer, fragment)
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package com.zerotier.one.util;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/19/2015.
|
|
||||||
*/
|
|
||||||
public class IPPacketUtils {
|
|
||||||
private static final String TAG = "IPPacketUtils";
|
|
||||||
|
|
||||||
public static InetAddress getSourceIP(byte[] data) {
|
|
||||||
byte[] addrBuffer = new byte[4];
|
|
||||||
System.arraycopy(data, 12, addrBuffer, 0, 4);
|
|
||||||
try {
|
|
||||||
return InetAddress.getByAddress(addrBuffer);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
Log.e(TAG, "Error creating InetAddress: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InetAddress getDestIP(byte[] data) {
|
|
||||||
byte[] addrBuffer = new byte[4];
|
|
||||||
System.arraycopy(data, 16, addrBuffer, 0, 4);
|
|
||||||
try {
|
|
||||||
return InetAddress.getByAddress(addrBuffer);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
Log.e(TAG, "Error creating InetAddress: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the 1's complement checksum of a region of bytes
|
|
||||||
*
|
|
||||||
* @param buffer
|
|
||||||
* @param startValue
|
|
||||||
* @param startByte
|
|
||||||
* @param endByte
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static long calculateChecksum(byte[] buffer, long startValue, int startByte, int endByte) {
|
|
||||||
|
|
||||||
int length = endByte - startByte;
|
|
||||||
int i = startByte;
|
|
||||||
long sum = startValue;
|
|
||||||
long data;
|
|
||||||
|
|
||||||
// Handle all pairs
|
|
||||||
while (length > 1) {
|
|
||||||
data = (((buffer[i] << 8) & 0xFF00) | ((buffer[i + 1]) & 0xFF));
|
|
||||||
sum += data;
|
|
||||||
// 1's complement carry bit correction in 16-bits (detecting sign extension)
|
|
||||||
if ((sum & 0xFFFF0000) > 0) {
|
|
||||||
sum = sum & 0xFFFF;
|
|
||||||
sum += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 2;
|
|
||||||
length -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle remaining byte in odd length buffers
|
|
||||||
if (length > 0) {
|
|
||||||
sum += (buffer[i] << 8 & 0xFF00);
|
|
||||||
// 1's complement carry bit correction in 16-bits (detecting sign extension)
|
|
||||||
if ((sum & 0xFFFF0000) > 0) {
|
|
||||||
sum = sum & 0xFFFF;
|
|
||||||
sum += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final 1's complement value correction to 16-bits
|
|
||||||
sum = ~sum;
|
|
||||||
sum = sum & 0xFFFF;
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package com.zerotier.one.util;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/13/2015.
|
|
||||||
*/
|
|
||||||
public class InetAddressUtils {
|
|
||||||
public static final String TAG = "InetAddressUtils";
|
|
||||||
|
|
||||||
public static byte[] addressToNetmask(InetAddress addr, int prefix) {
|
|
||||||
int numAddressBytes = addr.getAddress().length;
|
|
||||||
if(numAddressBytes > 4) {
|
|
||||||
throw new UnsupportedOperationException("IPv6 is not yet supported");
|
|
||||||
}
|
|
||||||
int numAddressBits = numAddressBytes * 8;
|
|
||||||
|
|
||||||
byte[] maskBytes = new byte[numAddressBytes];
|
|
||||||
for(int i = 0; i < numAddressBytes; ++i) {
|
|
||||||
maskBytes[i] = (byte)255;
|
|
||||||
}
|
|
||||||
int mask = ByteBuffer.wrap(maskBytes).getInt();
|
|
||||||
|
|
||||||
mask = mask >> (numAddressBits - prefix);
|
|
||||||
mask = mask << (numAddressBits - prefix);
|
|
||||||
|
|
||||||
return ByteBuffer.allocate(4).putInt(mask).array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InetAddress addressToRoute(InetAddress addr, int prefix) {
|
|
||||||
byte[] maskBytes = addressToNetmask(addr, prefix);
|
|
||||||
byte[] routeBytes = new byte[maskBytes.length];
|
|
||||||
InetAddress route = null;
|
|
||||||
try {
|
|
||||||
for(int i = 0; i < maskBytes.length; ++i) {
|
|
||||||
routeBytes[i] = (byte)(addr.getAddress()[i] & maskBytes[i]);
|
|
||||||
}
|
|
||||||
route = InetAddress.getByAddress(routeBytes);
|
|
||||||
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
Log.e(TAG, "Uknown Host Exception calculating route");
|
|
||||||
}
|
|
||||||
|
|
||||||
return route;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.zerotier.one.util;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/26/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkIdUtils {
|
|
||||||
/**
|
|
||||||
* Long will not parse a 64-bit hex string when the highest bit is 1 for some reasoon. So
|
|
||||||
* for converting network IDs in hex to a long, we must use big integer.
|
|
||||||
*
|
|
||||||
* @param hexString
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static long hexStringToLong(String hexString) {
|
|
||||||
BigInteger value = new BigInteger(hexString, 16);
|
|
||||||
return value.longValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,6 +25,10 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
#include "src/debug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
#include "sdkutils.hpp"
|
#include "sdkutils.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -479,52 +479,52 @@ namespace ZeroTier {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SDK_IPV6)
|
#if defined(SDK_IPV6)
|
||||||
inline struct netif * __netif_add(NETIF_ADD_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _netif_add(netif,state,init,input); }
|
inline struct netif * __netif_add(NETIF_ADD_SIG) throw() { Mutex::Lock _l(_lock); return _netif_add(netif,state,init,input); }
|
||||||
inline void __nd6_tmr(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); _nd6_tmr(); }
|
inline void __nd6_tmr(void) throw() { /**/ Mutex::Lock _l(_lock); _nd6_tmr(); }
|
||||||
inline void __netif_ip6_addr_set_state(NETIF_IP6_ADDR_SET_STATE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); _netif_ip6_addr_set_state(netif, addr_idx, state); }
|
inline void __netif_ip6_addr_set_state(NETIF_IP6_ADDR_SET_STATE_SIG) throw() { Mutex::Lock _l(_lock); _netif_ip6_addr_set_state(netif, addr_idx, state); }
|
||||||
inline void __netif_create_ip6_linklocal_address(NETIF_CREATE_IP6_LINKLOCAL_ADDRESS_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); _netif_create_ip6_linklocal_address(netif, from_mac_48bit); }
|
inline void __netif_create_ip6_linklocal_address(NETIF_CREATE_IP6_LINKLOCAL_ADDRESS_SIG) throw() { Mutex::Lock _l(_lock); _netif_create_ip6_linklocal_address(netif, from_mac_48bit); }
|
||||||
inline err_t __ethip6_output(ETHIP6_OUTPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _ethip6_output(netif,q,ip6addr); }
|
inline err_t __ethip6_output(ETHIP6_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _ethip6_output(netif,q,ip6addr); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void __netif_init(void) throw() { Mutex::Lock _l(_lock); _netif_init(); }
|
inline void __netif_init(void) throw() { Mutex::Lock _l(_lock); _netif_init(); }
|
||||||
// inline void __netif_set_addr(NETIF_SET_ADDR_SIG) throw() { Mutex::Lock _l(_lock); _netif_set_addr(netif, ipaddr, netmask, gw); }
|
// inline void __netif_set_addr(NETIF_SET_ADDR_SIG) throw() { Mutex::Lock _l(_lock); _netif_set_addr(netif, ipaddr, netmask, gw); }
|
||||||
inline void __lwip_init() throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _lwip_init(); }
|
inline void __lwip_init() throw() { Mutex::Lock _l(_lock); return _lwip_init(); }
|
||||||
inline err_t __tcp_write(TCP_WRITE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_write(pcb,arg,len,apiflags); }
|
inline err_t __tcp_write(TCP_WRITE_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_write(pcb,arg,len,apiflags); }
|
||||||
inline void __tcp_sent(TCP_SENT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_sent(pcb,sent); }
|
inline void __tcp_sent(TCP_SENT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_sent(pcb,sent); }
|
||||||
inline struct tcp_pcb * __tcp_new(TCP_NEW_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_new(); }
|
inline struct tcp_pcb * __tcp_new(TCP_NEW_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_new(); }
|
||||||
inline struct udp_pcb * __udp_new(UDP_NEW_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_new(); }
|
inline struct udp_pcb * __udp_new(UDP_NEW_SIG) throw() { Mutex::Lock _l(_lock); return _udp_new(); }
|
||||||
inline err_t __udp_connect(UDP_CONNECT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_connect(pcb,ipaddr,port); }
|
inline err_t __udp_connect(UDP_CONNECT_SIG) throw() { Mutex::Lock _l(_lock); return _udp_connect(pcb,ipaddr,port); }
|
||||||
inline err_t __udp_send(UDP_SEND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_send(pcb,p); }
|
inline err_t __udp_send(UDP_SEND_SIG) throw() { Mutex::Lock _l(_lock); return _udp_send(pcb,p); }
|
||||||
inline err_t __udp_sendto(UDP_SENDTO_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_sendto(pcb,p,dst_ip,dst_port); }
|
inline err_t __udp_sendto(UDP_SENDTO_SIG) throw() { Mutex::Lock _l(_lock); return _udp_sendto(pcb,p,dst_ip,dst_port); }
|
||||||
inline void __udp_recv(UDP_RECV_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_recv(pcb,recv,recv_arg); }
|
inline void __udp_recv(UDP_RECV_SIG) throw() { Mutex::Lock _l(_lock); return _udp_recv(pcb,recv,recv_arg); }
|
||||||
inline err_t __udp_bind(UDP_BIND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_bind(pcb,ipaddr,port); }
|
inline err_t __udp_bind(UDP_BIND_SIG) throw() { Mutex::Lock _l(_lock); return _udp_bind(pcb,ipaddr,port); }
|
||||||
inline void __udp_remove(UDP_REMOVE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_remove(pcb); }
|
inline void __udp_remove(UDP_REMOVE_SIG) throw() { Mutex::Lock _l(_lock); return _udp_remove(pcb); }
|
||||||
inline u16_t __tcp_sndbuf(TCP_SNDBUF_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_sndbuf(pcb); }
|
inline u16_t __tcp_sndbuf(TCP_SNDBUF_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_sndbuf(pcb); }
|
||||||
inline err_t __tcp_connect(TCP_CONNECT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_connect(pcb,ipaddr,port,connected); }
|
inline err_t __tcp_connect(TCP_CONNECT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_connect(pcb,ipaddr,port,connected); }
|
||||||
inline void __tcp_recv(TCP_RECV_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_recv(pcb,recv); }
|
inline void __tcp_recv(TCP_RECV_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_recv(pcb,recv); }
|
||||||
inline void __tcp_recved(TCP_RECVED_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_recved(pcb,len); }
|
inline void __tcp_recved(TCP_RECVED_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_recved(pcb,len); }
|
||||||
inline void __tcp_err(TCP_ERR_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_err(pcb,err); }
|
inline void __tcp_err(TCP_ERR_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_err(pcb,err); }
|
||||||
inline void __tcp_poll(TCP_POLL_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_poll(pcb,poll,interval); }
|
inline void __tcp_poll(TCP_POLL_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_poll(pcb,poll,interval); }
|
||||||
inline void __tcp_arg(TCP_ARG_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _tcp_arg(pcb,arg); }
|
inline void __tcp_arg(TCP_ARG_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_arg(pcb,arg); }
|
||||||
inline err_t __tcp_close(TCP_CLOSE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_close(pcb); }
|
inline err_t __tcp_close(TCP_CLOSE_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_close(pcb); }
|
||||||
inline void __tcp_abort(TCP_ABORT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_abort(pcb); }
|
inline void __tcp_abort(TCP_ABORT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_abort(pcb); }
|
||||||
inline err_t __tcp_output(TCP_OUTPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_output(pcb); }
|
inline err_t __tcp_output(TCP_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_output(pcb); }
|
||||||
inline void __tcp_accept(TCP_ACCEPT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_accept(pcb,accept); }
|
inline void __tcp_accept(TCP_ACCEPT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_accept(pcb,accept); }
|
||||||
inline struct tcp_pcb * __tcp_listen(TCP_LISTEN_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_listen(pcb); }
|
inline struct tcp_pcb * __tcp_listen(TCP_LISTEN_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_listen(pcb); }
|
||||||
inline struct tcp_pcb * __tcp_listen_with_backlog(TCP_LISTEN_WITH_BACKLOG_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_listen_with_backlog(pcb,backlog); }
|
inline struct tcp_pcb * __tcp_listen_with_backlog(TCP_LISTEN_WITH_BACKLOG_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_listen_with_backlog(pcb,backlog); }
|
||||||
inline err_t __tcp_bind(TCP_BIND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_bind(pcb,ipaddr,port); }
|
inline err_t __tcp_bind(TCP_BIND_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_bind(pcb,ipaddr,port); }
|
||||||
inline void __etharp_tmr(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _etharp_tmr(); }
|
inline void __etharp_tmr(void) throw() { Mutex::Lock _l(_lock); return _etharp_tmr(); }
|
||||||
inline void __tcp_tmr(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _tcp_tmr(); }
|
inline void __tcp_tmr(void) throw() { Mutex::Lock _l(_lock); return _tcp_tmr(); }
|
||||||
inline u8_t __pbuf_free(PBUF_FREE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pbuf_free(p); }
|
inline u8_t __pbuf_free(PBUF_FREE_SIG) throw() { Mutex::Lock _l(_lock); return _pbuf_free(p); }
|
||||||
inline struct pbuf * __pbuf_alloc(PBUF_ALLOC_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock_mem); return _pbuf_alloc(layer,length,type); }
|
inline struct pbuf * __pbuf_alloc(PBUF_ALLOC_SIG) throw() { Mutex::Lock _l(_lock_mem); return _pbuf_alloc(layer,length,type); }
|
||||||
inline u16_t __lwip_htons(LWIP_HTONS_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _lwip_htons(x); }
|
inline u16_t __lwip_htons(LWIP_HTONS_SIG) throw() { Mutex::Lock _l(_lock); return _lwip_htons(x); }
|
||||||
inline u16_t __lwip_ntohs(LWIP_NTOHS_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _lwip_ntohs(x); }
|
inline u16_t __lwip_ntohs(LWIP_NTOHS_SIG) throw() { Mutex::Lock _l(_lock); return _lwip_ntohs(x); }
|
||||||
//inline err_t __etharp_output(ETHARP_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _etharp_output(netif,q,ipaddr); }
|
//inline err_t __etharp_output(ETHARP_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _etharp_output(netif,q,ipaddr); }
|
||||||
inline err_t __ethernet_input(ETHERNET_INPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _ethernet_input(p,netif); }
|
inline err_t __ethernet_input(ETHERNET_INPUT_SIG) throw() { Mutex::Lock _l(_lock); return _ethernet_input(p,netif); }
|
||||||
inline void __tcp_input(TCP_INPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_input(p,inp); }
|
inline void __tcp_input(TCP_INPUT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_input(p,inp); }
|
||||||
inline err_t __ip_input(IP_INPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _ip_input(p,inp); }
|
inline err_t __ip_input(IP_INPUT_SIG) throw() { Mutex::Lock _l(_lock); return _ip_input(p,inp); }
|
||||||
inline void __netif_set_default(NETIF_SET_DEFAULT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _netif_set_default(netif); }
|
inline void __netif_set_default(NETIF_SET_DEFAULT_SIG) throw() { Mutex::Lock _l(_lock); return _netif_set_default(netif); }
|
||||||
inline void __netif_set_up(NETIF_SET_UP_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _netif_set_up(netif); }
|
inline void __netif_set_up(NETIF_SET_UP_SIG) throw() { Mutex::Lock _l(_lock); return _netif_set_up(netif); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|||||||
Reference in New Issue
Block a user