android_jni NDK build patch, also removed old unrelated SDK files

This commit is contained in:
Joseph Henry
2017-01-07 17:42:52 -08:00
parent 2741508520
commit 62e80da60b
67 changed files with 64 additions and 7680 deletions

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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
}

View File

@@ -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);
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -1,8 +0,0 @@
package com.zerotier.one.events;
/**
* Created by Grant on 8/4/2015.
*/
public class ManualDisconnectEvent {
public ManualDisconnectEvent() {}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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() {}
}

View File

@@ -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;
}
}

View File

@@ -1,8 +0,0 @@
package com.zerotier.one.events;
/**
* Created by Grant on 7/28/2015.
*/
public class NodeDestroyedEvent {
public NodeDestroyedEvent() {}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -1,10 +0,0 @@
package com.zerotier.one.events;
/**
* Created by Grant on 6/23/2015.
*/
public class RequestNetworkListEvent {
public RequestNetworkListEvent() {
}
}

View File

@@ -1,10 +0,0 @@
package com.zerotier.one.events;
/**
* Created by Grant on 8/1/2015.
*/
public class RequestNodeStatusEvent {
public RequestNodeStatusEvent() {
}
}

View File

@@ -1,8 +0,0 @@
package com.zerotier.one.events;
/**
* Created by Grant on 7/9/2015.
*/
public class StopEvent {
public StopEvent() {}
}

View File

@@ -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();
}
}
};
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}
}
}

View File

@@ -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;
}
}

View File

@@ -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.");
}
}

View File

@@ -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");
}
*/
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}

View File

@@ -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));
}
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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"
@@ -676,10 +680,10 @@ namespace ZeroTier
{ {
DEBUG_EXTRA("conn=%p", (void*)&conn); DEBUG_EXTRA("conn=%p", (void*)&conn);
lwIP_stack *stack = tap->lwipstack; lwIP_stack *stack = tap->lwipstack;
if(!conn || (!conn->TCP_pcb && !conn->UDP_pcb)) { if(!conn || (!conn->TCP_pcb && !conn->UDP_pcb)) {
DEBUG_ERROR(" invalid connection"); DEBUG_ERROR(" invalid connection");
return; return;
} }
if(conn->type == SOCK_DGRAM) { if(conn->type == SOCK_DGRAM) {
if(!conn->UDP_pcb) { if(!conn->UDP_pcb) {
DEBUG_ERROR(" invalid UDP_pcb, type=SOCK_DGRAM"); DEBUG_ERROR(" invalid UDP_pcb, type=SOCK_DGRAM");
@@ -704,24 +708,24 @@ namespace ZeroTier
} else if(err != ERR_OK) { } else if(err != ERR_OK) {
DEBUG_ERROR(" error sending packet - %d", err); DEBUG_ERROR(" error sending packet - %d", err);
} else { } else {
// Success // Success
int buf_remaining = (conn->txsz)-udp_trans_len; int buf_remaining = (conn->txsz)-udp_trans_len;
if(buf_remaining) if(buf_remaining)
memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining); memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining);
conn->txsz -= udp_trans_len; conn->txsz -= udp_trans_len;
#if DEBUG_LEVEL >= MSG_TRANSFER #if DEBUG_LEVEL >= MSG_TRANSFER
struct sockaddr_in * addr_in2 = (struct sockaddr_in *)conn->peer_addr; struct sockaddr_in * addr_in2 = (struct sockaddr_in *)conn->peer_addr;
int port = stack->__lwip_ntohs(addr_in2->sin_port); int port = stack->__lwip_ntohs(addr_in2->sin_port);
int ip = addr_in2->sin_addr.s_addr; int ip = addr_in2->sin_addr.s_addr;
unsigned char d[4]; unsigned char d[4];
d[0] = ip & 0xFF; d[0] = ip & 0xFF;
d[1] = (ip >> 8) & 0xFF; d[1] = (ip >> 8) & 0xFF;
d[2] = (ip >> 16) & 0xFF; d[2] = (ip >> 16) & 0xFF;
d[3] = (ip >> 24) & 0xFF; d[3] = (ip >> 24) & 0xFF;
DEBUG_TRANS("[UDP TX] ---> :: {TX: ------, RX: ------, sock=%p} :: %d bytes (dest_addr=%d.%d.%d.%d:%d)", DEBUG_TRANS("[UDP TX] ---> :: {TX: ------, RX: ------, sock=%p} :: %d bytes (dest_addr=%d.%d.%d.%d:%d)",
(void*)conn->sock, udp_trans_len, d[0], d[1], d[2], d[3], port); (void*)conn->sock, udp_trans_len, d[0], d[1], d[2], d[3], port);
#endif #endif
} }
stack->__pbuf_free(pb); stack->__pbuf_free(pb);
return; return;
@@ -764,7 +768,7 @@ namespace ZeroTier
DEBUG_ERROR("out of memory"); DEBUG_ERROR("out of memory");
return; return;
} else { } else {
// adjust buffer // adjust buffer
sz = (conn->txsz)-r; sz = (conn->txsz)-r;
if(sz) if(sz)
memmove(&conn->txbuf, (conn->txbuf+r), sz); memmove(&conn->txbuf, (conn->txbuf+r), sz);

View File

@@ -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