merging recent upgrades into master

This commit is contained in:
Joseph Henry
2017-03-19 22:47:51 -07:00
478 changed files with 36568 additions and 23934 deletions

View File

@@ -2,7 +2,7 @@
BUILD=build
INT=integrations
ZT1=zerotierone
ZT1=zto
OSTYPE=$(shell uname -s)

View File

@@ -3,6 +3,9 @@ ZeroTier SDK
ZeroTier-enabled apps, devices, and services.
- For a convenient BSD socket-style API, follow the rest of this document.
- For information on the core ZT API, see [ZeroTierOne.h](zerotierone/include/ZeroTierOne.h)
Secure virtual network access embedded directly into applications, games, and devices. Imagine starting an instance of your application or game and having it automatically be a member of your virtual network without having to rewrite your networking layer. Check out our [Integrations](integrations/) to learn how to integrate this into your application, device, or ecosystem.
The general idea is this:

View File

@@ -922,7 +922,7 @@ igmp3_report:
record->sources = short_be(sources);
record->mcast_group = p->mcast_group.addr;
if (IGMPFilter && !pico_tree_empty(IGMPFilter)) {
uint32_t *source_addr = (uint32_t *)((uint8_t *)record + sizeof(struct igmpv3_group_record));
uint32_t *source_addr = (uint32_t *)((void *)((uint8_t *)record + sizeof(struct igmpv3_group_record)));
i = 0;
pico_tree_foreach(index, IGMPFilter)
{

View File

@@ -91,7 +91,7 @@ static struct pico_frame *pico_frame_do_alloc(uint32_t size, int zerocopy, int e
return NULL;
}
p->usage_count = (uint32_t *)(((uint8_t*)p->buffer) + frame_buffer_size);
p->usage_count = (uint32_t *)((void *)(((uint8_t*)p->buffer) + frame_buffer_size));
} else {
p->buffer = NULL;
p->flags |= PICO_FRAME_FLAG_EXT_USAGE_COUNTER;
@@ -154,7 +154,7 @@ int pico_frame_grow(struct pico_frame *f, uint32_t size)
return -1;
}
f->usage_count = (uint32_t *)(((uint8_t*)f->buffer) + frame_buffer_size);
f->usage_count = (uint32_t *)((void *)(((uint8_t*)f->buffer) + frame_buffer_size));
*f->usage_count = usage_count;
f->buffer_len = size;
memcpy(f->buffer, oldbuf, oldsize);
@@ -247,7 +247,7 @@ static inline uint32_t pico_checksum_adder(uint32_t sum, void *data, uint32_t le
#endif
}
stop = (uint16_t *)(((uint8_t *)data) + len);
stop = (uint16_t *)((void *)(((uint8_t *)data) + len));
while (buf < stop) {
sum += *buf++;

View File

@@ -12,6 +12,7 @@ LOCAL_C_INCLUDES := $(LWIP)/include
LOCAL_C_INCLUDES += $(LWIP)/include/lwip
LOCAL_C_INCLUDES += $(LWIP)/include/lwip/priv
LOCAL_C_INCLUDES += $(ZTSDK)
LOCAL_C_INCLUDES += $(ZTSDK)/src
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers/lwip
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/nd6.c
# lwIP netif files
LOCAL_SRC_FILES += \
$(LWIP)/netif/ethernetif.c \
@@ -115,10 +115,4 @@ LOCAL_SRC_FILES += \
$(ZTSDK)/src/tap.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)

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

@@ -7,8 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
7C0463271DE362BD003E2B0E /* json.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463251DE362BD003E2B0E /* json.c */; };
7C0463281DE362D9003E2B0E /* json.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463251DE362BD003E2B0E /* json.c */; };
7C04632B1DE363BA003E2B0E /* ManagedRoute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */; };
7C04632C1DE363C9003E2B0E /* ManagedRoute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */; };
7C2228D11DCC1193006A2661 /* lwip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228CF1DCC1193006A2661 /* lwip.cpp */; };
@@ -18,7 +16,6 @@
7C5B40971DCC14E300C43410 /* picotcp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228D21DCC11A8006A2661 /* picotcp.cpp */; };
7C5B40981DCC14E300C43410 /* lwip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228CF1DCC1193006A2661 /* lwip.cpp */; };
7C7AF0241DFA1B8600AABE75 /* ManagedRoute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */; };
7C7AF0251DFA223100AABE75 /* BackgroundResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF58E1DBAD10A006585E7 /* BackgroundResolver.cpp */; };
7C7AF0261DFA22F300AABE75 /* ethernet.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5851DBACE7E006585E7 /* ethernet.c */; };
7C7D52831DBEADD200896C93 /* intercept.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52791DBEADD200896C93 /* intercept.c */; };
7C7D52841DBEADD200896C93 /* proxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527A1DBEADD200896C93 /* proxy.cpp */; };
@@ -39,8 +36,6 @@
7C7F164A1DBEB76F00C7AFFD /* service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527D1DBEADD200896C93 /* service.cpp */; };
7C7F164B1DBEB76F00C7AFFD /* sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527F1DBEADD200896C93 /* sockets.c */; };
7C7F164C1DBEB76F00C7AFFD /* tap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52801DBEADD200896C93 /* tap.cpp */; };
7C7F164D1DBEB7AB00C7AFFD /* BackgroundResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF58E1DBAD10A006585E7 /* BackgroundResolver.cpp */; };
7C7F164E1DBEB7AB00C7AFFD /* DeferredPackets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5891DBAD0BF006585E7 /* DeferredPackets.cpp */; };
7C7F164F1DBEB7AB00C7AFFD /* OneService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5821DBACB3E006585E7 /* OneService.cpp */; };
7C7F16501DBEB7AB00C7AFFD /* C25519.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5121DBAC872006585E7 /* C25519.cpp */; };
7C7F16511DBEB7AB00C7AFFD /* CertificateOfMembership.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5141DBAC872006585E7 /* CertificateOfMembership.cpp */; };
@@ -96,7 +91,6 @@
7C7F16851DBEB89600C7AFFD /* sys.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B471DB99E7900BD3F7F /* sys.c */; };
7C7F16861DBEB89600C7AFFD /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
7C7F16871DBEB89600C7AFFD /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4C1DB99E7900BD3F7F /* udp.c */; };
7C7F16881DBEB8B300C7AFFD /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0035A1D1217B2003E68DC /* lz4.c */; };
7C7F16891DBEB8B300C7AFFD /* http_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC003571D1217A1003E68DC /* http_parser.c */; };
7C969B4D1DB99E7900BD3F7F /* def.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3C1DB99E7900BD3F7F /* def.c */; };
7C969B4E1DB99E7900BD3F7F /* dns.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3D1DB99E7900BD3F7F /* dns.c */; };
@@ -150,13 +144,9 @@
7C969BD11DB99F9E00BD3F7F /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
7C969BD21DB99F9E00BD3F7F /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4C1DB99E7900BD3F7F /* udp.c */; };
7C969C7C1DBAA61700BD3F7F /* tcpip.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969C7B1DBAA61700BD3F7F /* tcpip.c */; };
7C9D4ED51DF246F200EF20CD /* json.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463251DE362BD003E2B0E /* json.c */; };
7CC003261D1216E3003E68DC /* ZeroTierSDK_iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CC003251D1216E3003E68DC /* ZeroTierSDK_iOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
7CC003591D1217A1003E68DC /* http_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC003571D1217A1003E68DC /* http_parser.c */; };
7CC0035C1D1217B2003E68DC /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0035A1D1217B2003E68DC /* lz4.c */; };
7CC004D01D131E37003E68DC /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0035A1D1217B2003E68DC /* lz4.c */; };
7CC004D11D131E37003E68DC /* http_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC003571D1217A1003E68DC /* http_parser.c */; };
7CC005201D1324B3003E68DC /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC0035A1D1217B2003E68DC /* lz4.c */; };
7CC005211D1324B3003E68DC /* http_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC003571D1217A1003E68DC /* http_parser.c */; };
7CD785601E08C7B500E03BF0 /* lwip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228CF1DCC1193006A2661 /* lwip.cpp */; };
7CD785611E08C7B500E03BF0 /* rpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527B1DBEADD200896C93 /* rpc.c */; };
@@ -164,8 +154,6 @@
7CD785631E08C7B500E03BF0 /* sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527F1DBEADD200896C93 /* sockets.c */; };
7CD785641E08C7B500E03BF0 /* tap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52801DBEADD200896C93 /* tap.cpp */; };
7CD785661E08C7B500E03BF0 /* ManagedRoute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7AF0231DFA1B5C00AABE75 /* ManagedRoute.cpp */; };
7CD785671E08C7B500E03BF0 /* BackgroundResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF58E1DBAD10A006585E7 /* BackgroundResolver.cpp */; };
7CD785681E08C7B500E03BF0 /* DeferredPackets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5891DBAD0BF006585E7 /* DeferredPackets.cpp */; };
7CD785691E08C7B500E03BF0 /* OneService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5821DBACB3E006585E7 /* OneService.cpp */; };
7CD7856A1E08C7B500E03BF0 /* C25519.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5121DBAC872006585E7 /* C25519.cpp */; };
7CD7856B1E08C7B500E03BF0 /* CertificateOfMembership.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5141DBAC872006585E7 /* CertificateOfMembership.cpp */; };
@@ -219,7 +207,6 @@
7CD7859B1E08C7E200E03BF0 /* sys.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B471DB99E7900BD3F7F /* sys.c */; };
7CD7859C1E08C7E200E03BF0 /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
7CD7859D1E08C7E200E03BF0 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4C1DB99E7900BD3F7F /* udp.c */; };
7CD7859E1E08C7E200E03BF0 /* json.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463251DE362BD003E2B0E /* json.c */; };
7CD7859F1E08C87A00E03BF0 /* proxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527A1DBEADD200896C93 /* proxy.cpp */; };
7CD785A01E08C87A00E03BF0 /* def.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3C1DB99E7900BD3F7F /* def.c */; };
7CD785A11E08C87A00E03BF0 /* dns.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3D1DB99E7900BD3F7F /* dns.c */; };
@@ -278,15 +265,10 @@
7CEAF5841DBACB3E006585E7 /* OneService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5821DBACB3E006585E7 /* OneService.cpp */; };
7CEAF5861DBACE7E006585E7 /* ethernet.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5851DBACE7E006585E7 /* ethernet.c */; };
7CEAF5881DBACEC3006585E7 /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5871DBACEC3006585E7 /* err.c */; };
7CEAF58B1DBAD0BF006585E7 /* DeferredPackets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5891DBAD0BF006585E7 /* DeferredPackets.cpp */; };
7CEAF58C1DBAD0E1006585E7 /* DeferredPackets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5891DBAD0BF006585E7 /* DeferredPackets.cpp */; };
7CEAF58D1DBAD0E1006585E7 /* OneService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5821DBACB3E006585E7 /* OneService.cpp */; };
7CEAF58F1DBAD10A006585E7 /* BackgroundResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF58E1DBAD10A006585E7 /* BackgroundResolver.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
7C0463251DE362BD003E2B0E /* json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = json.c; path = "../../../zerotierone/ext/json-parser/json.c"; sourceTree = "<group>"; };
7C0463261DE362BD003E2B0E /* json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = json.h; path = "../../../zerotierone/ext/json-parser/json.h"; sourceTree = "<group>"; };
7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ManagedRoute.cpp; path = ../../../zerotierone/osdep/ManagedRoute.cpp; sourceTree = "<group>"; };
7C04632A1DE363BA003E2B0E /* ManagedRoute.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ManagedRoute.hpp; path = ../../../zerotierone/osdep/ManagedRoute.hpp; sourceTree = "<group>"; };
7C2228CF1DCC1193006A2661 /* lwip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lwip.cpp; path = ../../../src/stack_drivers/lwip/lwip.cpp; sourceTree = "<group>"; };
@@ -404,8 +386,6 @@
7CC0034F1D12178D003E68DC /* SDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDK.h; path = ../../../src/SDK.h; sourceTree = "<group>"; };
7CC003571D1217A1003E68DC /* http_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = http_parser.c; path = "../../../zerotierone/ext/http-parser/http_parser.c"; sourceTree = "<group>"; };
7CC003581D1217A1003E68DC /* http_parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = http_parser.h; path = "../../../zerotierone/ext/http-parser/http_parser.h"; sourceTree = "<group>"; };
7CC0035A1D1217B2003E68DC /* lz4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lz4.c; path = ../../../zerotierone/ext/lz4/lz4.c; sourceTree = "<group>"; };
7CC0035B1D1217B2003E68DC /* lz4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lz4.h; path = ../../../zerotierone/ext/lz4/lz4.h; sourceTree = "<group>"; };
7CEAF4EE1DBAC80C006585E7 /* ClusterDefinition.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ClusterDefinition.hpp; path = ../../../zerotierone/service/ClusterDefinition.hpp; sourceTree = "<group>"; };
7CEAF4F11DBAC80C006585E7 /* ControlPlane.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ControlPlane.cpp; path = ../../../zerotierone/service/ControlPlane.cpp; sourceTree = "<group>"; };
7CEAF4F21DBAC80C006585E7 /* ControlPlane.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ControlPlane.hpp; path = ../../../zerotierone/service/ControlPlane.hpp; sourceTree = "<group>"; };
@@ -423,7 +403,6 @@
7CEAF50D1DBAC872006585E7 /* Address.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Address.hpp; path = ../../../zerotierone/node/Address.hpp; sourceTree = "<group>"; };
7CEAF50E1DBAC872006585E7 /* Array.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Array.hpp; path = ../../../zerotierone/node/Array.hpp; sourceTree = "<group>"; };
7CEAF50F1DBAC872006585E7 /* AtomicCounter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AtomicCounter.hpp; path = ../../../zerotierone/node/AtomicCounter.hpp; sourceTree = "<group>"; };
7CEAF5101DBAC872006585E7 /* BinarySemaphore.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = BinarySemaphore.hpp; path = ../../../zerotierone/node/BinarySemaphore.hpp; sourceTree = "<group>"; };
7CEAF5111DBAC872006585E7 /* Buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Buffer.hpp; path = ../../../zerotierone/node/Buffer.hpp; sourceTree = "<group>"; };
7CEAF5121DBAC872006585E7 /* C25519.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = C25519.cpp; path = ../../../zerotierone/node/C25519.cpp; sourceTree = "<group>"; };
7CEAF5131DBAC872006585E7 /* C25519.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = C25519.hpp; path = ../../../zerotierone/node/C25519.hpp; sourceTree = "<group>"; };
@@ -481,9 +460,6 @@
7CEAF5831DBACB3E006585E7 /* OneService.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = OneService.hpp; path = ../../../zerotierone/service/OneService.hpp; sourceTree = "<group>"; };
7CEAF5851DBACE7E006585E7 /* ethernet.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = ethernet.c; path = ../../../ext/lwip/src/netif/ethernet.c; sourceTree = "<group>"; };
7CEAF5871DBACEC3006585E7 /* err.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = err.c; path = ../../../ext/lwip/src/api/err.c; sourceTree = "<group>"; };
7CEAF5891DBAD0BF006585E7 /* DeferredPackets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeferredPackets.cpp; path = ../../../zerotierone/node/DeferredPackets.cpp; sourceTree = "<group>"; };
7CEAF58A1DBAD0BF006585E7 /* DeferredPackets.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = DeferredPackets.hpp; path = ../../../zerotierone/node/DeferredPackets.hpp; sourceTree = "<group>"; };
7CEAF58E1DBAD10A006585E7 /* BackgroundResolver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BackgroundResolver.cpp; path = ../../../zerotierone/osdep/BackgroundResolver.cpp; sourceTree = "<group>"; };
7CEAF5901DBADA69006585E7 /* tcp_in.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = tcp_in.c; path = ../../../ext/lwip/src/core/tcp_in.c; sourceTree = "<group>"; };
7CEAF5911DBADA69006585E7 /* tcp_out.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = tcp_out.c; path = ../../../ext/lwip/src/core/tcp_out.c; sourceTree = "<group>"; };
7CEAF5921DBADA69006585E7 /* tcp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = tcp.c; path = ../../../ext/lwip/src/core/tcp.c; sourceTree = "<group>"; };
@@ -558,10 +534,6 @@
7CC003101D12166B003E68DC /* ext */ = {
isa = PBXGroup;
children = (
7C0463251DE362BD003E2B0E /* json.c */,
7C0463261DE362BD003E2B0E /* json.h */,
7CC0035A1D1217B2003E68DC /* lz4.c */,
7CC0035B1D1217B2003E68DC /* lz4.h */,
7CC003571D1217A1003E68DC /* http_parser.c */,
7CC003581D1217A1003E68DC /* http_parser.h */,
);
@@ -673,15 +645,11 @@
7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */,
7C7AF0231DFA1B5C00AABE75 /* ManagedRoute.cpp */,
7C04632A1DE363BA003E2B0E /* ManagedRoute.hpp */,
7CEAF58E1DBAD10A006585E7 /* BackgroundResolver.cpp */,
7CEAF5891DBAD0BF006585E7 /* DeferredPackets.cpp */,
7CEAF58A1DBAD0BF006585E7 /* DeferredPackets.hpp */,
7CEAF5821DBACB3E006585E7 /* OneService.cpp */,
7CEAF5831DBACB3E006585E7 /* OneService.hpp */,
7CEAF50D1DBAC872006585E7 /* Address.hpp */,
7CEAF50E1DBAC872006585E7 /* Array.hpp */,
7CEAF50F1DBAC872006585E7 /* AtomicCounter.hpp */,
7CEAF5101DBAC872006585E7 /* BinarySemaphore.hpp */,
7CEAF5111DBAC872006585E7 /* Buffer.hpp */,
7CEAF5121DBAC872006585E7 /* C25519.cpp */,
7CEAF5131DBAC872006585E7 /* C25519.hpp */,
@@ -983,9 +951,7 @@
buildActionMask = 2147483647;
files = (
7C7AF0261DFA22F300AABE75 /* ethernet.c in Sources */,
7C7AF0251DFA223100AABE75 /* BackgroundResolver.cpp in Sources */,
7C04632B1DE363BA003E2B0E /* ManagedRoute.cpp in Sources */,
7C0463271DE362BD003E2B0E /* json.c in Sources */,
7CEAF5531DBAC872006585E7 /* Multicaster.cpp in Sources */,
7C2228D41DCC11A8006A2661 /* picotcp.cpp in Sources */,
7CEAF50B1DBAC841006585E7 /* PortMapper.cpp in Sources */,
@@ -995,7 +961,6 @@
7C969B691DB99E8E00BD3F7F /* icmp.c in Sources */,
7C2228D11DCC1193006A2661 /* lwip.cpp in Sources */,
7CEAF5521DBAC872006585E7 /* InetAddress.cpp in Sources */,
7CEAF58B1DBAD0BF006585E7 /* DeferredPackets.cpp in Sources */,
7CEAF55C1DBAC872006585E7 /* Salsa20.cpp in Sources */,
7CEAF5071DBAC841006585E7 /* Arp.cpp in Sources */,
7C7D52861DBEADD200896C93 /* service.cpp in Sources */,
@@ -1047,7 +1012,6 @@
7CEAF54D1DBAC872006585E7 /* Cluster.cpp in Sources */,
7C969B521DB99E7900BD3F7F /* mem.c in Sources */,
7C969B6C1DB99E8E00BD3F7F /* ip4_frag.c in Sources */,
7CC0035C1D1217B2003E68DC /* lz4.c in Sources */,
7CEAF55F1DBAC872006585E7 /* Switch.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1057,10 +1021,8 @@
buildActionMask = 2147483647;
files = (
7C7AF0241DFA1B8600AABE75 /* ManagedRoute.cpp in Sources */,
7C9D4ED51DF246F200EF20CD /* json.c in Sources */,
7C2228D51DCC11B8006A2661 /* picotcp.cpp in Sources */,
7C2228D61DCC11B8006A2661 /* lwip.cpp in Sources */,
7C7F16881DBEB8B300C7AFFD /* lz4.c in Sources */,
7C7F16891DBEB8B300C7AFFD /* http_parser.c in Sources */,
7C7F16721DBEB88700C7AFFD /* autoip.c in Sources */,
7C7F16731DBEB88700C7AFFD /* dhcp.c in Sources */,
@@ -1090,8 +1052,6 @@
7C7F166F1DBEB88700C7AFFD /* err.c in Sources */,
7C7F16701DBEB88700C7AFFD /* ethernet.c in Sources */,
7C7F16711DBEB88700C7AFFD /* tcpip.c in Sources */,
7C7F164D1DBEB7AB00C7AFFD /* BackgroundResolver.cpp in Sources */,
7C7F164E1DBEB7AB00C7AFFD /* DeferredPackets.cpp in Sources */,
7C7F164F1DBEB7AB00C7AFFD /* OneService.cpp in Sources */,
7C7F16501DBEB7AB00C7AFFD /* C25519.cpp in Sources */,
7C7F16511DBEB7AB00C7AFFD /* CertificateOfMembership.cpp in Sources */,
@@ -1133,7 +1093,6 @@
buildActionMask = 2147483647;
files = (
7C04632C1DE363C9003E2B0E /* ManagedRoute.cpp in Sources */,
7C0463281DE362D9003E2B0E /* json.c in Sources */,
7C5B40971DCC14E300C43410 /* picotcp.cpp in Sources */,
7C5B40981DCC14E300C43410 /* lwip.cpp in Sources */,
7C7D528B1DBEADE600896C93 /* intercept.c in Sources */,
@@ -1146,8 +1105,6 @@
7C969BCE1DB99F9E00BD3F7F /* tcp_in.c in Sources */,
7C969BCF1DB99F9E00BD3F7F /* tcp_out.c in Sources */,
7C969BD01DB99F9E00BD3F7F /* tcp.c in Sources */,
7CEAF58F1DBAD10A006585E7 /* BackgroundResolver.cpp in Sources */,
7CEAF58C1DBAD0E1006585E7 /* DeferredPackets.cpp in Sources */,
7CEAF58D1DBAD0E1006585E7 /* OneService.cpp in Sources */,
7CEAF5881DBACEC3006585E7 /* err.c in Sources */,
7CEAF5861DBACE7E006585E7 /* ethernet.c in Sources */,
@@ -1200,7 +1157,6 @@
7C969BCD1DB99F9E00BD3F7F /* sys.c in Sources */,
7C969BD11DB99F9E00BD3F7F /* timeouts.c in Sources */,
7C969BD21DB99F9E00BD3F7F /* udp.c in Sources */,
7CC004D01D131E37003E68DC /* lz4.c in Sources */,
7CC004D11D131E37003E68DC /* http_parser.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1235,7 +1191,6 @@
7CD7859B1E08C7E200E03BF0 /* sys.c in Sources */,
7CD7859C1E08C7E200E03BF0 /* timeouts.c in Sources */,
7CD7859D1E08C7E200E03BF0 /* udp.c in Sources */,
7CD7859E1E08C7E200E03BF0 /* json.c in Sources */,
7CD785871E08C7C300E03BF0 /* err.c in Sources */,
7CD785881E08C7C300E03BF0 /* ethernet.c in Sources */,
7CD785891E08C7C300E03BF0 /* tcpip.c in Sources */,
@@ -1245,8 +1200,6 @@
7CD785631E08C7B500E03BF0 /* sockets.c in Sources */,
7CD785641E08C7B500E03BF0 /* tap.cpp in Sources */,
7CD785661E08C7B500E03BF0 /* ManagedRoute.cpp in Sources */,
7CD785671E08C7B500E03BF0 /* BackgroundResolver.cpp in Sources */,
7CD785681E08C7B500E03BF0 /* DeferredPackets.cpp in Sources */,
7CD785691E08C7B500E03BF0 /* OneService.cpp in Sources */,
7CD7856A1E08C7B500E03BF0 /* C25519.cpp in Sources */,
7CD7856B1E08C7B500E03BF0 /* CertificateOfMembership.cpp in Sources */,
@@ -1274,7 +1227,6 @@
7CD785811E08C7B500E03BF0 /* OSUtils.cpp in Sources */,
7CD785821E08C7B500E03BF0 /* PortMapper.cpp in Sources */,
7CD785831E08C7B500E03BF0 /* ControlPlane.cpp in Sources */,
7CC005201D1324B3003E68DC /* lz4.c in Sources */,
7CC005211D1324B3003E68DC /* http_parser.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@@ -27,7 +27,7 @@ INCLUDES=
DEFS=
ARCH_FLAGS=-arch x86_64
CFLAGS=
CXXFLAGS=$(CFLAGS) -fno-rtti
CXXFLAGS=$(CFLAGS) -fno-rtti -std=c++11 -DZT_SDK
include objects.mk
@@ -91,18 +91,18 @@ CODESIGN_INSTALLER_CERT=
# Debug output for ZeroTier service
ifeq ($(ZT_DEBUG),1)
DEFS+=-DZT_TRACE
CFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
CXXFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
CFLAGS+=-Wall -Werror -g -pthread $(INCLUDES) $(DEFS)
CXXFLAGS+=-Wall -Werror -g -pthread $(INCLUDES) $(DEFS)
LDFLAGS=-ldl
STRIP?=echo
# The following line enables optimization for the crypto code, since
# C25519 in particular is almost UNUSABLE in -O0 even on a 3ghz box!
ext/lz4/lz4.o node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g -pthread $(INCLUDES) $(DEFS)
ext/lz4/lz4.o node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -Werror -O2 -g -pthread $(INCLUDES) $(DEFS)
else
CFLAGS?=-O3 -fstack-protector
CFLAGS+=-Wall -fPIE -fvisibility=hidden -pthread $(INCLUDES) -DNDEBUG $(DEFS)
CFLAGS+=-Wall -Werror -fPIE -fvisibility=hidden -pthread $(INCLUDES) -DNDEBUG $(DEFS)
CXXFLAGS?= -fstack-protector
CXXFLAGS+=-Wall -Wreorder -fPIE -fvisibility=hidden -fno-rtti -pthread $(INCLUDES) -DNDEBUG $(DEFS) -std=c++11
CXXFLAGS+=-Wall -Werror -Wreorder -fPIE -fvisibility=hidden -fno-rtti -pthread $(INCLUDES) -DNDEBUG $(DEFS) -std=c++11
LDFLAGS=-ldl -pie -Wl,-z,relro,-z,now
STRIP?=strip
STRIP+=--strip-all

View File

@@ -27,7 +27,7 @@ INCLUDES=
DEFS=
ARCH_FLAGS=-arch x86_64
CFLAGS=
CXXFLAGS=$(CFLAGS) -fno-rtti
CXXFLAGS=$(CFLAGS) -fno-rtti -std=c++11 -DZT_SDK
include objects.mk
@@ -80,7 +80,7 @@ INCLUDES+= -Iext \
# --------------------------------- ZT Config ----------------------------------
# ------------------------------------------------------------------------------
ZTFLAGS:=-DSDK -DZT_ONE_NO_ROOT_CHECK
ZTFLAGS:=-DZT_SDK -DZT_ONE_NO_ROOT_CHECK
# Disable codesign since open source users will not have ZeroTier's certs
CODESIGN=echo
@@ -254,14 +254,18 @@ osx_static_lib: lwip $(OBJS)
else
osx_static_lib: pico $(OBJS)
$(CXX) $(CXXFLAGS) $(STACK_FLAGS) $(DEFS) $(INCLUDES) $(ZTFLAGS) -DSDK_SERVICE -DSDK -DSDK_BUNDLED $(PICO_DRIVER_FILES) $(SDK_INTERCEPT_C_FILES) $(SDK_SERVICE_CPP_FILES) src/service.cpp -c
<<<<<<< HEAD
libtool -static -o build/libzt.a picotcp.o proxy.o tap.o one.o OneService.o service.o sockets.o rpc.o intercept.o OneService.o $(OBJS)
=======
libtool -static -o build/libzt.a picotcp.o proxy.o tap.o one.o OneService.o service.o sockets.o rpc.o intercept.o $(OBJS)
>>>>>>> dev
endif
# Builds zts_* library tests
osx_static_lib_tests:
mkdir -p $(TEST_OBJDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(INCLUDES) $(STACK_FLAGS) $(DEFS) -DSDK_SERVICE -DSDK -DSDK_BUNDLED -Isrc tests/shared_test/zts.tcpserver4.c -o $(TEST_OBJDIR)/$(OSTYPE).zts.tcpserver4.out -Lbuild -lzt -ldl
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(INCLUDES) $(STACK_FLAGS) $(DEFS) -DSDK_SERVICE -DSDK -DSDK_BUNDLED -Isrc tests/shared_test/zts.tcpclient4.c -o $(TEST_OBJDIR)/$(OSTYPE).zts.tcpclient4.out -Lbuild -lzt -ldl
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(INCLUDES) $(STACK_FLAGS) $(DEFS) -DSDK_SERVICE -DSDK -DSDK_BUNDLED -Isrc tests/shared_test/zts.udpserver4.c -o $(TEST_OBJDIR)/$(OSTYPE).zts.udpserver4.out -Lbuild -lzt -ldl
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(INCLUDES) $(STACK_FLAGS) $(DEFS) -DSDK_SERVICE -DSDK -DSDK_BUNDLED -Isrc tests/shared_test/zts.udpclient4.c -o $(TEST_OBJDIR)/$(OSTYPE).zts.udpclient4.out -Lbuild -lzt -ldl
# ------------------------------------------------------------------------------
# ---------------------------------- Android -----------------------------------

View File

@@ -1,32 +1,36 @@
OBJS=\
zerotierone/ext/json-parser/json.o \
zerotierone/ext/http-parser/http_parser.o \
zerotierone/ext/lz4/lz4.o \
zerotierone/node/C25519.o \
zerotierone/node/CertificateOfMembership.o \
zerotierone/node/Cluster.o \
zerotierone/node/DeferredPackets.o \
zerotierone/node/Identity.o \
zerotierone/node/IncomingPacket.o \
zerotierone/node/InetAddress.o \
zerotierone/node/Multicaster.o \
zerotierone/node/Network.o \
zerotierone/node/NetworkConfig.o \
zerotierone/node/Node.o \
zerotierone/node/OutboundMulticast.o \
zerotierone/node/Packet.o \
zerotierone/node/Path.o \
zerotierone/node/Peer.o \
zerotierone/node/Poly1305.o \
zerotierone/node/Salsa20.o \
zerotierone/node/SelfAwareness.o \
zerotierone/node/SHA512.o \
zerotierone/node/Switch.o \
zerotierone/node/Topology.o \
zerotierone/node/Utils.o \
zerotierone/osdep/BackgroundResolver.o \
zerotierone/osdep/ManagedRoute.o \
zerotierone/osdep/Http.o \
zerotierone/osdep/OSUtils.o \
zerotierone/service/ClusterGeoIpService.o \
zerotierone/service/ControlPlane.o
zto/controller/EmbeddedNetworkController.o \
zto/controller/JSONDB.o \
zto/node/C25519.o \
zto/node/Capability.o \
zto/node/CertificateOfMembership.o \
zto/node/CertificateOfOwnership.o \
zto/node/Cluster.o \
zto/node/Identity.o \
zto/node/IncomingPacket.o \
zto/node/InetAddress.o \
zto/node/Membership.o \
zto/node/Multicaster.o \
zto/node/Network.o \
zto/node/NetworkConfig.o \
zto/node/Node.o \
zto/node/OutboundMulticast.o \
zto/node/Packet.o \
zto/node/Path.o \
zto/node/Peer.o \
zto/node/Poly1305.o \
zto/node/Revocation.o \
zto/node/Salsa20.o \
zto/node/SelfAwareness.o \
zto/node/SHA512.o \
zto/node/Switch.o \
zto/node/Tag.o \
zto/node/Topology.o \
zto/node/Utils.o \
zto/osdep/ManagedRoute.o \
zto/osdep/Http.o \
zto/osdep/OSUtils.o \
zto/service/ClusterGeoIpService.o \
zto/service/SoftwareUpdater.o \
zto/ext/http-parser/http_parser.o

View File

@@ -26,16 +26,20 @@
* LLC. Start here: http://www.zerotier.com/
*/
#include <pthread.h>
#include <sys/syscall.h>
#include <sys/types.h>
#ifndef _SDK_DEBUG_H_
#define _SDK_DEBUG_H_
#define DEBUG_LEVEL 4 // Set this to adjust what you'd like to see in the debug traces
#define DEBUG_LEVEL 1 // Set this to adjust what you'd like to see in the debug traces
#define MSG_ERROR 1 // Errors
#define MSG_TRANSFER 2 // RX/TX specific statements
#define MSG_INFO 3 // Information which is generally useful to any developer
#define MSG_EXTRA 4 // If nothing in your world makes sense
#define MSG_FLOW 5 // High-level flow messages
#define __SHOW_FILENAMES__ true
#define __SHOW_COLOR__ true
@@ -79,6 +83,12 @@
extern "C" {
#endif
#ifdef __linux__
#define THREAD_ID (long)getpid()
#elif __APPLE__
#define THREAD_ID (long)syscall(SYS_thread_selfid)
#endif
#if defined(__ANDROID__)
#include <jni.h>
#include <android/log.h>
@@ -87,10 +97,11 @@ extern "C" {
//#if defined(SDK_DEBUG)
#if DEBUG_LEVEL >= MSG_ERROR
#define DEBUG_ERROR(fmt, args...) fprintf(stderr, RED "ZT_ERROR: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_ERROR(fmt, args...) fprintf(stderr, RED "ZT_ERROR[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#else
#define DEBUG_ERROR(fmt, args...)
#endif
#if DEBUG_LEVEL >= MSG_INFO
#if defined(__ANDROID__)
#define DEBUG_INFO(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_INFO : %14s:%4d:%20s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
@@ -98,33 +109,47 @@ extern "C" {
#define DEBUG_ATTN(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#define DEBUG_STACK(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_STACK: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else
#define DEBUG_INFO(fmt, args...) fprintf(stderr, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_ATTN(fmt, args...) fprintf(stderr, CYN "ZT_INFO : %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_STACK(fmt, args...) fprintf(stderr, YEL "ZT_STACK: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_BLANK(fmt, args...) fprintf(stderr, "ZT_INFO : %14s:%4d:" fmt "\n", __FILENAME__, __LINE__, ##args)
#define DEBUG_INFO(fmt, args...) fprintf(stderr, "ZT_INFO [%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_ATTN(fmt, args...) fprintf(stderr, CYN "ZT_ATTN [%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_STACK(fmt, args...) fprintf(stderr, YEL "ZT_STACK[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_BLANK(fmt, args...) fprintf(stderr, "ZT_INFO [%ld] : %14s:%4d:" fmt "\n", THREAD_ID, __FILENAME__, __LINE__, ##args)
#endif
#else
#define DEBUG_INFO(fmt, args...)
#define DEBUG_BLANK(fmt, args...)
#define DEBUG_ATTN(fmt, args...)
#define DEBUG_STACK(fmt, args...)
#endif
#if DEBUG_LEVEL >= MSG_TRANSFER
#if defined(__ANDROID__)
#define DEBUG_TRANS(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_TRANS : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else
#define DEBUG_TRANS(fmt, args...) fprintf(stderr, GRN "ZT_TRANS: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_TRANS(fmt, args...) fprintf(stderr, GRN "ZT_TRANS[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_TRANS(fmt, args...)
#endif
#if DEBUG_LEVEL >= MSG_EXTRA
#if defined(__ANDROID__)
#define DEBUG_EXTRA(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_EXTRA : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else
#define DEBUG_EXTRA(fmt, args...) fprintf(stderr, "ZT_EXTRA: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_EXTRA(fmt, args...) fprintf(stderr, "ZT_EXTRA[%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_EXTRA(fmt, args...)
#endif
#if DEBUG_LEVEL >= MSG_FLOW
#if defined(__ANDROID__)
#define DEBUG_FLOW(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_FLOW : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
#else
#define DEBUG_FLOW(fmt, args...) fprintf(stderr, "ZT_FLOW [%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
#endif
#else
#define DEBUG_FLOW(fmt, args...)
#endif
//#endif
#ifdef __cplusplus

View File

@@ -25,18 +25,15 @@
* LLC. Start here: http://www.zerotier.com/
*/
// --- lwIP
#define APPLICATION_POLL_FREQ 2
#define ZT_LWIP_TCP_TIMER_INTERVAL 50
#define STATUS_TMR_INTERVAL 500 // How often we check connection statuses (in ms)
#define SDK_MTU 1200//ZT_MAX_MTU // 2800, usually
// --- picoTCP
#define UNIX_SOCK_BUF_SIZE 1024*1024
#define ZT_PHY_POLL_INTERVAL 50 // in ms
// picoTCP
#define MAX_PICO_FRAME_RX_BUF_SZ ZT_MAX_MTU * 128
// --- jip
// --- General
// General
// TCP Buffer sizes
#define DEFAULT_TCP_TX_BUF_SZ 1024 * 1024
#define DEFAULT_TCP_RX_BUF_SZ 1024 * 1024
@@ -49,4 +46,9 @@
// UDP Buffer sizes (should be about the size of your MTU)
#define DEFAULT_UDP_TX_BUF_SZ ZT_MAX_MTU
#define DEFAULT_UDP_RX_BUF_SZ ZT_MAX_MTU * 128
#define DEFAULT_UDP_RX_BUF_SZ ZT_MAX_MTU * 10
// lwIP
#define APPLICATION_POLL_FREQ 2
#define ZT_LWIP_TCP_TIMER_INTERVAL 50
#define STATUS_TMR_INTERVAL 500 // How often we check connection statuses (in ms)

View File

@@ -28,6 +28,17 @@
#ifndef _ZT_SDK_H
#define _ZT_SDK_H 1
#include <sys/socket.h>
#include <stdbool.h>
// ------------------------------------------------------------------------------
// ---------------------------- Compilation flag checks -------------------------
// ------------------------------------------------------------------------------
#define INTERCEPT_ENABLED 111
#define INTERCEPT_DISABLED 222
#define MAX_DIR_SZ 256 // Max path length used for home dir
#if defined(SDK_SERVICE)
// Sanity checks for compilation
#if !defined(SDK_LWIP) && !defined(SDK_PICOTCP)
@@ -44,22 +55,37 @@
#endif
#endif
<<<<<<< HEAD
#include <sys/socket.h>
#include <stdbool.h>
#define SETSOCKOPT_SIG int fd, int level, int optname, const void *optval, socklen_t optlen
#define GETSOCKOPT_SIG int fd, int level, int optname, void *optval, socklen_t *optlen
=======
// ------------------------------------------------------------------------------
// -------------- Socket API function signatures for convenience ----------------
// ------------------------------------------------------------------------------
#define SETSOCKOPT_SIG int fd, int level, int optname, const void *optval, socklen_t optlen
#define GETSOCKOPT_SIG int fd, int level, int optname, void *optval, socklen_t *optlen
>>>>>>> dev
#define SENDMSG_SIG int fd, const struct msghdr *msg, int flags
#define SENDTO_SIG int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen
#define RECV_SIG int fd, void *buf, size_t len, int flags
#define RECVFROM_SIG int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen
#define RECVMSG_SIG int fd, struct msghdr *msg,int flags
<<<<<<< HEAD
#define SEND_SIG int fd, const void *buf, size_t len, int flags
#define WRITE_SIG int fd, const void *buf, size_t len
#define READ_SIG int fd, void *buf, size_t len
=======
#define SEND_SIG int fd, const void *buf, size_t len, int flags
#define WRITE_SIG int fd, const void *buf, size_t len
#define READ_SIG int fd, void *buf, size_t len
>>>>>>> dev
#define SOCKET_SIG int socket_family, int socket_type, int protocol
#define CONNECT_SIG int fd, const struct sockaddr *addr, socklen_t addrlen
#define BIND_SIG int fd, const struct sockaddr *addr, socklen_t addrlen
@@ -80,15 +106,15 @@
extern "C" {
#endif
#define INTERCEPT_ENABLED 111
#define INTERCEPT_DISABLED 222
#define MAX_DIR_SZ 256 // Max path length used for home dir
extern void load_symbols();
extern void zts_init_rpc(const char *path, const char *nwid);
extern char *api_netpath;
extern char *debug_logfile;
// ------------------------------------------------------------------------------
// ------------------------- Ancient INTERCEPT-related cruft --------------------
// ------------------------------------------------------------------------------
// Function pointers to original system calls
// - These are used when we detect that either the intercept is not
// available or that ZeroTier hasn't administered the given socket
@@ -116,41 +142,34 @@ extern char *debug_logfile;
extern int (*realclose)(CLOSE_SIG);
extern int (*realgetsockname)(GETSOCKNAME_SIG);
// Direct call
// - Skips intercept
// - Uses RPC
// - Depending on the target, the API will be exposed as zt_* in
// the specific way needed for that platform, but will be implemented
// in terms of zts_*
// ------------------------------------------------------------------------------
// ---------------------------- Direct API call section -------------------------
// ------------------------------------------------------------------------------
// SOCKS5 Proxy Controls
int zts_start_proxy_server(const char *homepath, const char * nwid, struct sockaddr_storage * addr);
int zts_stop_proxy_server(const char *nwid);
int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage *addr);
bool zts_proxy_is_running(const char *nwid);
// ZT Service Controls
void zts_start_service(const char *path);
void *zts_start_core_service(void *thread_id);
void zts_stop_service();
void zts_stop();
bool zts_service_is_running();
void zts_join_network(const char * nwid);
void zts_join_network_soft(const char * filepath, const char * nwid);
void zts_leave_network_soft(const char * filepath, const char * nwid);
void zts_leave_network(const char * nwid);
// void zts_get_addresses(const char * nwid, char * addrstr);
void zts_get_ipv4_address(const char *nwid, char *addrstr);
void zts_get_ipv6_address(const char *nwid, char *addrstr);
bool zts_has_address(const char *nwid);
int zts_get_device_id();
bool zts_is_relayed();
int zts_get_device_id(char *devID);
int zts_get_device_id_from_file(const char *filepath, char *devID);
char *zts_get_homepath();
// ZT Intercept/RPC Controls
// TODO: Remove any?
//void set_intercept_status(int mode); // TODO: Rethink this
//void init_service(int key, const char * path);
//void init_service_and_rpc(int key, const char * path, const char * nwid);
//void init_intercept(int key);
void zts_get_6plane_addr(char *addr, const char *nwid, const char *devID);
void zts_get_rfc4193_addr(char *addr, const char *nwid, const char *devID);
// BSD-like socket API
int zts_socket(SOCKET_SIG);
int zts_connect(CONNECT_SIG);
int zts_bind(BIND_SIG);
@@ -165,12 +184,10 @@ int zts_getsockname(GETSOCKNAME_SIG);
int zts_getpeername(GETPEERNAME_SIG);
int zts_close(CLOSE_SIG);
int zts_fcntl(FCNTL_SIG);
ssize_t zts_sendto(SENDTO_SIG);
ssize_t zts_sendmsg(SENDMSG_SIG);
ssize_t zts_recvfrom(RECVFROM_SIG);
ssize_t zts_recvmsg(RECVMSG_SIG);
#if defined(__UNITY_3D__)
ssize_t zts_recv(int fd, void *buf, int len);
ssize_t zts_send(int fd, void *buf, int len);
@@ -183,7 +200,10 @@ ssize_t zts_recvmsg(RECVMSG_SIG);
void zt_leave_network(const char * nwid);
#endif
// Android JNI Direct-call API
// ------------------------------------------------------------------------------
// --------------------- Direct API call section (for Android) ------------------
// ------------------------------------------------------------------------------
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
#if defined(__ANDROID__)
// ZT SERVICE CONTROLS
@@ -226,7 +246,7 @@ ssize_t zts_recvmsg(RECVMSG_SIG);
// Prototypes for redefinition of syscalls
// - Implemented in SDK_Intercept.c
// - Implemented in intercept.c
#if defined(SDK_INTERCEPT)
int socket(SOCKET_SIG);
int connect(CONNECT_SIG);

View File

@@ -45,29 +45,29 @@
#include "OneService.hpp"
#include "Utils.hpp"
#include "OSUtils.hpp"
#include "InetAddress.hpp"
#include "tap.hpp"
#include "sdk.h"
#include "debug.h"
std::string service_path;
pthread_t intercept_thread;
int * intercept_thread_id;
pthread_key_t thr_id_key;
static ZeroTier::OneService *volatile zt1Service;
std::string localHomeDir; // Local shortened path
std::string givenHomeDir; // What the user/application provides as a suggestion
std::string homeDir; // The resultant platform-specific dir we *must* use internally
std::string netDir;
std::string rpcNWID;
bool rpcEnabled;
#ifdef __cplusplus
extern "C" {
#endif
static ZeroTier::OneService *zt1Service;
std::string service_path;
std::string localHomeDir; // Local shortened path
std::string givenHomeDir; // What the user/application provides as a suggestion
std::string homeDir; // The resultant platform-specific dir we *must* use internally
std::string netDir; // Where network .conf files are to be written
pthread_t intercept_thread;
pthread_key_t thr_id_key;
int * intercept_thread_id;
// ------------------------------------------------------------------------------
// --------------------------------- Base zts_* API -----------------------------
// ------------------------------------------------------------------------------
@@ -123,7 +123,7 @@ int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage * ad
// Basic ZT service controls
// Will also spin up a SOCKS5 proxy server if USE_SOCKS_PROXY is set
void zts_join_network(const char * nwid) {
DEBUG_INFO();
DEBUG_ERROR();
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
if(!ZeroTier::OSUtils::mkdir(netDir)) {
DEBUG_ERROR("unable to create: %s", netDir.c_str());
@@ -140,26 +140,50 @@ void zts_join_network(const char * nwid) {
zts_start_proxy_server(homeDir.c_str(), nwid, NULL); // NULL addr for default
#endif
}
//
// Just create the dir and conf file required, don't instruct the core to do anything
void zts_join_network_soft(const char * filepath, const char * nwid) {
std::string net_dir = std::string(filepath) + "/networks.d/";
std::string confFile = net_dir + std::string(nwid) + ".conf";
if(!ZeroTier::OSUtils::mkdir(net_dir)) {
DEBUG_ERROR("unable to create: %s", net_dir.c_str());
}
if(!ZeroTier::OSUtils::fileExists(confFile.c_str(),false)) {
if(!ZeroTier::OSUtils::writeFile(confFile.c_str(), "")) {
DEBUG_ERROR("unable to write network conf file: %s", confFile.c_str());
}
}
}
// Prevent service from joining network upon startup
void zts_leave_network_soft(const char * filepath, const char * nwid) {
std::string net_dir = std::string(filepath) + "/networks.d/";
ZeroTier::OSUtils::rm((net_dir + nwid + ".conf").c_str());
}
// Instruct the service to leave the network
void zts_leave_network(const char * nwid) {
if(zt1Service)
zt1Service->leave(nwid);
}
//
// Check whether the service is running
bool zts_service_is_running() {
return !zt1Service ? false : zt1Service->isRunning();
}
//
// Stop the service
void zts_stop_service() {
if(zt1Service)
zt1Service->terminate();
}
// Stop the service, proxy server, stack, etc
void zts_stop() {
DEBUG_INFO("Stopping STSDK");
zts_stop_service();
/* TODO: kill each proxy server as well
zts_stop_proxy_server(...); */
}
// FIXME: Re-implemented to make it play nicer with the C-linkage required for Xcode integrations
// Now only returns first assigned address per network. Shouldn't normally be a problem.
// Get IPV4 Address for this device on given network
bool zts_has_address(const char *nwid)
{
char ipv4_addr[64], ipv6_addr[64];
@@ -172,8 +196,6 @@ bool zts_has_address(const char *nwid)
}
return true;
}
void zts_get_ipv4_address(const char *nwid, char *addrstr)
{
uint64_t nwid_int = strtoull(nwid, NULL, 16);
@@ -211,23 +233,46 @@ void zts_get_ipv6_address(const char *nwid, char *addrstr)
memcpy(addrstr, "-1.-1.-1.-1/-1", 14);
}
}
// Get device ID
int zts_get_device_id()
{
// zt->node->status
/* TODO */ return 0;
// Get device ID (from running service)
int zts_get_device_id(char *devID) {
if(zt1Service) {
char id[10];
sprintf(id, "%lx",zt1Service->getNode()->address());
memcpy(devID, id, 10);
return 0;
}
//
bool zts_is_relayed() {
// TODO
// zt1Service->getNode()->peers()
return false;
else
return -1;
}
// Get device ID (from file)
int zts_get_device_id_from_file(const char *filepath, char *devID) {
std::string fname("identity.public");
std::string fpath(filepath);
if(ZeroTier::OSUtils::fileExists((fpath + ZT_PATH_SEPARATOR_S + fname).c_str(),false)) {
std::string oldid;
ZeroTier::OSUtils::readFile((fpath + ZT_PATH_SEPARATOR_S + fname).c_str(),oldid);
memcpy(devID, oldid.c_str(), 10); // first 10 bytes of file
return 0;
}
return -1;
}
// Return the home path for this instance of ZeroTier
char *zts_get_homepath() {
return (char*)givenHomeDir.c_str();
}
// Returns a 6PLANE IPv6 address given a network ID and zerotier ID
void zts_get_6plane_addr(char *addr, const char *nwid, const char *devID)
{
ZeroTier::InetAddress _6planeAddr = ZeroTier::InetAddress::makeIpv66plane(ZeroTier::Utils::hexStrToU64(nwid),ZeroTier::Utils::hexStrToU64(devID));
memcpy(addr, _6planeAddr.toIpString().c_str(), 40);
}
// Returns a RFC 4193 IPv6 address given a network ID and zerotier ID
void zts_get_rfc4193_addr(char *addr, const char *nwid, const char *devID)
{
ZeroTier::InetAddress _6planeAddr = ZeroTier::InetAddress::makeIpv6rfc4193(ZeroTier::Utils::hexStrToU64(nwid),ZeroTier::Utils::hexStrToU64(devID));
memcpy(addr, _6planeAddr.toIpString().c_str(), 40);
}
// ------------------------------------------------------------------------------
// ----------------------------- .NET Interop functions -------------------------
@@ -288,7 +333,6 @@ void zts_start_service(const char *path)
}
//void init_service_and_rpc(int key, const char * path, const char * nwid) {
// rpcEnabled = true;
// rpcNWID = nwid;
// init_service(key, path);
//}
@@ -483,7 +527,7 @@ void *zts_start_core_service(void *thread_id) {
// Construct path for network config and supporting service files
if (homeDir.length()) {
std::vector<std::string> hpsp(ZeroTier::Utils::split(homeDir.c_str(),ZT_PATH_SEPARATOR_S,"",""));
std::vector<std::string> hpsp(ZeroTier::OSUtils::split(homeDir.c_str(),ZT_PATH_SEPARATOR_S,"",""));
std::string ptmp;
if (homeDir[0] == ZT_PATH_SEPARATOR)
ptmp.push_back(ZT_PATH_SEPARATOR);
@@ -504,17 +548,7 @@ void *zts_start_core_service(void *thread_id) {
return NULL;
}
//chdir(current_dir); // Return to previous current working directory (at the request of Unity3D)
#if defined(__UNITY_3D__)
DEBUG_INFO("starting service...");
#endif
DEBUG_INFO("starting service...");
// Initialize RPC
// TODO: remove?
if(rpcEnabled) {
zts_init_rpc(localHomeDir.c_str(), rpcNWID.c_str());
}
// Generate random port for new service instance
unsigned int randp = 0;

View File

@@ -73,6 +73,7 @@
#include "sdk.h"
#include "debug.h"
#include "rpc.h"
#include "defs.h"
#include "Constants.hpp" // For Tap's MTU
@@ -100,16 +101,19 @@ int (*realclose)(CLOSE_SIG);
// If no path, construct one or get it fron system env vars
if(!api_netpath) {
rpc_mutex_init();
// Provided by user
#if defined(SDK_BUNDLED)
// Get the path/nwid from the user application
// netpath = [path + "/nc_" + nwid]
char *fullpath = (char *)malloc(strlen(path)+strlen(nwid)+1+4);
if(fullpath) {
zts_join_network_soft(path, nwid);
strcpy(fullpath, path);
strcat(fullpath, "/nc_");
strcat(fullpath, nwid);
api_netpath = fullpath;
}
// Provided by Env
#else
// Get path/nwid from environment variables
if (!api_netpath) {
@@ -191,7 +195,7 @@ int (*realclose)(CLOSE_SIG);
ssize_t zts_sendto(SENDTO_SIG) // Used as internal implementation
#endif
{
DEBUG_EXTRA("fd=%d", fd);
//DEBUG_EXTRA("fd=%d", fd);
if(len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
errno = EMSGSIZE; // Msg is too large
return -1;
@@ -232,7 +236,7 @@ int (*realclose)(CLOSE_SIG);
ssize_t zts_sendmsg(SENDMSG_SIG)
#endif
{
DEBUG_EXTRA("fd=%d",fd);
//DEBUG_EXTRA("fd=%d",fd);
char * p, * buf;
size_t tot_len = 0;
size_t err;
@@ -280,7 +284,7 @@ int (*realclose)(CLOSE_SIG);
{
struct sockaddr_in addr;
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
unsigned char buffer[ZT_MAX_MTU];
unsigned char buffer[SDK_MTU];
int payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
int rxbytes = zts_recvfrom(fd, &buffer, len, flags, &addr, sizeof(struct sockaddr_storage));
if(rxbytes > 0)
@@ -304,19 +308,42 @@ int (*realclose)(CLOSE_SIG);
ssize_t zts_recvfrom(RECVFROM_SIG)
#endif
{
int payload_offset, tmpsz = 0; // payload size
char tmpbuf[ZT_MAX_MTU];
if(read(fd, tmpbuf, ZT_MAX_MTU) > 0) {
int read_chunk_sz = 0, payload_offset, tmpsz=0, pnum=0; // payload size
char tmpbuf[SDK_MTU];
memset(tmpbuf, 0, SDK_MTU);
// Attempt to read SDK_MTU sized chunk
int total_read = 0, n=0;
// Read the entire SDK_MTU-sized chunk from the service socket
while(total_read < SDK_MTU) {
n = read(fd, tmpbuf+total_read, SDK_MTU);
if(n>0)
total_read += n;
else
return n;
}
if(n > 0) {
// No matter how much we read from the service, only copy 'read_chunk_sz'
// into the app's buffer
read_chunk_sz = len < SDK_MTU ? len : SDK_MTU;
// TODO: case for address size mismatch?
memcpy(addr, tmpbuf, *addrlen);
memcpy(&tmpsz, tmpbuf + sizeof(struct sockaddr_storage), sizeof(tmpsz));
memcpy(&pnum, tmpbuf + sizeof(struct sockaddr_storage) + sizeof(int), sizeof(int));
if(tmpsz > SDK_MTU || tmpsz < 0) {
DEBUG_ERROR("An error occured somewhere in the SDK, read=%d", n);
return -1;
}
payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
memcpy(buf, tmpbuf + payload_offset, ZT_MAX_MTU-payload_offset);
memcpy(buf, tmpbuf + payload_offset, read_chunk_sz);
}
else {
perror("read:\n");
return -1;
}
return tmpsz;
return read_chunk_sz;
}
//#endif
@@ -332,7 +359,7 @@ int (*realclose)(CLOSE_SIG);
ssize_t zts_recvmsg(RECVMSG_SIG)
#endif
{
DEBUG_EXTRA("fd=%d", fd);
//DEBUG_EXTRA("fd=%d", fd);
ssize_t err, n, tot_len = 0;
char *buf, *p;
struct iovec *iov = msg->msg_iov;
@@ -541,7 +568,7 @@ int (*realclose)(CLOSE_SIG);
#endif
{
get_api_netpath();
DEBUG_INFO("fd=%d", fd);
//DEBUG_INFO("fd=%d", fd);
struct connect_st rpc_st;
rpc_st.fd = fd;
memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));

View File

@@ -25,6 +25,10 @@
* LLC. Start here: http://www.zerotier.com/
*/
#if defined(__ANDROID__)
#include "src/debug.h"
#endif
#include "tap.hpp"
#include "sdkutils.hpp"

View File

@@ -479,52 +479,52 @@ namespace ZeroTier {
#endif
#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 void __nd6_tmr(void) throw() { /*DEBUG_STACK();*/ 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_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 err_t __ethip6_output(ETHIP6_OUTPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _ethip6_output(netif,q,ip6addr); }
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() { /**/ Mutex::Lock _l(_lock); _nd6_tmr(); }
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() { Mutex::Lock _l(_lock); _netif_create_ip6_linklocal_address(netif, from_mac_48bit); }
inline err_t __ethip6_output(ETHIP6_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _ethip6_output(netif,q,ip6addr); }
#endif
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 __lwip_init() throw() { DEBUG_STACK(); 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 void __tcp_sent(TCP_SENT_SIG) throw() { DEBUG_STACK(); 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 udp_pcb * __udp_new(UDP_NEW_SIG) throw() { DEBUG_STACK(); 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_send(UDP_SEND_SIG) throw() { DEBUG_STACK(); 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 void __udp_recv(UDP_RECV_SIG) throw() { DEBUG_STACK(); 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 void __udp_remove(UDP_REMOVE_SIG) throw() { DEBUG_STACK(); 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 err_t __tcp_connect(TCP_CONNECT_SIG) throw() { DEBUG_STACK(); 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_recved(TCP_RECVED_SIG) throw() { DEBUG_STACK(); 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_poll(TCP_POLL_SIG) throw() { DEBUG_STACK(); 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 err_t __tcp_close(TCP_CLOSE_SIG) throw() { DEBUG_STACK(); 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 err_t __tcp_output(TCP_OUTPUT_SIG) throw() { DEBUG_STACK(); 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 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_with_backlog(TCP_LISTEN_WITH_BACKLOG_SIG) throw() { DEBUG_STACK(); 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 void __etharp_tmr(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _etharp_tmr(); }
inline void __tcp_tmr(void) throw() { /*DEBUG_STACK();*/ 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 struct pbuf * __pbuf_alloc(PBUF_ALLOC_SIG) throw() { /*DEBUG_STACK();*/ 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_ntohs(LWIP_NTOHS_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _lwip_ntohs(x); }
inline void __lwip_init() throw() { Mutex::Lock _l(_lock); return _lwip_init(); }
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() { Mutex::Lock _l(_lock); return _tcp_sent(pcb,sent); }
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() { Mutex::Lock _l(_lock); return _udp_new(); }
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() { Mutex::Lock _l(_lock); return _udp_send(pcb,p); }
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() { Mutex::Lock _l(_lock); return _udp_recv(pcb,recv,recv_arg); }
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() { Mutex::Lock _l(_lock); return _udp_remove(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() { Mutex::Lock _l(_lock); return _tcp_connect(pcb,ipaddr,port,connected); }
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() { Mutex::Lock _l(_lock); return _tcp_recved(pcb,len); }
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() { Mutex::Lock _l(_lock); return _tcp_poll(pcb,poll,interval); }
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() { Mutex::Lock _l(_lock); return _tcp_close(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() { Mutex::Lock _l(_lock); return _tcp_output(pcb); }
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() { Mutex::Lock _l(_lock); return _tcp_listen(pcb); }
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() { Mutex::Lock _l(_lock); return _tcp_bind(pcb,ipaddr,port); }
inline void __etharp_tmr(void) throw() { Mutex::Lock _l(_lock); return _etharp_tmr(); }
inline void __tcp_tmr(void) throw() { Mutex::Lock _l(_lock); return _tcp_tmr(); }
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() { Mutex::Lock _l(_lock_mem); return _pbuf_alloc(layer,length,type); }
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() { 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 __ethernet_input(ETHERNET_INPUT_SIG) throw() { DEBUG_STACK(); 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 err_t __ip_input(IP_INPUT_SIG) throw() { DEBUG_STACK(); 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_up(NETIF_SET_UP_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _netif_set_up(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() { Mutex::Lock _l(_lock); return _tcp_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() { Mutex::Lock _l(_lock); return _netif_set_default(netif); }
inline void __netif_set_up(NETIF_SET_UP_SIG) throw() { Mutex::Lock _l(_lock); return _netif_set_up(netif); }
};
} // namespace ZeroTier

View File

@@ -40,21 +40,6 @@
namespace ZeroTier {
// This may be removed in production
void check_buffer_states(Connection *conn)
{
#if defined(SDK_DEBUG)
if(conn->rxsz < 0) {
DEBUG_ERROR("conn->rxsz < 0");
exit(0);
}
if(conn->txsz < 0) {
DEBUG_ERROR("conn->txsz < 0");
exit(0);
}
#endif
}
// Reference to the tap interface
// This is needed due to the fact that there's a lot going on in the tap interface
// that needs to be updated on each of the network stack's callbacks and not every
@@ -121,20 +106,19 @@ namespace ZeroTier {
}
}
// I/O thread loop
// Main stack loop
void pico_loop(NetconEthernetTap *tap)
{
DEBUG_INFO();
while(tap->_run)
{
tap->_phy.poll(50); // in ms
//usleep(50);
tap->_phy.poll(ZT_PHY_POLL_INTERVAL); // in ms
tap->picostack->__pico_stack_tick();
}
}
// RX packets from network onto internal buffer
// Also notifies the tap service that data can be read
// RX packets from [ZT->STACK] onto RXBUF
// Also notify the tap service that data can be read:
// [RXBUF -> (ZTSOCK->APP)]
// -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
// | |
@@ -144,8 +128,7 @@ namespace ZeroTier {
// After this step, buffer will be emptied periodically by pico_handleRead()
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
{
// TODO: Verify
// DEBUG_INFO("picosock=%p", s);
DEBUG_INFO();
Connection *conn = tap->getConnection(s);
if(conn) {
int r;
@@ -158,11 +141,9 @@ namespace ZeroTier {
do {
int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz;
if(avail) {
// r = tap->picostack->__pico_socket_read(s, conn->rxbuf + (conn->rxsz), ZT_MAX_MTU);
r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), ZT_MAX_MTU, (void *)&peer.ip4.addr, &port);
r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), SDK_MTU, (void *)&peer.ip4.addr, &port);
// DEBUG_ATTN("received packet (%d byte) from %08X:%u", r, long_be2(peer.ip4.addr), short_be(port));
tap->_phy.setNotifyWritable(conn->sock, true);
//DEBUG_EXTRA("read=%d", r);
if (r > 0)
conn->rxsz += r;
}
@@ -175,7 +156,7 @@ namespace ZeroTier {
DEBUG_ERROR("invalid connection");
}
// RX packets from network onto internal buffer
// RX packets from the stack onto internal buffer
// Also notifies the tap service that data can be read
// -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
@@ -190,6 +171,8 @@ namespace ZeroTier {
//
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
{
DEBUG_INFO();
Connection *conn = tap->getConnection(s);
if(conn) {
@@ -199,16 +182,15 @@ namespace ZeroTier {
struct pico_ip6 ip6;
} peer;
char tmpbuf[ZT_MAX_MTU];
int tot = 0;
char tmpbuf[SDK_MTU];
unsigned char *addr_pos, *sz_pos, *payload_pos;
struct sockaddr_in addr_in;
addr_in.sin_addr.s_addr = peer.ip4.addr;
addr_in.sin_port = port;
// RX
int r = tap->picostack->__pico_socket_recvfrom(s, tmpbuf, ZT_MAX_MTU, (void *)&peer.ip4.addr, &port);
DEBUG_EXTRA("read=%d", r);
int r = tap->picostack->__pico_socket_recvfrom(s, tmpbuf, SDK_MTU, (void *)&peer.ip4.addr, &port);
DEBUG_FLOW(" [ RXBUF <- STACK] Receiving (%d) from stack, copying to receving buffer", r);
// Mutex::Lock _l2(tap->_rx_buf_m);
// struct sockaddr_in6 addr_in6;
@@ -216,23 +198,25 @@ namespace ZeroTier {
// addr_in6.sin6_port = Utils::ntoh(s->remote_port);
// DEBUG_ATTN("remote_port=%d, local_port=%d", s->remote_port, Utils::ntoh(s->local_port));
picotap->_rx_buf_m.lock();
if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
DEBUG_INFO("UDP RX buffer full. Discarding oldest payload segment");
memmove(conn->rxbuf, conn->rxbuf + ZT_MAX_MTU, DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU);
addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU); // TODO:
//DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment");
memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU);
addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - SDK_MTU); // TODO:
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
conn->rxsz -= ZT_MAX_MTU;
conn->rxsz -= SDK_MTU;
}
else {
addr_pos = conn->rxbuf + conn->rxsz; // where we'll prepend the size of the address
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
}
payload_pos = addr_pos + sizeof(struct sockaddr_storage) + sizeof(tot);
payload_pos = addr_pos + sizeof(struct sockaddr_storage) + sizeof(r);
memcpy(addr_pos, &addr_in, sizeof(struct sockaddr_storage));
// Adjust buffer size
if(r) {
conn->rxsz += ZT_MAX_MTU;
conn->rxsz += SDK_MTU;
memcpy(sz_pos, &r, sizeof(r));
tap->phyOnUnixWritable(conn->sock, NULL, true);
//tap->_phy.setNotifyWritable(conn->sock, false);
@@ -241,6 +225,8 @@ namespace ZeroTier {
DEBUG_ERROR("unable to read from picosock=%p", s);
}
memcpy(payload_pos, tmpbuf, r); // write payload to app's socket
//DEBUG_EXTRA(" Copied onto rxbuf (%d) from stack socket", r);
picotap->_rx_buf_m.unlock();
return;
}
}
@@ -257,7 +243,7 @@ namespace ZeroTier {
// Only called from a locked context, no need to lock anything
if(conn->txsz > 0) {
int r, max_write_len = conn->txsz < ZT_MAX_MTU ? conn->txsz : ZT_MAX_MTU;
int r, max_write_len = conn->txsz < SDK_MTU ? conn->txsz : SDK_MTU;
if((r = tap->picostack->__pico_socket_write(s, &conn->txbuf, max_write_len)) < 0) {
DEBUG_ERROR("unable to write to picosock=%p", s);
return;
@@ -276,6 +262,7 @@ namespace ZeroTier {
// Main callback for TCP connections
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
{
DEBUG_INFO();
int err;
Mutex::Lock _l(picotap->_tcpconns_m);
Connection *conn = picotap->getConnection(s);
@@ -365,7 +352,7 @@ namespace ZeroTier {
// -----------------------------------------
int pico_eth_send(struct pico_device *dev, void *buf, int len)
{
DEBUG_INFO("len=%d", len);
//DEBUG_INFO("len=%d", len);
struct pico_eth_hdr *ethhdr;
ethhdr = (struct pico_eth_hdr *)buf;
@@ -389,35 +376,61 @@ namespace ZeroTier {
// It will then periodically be transfered into the network stack via pico_eth_poll()
void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
{
// DEBUG_INFO();
DEBUG_INFO();
// Since picoTCP only allows the reception of frames from within the polling function, we
// must enqueue each frame into a memory structure shared by both threads. This structure will
Mutex::Lock _l(tap->_pico_frame_rxbuf_m);
if(len > ((1024 * 1024) - tap->pico_frame_rxbuf_tot)) {
DEBUG_ERROR("dropping packet (len = %d) - not enough space left on RX frame buffer", len);
return;
}
//if(len != memcpy(pico_frame_rxbuf, data, len)) {
// DEBUG_ERROR("dropping packet (len = %d) - unable to copy contents of frame to RX frame buffer", len);
// return;
//}
// assemble new eth header
struct pico_eth_hdr ethhdr;
from.copyTo(ethhdr.saddr, 6);
to.copyTo(ethhdr.daddr, 6);
ethhdr.proto = Utils::hton((uint16_t)etherType);
int newlen = len+sizeof(struct pico_eth_hdr);
//
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot, &newlen, sizeof(newlen)); // size of frame
int newlen = len + sizeof(int) + sizeof(struct pico_eth_hdr);
int mylen;
while(newlen > (MAX_PICO_FRAME_RX_BUF_SZ-tap->pico_frame_rxbuf_tot) && ethhdr.proto == 56710)
{
mylen = 0;
DEBUG_ERROR(" [ ZTWIRE -> FBUF ] not enough space left on RX frame buffer, dropping oldest packet in buffer");
/*
memcpy(&mylen, picotap->pico_frame_rxbuf, sizeof(len));
memmove(tap->pico_frame_rxbuf, tap->pico_frame_rxbuf + mylen, MAX_PICO_FRAME_RX_BUF_SZ-mylen); // shift buffer
picotap->pico_frame_rxbuf_tot-=mylen;
*/
memset(tap->pico_frame_rxbuf,0,MAX_PICO_FRAME_RX_BUF_SZ);
picotap->pico_frame_rxbuf_tot=0;
}
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot, &newlen, sizeof(newlen)); // size of frame + meta
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), &ethhdr, sizeof(ethhdr)); // new eth header
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
tap->pico_frame_rxbuf_tot += len + sizeof(len) + sizeof(ethhdr);
// DEBUG_INFO("RX frame buffer %3f full", (float)pico_frame_rxbuf_tot / (float)(1024 * 1024));
// DEBUG_INFO("len=%d", len);
tap->pico_frame_rxbuf_tot += newlen;
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Move FRAME(sz=%d) into FBUF(sz=%d), data_len=%d", newlen, picotap->pico_frame_rxbuf_tot, len);
/*
char graph[GRAPH_BUF_SZ];
gengraph(&graph, GRAPH_BUF_SZ, '|', 0.6);
DEBUG_FLOW(graph);
*/
//}
//else
//{
/*
if(newlen > (MAX_PICO_FRAME_RX_BUF_SZ-tap->pico_frame_rxbuf_tot)) {
DEBUG_ERROR("dropping packet (len = %d) - not enough space left on RX frame buffer", len);
return;
}
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot, &newlen, sizeof(newlen)); // size of frame + meta
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), &ethhdr, sizeof(ethhdr)); // new eth header
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
tap->pico_frame_rxbuf_tot += newlen;
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Moved FRAME(sz=%d) into FBUF(sz=%d), data_len=%d, ethhdr.proto=%d", newlen, picotap->pico_frame_rxbuf_tot, len, ethhdr.proto);
*/
//}
}
// Called periodically by the stack, this removes data from the locked memory buffer and feeds it into the stack.
// Called periodically by the stack, this removes data from the locked memory buffer (FBUF) and feeds it into the stack.
// A maximum of 'loop_score' frames can be processed in each call
// -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
@@ -427,22 +440,28 @@ namespace ZeroTier {
// -----------------------------------------
int pico_eth_poll(struct pico_device *dev, int loop_score)
{
// DEBUG_EXTRA();
//DEBUG_ERROR();
// OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
unsigned char frame[ZT_MAX_MTU];
uint32_t len;
while (picotap->pico_frame_rxbuf_tot > 0) {
unsigned char frame[SDK_MTU];
int len;
while (picotap->pico_frame_rxbuf_tot > 0 && loop_score > 0) {
DEBUG_INFO(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot);
memset(frame, 0, sizeof(frame));
len = 0;
memcpy(&len, picotap->pico_frame_rxbuf, sizeof(len)); // get frame len
memcpy(frame, picotap->pico_frame_rxbuf + sizeof(len), len); // get frame data
memmove(picotap->pico_frame_rxbuf, picotap->pico_frame_rxbuf + sizeof(len) + len, ZT_MAX_MTU-(sizeof(len) + len));
picotap->picostack->__pico_stack_recv(dev, (uint8_t*)frame, len);
picotap->pico_frame_rxbuf_tot-=(sizeof(len) + len);
// DEBUG_EXTRA("RX frame buffer %3f full", (float)(picotap->pico_frame_rxbuf_tot) / (float)(MAX_PICO_FRAME_RX_BUF_SZ));
if(len >= 0) {
DEBUG_FLOW(" [ FBUF -> STACK] Moving FRAME of size (%d) from FBUF(sz=%d) into stack",len, picotap->pico_frame_rxbuf_tot-len);
memcpy(frame, picotap->pico_frame_rxbuf + sizeof(len), len-(sizeof(len)) ); // get frame data
memmove(picotap->pico_frame_rxbuf, picotap->pico_frame_rxbuf + len, MAX_PICO_FRAME_RX_BUF_SZ-len); // shift buffer
picotap->picostack->__pico_stack_recv(dev, (uint8_t*)frame, (len-sizeof(len)));
picotap->pico_frame_rxbuf_tot-=len;
}
else {
DEBUG_ERROR("Skipping frame of size (%d)",len);
exit(0);
}
loop_score--;
}
return loop_score;
@@ -475,10 +494,28 @@ namespace ZeroTier {
*uptr = newConn;
newConn->type = socket_rpc->socket_type;
newConn->sock = sock;
/*
int res = 0;
int sendbuff = UNIX_SOCK_BUF_SIZE;
socklen_t optlen = sizeof(sendbuff);
res = setsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_RCVBUF, &sendbuff, sizeof(sendbuff));
if(res == -1)
DEBUG_ERROR("Error while setting RX buffer limits");
res = setsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));
if(res == -1)
DEBUG_ERROR("Error while setting TX buffer limits");
// Get buffer size
// optlen = sizeof(sendbuff);
// res = getsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
// DEBUG_INFO("buflen=%d", sendbuff);
*/
newConn->local_addr = NULL;
// newConn->peer_addr = NULL;
newConn->picosock = psock;
picotap->_Connections.push_back(newConn);
memset(newConn->rxbuf, 0, DEFAULT_UDP_RX_BUF_SZ);
return newConn;
}
else {
@@ -496,13 +533,13 @@ namespace ZeroTier {
// -----------------------------------------
void pico_handleWrite(Connection *conn)
{
DEBUG_INFO();
//DEBUG_INFO();
if(!conn || !conn->picosock) {
DEBUG_ERROR(" invalid connection");
return;
}
int max, r, max_write_len = conn->txsz < ZT_MAX_MTU ? conn->txsz : ZT_MAX_MTU;
int max, r, max_write_len = conn->txsz < SDK_MTU ? conn->txsz : SDK_MTU;
if((r = picotap->picostack->__pico_socket_write(conn->picosock, &conn->txbuf, max_write_len)) < 0) {
DEBUG_ERROR("unable to write to picosock=%p, r=%d", (conn->picosock), r);
return;
@@ -542,16 +579,15 @@ namespace ZeroTier {
}
if(conn->type == SOCK_DGRAM) {
max = DEFAULT_UDP_TX_BUF_SZ;
DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
(float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
//DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
// (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
}
check_buffer_states(conn);
}
// Instructs the stack to connect to a remote host
void pico_handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
{
DEBUG_INFO();
//DEBUG_INFO();
if(conn->picosock) {
struct sockaddr_in *addr = (struct sockaddr_in *) &connect_rpc->addr;
int ret;
@@ -562,7 +598,7 @@ namespace ZeroTier {
char ipv4_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(in4->sin_addr), ipv4_str, INET_ADDRSTRLEN);
picotap->picostack->__pico_string_to_ipv4(ipv4_str, &(zaddr.addr));
DEBUG_ATTN("addr=%s:%d", ipv4_str, Utils::ntoh(addr->sin_port));
//DEBUG_ATTN("addr=%s:%d", ipv4_str, Utils::ntoh(addr->sin_port));
ret = picotap->picostack->__pico_socket_connect(conn->picosock, &zaddr, addr->sin_port);
#elif defined(SDK_IPV6) // "fd56:5799:d8f6:1238:8c99:9322:30ce:418a"
struct pico_ip6 zaddr;
@@ -570,7 +606,7 @@ namespace ZeroTier {
char ipv6_str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &(in6->sin6_addr), ipv6_str, INET6_ADDRSTRLEN);
picotap->picostack->__pico_string_to_ipv6(ipv6_str, zaddr.addr);
DEBUG_ATTN("addr=%s:%d", ipv6_str, Utils::ntoh(addr->sin_port));
//DEBUG_ATTN("addr=%s:%d", ipv6_str, Utils::ntoh(addr->sin_port));
ret = picotap->picostack->__pico_socket_connect(conn->picosock, &zaddr, addr->sin_port);
#endif
@@ -661,6 +697,7 @@ namespace ZeroTier {
}
// Feeds data into the local app socket from the I/O buffer associated with the "connection"
// [ (APP<-ZTSOCK) <- RXBUF ]
// -----------------------------------------
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
// | |
@@ -669,42 +706,53 @@ namespace ZeroTier {
// -----------------------------------------
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
{
DEBUG_INFO();
if(!lwip_invoked) {
// The stack thread writes to RXBUF as well
picotap->_tcpconns_m.lock();
picotap->_rx_buf_m.lock();
}
DEBUG_ATTN();
int tot = 0, n = -1;
Connection *conn = picotap->getConnection(sock);
if(conn && conn->rxsz) {
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ;
int n = -1;
// extract address and payload size info
if(conn->type==SOCK_DGRAM) {
n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, ZT_MAX_MTU);
DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] attempting write, RXBUF(%d)", conn->rxsz);
// Try to write SDK_MTU-sized chunk to app socket
while(tot < SDK_MTU) {
n = picotap->_phy.streamSend(conn->sock, (conn->rxbuf)+tot, SDK_MTU);
tot += n;
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] wrote = %d, total = %d", n, tot);
}
// DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int));
struct sockaddr_storage addr;
memcpy(&addr, conn->rxbuf, addr_sz_offset);
// adjust buffer
if(conn->rxsz-n > 0) // If more remains on buffer
memcpy(conn->rxbuf, conn->rxbuf+ZT_MAX_MTU, conn->rxsz - ZT_MAX_MTU);
conn->rxsz -= ZT_MAX_MTU;
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Copying data from receiving buffer to ZT-controlled app socket (n=%d, payload_sz=%d)", n, payload_sz);
if(conn->rxsz-n > 0) { // If more remains on buffer
memcpy(conn->rxbuf, conn->rxbuf+SDK_MTU, conn->rxsz - SDK_MTU);
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Data(%d) still on buffer, moving it up by one MTU", conn->rxsz-n);
////memset(conn->rxbuf, 0, DEFAULT_UDP_RX_BUF_SZ);
////conn->rxsz=SDK_MTU;
}
conn->rxsz -= SDK_MTU;
}
if(conn->type==SOCK_STREAM) {
n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, conn->rxsz);
DEBUG_EXTRA("SOCK_STREAM, conn=%p, physock=%p, n=%d", conn, sock, n);
if(conn->rxsz-n > 0) // If more remains on buffer
memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n);
conn->rxsz -= n;
}
if(n) {
if(conn->type==SOCK_STREAM) {
DEBUG_TRANS("[TCP RX] <--- :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
(float)conn->txsz / max, (float)conn->rxsz / max, conn->sock, n);
//DEBUG_TRANS("[TCP RX] <--- :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
// (float)conn->txsz / max, (float)conn->rxsz / max, conn->sock, n);
}
if(conn->rxsz == 0) {
picotap->_phy.setNotifyWritable(sock, false);
@@ -717,13 +765,12 @@ namespace ZeroTier {
picotap->_phy.setNotifyWritable(sock, false);
}
}
picotap->_phy.whack();
check_buffer_states(conn);
//picotap->_phy.whack();
if(!lwip_invoked) {
picotap->_tcpconns_m.unlock();
picotap->_rx_buf_m.unlock();
}
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Emitted (%d) from RXBUF(%d) to socket", tot, conn->rxsz);
}
// Closes a pico_socket

View File

@@ -265,31 +265,31 @@ namespace ZeroTier {
dlclose(_libref);
}
inline void __pico_stack_init(void) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); _pico_stack_init(); }
inline void __pico_stack_init(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); _pico_stack_init(); }
inline void __pico_stack_tick(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); _pico_stack_tick(); }
inline int __pico_ipv4_to_string(PICO_IPV4_TO_STRING_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_ipv4_to_string(ipbuf, ip); }
inline int __pico_ipv4_link_add(PICO_IPV4_LINK_ADD_SIG) throw() { DEBUG_STACK(); /*Mutex::Lock _l(_lock);*/ return _pico_ipv4_link_add(dev, address, netmask); }
inline int __pico_device_init(PICO_DEVICE_INIT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_device_init(dev, name, mac); }
inline int __pico_stack_recv(PICO_STACK_RECV_SIG) throw() { DEBUG_STACK(); /*Mutex::Lock _l(_lock);*/ return _pico_stack_recv(dev, buffer, len); }
inline int __pico_icmp4_ping(PICO_ICMP4_PING_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_icmp4_ping(dst, count, interval, timeout, size, cb); }
inline int __pico_string_to_ipv4(PICO_STRING_TO_IPV4_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_string_to_ipv4(ipstr, ip); }
inline int __pico_string_to_ipv6(PICO_STRING_TO_IPV6_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_string_to_ipv6(ipstr, ip); }
inline int __pico_socket_setoption(PICO_SOCKET_SETOPTION_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_setoption(s, option, value); }
inline uint32_t __pico_timer_add(PICO_TIMER_ADD_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_timer_add(expire, timer, arg); }
inline int __pico_ipv4_to_string(PICO_IPV4_TO_STRING_SIG) throw() {/* DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_ipv4_to_string(ipbuf, ip); }
inline int __pico_ipv4_link_add(PICO_IPV4_LINK_ADD_SIG) throw() { /*DEBUG_STACK();*/ /*Mutex::Lock _l(_lock);*/ return _pico_ipv4_link_add(dev, address, netmask); }
inline int __pico_device_init(PICO_DEVICE_INIT_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_device_init(dev, name, mac); }
inline int __pico_stack_recv(PICO_STACK_RECV_SIG) throw() { /*DEBUG_STACK();*/ /*Mutex::Lock _l(_lock);*/ return _pico_stack_recv(dev, buffer, len); }
inline int __pico_icmp4_ping(PICO_ICMP4_PING_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_icmp4_ping(dst, count, interval, timeout, size, cb); }
inline int __pico_string_to_ipv4(PICO_STRING_TO_IPV4_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_string_to_ipv4(ipstr, ip); }
inline int __pico_string_to_ipv6(PICO_STRING_TO_IPV6_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_string_to_ipv6(ipstr, ip); }
inline int __pico_socket_setoption(PICO_SOCKET_SETOPTION_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_socket_setoption(s, option, value); }
inline uint32_t __pico_timer_add(PICO_TIMER_ADD_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_timer_add(expire, timer, arg); }
inline int __pico_socket_send(PICO_SOCKET_SEND_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_socket_send(s, buf, len); }
inline int __pico_socket_sendto(PICO_SOCKET_SENDTO_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_socket_sendto(s, buf, len, dst, remote_port); }
inline int __pico_socket_recv(PICO_SOCKET_RECV_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_socket_recv(s, buf, len); }
inline int __pico_socket_recvfrom(PICO_SOCKET_RECVFROM_SIG) throw() { /*DEBUG_STACK();*/ /*Mutex::Lock _l(_lock);*/ return _pico_socket_recvfrom(s, buf, len, orig, remote_port); }
inline struct pico_socket * __pico_socket_open(PICO_SOCKET_OPEN_SIG) throw() { DEBUG_ATTN(); return _pico_socket_open(net, proto, wakeup); }
inline int __pico_socket_bind(PICO_SOCKET_BIND_SIG) throw() { DEBUG_ATTN(); Mutex::Lock _l(_lock); return _pico_socket_bind(s, local_addr, port); }
inline int __pico_socket_connect(PICO_SOCKET_CONNECT_SIG) throw() { DEBUG_ATTN(); Mutex::Lock _l(_lock); return _pico_socket_connect(s, srv_addr, remote_port); }
inline int __pico_socket_listen(PICO_SOCKET_LISTEN_SIG) throw() { DEBUG_ATTN(); Mutex::Lock _l(_lock); return _pico_socket_listen(s, backlog); }
inline struct pico_socket * __pico_socket_open(PICO_SOCKET_OPEN_SIG) throw() { /*DEBUG_ATTN();*/ return _pico_socket_open(net, proto, wakeup); }
inline int __pico_socket_bind(PICO_SOCKET_BIND_SIG) throw() { /*DEBUG_ATTN();*/ Mutex::Lock _l(_lock); return _pico_socket_bind(s, local_addr, port); }
inline int __pico_socket_connect(PICO_SOCKET_CONNECT_SIG) throw() { /*DEBUG_ATTN();*/ Mutex::Lock _l(_lock); return _pico_socket_connect(s, srv_addr, remote_port); }
inline int __pico_socket_listen(PICO_SOCKET_LISTEN_SIG) throw() { /*DEBUG_ATTN();*/ Mutex::Lock _l(_lock); return _pico_socket_listen(s, backlog); }
inline int __pico_socket_read(PICO_SOCKET_READ_SIG) throw() { /*DEBUG_STACK();*/ /*Mutex::Lock _l(_lock); */ return _pico_socket_read(s, buf, len); }
inline int __pico_socket_write(PICO_SOCKET_WRITE_SIG) throw() { /*DEBUG_STACK();*/ /*Mutex::Lock _l(_lock);*/ return _pico_socket_write(s, buf, len); }
inline int __pico_socket_close(PICO_SOCKET_CLOSE_SIG) throw() { DEBUG_STACK(); /*Mutex::Lock _l(_lock);*/ return _pico_socket_close(s); }
inline int __pico_socket_shutdown(PICO_SOCKET_SHUTDOWN_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_shutdown(s, mode); }
inline struct pico_socket * __pico_socket_accept(PICO_SOCKET_ACCEPT_SIG) throw() { DEBUG_ATTN(); /*Mutex::Lock _l(_lock);*/ return _pico_socket_accept(s, orig, port); }
inline int __pico_ipv6_link_add(PICO_IPV6_LINK_ADD_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_ipv6_link_add(dev, address, netmask); }
inline int __pico_socket_close(PICO_SOCKET_CLOSE_SIG) throw() { /*DEBUG_STACK();*/ /*Mutex::Lock _l(_lock);*/ return _pico_socket_close(s); }
inline int __pico_socket_shutdown(PICO_SOCKET_SHUTDOWN_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_socket_shutdown(s, mode); }
inline struct pico_socket * __pico_socket_accept(PICO_SOCKET_ACCEPT_SIG) throw() { /*DEBUG_ATTN();*/ /*Mutex::Lock _l(_lock);*/ return _pico_socket_accept(s, orig, port); }
inline int __pico_ipv6_link_add(PICO_IPV6_LINK_ADD_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _pico_ipv6_link_add(dev, address, netmask); }
};
} // namespace ZeroTier

View File

@@ -63,7 +63,7 @@ namespace ZeroTier {
int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno)
{
//#if !defined(USE_SOCKS_PROXY)
DEBUG_EXTRA("fd=%d, retval=%d, errno=%d", fd, retval, _errno);
//DEBUG_EXTRA("fd=%d, retval=%d, errno=%d", fd, retval, _errno);
int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
char retmsg[sz];
memset(&retmsg, 0, sizeof(retmsg));
@@ -328,7 +328,7 @@ void NetconEthernetTap::closeConnection(PhySocket *sock)
}
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) {
DEBUG_EXTRA("physock=%p", sock);
//DEBUG_EXTRA("physock=%p", sock);
Mutex::Lock _l(_tcpconns_m);
//closeConnection(sock);
}
@@ -359,7 +359,7 @@ void NetconEthernetTap::phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_
void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len)
{
DEBUG_EXTRA("physock=%p, len=%d", sock, (int)len);
//DEBUG_EXTRA("physock=%p, len=%d", sock, (int)len);
uint64_t CANARY_num;
pid_t pid, tid;
ssize_t wlen = len;
@@ -384,7 +384,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
// DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
if(cmd == RPC_SOCKET) {
DEBUG_INFO("RPC_SOCKET, physock=%p", sock);
//DEBUG_INFO("RPC_SOCKET, physock=%p", sock);
// Create new lwip socket and associate it with this sock
struct socket_st socket_rpc;
memcpy(&socket_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct socket_st));
@@ -478,31 +478,31 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
// DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
switch(cmd) {
case RPC_BIND:
DEBUG_INFO("RPC_BIND, physock=%p", sock);
//DEBUG_INFO("RPC_BIND, physock=%p", sock);
struct bind_st bind_rpc;
memcpy(&bind_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct bind_st));
handleBind(sock, rpcSock, uptr, &bind_rpc);
break;
case RPC_LISTEN:
DEBUG_INFO("RPC_LISTEN, physock=%p", sock);
//DEBUG_INFO("RPC_LISTEN, physock=%p", sock);
struct listen_st listen_rpc;
memcpy(&listen_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct listen_st));
handleListen(sock, rpcSock, uptr, &listen_rpc);
break;
case RPC_GETSOCKNAME:
DEBUG_INFO("RPC_GETSOCKNAME, physock=%p", sock);
//DEBUG_INFO("RPC_GETSOCKNAME, physock=%p", sock);
struct getsockname_st getsockname_rpc;
memcpy(&getsockname_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st));
handleGetsockname(sock, rpcSock, uptr, &getsockname_rpc);
break;
case RPC_GETPEERNAME:
DEBUG_INFO("RPC_GETPEERNAME, physock=%p", sock);
//DEBUG_INFO("RPC_GETPEERNAME, physock=%p", sock);
struct getsockname_st getpeername_rpc;
memcpy(&getpeername_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st));
handleGetpeername(sock, rpcSock, uptr, &getpeername_rpc);
break;
case RPC_CONNECT:
DEBUG_INFO("RPC_CONNECT, physock=%p", sock);
//DEBUG_INFO("RPC_CONNECT, physock=%p", sock);
struct connect_st connect_rpc;
memcpy(&connect_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct connect_st));
handleConnect(sock, rpcSock, conn, &connect_rpc);
@@ -574,7 +574,7 @@ int NetconEthernetTap::handleConnectProxy(PhySocket *sock, struct sockaddr_in *r
// Connect a stack's PCB/socket/Connection object to a remote host
void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
{
DEBUG_ATTN("physock=%p", sock);
//DEBUG_ATTN("physock=%p", sock);
Mutex::Lock _l(_tcpconns_m);
#if defined(SDK_PICOTCP)
pico_handleConnect(sock, rpcSock, conn, connect_rpc);

View File

@@ -1,48 +0,0 @@
// UDP Client test program (IPV6)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <cstdlib>
#include "sdk.h"
#define MAXBUF 65536
int main(int argc, char* argv[])
{
int status;
struct addrinfo sainfo, *psinfo;
struct hostent *server;
char buffer[MAXBUF];
int sock, portno, n;
struct sockaddr_in6 serv_addr;
if(argc < 2)
printf("Specify a port number\n"), exit(1);
sock = socket(PF_INET6, SOCK_DGRAM,0);
portno = atoi(argv[2]);
server = gethostbyname2(argv[1],AF_INET6);
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin6_flowinfo = 0;
serv_addr.sin6_family = AF_INET6;
memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
serv_addr.sin6_port = htons(portno);
sprintf(buffer,"Ciao");
status = sendto(sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
printf("buffer : %s \t%d\n", buffer, status);
close(sock);
return 0;
}

View File

@@ -1,55 +0,0 @@
// UDP Server test program (IPV6)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include "sdk.h"
#define MAXBUF 65536
int main(int argc, char *argv[])
{
if(argc < 3) {
printf("usage: client <port> <netpath> <nwid>\n");
return 1;
}
zts_init_rpc(argv[2],argv[3]);
int sock;
int n;
struct sockaddr_in6 sin6;
socklen_t sin6len;
char buffer[MAXBUF];
sock = socket(PF_INET6, SOCK_DGRAM,0);
sin6len = sizeof(struct sockaddr_in6);
memset(&sin6, 0, sin6len);
sin6.sin6_port = htons(atoi(argv[1]));
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = in6addr_any;
n = bind(sock, (struct sockaddr *)&sin6, sin6len);
if(-1 == n)
perror("bind"), exit(1);
//n = getsockname(sock, (struct sockaddr *)&sin6, &sin6len);
//printf("%d\n", ntohs(sin6.sin6_port));
while (1) {
sleep(1);
n = recvfrom(sock, buffer, MAXBUF, 0, (struct sockaddr *)&sin6, &sin6len);
printf("n = %d, buffer : %s\n", n, buffer);
}
shutdown(sock, 2);
close(sock);
return 0;
}

View File

@@ -4,8 +4,8 @@
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstdlib>
#include "sdk.h"
int atoi(const char *str);
@@ -19,6 +19,12 @@ int main(int argc , char *argv[])
printf("usage: client <addr> <port> <netpath> <nwid>\n");
return 1;
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[3],argv[4]);
int sock, port = atoi(argv[2]);

View File

@@ -4,13 +4,12 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <cstdlib>
#include "sdk.h"
void error(char *msg) {
@@ -25,9 +24,17 @@ int main(int argc, char *argv[]) {
char buffer[256] = "This is a string from client!";
if(argc < 3) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(0);
printf("usage: client <addr> <port> <netpath> <nwid>\n");
return 1;
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[3],argv[4]);
portno = atoi(argv[2]);
printf("\nIPv6 TCP Client Started...\n");

View File

@@ -4,8 +4,8 @@
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstdlib>
#include "sdk.h"
int atoi(const char *str);
@@ -13,9 +13,15 @@ int atoi(const char *str);
int main(int argc , char *argv[])
{
if(argc < 3) {
printf("usage: client <port> <netpath> <nwid>\n");
printf("usage: server <port> <netpath> <nwid>\n");
return 1;
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[2],argv[3]);
int sock, client_sock, c, read_size, port = atoi(argv[1]);

View File

@@ -29,9 +29,15 @@ int main(int argc, char *argv[]) {
char client_addr_ipv6[100];
if(argc < 3) {
printf("usage: client <port> <netpath> <nwid>\n");
printf("usage: server <port> <netpath> <nwid>\n");
return 1;
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[2],argv[3]);
printf("\nIPv6 TCP Server Started...\n");

View File

@@ -9,15 +9,12 @@
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <cstdlib>
#include "sdk.h"
#define BUFSIZE 1024
/*
* error - wrapper for perror
*/
void error(char *msg) {
perror(msg);
exit(0);
@@ -36,6 +33,14 @@ int main(int argc, char **argv) {
fprintf(stderr,"usage: %s <hostname> <port>\n", argv[0]);
exit(0);
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[3],argv[4]);
hostname = argv[1];
portno = atoi(argv[2]);
@@ -80,7 +85,7 @@ int main(int argc, char **argv) {
/* print the server's reply */
memset(buf, 0, sizeof(buf));
n = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *)&serveraddr, (socklen_t *)&serverlen);
n = zts_recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *)&serveraddr, (socklen_t *)&serverlen);
//if (n < 0)
// printf("ERROR in recvfrom: %d", n);
printf("Echo from server: %s", buf);

65
tests/zts/zts.udpclient6.c Executable file
View File

@@ -0,0 +1,65 @@
// UDP Client test program (IPV6)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <cstdlib>
#include <fcntl.h>
#include "sdk.h"
#define MAXBUF 65536
#define TESTBUF 1024
int main(int argc, char* argv[])
{
int status, sock, portno, n;
struct addrinfo sainfo, *psinfo;
struct hostent *server;
char buffer[MAXBUF];
struct sockaddr_in6 serv_addr;
if(argc < 3) {
printf("usage: client <addr> <port> <netpath> <nwid>\n");
return 1;
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[3],argv[4]);
sock = zts_socket(AF_INET6, SOCK_DGRAM,0);
portno = atoi(argv[2]);
server = gethostbyname2(argv[1],AF_INET6);
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin6_flowinfo = 0;
serv_addr.sin6_family = AF_INET6;
memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
serv_addr.sin6_port = htons(portno);
sprintf(buffer,"Welcome to the machine");
//memset(buffer, 1, TESTBUF);
fcntl(sock, F_SETFL, O_NONBLOCK);
while(1)
{
//usleep(50000);
status = zts_sendto(sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
if(status > 0)
printf("sendto() : %s \t%d\n", buffer, status);
}
close(sock);
zts_stop(); /* Shut down ZT */
return 0;
}

View File

@@ -8,8 +8,8 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cstdlib>
#include "sdk.h"
#define MAXBUF 1024*1024
@@ -23,30 +23,32 @@ void echo(int sock) {
while(1) {
sleep(1);
//usleep(50);
count++;
// read a datagram from the socket (put result in bufin)
n=recvfrom(sock,bufin,MAXBUF,0,(struct sockaddr *)&remote,&len);
// read a datagram from the socket
n=zts_recvfrom(sock,bufin,MAXBUF,0,(struct sockaddr *)&remote,&len);
// print out the address of the sender
printf("DGRAM from %s:%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
if (n<0) {
perror("Error receiving data");
} else {
printf("GOT %d BYTES (count = %ld)\n", n, count);
// Got something, just send it back
// sendto(sock,bufin,n,0,(struct sockaddr *)&remote,len);
printf("RX = %s\n", bufin);
printf("RX (%d bytes) = %s\n", n, bufin);
}
}
}
int main(int argc, char *argv[]) {
if(argc < 3) {
printf("usage: client <port> <netpath> <nwid>\n");
return 1;
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[2],argv[3]);
int sock, port = atoi(argv[1]);
@@ -55,7 +57,7 @@ int main(int argc, char *argv[]) {
struct sockaddr_in skaddr2;
// Create socket
if ((sock = socket( PF_INET, SOCK_DGRAM, 0)) < 0) {
if ((sock = zts_socket( PF_INET, SOCK_DGRAM, 0)) < 0) {
printf("error creating socket\n");
return 0;
}
@@ -64,28 +66,14 @@ int main(int argc, char *argv[]) {
skaddr.sin_addr.s_addr = htonl(INADDR_ANY);
skaddr.sin_port = htons(port);
// Bind to address
if (bind(sock, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) {
if (zts_bind(sock, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) {
printf("error binding\n");
return 0;
}
// find out what port we were assigned
len = sizeof( skaddr2 );
//if (getsockname(sock, (struct sockaddr *) &skaddr2, &len)<0) {
// printf("error getsockname\n");
// return 0;
//}
// Display address:port to verify it was sent over RPC correctly
/*
port = ntohs(skaddr2.sin_port);
int ip = skaddr2.sin_addr.s_addr;
unsigned char d[4];
d[0] = ip & 0xFF;
d[1] = (ip >> 8) & 0xFF;
d[2] = (ip >> 16) & 0xFF;
d[3] = (ip >> 24) & 0xFF;
printf("bound to address: %d.%d.%d.%d : %d\n", d[0],d[1],d[2],d[3], port);
*/
// RX
echo(sock);
return(0);
return 0;
}

68
tests/zts/zts.udpserver6.c Executable file
View File

@@ -0,0 +1,68 @@
// UDP Server test program (IPV6)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include <arpa/inet.h>
#include <fcntl.h>
#include "sdk.h"
#define MAXBUF 128
int main(int argc, char *argv[])
{
if(argc < 3) {
printf("usage: server <port> <netpath> <nwid>\n");
return 1;
}
/* Starts ZeroTier core service in separate thread, loads user-space TCP/IP stack
and sets up a private AF_UNIX socket between ZeroTier library and your app. Any
subsequent zts_* socket API calls (shown below) are mediated over this hidden AF_UNIX
socket and are spoofed to appear as AF_INET sockets. The implementation of this API
is in src/sockets.c */
zts_init_rpc(argv[2],argv[3]);
int sock, n;
struct sockaddr_in6 sin6;
socklen_t sin6len;
char buffer[MAXBUF];
memset(buffer, 0, MAXBUF);
sock = zts_socket(PF_INET6, SOCK_DGRAM,0);
sin6len = sizeof(struct sockaddr_in6);
memset(&sin6, 0, sin6len);
sin6.sin6_port = htons(atoi(argv[1]));
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = in6addr_any;
n = zts_bind(sock, (struct sockaddr *)&sin6, sin6len);
if(-1 == n)
perror("bind"), exit(1);
//n = getsockname(sock, (struct sockaddr *)&sin6, &sin6len);
//printf("%d\n", ntohs(sin6.sin6_port));
//fcntl(sock, F_SETFL, O_NONBLOCK);
while (1) {
//usleep(50000);
n = zts_recvfrom(sock, buffer, MAXBUF, 0, (struct sockaddr *)&sin6, &sin6len);
//if(n > 0)
printf("recvfrom(): n = %d, buffer : %s\n", n, buffer);
}
shutdown(sock, 2);
close(sock);
zts_stop(); /* Shut down ZT */
return 0;
}

View File

@@ -1 +0,0 @@
'\" -*- coding: utf-8 -*-

View File

@@ -1,26 +0,0 @@
Copyright (C) 2012, 2013 James McLaughlin et al. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

File diff suppressed because it is too large Load Diff

View File

@@ -1,283 +0,0 @@
/* vim: set et ts=3 sw=3 sts=3 ft=c:
*
* Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved.
* https://github.com/udp/json-parser
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _JSON_H
#define _JSON_H
#ifndef json_char
#define json_char char
#endif
#ifndef json_int_t
#ifndef _MSC_VER
#include <inttypes.h>
#define json_int_t int64_t
#else
#define json_int_t __int64
#endif
#endif
#include <stdlib.h>
#ifdef __cplusplus
#include <string.h>
extern "C"
{
#endif
typedef struct
{
unsigned long max_memory;
int settings;
/* Custom allocator support (leave null to use malloc/free)
*/
void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);
void * user_data; /* will be passed to mem_alloc and mem_free */
size_t value_extra; /* how much extra space to allocate for values? */
} json_settings;
#define json_enable_comments 0x01
typedef enum
{
json_none,
json_object,
json_array,
json_integer,
json_double,
json_string,
json_boolean,
json_null
} json_type;
extern const struct _json_value json_value_none;
typedef struct _json_object_entry
{
json_char * name;
unsigned int name_length;
struct _json_value * value;
} json_object_entry;
typedef struct _json_value
{
struct _json_value * parent;
json_type type;
union
{
int boolean;
json_int_t integer;
double dbl;
struct
{
unsigned int length;
json_char * ptr; /* null terminated */
} string;
struct
{
unsigned int length;
json_object_entry * values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} object;
struct
{
unsigned int length;
struct _json_value ** values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} array;
} u;
union
{
struct _json_value * next_alloc;
void * object_mem;
} _reserved;
#ifdef JSON_TRACK_SOURCE
/* Location of the value in the source JSON
*/
unsigned int line, col;
#endif
/* Some C++ operator sugar */
#ifdef __cplusplus
public:
inline _json_value ()
{ memset (this, 0, sizeof (_json_value));
}
inline const struct _json_value &operator [] (int index) const
{
if (type != json_array || index < 0
|| ((unsigned int) index) >= u.array.length)
{
return json_value_none;
}
return *u.array.values [index];
}
inline const struct _json_value &operator [] (const char * index) const
{
if (type != json_object)
return json_value_none;
for (unsigned int i = 0; i < u.object.length; ++ i)
if (!strcmp (u.object.values [i].name, index))
return *u.object.values [i].value;
return json_value_none;
}
inline operator const char * () const
{
switch (type)
{
case json_string:
return u.string.ptr;
default:
return "";
};
}
inline operator json_int_t () const
{
switch (type)
{
case json_integer:
return u.integer;
case json_double:
return (json_int_t) u.dbl;
default:
return 0;
};
}
inline operator bool () const
{
if (type != json_boolean)
return false;
return u.boolean != 0;
}
inline operator double () const
{
switch (type)
{
case json_integer:
return (double) u.integer;
case json_double:
return u.dbl;
default:
return 0;
};
}
#endif
} json_value;
json_value * json_parse (const json_char * json,
size_t length);
#define json_error_max 128
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error);
void json_value_free (json_value *);
/* Not usually necessary, unless you used a custom mem_alloc and now want to
* use a custom mem_free.
*/
void json_value_free_ex (json_settings * settings,
json_value *);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,360 +0,0 @@
/*
LZ4 - Fast LZ compression algorithm
Header File
Copyright (C) 2011-2015, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/
#pragma once
#if defined (__cplusplus)
extern "C" {
#endif
/*
* lz4.h provides block compression functions, and gives full buffer control to programmer.
* If you need to generate inter-operable compressed data (respecting LZ4 frame specification),
* and can let the library handle its own memory, please use lz4frame.h instead.
*/
/**************************************
* Version
**************************************/
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
int LZ4_versionNumber (void);
/**************************************
* Tuning parameter
**************************************/
/*
* LZ4_MEMORY_USAGE :
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
* Increasing memory usage improves compression ratio
* Reduced memory usage can improve speed, due to cache effect
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
*/
#define LZ4_MEMORY_USAGE 14
/**************************************
* Simple Functions
**************************************/
int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
/*
LZ4_compress_default() :
Compresses 'sourceSize' bytes from buffer 'source'
into already allocated 'dest' buffer of size 'maxDestSize'.
Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
It also runs faster, so it's a recommended setting.
If the function cannot compress 'source' into a more limited 'dest' budget,
compression stops *immediately*, and the function result is zero.
As a consequence, 'dest' content is not valid.
This function never writes outside 'dest' buffer, nor read outside 'source' buffer.
sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
maxDestSize : full or partial size of buffer 'dest' (which must be already allocated)
return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
or 0 if compression fails
LZ4_decompress_safe() :
compressedSize : is the precise full size of the compressed block.
maxDecompressedSize : is the size of destination buffer, which must be already allocated.
return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
If destination buffer is not large enough, decoding will stop and output an error code (<0).
If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function is protected against buffer overflow exploits, including malicious data packets.
It never writes outside output buffer, nor reads outside input buffer.
*/
/**************************************
* Advanced Functions
**************************************/
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
/*
LZ4_compressBound() :
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
This function is primarily useful for memory allocation purposes (destination buffer size).
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize)
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
return : maximum output size in a "worst case" scenario
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
*/
int LZ4_compressBound(int inputSize);
/*
LZ4_compress_fast() :
Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
An acceleration value of "1" is the same as regular LZ4_compress_default()
Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
*/
int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
/*
LZ4_compress_fast_extState() :
Same compression function, just using an externally allocated memory space to store compression state.
Use LZ4_sizeofState() to know how much memory must be allocated,
and allocate it on 8-bytes boundaries (using malloc() typically).
Then, provide it as 'void* state' to compression function.
*/
int LZ4_sizeofState(void);
int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
/*
LZ4_compress_destSize() :
Reverse the logic, by compressing as much data as possible from 'source' buffer
into already allocated buffer 'dest' of size 'targetDestSize'.
This function either compresses the entire 'source' content into 'dest' if it's large enough,
or fill 'dest' buffer completely with as much data as possible from 'source'.
*sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'.
New value is necessarily <= old value.
return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
or 0 if compression fails
*/
int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize);
/*
LZ4_decompress_fast() :
originalSize : is the original and therefore uncompressed size
return : the number of bytes read from the source buffer (in other words, the compressed size)
If the source stream is detected malformed, the function will stop decoding and return a negative result.
Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
note : This function fully respect memory boundaries for properly formed compressed data.
It is a bit faster than LZ4_decompress_safe().
However, it does not provide any protection against intentionally modified data stream (malicious input).
Use this function in trusted environment only (data to decode comes from a trusted source).
*/
int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
/*
LZ4_decompress_safe_partial() :
This function decompress a compressed block of size 'compressedSize' at position 'source'
into destination buffer 'dest' of size 'maxDecompressedSize'.
The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
reducing decompression time.
return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize)
Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
Always control how many bytes were decoded.
If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
*/
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
/***********************************************
* Streaming Compression Functions
***********************************************/
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
/*
* LZ4_stream_t
* information structure to track an LZ4 stream.
* important : init this structure content before first use !
* note : only allocated directly the structure if you are statically linking LZ4
* If you are using liblz4 as a DLL, please use below construction methods instead.
*/
typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
/*
* LZ4_resetStream
* Use this function to init an allocated LZ4_stream_t structure
*/
void LZ4_resetStream (LZ4_stream_t* streamPtr);
/*
* LZ4_createStream will allocate and initialize an LZ4_stream_t structure
* LZ4_freeStream releases its memory.
* In the context of a DLL (liblz4), please use these methods rather than the static struct.
* They are more future proof, in case of a change of LZ4_stream_t size.
*/
LZ4_stream_t* LZ4_createStream(void);
int LZ4_freeStream (LZ4_stream_t* streamPtr);
/*
* LZ4_loadDict
* Use this function to load a static dictionary into LZ4_stream.
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
* Loading a size of 0 is allowed.
* Return : dictionary size, in bytes (necessarily <= 64 KB)
*/
int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
/*
* LZ4_compress_fast_continue
* Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio.
* Important : Previous data blocks are assumed to still be present and unmodified !
* 'dst' buffer must be already allocated.
* If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
* If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
*/
int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration);
/*
* LZ4_saveDict
* If previously compressed data block is not guaranteed to remain available at its memory location
* save it into a safer place (char* safeBuffer)
* Note : you don't need to call LZ4_loadDict() afterwards,
* dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue()
* Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error
*/
int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
/************************************************
* Streaming Decompression Functions
************************************************/
#define LZ4_STREAMDECODESIZE_U64 4
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t;
/*
* LZ4_streamDecode_t
* information structure to track an LZ4 stream.
* init this structure content using LZ4_setStreamDecode or memset() before first use !
*
* In the context of a DLL (liblz4) please prefer usage of construction methods below.
* They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
* LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
* LZ4_freeStreamDecode releases its memory.
*/
LZ4_streamDecode_t* LZ4_createStreamDecode(void);
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
/*
* LZ4_setStreamDecode
* Use this function to instruct where to find the dictionary.
* Setting a size of 0 is allowed (same effect as reset).
* Return : 1 if OK, 0 if error
*/
int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
/*
*_continue() :
These decoding functions allow decompression of multiple blocks in "streaming" mode.
Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
In the case of a ring buffers, decoding buffer must be either :
- Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
- Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block.
In which case, encoding and decoding buffers do not need to be synchronized,
and encoding ring buffer can have any size, including small ones ( < 64 KB).
- _At least_ 64 KB + 8 bytes + maxBlockSize.
In which case, encoding and decoding buffers do not need to be synchronized,
and encoding ring buffer can have any size, including larger than decoding buffer.
Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
and indicate where it is saved using LZ4_setStreamDecode()
*/
int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
/*
Advanced decoding functions :
*_usingDict() :
These decoding functions work the same as
a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue()
They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure.
*/
int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
/**************************************
* Obsolete Functions
**************************************/
/* Deprecate Warnings */
/* Should these warnings messages be a problem,
it is generally possible to disable them,
with -Wno-deprecated-declarations for gcc
or _CRT_SECURE_NO_WARNINGS in Visual for example.
You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
# define LZ4_DEPRECATE_WARNING_DEFBLOCK
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
# if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
# elif (LZ4_GCC_VERSION >= 301)
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
# elif defined(_MSC_VER)
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
# else
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
# define LZ4_DEPRECATED(message)
# endif
#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */
/* Obsolete compression functions */
/* These functions are planned to start generate warnings by r131 approximately */
int LZ4_compress (const char* source, char* dest, int sourceSize);
int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
/* Obsolete decompression functions */
/* These function names are completely deprecated and must no longer be used.
They are only provided here for compatibility with older programs.
- LZ4_uncompress is the same as LZ4_decompress_fast
- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
These function prototypes are now disabled; uncomment them only if you really need them.
It is highly recommended to stop using these prototypes and migrate to maintained ones */
/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */
/* Obsolete streaming functions; use new streaming interface whenever possible */
LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer);
LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void);
LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer);
LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state);
/* Obsolete streaming decoding functions */
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
#if defined (__cplusplus)
}
#endif

View File

@@ -1,65 +0,0 @@
CC=cc
CXX=c++
INCLUDES=
DEFS=
LIBS=
include objects.mk
OBJS+=osdep/BSDEthernetTap.o ext/lz4/lz4.o ext/json-parser/json.o ext/http-parser/http_parser.o
# "make official" is a shortcut for this
ifeq ($(ZT_OFFICIAL_RELEASE),1)
DEFS+=-DZT_OFFICIAL_RELEASE
endif
# Build with ZT_ENABLE_CLUSTER=1 to build with cluster support
ifeq ($(ZT_ENABLE_CLUSTER),1)
DEFS+=-DZT_ENABLE_CLUSTER
endif
# "make debug" is a shortcut for this
ifeq ($(ZT_DEBUG),1)
DEFS+=-DZT_TRACE
CFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
LDFLAGS+=
STRIP=echo
# The following line enables optimization for the crypto code, since
# C25519 in particular is almost UNUSABLE in heavy testing without it.
ext/lz4/lz4.o node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g -pthread $(INCLUDES) $(DEFS)
else
CFLAGS?=-O3 -fstack-protector
CFLAGS+=-Wall -fPIE -fvisibility=hidden -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS)
LDFLAGS+=-pie -Wl,-z,relro,-z,now
STRIP=strip --strip-all
endif
CXXFLAGS+=$(CFLAGS) -fno-rtti
all: one
one: $(OBJS) service/OneService.o one.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o $(LIBS)
$(STRIP) zerotier-one
ln -sf zerotier-one zerotier-idtool
ln -sf zerotier-one zerotier-cli
selftest: $(OBJS) selftest.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
$(STRIP) zerotier-selftest
# No installer on FreeBSD yet
#installer: one FORCE
# ./buildinstaller.sh
clean:
rm -rf *.o node/*.o controller/*.o osdep/*.o service/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o build-* zerotier-one zerotier-idtool zerotier-selftest zerotier-cli ZeroTierOneInstaller-*
debug: FORCE
make -j 4 ZT_DEBUG=1
#official: FORCE
# make -j 4 ZT_OFFICIAL_RELEASE=1
# ./buildinstaller.sh
FORCE:

View File

@@ -1,114 +0,0 @@
ifeq ($(origin CC),default)
CC=$(shell if [ -e /usr/bin/clang ]; then echo clang; else echo gcc; fi)
endif
ifeq ($(origin CXX),default)
CXX=$(shell if [ -e /usr/bin/clang++ ]; then echo clang++; else echo g++; fi)
endif
INCLUDES=
DEFS=
LIBS=
ARCH_FLAGS=-arch x86_64
include objects.mk
OBJS+=osdep/OSXEthernetTap.o ext/lz4/lz4.o ext/json-parser/json.o ext/http-parser/http_parser.o
# Disable codesign since open source users will not have ZeroTier's certs
CODESIGN=echo
PRODUCTSIGN=echo
CODESIGN_APP_CERT=
CODESIGN_INSTALLER_CERT=
# Build with libminiupnpc by default for Mac -- desktops/laptops almost always want this
ZT_USE_MINIUPNPC?=1
# For internal use only -- signs everything with ZeroTier's developer cert
ifeq ($(ZT_OFFICIAL_RELEASE),1)
DEFS+=-DZT_OFFICIAL_RELEASE -DZT_AUTO_UPDATE
ZT_USE_MINIUPNPC=1
CODESIGN=codesign
PRODUCTSIGN=productsign
CODESIGN_APP_CERT="Developer ID Application: ZeroTier Networks LLC (8ZD9JUCZ4V)"
CODESIGN_INSTALLER_CERT="Developer ID Installer: ZeroTier Networks LLC (8ZD9JUCZ4V)"
endif
ifeq ($(ZT_ENABLE_CLUSTER),1)
DEFS+=-DZT_ENABLE_CLUSTER
endif
ifeq ($(ZT_AUTO_UPDATE),1)
DEFS+=-DZT_AUTO_UPDATE
endif
ifeq ($(ZT_USE_MINIUPNPC),1)
DEFS+=-DMACOSX -DZT_USE_MINIUPNPC -DMINIUPNP_STATICLIB -D_DARWIN_C_SOURCE -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR -D_BSD_SOURCE -D_DEFAULT_SOURCE -DOS_STRING=\"Darwin/15.0.0\" -DMINIUPNPC_VERSION_STRING=\"2.0\" -DUPNP_VERSION_STRING=\"UPnP/1.1\" -DENABLE_STRNATPMPERR
OBJS+=ext/libnatpmp/natpmp.o ext/libnatpmp/getgateway.o ext/miniupnpc/connecthostport.o ext/miniupnpc/igd_desc_parse.o ext/miniupnpc/minisoap.o ext/miniupnpc/minissdpc.o ext/miniupnpc/miniupnpc.o ext/miniupnpc/miniwget.o ext/miniupnpc/minixml.o ext/miniupnpc/portlistingparse.o ext/miniupnpc/receivedata.o ext/miniupnpc/upnpcommands.o ext/miniupnpc/upnpdev.o ext/miniupnpc/upnperrors.o ext/miniupnpc/upnpreplyparse.o osdep/PortMapper.o
endif
ifeq ($(ZT_ENABLE_NETWORK_CONTROLLER),1)
DEFS+=-DZT_ENABLE_NETWORK_CONTROLLER
LIBS+=-L/usr/local/lib -lsqlite3
OBJS+=controller/SqliteNetworkController.o
endif
# Debug mode -- dump trace output, build binary with -g
ifeq ($(ZT_DEBUG),1)
DEFS+=-DZT_TRACE
CFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
STRIP=echo
# The following line enables optimization for the crypto code, since
# C25519 in particular is almost UNUSABLE in heavy testing without it.
ext/lz4/lz4.o node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g -pthread $(INCLUDES) $(DEFS)
else
CFLAGS?=-Ofast -fstack-protector-strong
CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -pthread -mmacosx-version-min=10.7 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS)
STRIP=strip
endif
CXXFLAGS=$(CFLAGS) -fno-rtti
all: one
one: $(OBJS) service/OneService.o one.o
$(CXX) $(CXXFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o $(LIBS)
$(STRIP) zerotier-one
ln -sf zerotier-one zerotier-idtool
ln -sf zerotier-one zerotier-cli
$(CODESIGN) -f -s $(CODESIGN_APP_CERT) zerotier-one
$(CODESIGN) -vvv zerotier-one
cli: FORCE
$(CXX) -Os -mmacosx-version-min=10.7 -std=c++11 -stdlib=libc++ -o zerotier cli/zerotier.cpp osdep/OSUtils.cpp node/InetAddress.cpp node/Utils.cpp node/Salsa20.cpp node/Identity.cpp node/SHA512.cpp node/C25519.cpp -lcurl
$(STRIP) zerotier
selftest: $(OBJS) selftest.o
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
$(STRIP) zerotier-selftest
# Requires Packages: http://s.sudre.free.fr/Software/Packages/about.html
mac-dist-pkg: FORCE
packagesbuild "ext/installfiles/mac/ZeroTier One.pkgproj"
rm -f "ZeroTier One Signed.pkg"
$(PRODUCTSIGN) --sign $(CODESIGN_INSTALLER_CERT) "ZeroTier One.pkg" "ZeroTier One Signed.pkg"
if [ -f "ZeroTier One Signed.pkg" ]; then mv -f "ZeroTier One Signed.pkg" "ZeroTier One.pkg"; fi
# For ZeroTier, Inc. to build official signed packages
official: FORCE
make clean
make ZT_OFFICIAL_RELEASE=1 -j 4 one
make ZT_OFFICIAL_RELEASE=1 mac-dist-pkg
clean:
rm -rf *.dSYM build-* *.pkg *.dmg *.o node/*.o controller/*.o service/*.o osdep/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o $(OBJS) zerotier-one zerotier-idtool zerotier-selftest zerotier-cli zerotier ZeroTierOneInstaller-* mkworld doc/node_modules
distclean: clean
rm -rf doc/node_modules
# For those building from source -- installs signed binary tap driver in system ZT home
install-mac-tap: FORCE
mkdir -p /Library/Application\ Support/ZeroTier/One
rm -rf /Library/Application\ Support/ZeroTier/One/tap.kext
cp -R ext/bin/tap-mac/tap.kext /Library/Application\ Support/ZeroTier/One
chown -R root:wheel /Library/Application\ Support/ZeroTier/One/tap.kext
FORCE:

View File

@@ -1,97 +0,0 @@
/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
*
* 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/>.
*/
#ifndef ZT_BINARYSEMAPHORE_HPP
#define ZT_BINARYSEMAPHORE_HPP
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "Constants.hpp"
#include "NonCopyable.hpp"
#ifdef __WINDOWS__
#include <Windows.h>
namespace ZeroTier {
class BinarySemaphore : NonCopyable
{
public:
BinarySemaphore() throw() { _sem = CreateSemaphore(NULL,0,1,NULL); }
~BinarySemaphore() { CloseHandle(_sem); }
inline void wait() { WaitForSingleObject(_sem,INFINITE); }
inline void post() { ReleaseSemaphore(_sem,1,NULL); }
private:
HANDLE _sem;
};
} // namespace ZeroTier
#else // !__WINDOWS__
#include <pthread.h>
namespace ZeroTier {
class BinarySemaphore : NonCopyable
{
public:
BinarySemaphore()
{
pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0);
pthread_cond_init(&_cond,(const pthread_condattr_t *)0);
_f = false;
}
~BinarySemaphore()
{
pthread_cond_destroy(&_cond);
pthread_mutex_destroy(&_mh);
}
inline void wait()
{
pthread_mutex_lock(const_cast <pthread_mutex_t *>(&_mh));
while (!_f)
pthread_cond_wait(const_cast <pthread_cond_t *>(&_cond),const_cast <pthread_mutex_t *>(&_mh));
_f = false;
pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh));
}
inline void post()
{
pthread_mutex_lock(const_cast <pthread_mutex_t *>(&_mh));
_f = true;
pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh));
pthread_cond_signal(const_cast <pthread_cond_t *>(&_cond));
}
private:
pthread_cond_t _cond;
pthread_mutex_t _mh;
volatile bool _f;
};
} // namespace ZeroTier
#endif // !__WINDOWS__
#endif

Some files were not shown because too many files have changed in this diff Show More