merging recent upgrades into master
This commit is contained in:
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
BUILD=build
|
BUILD=build
|
||||||
INT=integrations
|
INT=integrations
|
||||||
ZT1=zerotierone
|
ZT1=zto
|
||||||
|
|
||||||
OSTYPE=$(shell uname -s)
|
OSTYPE=$(shell uname -s)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ ZeroTier SDK
|
|||||||
|
|
||||||
ZeroTier-enabled apps, devices, and services.
|
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.
|
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:
|
The general idea is this:
|
||||||
|
|||||||
@@ -922,7 +922,7 @@ igmp3_report:
|
|||||||
record->sources = short_be(sources);
|
record->sources = short_be(sources);
|
||||||
record->mcast_group = p->mcast_group.addr;
|
record->mcast_group = p->mcast_group.addr;
|
||||||
if (IGMPFilter && !pico_tree_empty(IGMPFilter)) {
|
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;
|
i = 0;
|
||||||
pico_tree_foreach(index, IGMPFilter)
|
pico_tree_foreach(index, IGMPFilter)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ static struct pico_frame *pico_frame_do_alloc(uint32_t size, int zerocopy, int e
|
|||||||
return NULL;
|
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 {
|
} else {
|
||||||
p->buffer = NULL;
|
p->buffer = NULL;
|
||||||
p->flags |= PICO_FRAME_FLAG_EXT_USAGE_COUNTER;
|
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;
|
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->usage_count = usage_count;
|
||||||
f->buffer_len = size;
|
f->buffer_len = size;
|
||||||
memcpy(f->buffer, oldbuf, oldsize);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
stop = (uint16_t *)(((uint8_t *)data) + len);
|
stop = (uint16_t *)((void *)(((uint8_t *)data) + len));
|
||||||
|
|
||||||
while (buf < stop) {
|
while (buf < stop) {
|
||||||
sum += *buf++;
|
sum += *buf++;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ LOCAL_C_INCLUDES := $(LWIP)/include
|
|||||||
LOCAL_C_INCLUDES += $(LWIP)/include/lwip
|
LOCAL_C_INCLUDES += $(LWIP)/include/lwip
|
||||||
LOCAL_C_INCLUDES += $(LWIP)/include/lwip/priv
|
LOCAL_C_INCLUDES += $(LWIP)/include/lwip/priv
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES += $(ZTSDK)
|
||||||
LOCAL_C_INCLUDES += $(ZTSDK)/src
|
LOCAL_C_INCLUDES += $(ZTSDK)/src
|
||||||
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers/lwip
|
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers/lwip
|
||||||
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers
|
LOCAL_C_INCLUDES += $(ZTSDK)/src/stack_drivers
|
||||||
@@ -100,7 +101,6 @@ LOCAL_SRC_FILES += $(LWIP)/core/ipv4/autoip.c \
|
|||||||
# $(LWIP)/core/ipv6/mld6.c \
|
# $(LWIP)/core/ipv6/mld6.c \
|
||||||
# $(LWIP)/core/ipv6/nd6.c
|
# $(LWIP)/core/ipv6/nd6.c
|
||||||
|
|
||||||
|
|
||||||
# lwIP netif files
|
# lwIP netif files
|
||||||
LOCAL_SRC_FILES += \
|
LOCAL_SRC_FILES += \
|
||||||
$(LWIP)/netif/ethernetif.c \
|
$(LWIP)/netif/ethernetif.c \
|
||||||
@@ -115,10 +115,4 @@ LOCAL_SRC_FILES += \
|
|||||||
$(ZTSDK)/src/tap.cpp \
|
$(ZTSDK)/src/tap.cpp \
|
||||||
$(ZTSDK)/src/stack_drivers/lwip/lwip.cpp
|
$(ZTSDK)/src/stack_drivers/lwip/lwip.cpp
|
||||||
|
|
||||||
# JNI Files
|
|
||||||
#LOCAL_SRC_FILES += \
|
|
||||||
# com_zerotierone_sdk_Node.cpp \
|
|
||||||
# ZT_jniutils.cpp \
|
|
||||||
# ZT_jnilookup.cpp
|
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ZT_jnilookup.h"
|
|
||||||
#include "ZT_jniutils.h"
|
|
||||||
|
|
||||||
JniLookup::JniLookup()
|
|
||||||
: m_jvm(NULL)
|
|
||||||
{
|
|
||||||
LOGV("JNI Cache Created");
|
|
||||||
}
|
|
||||||
|
|
||||||
JniLookup::JniLookup(JavaVM *jvm)
|
|
||||||
: m_jvm(jvm)
|
|
||||||
{
|
|
||||||
LOGV("JNI Cache Created");
|
|
||||||
}
|
|
||||||
|
|
||||||
JniLookup::~JniLookup()
|
|
||||||
{
|
|
||||||
LOGV("JNI Cache Destroyed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void JniLookup::setJavaVM(JavaVM *jvm)
|
|
||||||
{
|
|
||||||
LOGV("Assigned JVM to object");
|
|
||||||
m_jvm = jvm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jclass JniLookup::findClass(const std::string &name)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// get the class from the JVM
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
LOGE("Error retreiving JNI Environment");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jclass cls = env->FindClass(name.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
LOGE("Error finding class: %s", name.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cls;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jmethodID JniLookup::findMethod(jclass cls, const std::string &methodName, const std::string &methodSig)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodSig.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mid;
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID JniLookup::findStaticMethod(jclass cls, const std::string &methodName, const std::string &methodSig)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodSig.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mid;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID JniLookup::findField(jclass cls, const std::string &fieldName, const std::string &typeStr)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID fid = env->GetFieldID(cls, fieldName.c_str(), typeStr.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fid;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID JniLookup::findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr)
|
|
||||||
{
|
|
||||||
if(!m_jvm)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
JNIEnv *env = NULL;
|
|
||||||
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID fid = env->GetStaticFieldID(cls, fieldName.c_str(), typeStr.c_str());
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fid;
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ZT_JNILOOKUP_H_
|
|
||||||
#define ZT_JNILOOKUP_H_
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class JniLookup {
|
|
||||||
public:
|
|
||||||
JniLookup();
|
|
||||||
JniLookup(JavaVM *jvm);
|
|
||||||
~JniLookup();
|
|
||||||
|
|
||||||
void setJavaVM(JavaVM *jvm);
|
|
||||||
|
|
||||||
jclass findClass(const std::string &name);
|
|
||||||
jmethodID findMethod(jclass cls, const std::string &methodName, const std::string &methodSig);
|
|
||||||
jmethodID findStaticMethod(jclass cls, const std::string &methodName, const std::string &methodSig);
|
|
||||||
jfieldID findField(jclass cls, const std::string &fieldName, const std::string &typeStr);
|
|
||||||
jfieldID findStaticField(jclass cls, const std::string &fieldName, const std::string &typeStr);
|
|
||||||
private:
|
|
||||||
JavaVM *m_jvm;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,931 +0,0 @@
|
|||||||
#include "ZT_jniutils.h"
|
|
||||||
#include "ZT_jnilookup.h"
|
|
||||||
#include <string>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
extern JniLookup lookup;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jobject createResultObject(JNIEnv *env, ZT_ResultCode code)
|
|
||||||
{
|
|
||||||
jclass resultClass = NULL;
|
|
||||||
|
|
||||||
jobject resultObject = NULL;
|
|
||||||
|
|
||||||
resultClass = lookup.findClass("com/zerotier/sdk/ResultCode");
|
|
||||||
if(resultClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Couldnt find ResultCode class");
|
|
||||||
return NULL; // exception thrown
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fieldName;
|
|
||||||
switch(code)
|
|
||||||
{
|
|
||||||
case ZT_RESULT_OK:
|
|
||||||
LOGV("ZT_RESULT_OK");
|
|
||||||
fieldName = "RESULT_OK";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY:
|
|
||||||
LOGV("ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY");
|
|
||||||
fieldName = "RESULT_FATAL_ERROR_OUT_OF_MEMORY";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED:
|
|
||||||
LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED");
|
|
||||||
fieldName = "RESULT_FATAL_ERROR_DATA_STORE_FAILED";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_ERROR_NETWORK_NOT_FOUND:
|
|
||||||
LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED");
|
|
||||||
fieldName = "RESULT_ERROR_NETWORK_NOT_FOUND";
|
|
||||||
break;
|
|
||||||
case ZT_RESULT_FATAL_ERROR_INTERNAL:
|
|
||||||
default:
|
|
||||||
LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED");
|
|
||||||
fieldName = "RESULT_FATAL_ERROR_INTERNAL";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(resultClass, fieldName.c_str(), "Lcom/zerotier/sdk/ResultCode;");
|
|
||||||
if(env->ExceptionCheck() || enumField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error on FindStaticField");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
resultObject = env->GetStaticObjectField(resultClass, enumField);
|
|
||||||
if(env->ExceptionCheck() || resultObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error on GetStaticObjectField");
|
|
||||||
}
|
|
||||||
return resultObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status)
|
|
||||||
{
|
|
||||||
jobject statusObject = NULL;
|
|
||||||
|
|
||||||
jclass statusClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkStatus");
|
|
||||||
if(statusClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL; // exception thrown
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fieldName;
|
|
||||||
switch(status)
|
|
||||||
{
|
|
||||||
case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION:
|
|
||||||
fieldName = "NETWORK_STATUS_REQUESTING_CONFIGURATION";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_OK:
|
|
||||||
fieldName = "NETWORK_STATUS_OK";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_ACCESS_DENIED:
|
|
||||||
fieldName = "NETWORK_STATUS_ACCESS_DENIED";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_NOT_FOUND:
|
|
||||||
fieldName = "NETWORK_STATUS_NOT_FOUND";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_PORT_ERROR:
|
|
||||||
fieldName = "NETWORK_STATUS_PORT_ERROR";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_STATUS_CLIENT_TOO_OLD:
|
|
||||||
fieldName = "NETWORK_STATUS_CLIENT_TOO_OLD";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(statusClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkStatus;");
|
|
||||||
|
|
||||||
statusObject = env->GetStaticObjectField(statusClass, enumField);
|
|
||||||
|
|
||||||
return statusObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject createEvent(JNIEnv *env, ZT_Event event)
|
|
||||||
{
|
|
||||||
jclass eventClass = NULL;
|
|
||||||
jobject eventObject = NULL;
|
|
||||||
|
|
||||||
eventClass = lookup.findClass("com/zerotier/sdk/Event");
|
|
||||||
if(eventClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fieldName;
|
|
||||||
switch(event)
|
|
||||||
{
|
|
||||||
case ZT_EVENT_UP:
|
|
||||||
fieldName = "EVENT_UP";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_OFFLINE:
|
|
||||||
fieldName = "EVENT_OFFLINE";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_ONLINE:
|
|
||||||
fieldName = "EVENT_ONLINE";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_DOWN:
|
|
||||||
fieldName = "EVENT_DOWN";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION:
|
|
||||||
fieldName = "EVENT_FATAL_ERROR_IDENTITY_COLLISION";
|
|
||||||
break;
|
|
||||||
case ZT_EVENT_TRACE:
|
|
||||||
fieldName = "EVENT_TRACE";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(eventClass, fieldName.c_str(), "Lcom/zerotier/sdk/Event;");
|
|
||||||
|
|
||||||
eventObject = env->GetStaticObjectField(eventClass, enumField);
|
|
||||||
|
|
||||||
return eventObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject createPeerRole(JNIEnv *env, ZT_PeerRole role)
|
|
||||||
{
|
|
||||||
jclass peerRoleClass = NULL;
|
|
||||||
jobject peerRoleObject = NULL;
|
|
||||||
|
|
||||||
peerRoleClass = lookup.findClass("com/zerotier/sdk/PeerRole");
|
|
||||||
if(peerRoleClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fieldName;
|
|
||||||
switch(role)
|
|
||||||
{
|
|
||||||
case ZT_PEER_ROLE_LEAF:
|
|
||||||
fieldName = "PEER_ROLE_LEAF";
|
|
||||||
break;
|
|
||||||
case ZT_PEER_ROLE_RELAY:
|
|
||||||
fieldName = "PEER_ROLE_RELAY";
|
|
||||||
break;
|
|
||||||
case ZT_PEER_ROLE_ROOT:
|
|
||||||
fieldName = "PEER_ROLE_ROOTS";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(peerRoleClass, fieldName.c_str(), "Lcom/zerotier/sdk/PeerRole;");
|
|
||||||
|
|
||||||
peerRoleObject = env->GetStaticObjectField(peerRoleClass, enumField);
|
|
||||||
|
|
||||||
return peerRoleObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type)
|
|
||||||
{
|
|
||||||
jclass vntypeClass = NULL;
|
|
||||||
jobject vntypeObject = NULL;
|
|
||||||
|
|
||||||
vntypeClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkType");
|
|
||||||
if(env->ExceptionCheck() || vntypeClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fieldName;
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case ZT_NETWORK_TYPE_PRIVATE:
|
|
||||||
fieldName = "NETWORK_TYPE_PRIVATE";
|
|
||||||
break;
|
|
||||||
case ZT_NETWORK_TYPE_PUBLIC:
|
|
||||||
fieldName = "NETWORK_TYPE_PUBLIC";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(vntypeClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkType;");
|
|
||||||
vntypeObject = env->GetStaticObjectField(vntypeClass, enumField);
|
|
||||||
return vntypeObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op)
|
|
||||||
{
|
|
||||||
jclass vnetConfigOpClass = NULL;
|
|
||||||
jobject vnetConfigOpObject = NULL;
|
|
||||||
|
|
||||||
vnetConfigOpClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfigOperation");
|
|
||||||
if(env->ExceptionCheck() || vnetConfigOpClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fieldName;
|
|
||||||
switch(op)
|
|
||||||
{
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_UP";
|
|
||||||
break;
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE";
|
|
||||||
break;
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN";
|
|
||||||
break;
|
|
||||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY:
|
|
||||||
fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jfieldID enumField = lookup.findStaticField(vnetConfigOpClass, fieldName.c_str(), "Lcom/zerotier/sdk/VirtualNetworkConfigOperation;");
|
|
||||||
vnetConfigOpObject = env->GetStaticObjectField(vnetConfigOpClass, enumField);
|
|
||||||
return vnetConfigOpObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr)
|
|
||||||
{
|
|
||||||
LOGV("newInetAddress");
|
|
||||||
jclass inetAddressClass = NULL;
|
|
||||||
jmethodID inetAddress_getByAddress = NULL;
|
|
||||||
|
|
||||||
inetAddressClass = lookup.findClass("java/net/InetAddress");
|
|
||||||
if(env->ExceptionCheck() || inetAddressClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding InetAddress class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inetAddress_getByAddress = lookup.findStaticMethod(
|
|
||||||
inetAddressClass, "getByAddress", "([B)Ljava/net/InetAddress;");
|
|
||||||
if(env->ExceptionCheck() || inetAddress_getByAddress == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Erorr finding getByAddress() static method");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject inetAddressObj = NULL;
|
|
||||||
switch(addr.ss_family)
|
|
||||||
{
|
|
||||||
case AF_INET6:
|
|
||||||
{
|
|
||||||
sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr;
|
|
||||||
jbyteArray buff = env->NewByteArray(16);
|
|
||||||
if(buff == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating IPV6 byte array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetByteArrayRegion(buff, 0, 16, (jbyte*)ipv6->sin6_addr.s6_addr);
|
|
||||||
inetAddressObj = env->CallStaticObjectMethod(
|
|
||||||
inetAddressClass, inetAddress_getByAddress, buff);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AF_INET:
|
|
||||||
{
|
|
||||||
sockaddr_in *ipv4 = (sockaddr_in*)&addr;
|
|
||||||
jbyteArray buff = env->NewByteArray(4);
|
|
||||||
if(buff == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating IPV4 byte array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetByteArrayRegion(buff, 0, 4, (jbyte*)&ipv4->sin_addr);
|
|
||||||
inetAddressObj = env->CallStaticObjectMethod(
|
|
||||||
inetAddressClass, inetAddress_getByAddress, buff);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(env->ExceptionCheck() || inetAddressObj == NULL) {
|
|
||||||
LOGE("Error creating InetAddress object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return inetAddressObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr)
|
|
||||||
{
|
|
||||||
LOGV("newInetSocketAddress Called");
|
|
||||||
jclass inetSocketAddressClass = NULL;
|
|
||||||
jmethodID inetSocketAddress_constructor = NULL;
|
|
||||||
|
|
||||||
inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
|
|
||||||
if(env->ExceptionCheck() || inetSocketAddressClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding InetSocketAddress Class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject inetAddressObject = newInetAddress(env, addr);
|
|
||||||
|
|
||||||
if(env->ExceptionCheck() || inetAddressObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating new inet address");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inetSocketAddress_constructor = lookup.findMethod(
|
|
||||||
inetSocketAddressClass, "<init>", "(Ljava/net/InetAddress;I)V");
|
|
||||||
if(env->ExceptionCheck() || inetSocketAddress_constructor == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding InetSocketAddress constructor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int port = 0;
|
|
||||||
switch(addr.ss_family)
|
|
||||||
{
|
|
||||||
case AF_INET6:
|
|
||||||
{
|
|
||||||
LOGV("IPV6 Address");
|
|
||||||
sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr;
|
|
||||||
port = ntohs(ipv6->sin6_port);
|
|
||||||
LOGV("Port %d", port);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AF_INET:
|
|
||||||
{
|
|
||||||
LOGV("IPV4 Address");
|
|
||||||
sockaddr_in *ipv4 = (sockaddr_in*)&addr;
|
|
||||||
port = ntohs(ipv4->sin_port);
|
|
||||||
LOGV("Port: %d", port);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
LOGE("ERROR: addr.ss_family is not set or unknown");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
jobject inetSocketAddressObject = env->NewObject(inetSocketAddressClass, inetSocketAddress_constructor, inetAddressObject, port);
|
|
||||||
if(env->ExceptionCheck() || inetSocketAddressObject == NULL) {
|
|
||||||
LOGE("Error creating InetSocketAddress object");
|
|
||||||
}
|
|
||||||
return inetSocketAddressObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc)
|
|
||||||
{
|
|
||||||
jclass multicastGroupClass = NULL;
|
|
||||||
jmethodID multicastGroup_constructor = NULL;
|
|
||||||
|
|
||||||
jfieldID macField = NULL;
|
|
||||||
jfieldID adiField = NULL;
|
|
||||||
|
|
||||||
multicastGroupClass = lookup.findClass("com/zerotier/sdk/MulticastGroup");
|
|
||||||
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
multicastGroup_constructor = lookup.findMethod(
|
|
||||||
multicastGroupClass, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || multicastGroup_constructor == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject multicastGroupObj = env->NewObject(multicastGroupClass, multicastGroup_constructor);
|
|
||||||
if(env->ExceptionCheck() || multicastGroupObj == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
macField = lookup.findField(multicastGroupClass, "mac", "J");
|
|
||||||
if(env->ExceptionCheck() || macField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
adiField = lookup.findField(multicastGroupClass, "adi", "J");
|
|
||||||
if(env->ExceptionCheck() || adiField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetLongField(multicastGroupObj, macField, mc.mac);
|
|
||||||
env->SetLongField(multicastGroupObj, adiField, mc.adi);
|
|
||||||
|
|
||||||
return multicastGroupObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp)
|
|
||||||
{
|
|
||||||
LOGV("newPeerPhysicalPath Called");
|
|
||||||
jclass pppClass = NULL;
|
|
||||||
|
|
||||||
jfieldID addressField = NULL;
|
|
||||||
jfieldID lastSendField = NULL;
|
|
||||||
jfieldID lastReceiveField = NULL;
|
|
||||||
jfieldID activeField = NULL;
|
|
||||||
jfieldID preferredField = NULL;
|
|
||||||
|
|
||||||
jmethodID ppp_constructor = NULL;
|
|
||||||
|
|
||||||
pppClass = lookup.findClass("com/zerotier/sdk/PeerPhysicalPath");
|
|
||||||
if(env->ExceptionCheck() || pppClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding PeerPhysicalPath class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
addressField = lookup.findField(pppClass, "address", "Ljava/net/InetSocketAddress;");
|
|
||||||
if(env->ExceptionCheck() || addressField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding address field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastSendField = lookup.findField(pppClass, "lastSend", "J");
|
|
||||||
if(env->ExceptionCheck() || lastSendField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding lastSend field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastReceiveField = lookup.findField(pppClass, "lastReceive", "J");
|
|
||||||
if(env->ExceptionCheck() || lastReceiveField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding lastReceive field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
activeField = lookup.findField(pppClass, "active", "Z");
|
|
||||||
if(env->ExceptionCheck() || activeField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding active field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
preferredField = lookup.findField(pppClass, "preferred", "Z");
|
|
||||||
if(env->ExceptionCheck() || preferredField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding preferred field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ppp_constructor = lookup.findMethod(pppClass, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || ppp_constructor == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding PeerPhysicalPath constructor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject pppObject = env->NewObject(pppClass, ppp_constructor);
|
|
||||||
if(env->ExceptionCheck() || pppObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating PPP object");
|
|
||||||
return NULL; // out of memory
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject addressObject = newInetSocketAddress(env, ppp.address);
|
|
||||||
if(env->ExceptionCheck() || addressObject == NULL) {
|
|
||||||
LOGE("Error creating InetSocketAddress object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetObjectField(pppObject, addressField, addressObject);
|
|
||||||
env->SetLongField(pppObject, lastSendField, ppp.lastSend);
|
|
||||||
env->SetLongField(pppObject, lastReceiveField, ppp.lastReceive);
|
|
||||||
env->SetBooleanField(pppObject, activeField, ppp.active);
|
|
||||||
env->SetBooleanField(pppObject, preferredField, ppp.preferred);
|
|
||||||
|
|
||||||
if(env->ExceptionCheck()) {
|
|
||||||
LOGE("Exception assigning fields to PeerPhysicalPath object");
|
|
||||||
}
|
|
||||||
|
|
||||||
return pppObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newPeer(JNIEnv *env, const ZT_Peer &peer)
|
|
||||||
{
|
|
||||||
LOGV("newPeer called");
|
|
||||||
|
|
||||||
jclass peerClass = NULL;
|
|
||||||
|
|
||||||
jfieldID addressField = NULL;
|
|
||||||
jfieldID lastUnicastFrameField = NULL;
|
|
||||||
jfieldID lastMulticastFrameField = NULL;
|
|
||||||
jfieldID versionMajorField = NULL;
|
|
||||||
jfieldID versionMinorField = NULL;
|
|
||||||
jfieldID versionRevField = NULL;
|
|
||||||
jfieldID latencyField = NULL;
|
|
||||||
jfieldID roleField = NULL;
|
|
||||||
jfieldID pathsField = NULL;
|
|
||||||
|
|
||||||
jmethodID peer_constructor = NULL;
|
|
||||||
|
|
||||||
peerClass = lookup.findClass("com/zerotier/sdk/Peer");
|
|
||||||
if(env->ExceptionCheck() || peerClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding Peer class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
addressField = lookup.findField(peerClass, "address", "J");
|
|
||||||
if(env->ExceptionCheck() || addressField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding address field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastUnicastFrameField = lookup.findField(peerClass, "lastUnicastFrame", "J");
|
|
||||||
if(env->ExceptionCheck() || lastUnicastFrameField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding lastUnicastFrame field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastMulticastFrameField = lookup.findField(peerClass, "lastMulticastFrame", "J");
|
|
||||||
if(env->ExceptionCheck() || lastMulticastFrameField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding lastMulticastFrame field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
versionMajorField = lookup.findField(peerClass, "versionMajor", "I");
|
|
||||||
if(env->ExceptionCheck() || versionMajorField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding versionMajor field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
versionMinorField = lookup.findField(peerClass, "versionMinor", "I");
|
|
||||||
if(env->ExceptionCheck() || versionMinorField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding versionMinor field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
versionRevField = lookup.findField(peerClass, "versionRev", "I");
|
|
||||||
if(env->ExceptionCheck() || versionRevField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding versionRev field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
latencyField = lookup.findField(peerClass, "latency", "I");
|
|
||||||
if(env->ExceptionCheck() || latencyField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding latency field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
roleField = lookup.findField(peerClass, "role", "Lcom/zerotier/sdk/PeerRole;");
|
|
||||||
if(env->ExceptionCheck() || roleField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding role field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pathsField = lookup.findField(peerClass, "paths", "[Lcom/zerotier/sdk/PeerPhysicalPath;");
|
|
||||||
if(env->ExceptionCheck() || pathsField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding paths field of Peer object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer_constructor = lookup.findMethod(peerClass, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || peer_constructor == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding Peer constructor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject peerObject = env->NewObject(peerClass, peer_constructor);
|
|
||||||
if(env->ExceptionCheck() || peerObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating Peer object");
|
|
||||||
return NULL; // out of memory
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetLongField(peerObject, addressField, (jlong)peer.address);
|
|
||||||
env->SetLongField(peerObject, lastUnicastFrameField, (jlong)peer.lastUnicastFrame);
|
|
||||||
env->SetLongField(peerObject, lastMulticastFrameField, (jlong)peer.lastMulticastFrame);
|
|
||||||
env->SetIntField(peerObject, versionMajorField, peer.versionMajor);
|
|
||||||
env->SetIntField(peerObject, versionMinorField, peer.versionMinor);
|
|
||||||
env->SetIntField(peerObject, versionRevField, peer.versionRev);
|
|
||||||
env->SetIntField(peerObject, latencyField, peer.latency);
|
|
||||||
env->SetObjectField(peerObject, roleField, createPeerRole(env, peer.role));
|
|
||||||
|
|
||||||
jclass peerPhysicalPathClass = lookup.findClass("com/zerotier/sdk/PeerPhysicalPath");
|
|
||||||
if(env->ExceptionCheck() || peerPhysicalPathClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding PeerPhysicalPath class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobjectArray arrayObject = env->NewObjectArray(
|
|
||||||
peer.pathCount, peerPhysicalPathClass, NULL);
|
|
||||||
if(env->ExceptionCheck() || arrayObject == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating PeerPhysicalPath[] array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < peer.pathCount; ++i)
|
|
||||||
{
|
|
||||||
jobject path = newPeerPhysicalPath(env, peer.paths[i]);
|
|
||||||
|
|
||||||
env->SetObjectArrayElement(arrayObject, i, path);
|
|
||||||
if(env->ExceptionCheck()) {
|
|
||||||
LOGE("exception assigning PeerPhysicalPath to array");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetObjectField(peerObject, pathsField, arrayObject);
|
|
||||||
|
|
||||||
return peerObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig)
|
|
||||||
{
|
|
||||||
jclass vnetConfigClass = NULL;
|
|
||||||
jmethodID vnetConfig_constructor = NULL;
|
|
||||||
jfieldID nwidField = NULL;
|
|
||||||
jfieldID macField = NULL;
|
|
||||||
jfieldID nameField = NULL;
|
|
||||||
jfieldID statusField = NULL;
|
|
||||||
jfieldID typeField = NULL;
|
|
||||||
jfieldID mtuField = NULL;
|
|
||||||
jfieldID dhcpField = NULL;
|
|
||||||
jfieldID bridgeField = NULL;
|
|
||||||
jfieldID broadcastEnabledField = NULL;
|
|
||||||
jfieldID portErrorField = NULL;
|
|
||||||
jfieldID enabledField = NULL;
|
|
||||||
jfieldID netconfRevisionField = NULL;
|
|
||||||
jfieldID multicastSubscriptionsField = NULL;
|
|
||||||
jfieldID assignedAddressesField = NULL;
|
|
||||||
|
|
||||||
vnetConfigClass = lookup.findClass("com/zerotier/sdk/VirtualNetworkConfig");
|
|
||||||
if(vnetConfigClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Couldn't find com.zerotier.sdk.VirtualNetworkConfig");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vnetConfig_constructor = lookup.findMethod(
|
|
||||||
vnetConfigClass, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || vnetConfig_constructor == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Couldn't find VirtualNetworkConfig Constructor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject vnetConfigObj = env->NewObject(vnetConfigClass, vnetConfig_constructor);
|
|
||||||
if(env->ExceptionCheck() || vnetConfigObj == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating new VirtualNetworkConfig object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nwidField = lookup.findField(vnetConfigClass, "nwid", "J");
|
|
||||||
if(env->ExceptionCheck() || nwidField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting nwid field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
macField = lookup.findField(vnetConfigClass, "mac", "J");
|
|
||||||
if(env->ExceptionCheck() || macField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting mac field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nameField = lookup.findField(vnetConfigClass, "name", "Ljava/lang/String;");
|
|
||||||
if(env->ExceptionCheck() || nameField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting name field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
statusField = lookup.findField(vnetConfigClass, "status", "Lcom/zerotier/sdk/VirtualNetworkStatus;");
|
|
||||||
if(env->ExceptionCheck() || statusField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting status field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
typeField = lookup.findField(vnetConfigClass, "type", "Lcom/zerotier/sdk/VirtualNetworkType;");
|
|
||||||
if(env->ExceptionCheck() || typeField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting type field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mtuField = lookup.findField(vnetConfigClass, "mtu", "I");
|
|
||||||
if(env->ExceptionCheck() || mtuField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting mtu field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dhcpField = lookup.findField(vnetConfigClass, "dhcp", "Z");
|
|
||||||
if(env->ExceptionCheck() || dhcpField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting dhcp field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridgeField = lookup.findField(vnetConfigClass, "bridge", "Z");
|
|
||||||
if(env->ExceptionCheck() || bridgeField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting bridge field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
broadcastEnabledField = lookup.findField(vnetConfigClass, "broadcastEnabled", "Z");
|
|
||||||
if(env->ExceptionCheck() || broadcastEnabledField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting broadcastEnabled field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
portErrorField = lookup.findField(vnetConfigClass, "portError", "I");
|
|
||||||
if(env->ExceptionCheck() || portErrorField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting portError field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
enabledField = lookup.findField(vnetConfigClass, "enabled", "Z");
|
|
||||||
if(env->ExceptionCheck() || enabledField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting enabled field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
netconfRevisionField = lookup.findField(vnetConfigClass, "netconfRevision", "J");
|
|
||||||
if(env->ExceptionCheck() || netconfRevisionField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting netconfRevision field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
multicastSubscriptionsField = lookup.findField(vnetConfigClass, "multicastSubscriptions", "[Lcom/zerotier/sdk/MulticastGroup;");
|
|
||||||
if(env->ExceptionCheck() || multicastSubscriptionsField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting multicastSubscriptions field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
assignedAddressesField = lookup.findField(vnetConfigClass, "assignedAddresses", "[Ljava/net/InetSocketAddress;");
|
|
||||||
if(env->ExceptionCheck() || assignedAddressesField == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error getting assignedAddresses field");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetLongField(vnetConfigObj, nwidField, vnetConfig.nwid);
|
|
||||||
env->SetLongField(vnetConfigObj, macField, vnetConfig.mac);
|
|
||||||
jstring nameStr = env->NewStringUTF(vnetConfig.name);
|
|
||||||
if(env->ExceptionCheck() || nameStr == NULL)
|
|
||||||
{
|
|
||||||
return NULL; // out of memory
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, nameField, nameStr);
|
|
||||||
|
|
||||||
jobject statusObject = createVirtualNetworkStatus(env, vnetConfig.status);
|
|
||||||
if(env->ExceptionCheck() || statusObject == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, statusField, statusObject);
|
|
||||||
|
|
||||||
jobject typeObject = createVirtualNetworkType(env, vnetConfig.type);
|
|
||||||
if(env->ExceptionCheck() || typeObject == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, typeField, typeObject);
|
|
||||||
|
|
||||||
env->SetIntField(vnetConfigObj, mtuField, (int)vnetConfig.mtu);
|
|
||||||
env->SetBooleanField(vnetConfigObj, dhcpField, vnetConfig.dhcp);
|
|
||||||
env->SetBooleanField(vnetConfigObj, bridgeField, vnetConfig.bridge);
|
|
||||||
env->SetBooleanField(vnetConfigObj, broadcastEnabledField, vnetConfig.broadcastEnabled);
|
|
||||||
env->SetBooleanField(vnetConfigObj, enabledField, vnetConfig.enabled);
|
|
||||||
env->SetIntField(vnetConfigObj, portErrorField, vnetConfig.portError);
|
|
||||||
|
|
||||||
jclass multicastGroupClass = lookup.findClass("com/zerotier/sdk/MulticastGroup");
|
|
||||||
if(env->ExceptionCheck() || multicastGroupClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding MulticastGroup class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobjectArray mcastSubsArrayObj = env->NewObjectArray(
|
|
||||||
vnetConfig.multicastSubscriptionCount, multicastGroupClass, NULL);
|
|
||||||
if(env->ExceptionCheck() || mcastSubsArrayObj == NULL) {
|
|
||||||
LOGE("Error creating MulticastGroup[] array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < vnetConfig.multicastSubscriptionCount; ++i)
|
|
||||||
{
|
|
||||||
jobject mcastObj = newMulticastGroup(env, vnetConfig.multicastSubscriptions[i]);
|
|
||||||
env->SetObjectArrayElement(mcastSubsArrayObj, i, mcastObj);
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
LOGE("Error assigning MulticastGroup to array");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
env->SetObjectField(vnetConfigObj, multicastSubscriptionsField, mcastSubsArrayObj);
|
|
||||||
|
|
||||||
jclass inetSocketAddressClass = lookup.findClass("java/net/InetSocketAddress");
|
|
||||||
if(env->ExceptionCheck() || inetSocketAddressClass == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error finding InetSocketAddress class");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobjectArray assignedAddrArrayObj = env->NewObjectArray(
|
|
||||||
vnetConfig.assignedAddressCount, inetSocketAddressClass, NULL);
|
|
||||||
if(env->ExceptionCheck() || assignedAddrArrayObj == NULL)
|
|
||||||
{
|
|
||||||
LOGE("Error creating InetSocketAddress[] array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < vnetConfig.assignedAddressCount; ++i)
|
|
||||||
{
|
|
||||||
jobject inetAddrObj = newInetSocketAddress(env, vnetConfig.assignedAddresses[i]);
|
|
||||||
env->SetObjectArrayElement(assignedAddrArrayObj, i, inetAddrObj);
|
|
||||||
if(env->ExceptionCheck())
|
|
||||||
{
|
|
||||||
LOGE("Error assigning InetSocketAddress to array");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetObjectField(vnetConfigObj, assignedAddressesField, assignedAddrArrayObj);
|
|
||||||
|
|
||||||
return vnetConfigObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags)
|
|
||||||
{
|
|
||||||
// create a com.zerotier.sdk.Version object
|
|
||||||
jclass versionClass = NULL;
|
|
||||||
jmethodID versionConstructor = NULL;
|
|
||||||
|
|
||||||
versionClass = lookup.findClass("com/zerotier/sdk/Version");
|
|
||||||
if(env->ExceptionCheck() || versionClass == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
versionConstructor = lookup.findMethod(
|
|
||||||
versionClass, "<init>", "()V");
|
|
||||||
if(env->ExceptionCheck() || versionConstructor == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject versionObj = env->NewObject(versionClass, versionConstructor);
|
|
||||||
if(env->ExceptionCheck() || versionObj == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy data to Version object
|
|
||||||
jfieldID majorField = NULL;
|
|
||||||
jfieldID minorField = NULL;
|
|
||||||
jfieldID revisionField = NULL;
|
|
||||||
jfieldID featureFlagsField = NULL;
|
|
||||||
|
|
||||||
majorField = lookup.findField(versionClass, "major", "I");
|
|
||||||
if(env->ExceptionCheck() || majorField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
minorField = lookup.findField(versionClass, "minor", "I");
|
|
||||||
if(env->ExceptionCheck() || minorField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
revisionField = lookup.findField(versionClass, "revision", "I");
|
|
||||||
if(env->ExceptionCheck() || revisionField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
featureFlagsField = lookup.findField(versionClass, "featureFlags", "J");
|
|
||||||
if(env->ExceptionCheck() || featureFlagsField == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->SetIntField(versionObj, majorField, (jint)major);
|
|
||||||
env->SetIntField(versionObj, minorField, (jint)minor);
|
|
||||||
env->SetIntField(versionObj, revisionField, (jint)rev);
|
|
||||||
env->SetLongField(versionObj, featureFlagsField, (jlong)featureFlags);
|
|
||||||
|
|
||||||
return versionObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#ifndef ZT_jniutils_h_
|
|
||||||
#define ZT_jniutils_h_
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <jni.h>
|
|
||||||
#include <ZeroTierOne.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LOG_TAG "ZeroTierOneJNI"
|
|
||||||
|
|
||||||
#if __ANDROID__
|
|
||||||
#include <android/log.h>
|
|
||||||
#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
|
||||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
|
|
||||||
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
|
||||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
|
||||||
#else
|
|
||||||
#define LOGV(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#define LOGI(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#define LOGD(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#define LOGE(...) fprintf(stdout, __VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jobject createResultObject(JNIEnv *env, ZT_ResultCode code);
|
|
||||||
jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status);
|
|
||||||
jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type);
|
|
||||||
jobject createEvent(JNIEnv *env, ZT_Event event);
|
|
||||||
jobject createPeerRole(JNIEnv *env, ZT_PeerRole role);
|
|
||||||
jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op);
|
|
||||||
|
|
||||||
jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr);
|
|
||||||
jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr);
|
|
||||||
|
|
||||||
jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc);
|
|
||||||
|
|
||||||
jobject newPeer(JNIEnv *env, const ZT_Peer &peer);
|
|
||||||
jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp);
|
|
||||||
|
|
||||||
jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &config);
|
|
||||||
|
|
||||||
jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,133 +0,0 @@
|
|||||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
|
||||||
#include <jni.h>
|
|
||||||
/* Header for class com_zerotier_sdk_Node */
|
|
||||||
|
|
||||||
#ifndef _Included_com_zerotierone_sdk_Node
|
|
||||||
#define _Included_com_zerotierone_sdk_Node
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: node_init
|
|
||||||
* Signature: (J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: node_delete
|
|
||||||
* Signature: (J)V
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: processVirtualNetworkFrame
|
|
||||||
* Signature: (JJJJJII[B[J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong, jlong, jint, jint, jbyteArray, jlongArray);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: processWirePacket
|
|
||||||
* Signature: (JJLjava/net/InetSockAddress;Ljava/net/InetSockAddress;[B[J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jobject, jobject, jbyteArray, jlongArray);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: processBackgroundTasks
|
|
||||||
* Signature: (JJ[J)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlongArray);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: join
|
|
||||||
* Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join
|
|
||||||
(JNIEnv *, jobject, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: leave
|
|
||||||
* Signature: (JJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave
|
|
||||||
(JNIEnv *, jobject, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: multicastSubscribe
|
|
||||||
* Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: multicastUnsubscribe
|
|
||||||
* Signature: (JJJJ)Lcom/zerotier/sdk/ResultCode;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe
|
|
||||||
(JNIEnv *, jobject, jlong, jlong, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: address
|
|
||||||
* Signature: (J)J
|
|
||||||
*/
|
|
||||||
JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: status
|
|
||||||
* Signature: (J)Lcom/zerotier/sdk/NodeStatus;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: networkConfig
|
|
||||||
* Signature: (JJ)Lcom/zerotier/sdk/VirtualNetworkConfig;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig
|
|
||||||
(JNIEnv *, jobject, jlong, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: version
|
|
||||||
* Signature: ()Lcom/zerotier/sdk/Version;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version
|
|
||||||
(JNIEnv *, jobject);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: peers
|
|
||||||
* Signature: (J)[Lcom/zerotier/sdk/Peer;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: com_zerotier_sdk_Node
|
|
||||||
* Method: networks
|
|
||||||
* Signature: (J)[Lcom/zerotier/sdk/VirtualNetworkConfig;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks
|
|
||||||
(JNIEnv *, jobject, jlong);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public interface DataStoreGetListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to get an object from the data store
|
|
||||||
*
|
|
||||||
* <p>Object names can contain forward slash (/) path separators. They will
|
|
||||||
* never contain .. or backslash (\), so this is safe to map as a Unix-style
|
|
||||||
* path if the underlying storage permits. For security reasons we recommend
|
|
||||||
* returning errors if .. or \ are used.</p>
|
|
||||||
*
|
|
||||||
* <p>The function must return the actual number of bytes read. If the object
|
|
||||||
* doesn't exist, it should return -1. -2 should be returned on other errors
|
|
||||||
* such as errors accessing underlying storage.</p>
|
|
||||||
*
|
|
||||||
* <p>If the read doesn't fit in the buffer, the max number of bytes should be
|
|
||||||
* read. The caller may call the function multiple times to read the whole
|
|
||||||
* object.</p>
|
|
||||||
*
|
|
||||||
* @param name Name of the object in the data store
|
|
||||||
* @param out_buffer buffer to put the object in
|
|
||||||
* @param bufferIndex index in the object to start reading
|
|
||||||
* @param out_objectSize long[1] to be set to the actual size of the object if it exists.
|
|
||||||
* @return the actual number of bytes read.
|
|
||||||
*/
|
|
||||||
public long onDataStoreGet(
|
|
||||||
String name,
|
|
||||||
byte[] out_buffer,
|
|
||||||
long bufferIndex,
|
|
||||||
long[] out_objectSize);
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public interface DataStorePutListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to store an object in the data store
|
|
||||||
*
|
|
||||||
* <p>If secure is true, the file should be set readable and writable only
|
|
||||||
* to the user running ZeroTier One. What this means is platform-specific.</p>
|
|
||||||
*
|
|
||||||
* <p>Name semantics are the same as {@link DataStoreGetListener}. This must return
|
|
||||||
* zero on success. You can return any OS-specific error code on failure, as these
|
|
||||||
* may be visible in logs or error messages and might aid in debugging.</p>
|
|
||||||
*
|
|
||||||
* @param name Object name
|
|
||||||
* @param buffer data to store
|
|
||||||
* @param secure set to user read/write only.
|
|
||||||
* @return 0 on success.
|
|
||||||
*/
|
|
||||||
public int onDataStorePut(
|
|
||||||
String name,
|
|
||||||
byte[] buffer,
|
|
||||||
boolean secure);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to delete an object from the data store
|
|
||||||
*
|
|
||||||
* @param name Object name
|
|
||||||
* @return 0 on success.
|
|
||||||
*/
|
|
||||||
public int onDelete(
|
|
||||||
String name);
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum Event {
|
|
||||||
/**
|
|
||||||
* Node has been initialized
|
|
||||||
*
|
|
||||||
* This is the first event generated, and is always sent. It may occur
|
|
||||||
* before Node's constructor returns.
|
|
||||||
*/
|
|
||||||
EVENT_UP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node is offline -- network does not seem to be reachable by any available strategy
|
|
||||||
*/
|
|
||||||
EVENT_OFFLINE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node is online -- at least one upstream node appears reachable
|
|
||||||
*
|
|
||||||
* Meta-data: none
|
|
||||||
*/
|
|
||||||
EVENT_ONLINE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node is shutting down
|
|
||||||
*
|
|
||||||
* <p>This is generated within Node's destructor when it is being shut down.
|
|
||||||
* It's done for convenience, since cleaning up other state in the event
|
|
||||||
* handler may appear more idiomatic.</p>
|
|
||||||
*/
|
|
||||||
EVENT_DOWN,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Your identity has collided with another node's ZeroTier address
|
|
||||||
*
|
|
||||||
* <p>This happens if two different public keys both hash (via the algorithm
|
|
||||||
* in Identity::generate()) to the same 40-bit ZeroTier address.</p>
|
|
||||||
*
|
|
||||||
* <p>This is something you should "never" see, where "never" is defined as
|
|
||||||
* once per 2^39 new node initializations / identity creations. If you do
|
|
||||||
* see it, you're going to see it very soon after a node is first
|
|
||||||
* initialized.</p>
|
|
||||||
*
|
|
||||||
* <p>This is reported as an event rather than a return code since it's
|
|
||||||
* detected asynchronously via error messages from authoritative nodes.</p>
|
|
||||||
*
|
|
||||||
* <p>If this occurs, you must shut down and delete the node, delete the
|
|
||||||
* identity.secret record/file from the data store, and restart to generate
|
|
||||||
* a new identity. If you don't do this, you will not be able to communicate
|
|
||||||
* with other nodes.</p>
|
|
||||||
*
|
|
||||||
* <p>We'd automate this process, but we don't think silently deleting
|
|
||||||
* private keys or changing our address without telling the calling code
|
|
||||||
* is good form. It violates the principle of least surprise.</p>
|
|
||||||
*
|
|
||||||
* <p>You can technically get away with not handling this, but we recommend
|
|
||||||
* doing so in a mature reliable application. Besides, handling this
|
|
||||||
* condition is a good way to make sure it never arises. It's like how
|
|
||||||
* umbrellas prevent rain and smoke detectors prevent fires. They do, right?</p>
|
|
||||||
*/
|
|
||||||
EVENT_FATAL_ERROR_IDENTITY_COLLISION,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trace (debugging) message
|
|
||||||
*
|
|
||||||
* <p>These events are only generated if this is a TRACE-enabled build.</p>
|
|
||||||
*
|
|
||||||
* <p>Meta-data: {@link String}, TRACE message</p>
|
|
||||||
*/
|
|
||||||
EVENT_TRACE
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.lang.String;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface to handle callbacks for ZeroTier One events.
|
|
||||||
*/
|
|
||||||
public interface EventListener {
|
|
||||||
/**
|
|
||||||
* Callback for events with no other associated metadata
|
|
||||||
*
|
|
||||||
* @param event {@link Event} enum
|
|
||||||
*/
|
|
||||||
public void onEvent(Event event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trace messages
|
|
||||||
*
|
|
||||||
* <p>These events are only generated if the underlying ZeroTierOne SDK is a TRACE-enabled build.</p>
|
|
||||||
*
|
|
||||||
* @param message the trace message
|
|
||||||
*/
|
|
||||||
public void onTrace(String message);
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
|
|
||||||
public final class MulticastGroup {
|
|
||||||
private MulticastGroup() {}
|
|
||||||
|
|
||||||
private long mac;
|
|
||||||
private long adi;
|
|
||||||
|
|
||||||
public boolean equals(MulticastGroup other) {
|
|
||||||
return mac == other.mac && adi == other.adi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MAC address (least significant 48 bits)
|
|
||||||
*/
|
|
||||||
public final long getMacAddress() {
|
|
||||||
return mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Additional distinguishing information (usually zero)
|
|
||||||
*/
|
|
||||||
public final long getAdi() {
|
|
||||||
return adi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple library class for working with JNI (Java Native Interface)
|
|
||||||
*
|
|
||||||
* @see http://adamheinrich.com/2012/how-to-load-native-jni-library-from-jar
|
|
||||||
*
|
|
||||||
* @author Adam Heirnich <adam@adamh.cz>, http://www.adamh.cz
|
|
||||||
*/
|
|
||||||
public class NativeUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor - this class will never be instanced
|
|
||||||
*/
|
|
||||||
private NativeUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads library from current JAR archive
|
|
||||||
*
|
|
||||||
* The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting.
|
|
||||||
* Method uses String as filename because the pathname is "abstract", not system-dependent.
|
|
||||||
*
|
|
||||||
* @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext
|
|
||||||
* @throws IOException If temporary file creation or read/write operation fails
|
|
||||||
* @throws IllegalArgumentException If source file (param path) does not exist
|
|
||||||
* @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}).
|
|
||||||
*/
|
|
||||||
public static void loadLibraryFromJar(String path) throws IOException {
|
|
||||||
|
|
||||||
if (!path.startsWith("/")) {
|
|
||||||
throw new IllegalArgumentException("The path has to be absolute (start with '/').");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain filename from path
|
|
||||||
String[] parts = path.split("/");
|
|
||||||
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
|
|
||||||
|
|
||||||
// Split filename to prexif and suffix (extension)
|
|
||||||
String prefix = "";
|
|
||||||
String suffix = null;
|
|
||||||
if (filename != null) {
|
|
||||||
parts = filename.split("\\.", 2);
|
|
||||||
prefix = parts[0];
|
|
||||||
suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the filename is okay
|
|
||||||
if (filename == null || prefix.length() < 3) {
|
|
||||||
throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare temporary file
|
|
||||||
File temp = File.createTempFile(prefix, suffix);
|
|
||||||
temp.deleteOnExit();
|
|
||||||
|
|
||||||
if (!temp.exists()) {
|
|
||||||
throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare buffer for data copying
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int readBytes;
|
|
||||||
|
|
||||||
// Open and check input stream
|
|
||||||
InputStream is = NativeUtils.class.getResourceAsStream(path);
|
|
||||||
if (is == null) {
|
|
||||||
throw new FileNotFoundException("File " + path + " was not found inside JAR.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open output stream and copy data between source file in JAR and the temporary file
|
|
||||||
OutputStream os = new FileOutputStream(temp);
|
|
||||||
try {
|
|
||||||
while ((readBytes = is.read(buffer)) != -1) {
|
|
||||||
os.write(buffer, 0, readBytes);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
// If read/write fails, close streams safely before throwing an exception
|
|
||||||
os.close();
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, load the library
|
|
||||||
System.load(temp.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,442 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ZeroTier One node
|
|
||||||
*/
|
|
||||||
public class Node {
|
|
||||||
|
|
||||||
//public static native int load_symbols();
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
//System.loadLibrary("ZeroTierOneJNI");
|
|
||||||
|
|
||||||
// test call
|
|
||||||
//System.out.println("load_symbols() = " + load_symbols());
|
|
||||||
|
|
||||||
|
|
||||||
} catch (UnsatisfiedLinkError e) {
|
|
||||||
try {
|
|
||||||
if(System.getProperty("os.name").startsWith("Windows")) {
|
|
||||||
System.out.println("Arch: " + System.getProperty("sun.arch.data.model"));
|
|
||||||
if(System.getProperty("sun.arch.data.model").equals("64")) {
|
|
||||||
NativeUtils.loadLibraryFromJar("/lib/ZeroTierOneJNI_win64.dll");
|
|
||||||
} else {
|
|
||||||
NativeUtils.loadLibraryFromJar("/lib/ZeroTierOneJNI_win32.dll");
|
|
||||||
}
|
|
||||||
} else if(System.getProperty("os.name").startsWith("Mac")) {
|
|
||||||
NativeUtils.loadLibraryFromJar("/lib/libZeroTierOneJNI.jnilib");
|
|
||||||
} else {
|
|
||||||
// TODO: Linux
|
|
||||||
}
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ioe.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String TAG = "NODE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node ID for JNI purposes.
|
|
||||||
* Currently set to the now value passed in at the constructor
|
|
||||||
*
|
|
||||||
* -1 if the node has already been closed
|
|
||||||
*/
|
|
||||||
private long nodeId;
|
|
||||||
|
|
||||||
private final DataStoreGetListener getListener;
|
|
||||||
private final DataStorePutListener putListener;
|
|
||||||
private final PacketSender sender;
|
|
||||||
private final EventListener eventListener;
|
|
||||||
private final VirtualNetworkFrameListener frameListener;
|
|
||||||
private final VirtualNetworkConfigListener configListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new ZeroTier One node
|
|
||||||
*
|
|
||||||
* <p>Note that this can take a few seconds the first time it's called, as it
|
|
||||||
* will generate an identity.</p>
|
|
||||||
*
|
|
||||||
* @param now Current clock in milliseconds
|
|
||||||
* @param getListener User written instance of the {@link DataStoreGetListener} interface called to get objects from persistent storage. This instance must be unique per Node object.
|
|
||||||
* @param putListener User written intstance of the {@link DataStorePutListener} interface called to put objects in persistent storage. This instance must be unique per Node object.
|
|
||||||
* @param sender
|
|
||||||
* @param eventListener User written instance of the {@link EventListener} interface to receive status updates and non-fatal error notices. This instance must be unique per Node object.
|
|
||||||
* @param frameListener
|
|
||||||
* @param configListener User written instance of the {@link VirtualNetworkConfigListener} interface to be called when virtual LANs are created, deleted, or their config parameters change. This instance must be unique per Node object.
|
|
||||||
*/
|
|
||||||
public Node(long now,
|
|
||||||
DataStoreGetListener getListener,
|
|
||||||
DataStorePutListener putListener,
|
|
||||||
PacketSender sender,
|
|
||||||
EventListener eventListener,
|
|
||||||
VirtualNetworkFrameListener frameListener,
|
|
||||||
VirtualNetworkConfigListener configListener) throws NodeException
|
|
||||||
{
|
|
||||||
this.nodeId = now;
|
|
||||||
|
|
||||||
this.getListener = getListener;
|
|
||||||
this.putListener = putListener;
|
|
||||||
this.sender = sender;
|
|
||||||
this.eventListener = eventListener;
|
|
||||||
this.frameListener = frameListener;
|
|
||||||
this.configListener = configListener;
|
|
||||||
|
|
||||||
ResultCode rc = node_init(now);
|
|
||||||
if(rc != ResultCode.RESULT_OK)
|
|
||||||
{
|
|
||||||
// TODO: Throw Exception
|
|
||||||
throw new NodeException(rc.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close this Node.
|
|
||||||
*
|
|
||||||
* <p>The Node object can no longer be used once this method is called.</p>
|
|
||||||
*/
|
|
||||||
public void close() {
|
|
||||||
if(nodeId != -1) {
|
|
||||||
node_delete(nodeId);
|
|
||||||
nodeId = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a frame from a virtual network port
|
|
||||||
*
|
|
||||||
* @param now Current clock in milliseconds
|
|
||||||
* @param nwid ZeroTier 64-bit virtual network ID
|
|
||||||
* @param sourceMac Source MAC address (least significant 48 bits)
|
|
||||||
* @param destMac Destination MAC address (least significant 48 bits)
|
|
||||||
* @param etherType 16-bit Ethernet frame type
|
|
||||||
* @param vlanId 10-bit VLAN ID or 0 if none
|
|
||||||
* @param frameData Frame payload data
|
|
||||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode processVirtualNetworkFrame(
|
|
||||||
long now,
|
|
||||||
long nwid,
|
|
||||||
long sourceMac,
|
|
||||||
long destMac,
|
|
||||||
int etherType,
|
|
||||||
int vlanId,
|
|
||||||
byte[] frameData,
|
|
||||||
long[] nextBackgroundTaskDeadline) {
|
|
||||||
return processVirtualNetworkFrame(
|
|
||||||
nodeId, now, nwid, sourceMac, destMac, etherType, vlanId,
|
|
||||||
frameData, nextBackgroundTaskDeadline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a packet received from the physical wire
|
|
||||||
*
|
|
||||||
* @param now Current clock in milliseconds
|
|
||||||
* @param remoteAddress Origin of packet
|
|
||||||
* @param packetData Packet data
|
|
||||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode processWirePacket(
|
|
||||||
long now,
|
|
||||||
InetSocketAddress localAddress,
|
|
||||||
InetSocketAddress remoteAddress,
|
|
||||||
byte[] packetData,
|
|
||||||
long[] nextBackgroundTaskDeadline) {
|
|
||||||
return processWirePacket(
|
|
||||||
nodeId, now, localAddress, remoteAddress, packetData,
|
|
||||||
nextBackgroundTaskDeadline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform periodic background operations
|
|
||||||
*
|
|
||||||
* @param now Current clock in milliseconds
|
|
||||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode processBackgroundTasks(long now, long[] nextBackgroundTaskDeadline) {
|
|
||||||
return processBackgroundTasks(nodeId, now, nextBackgroundTaskDeadline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Join a network
|
|
||||||
*
|
|
||||||
* <p>This may generate calls to the port config callback before it returns,
|
|
||||||
* or these may be deffered if a netconf is not available yet.</p>
|
|
||||||
*
|
|
||||||
* <p>If we are already a member of the network, nothing is done and OK is
|
|
||||||
* returned.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit ZeroTier network ID
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode join(long nwid) {
|
|
||||||
return join(nodeId, nwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Leave a network
|
|
||||||
*
|
|
||||||
* <p>If a port has been configured for this network this will generate a call
|
|
||||||
* to the port config callback with a NULL second parameter to indicate that
|
|
||||||
* the port is now deleted.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode leave(long nwid) {
|
|
||||||
return leave(nodeId, nwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to an Ethernet multicast group
|
|
||||||
*
|
|
||||||
* <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
|
|
||||||
* broadcast address) but with an ADI equal to each IPv4 address in host
|
|
||||||
* byte order. This converts ARP from a non-scalable broadcast protocol to
|
|
||||||
* a scalable multicast protocol with perfect address specificity.</p>
|
|
||||||
*
|
|
||||||
* <p>If this is not done, ARP will not work reliably.</p>
|
|
||||||
*
|
|
||||||
* <p>Multiple calls to subscribe to the same multicast address will have no
|
|
||||||
* effect. It is perfectly safe to do this.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastSubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup) {
|
|
||||||
return multicastSubscribe(nodeId, nwid, multicastGroup, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to an Ethernet multicast group
|
|
||||||
*
|
|
||||||
* <p>ADI stands for additional distinguishing information. This defaults to zero
|
|
||||||
* and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
|
|
||||||
* and this must be done.</p>
|
|
||||||
*
|
|
||||||
* <p>For IPv4 ARP, the implementation must subscribe to 0xffffffffffff (the
|
|
||||||
* broadcast address) but with an ADI equal to each IPv4 address in host
|
|
||||||
* byte order. This converts ARP from a non-scalable broadcast protocol to
|
|
||||||
* a scalable multicast protocol with perfect address specificity.</p>
|
|
||||||
*
|
|
||||||
* <p>If this is not done, ARP will not work reliably.</p>
|
|
||||||
*
|
|
||||||
* <p>Multiple calls to subscribe to the same multicast address will have no
|
|
||||||
* effect. It is perfectly safe to do this.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastSubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi) {
|
|
||||||
return multicastSubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe from an Ethernet multicast group (or all groups)
|
|
||||||
*
|
|
||||||
* <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
|
|
||||||
* you are not subscribed to a group this has no effect.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastUnsubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup) {
|
|
||||||
return multicastUnsubscribe(nodeId, nwid, multicastGroup, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe from an Ethernet multicast group (or all groups)
|
|
||||||
*
|
|
||||||
* <p>If multicastGroup is zero (0), this will unsubscribe from all groups. If
|
|
||||||
* you are not subscribed to a group this has no effect.</p>
|
|
||||||
*
|
|
||||||
* <p>This does not generate an update call to the {@link VirtualNetworkConfigListener#onNetworkConfigurationUpdated} method.</p>
|
|
||||||
*
|
|
||||||
* <p>ADI stands for additional distinguishing information. This defaults to zero
|
|
||||||
* and is rarely used. Right now its only use is to enable IPv4 ARP to scale,
|
|
||||||
* and this must be done.</p>
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
|
||||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
|
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
|
||||||
*/
|
|
||||||
public ResultCode multicastUnsubscribe(
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi) {
|
|
||||||
return multicastUnsubscribe(nodeId, nwid, multicastGroup, multicastAdi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get this node's 40-bit ZeroTier address
|
|
||||||
*
|
|
||||||
* @return ZeroTier address (least significant 40 bits of 64-bit int)
|
|
||||||
*/
|
|
||||||
public long address() {
|
|
||||||
return address(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of this node
|
|
||||||
*
|
|
||||||
* @return @{link NodeStatus} struct with the current node status.
|
|
||||||
*/
|
|
||||||
public NodeStatus status() {
|
|
||||||
return status(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of known peer nodes
|
|
||||||
*
|
|
||||||
* @return List of known peers or NULL on failure
|
|
||||||
*/
|
|
||||||
public Peer[] peers() {
|
|
||||||
return peers(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of a virtual network
|
|
||||||
*
|
|
||||||
* @param nwid 64-bit network ID
|
|
||||||
* @return {@link VirtualNetworkConfig} or NULL if we are not a member of this network
|
|
||||||
*/
|
|
||||||
public VirtualNetworkConfig networkConfig(long nwid) {
|
|
||||||
return networkConfig(nodeId, nwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enumerate and get status of all networks
|
|
||||||
*
|
|
||||||
* @return List of networks or NULL on failure
|
|
||||||
*/
|
|
||||||
public VirtualNetworkConfig[] networks() {
|
|
||||||
return networks(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get ZeroTier One version
|
|
||||||
*
|
|
||||||
* @return {@link Version} object with ZeroTierOne version information.
|
|
||||||
*/
|
|
||||||
public Version getVersion() {
|
|
||||||
return version();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// function declarations for JNI
|
|
||||||
//
|
|
||||||
private native ResultCode node_init(long now);
|
|
||||||
|
|
||||||
private native void node_delete(long nodeId);
|
|
||||||
|
|
||||||
private native ResultCode processVirtualNetworkFrame(
|
|
||||||
long nodeId,
|
|
||||||
long now,
|
|
||||||
long nwid,
|
|
||||||
long sourceMac,
|
|
||||||
long destMac,
|
|
||||||
int etherType,
|
|
||||||
int vlanId,
|
|
||||||
byte[] frameData,
|
|
||||||
long[] nextBackgroundTaskDeadline);
|
|
||||||
|
|
||||||
private native ResultCode processWirePacket(
|
|
||||||
long nodeId,
|
|
||||||
long now,
|
|
||||||
InetSocketAddress localAddress,
|
|
||||||
InetSocketAddress remoteAddress,
|
|
||||||
byte[] packetData,
|
|
||||||
long[] nextBackgroundTaskDeadline);
|
|
||||||
|
|
||||||
private native ResultCode processBackgroundTasks(
|
|
||||||
long nodeId,
|
|
||||||
long now,
|
|
||||||
long[] nextBackgroundTaskDeadline);
|
|
||||||
|
|
||||||
private native ResultCode join(long nodeId, long nwid);
|
|
||||||
|
|
||||||
private native ResultCode leave(long nodeId, long nwid);
|
|
||||||
|
|
||||||
private native ResultCode multicastSubscribe(
|
|
||||||
long nodeId,
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi);
|
|
||||||
|
|
||||||
private native ResultCode multicastUnsubscribe(
|
|
||||||
long nodeId,
|
|
||||||
long nwid,
|
|
||||||
long multicastGroup,
|
|
||||||
long multicastAdi);
|
|
||||||
|
|
||||||
private native long address(long nodeId);
|
|
||||||
|
|
||||||
private native NodeStatus status(long nodeId);
|
|
||||||
|
|
||||||
private native VirtualNetworkConfig networkConfig(long nodeId, long nwid);
|
|
||||||
|
|
||||||
private native Version version();
|
|
||||||
|
|
||||||
private native Peer[] peers(long nodeId);
|
|
||||||
|
|
||||||
private native VirtualNetworkConfig[] networks(long nodeId);
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public final class NodeStatus {
|
|
||||||
private long address;
|
|
||||||
private String publicIdentity;
|
|
||||||
private String secretIdentity;
|
|
||||||
private boolean online;
|
|
||||||
|
|
||||||
private NodeStatus() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 40-bit ZeroTier address of this node
|
|
||||||
*/
|
|
||||||
public final long getAddres() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public identity in string-serialized form (safe to send to others)
|
|
||||||
*
|
|
||||||
* <p>This identity will remain valid as long as the node exists.</p>
|
|
||||||
*/
|
|
||||||
public final String getPublicIdentity() {
|
|
||||||
return publicIdentity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Full identity including secret key in string-serialized form
|
|
||||||
*
|
|
||||||
* <p>This identity will remain valid as long as the node exists.</p>
|
|
||||||
*/
|
|
||||||
public final String getSecretIdentity() {
|
|
||||||
return secretIdentity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if some kind of connectivity appears available
|
|
||||||
*/
|
|
||||||
public final boolean isOnline() {
|
|
||||||
return online;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
|
|
||||||
public interface PacketSender {
|
|
||||||
/**
|
|
||||||
* Function to send a ZeroTier packet out over the wire
|
|
||||||
*
|
|
||||||
* <p>The function must return zero on success and may return any error code
|
|
||||||
* on failure. Note that success does not (of course) guarantee packet
|
|
||||||
* delivery. It only means that the packet appears to have been sent.</p>
|
|
||||||
*
|
|
||||||
* @param localAddr {@link InetSocketAddress} to send from. Set to null if not specified.
|
|
||||||
* @param remoteAddr {@link InetSocketAddress} to send to
|
|
||||||
* @param packetData data to send
|
|
||||||
* @return 0 on success, any error code on failure.
|
|
||||||
*/
|
|
||||||
public int onSendPacketRequested(
|
|
||||||
InetSocketAddress localAddr,
|
|
||||||
InetSocketAddress remoteAddr,
|
|
||||||
byte[] packetData,
|
|
||||||
int ttl);
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Peer status result
|
|
||||||
*/
|
|
||||||
public final class Peer {
|
|
||||||
private long address;
|
|
||||||
private long lastUnicastFrame;
|
|
||||||
private long lastMulticastFrame;
|
|
||||||
private int versionMajor;
|
|
||||||
private int versionMinor;
|
|
||||||
private int versionRev;
|
|
||||||
private int latency;
|
|
||||||
private PeerRole role;
|
|
||||||
private PeerPhysicalPath[] paths;
|
|
||||||
|
|
||||||
private Peer() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZeroTier address (40 bits)
|
|
||||||
*/
|
|
||||||
public final long address() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time we last received a unicast frame from this peer
|
|
||||||
*/
|
|
||||||
public final long lastUnicastFrame() {
|
|
||||||
return lastUnicastFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time we last received a multicast rame from this peer
|
|
||||||
*/
|
|
||||||
public final long lastMulticastFrame() {
|
|
||||||
return lastMulticastFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote major version or -1 if not known
|
|
||||||
*/
|
|
||||||
public final int versionMajor() {
|
|
||||||
return versionMajor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote minor version or -1 if not known
|
|
||||||
*/
|
|
||||||
public final int versionMinor() {
|
|
||||||
return versionMinor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote revision or -1 if not known
|
|
||||||
*/
|
|
||||||
public final int versionRev() {
|
|
||||||
return versionRev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Last measured latency in milliseconds or zero if unknown
|
|
||||||
*/
|
|
||||||
public final int latency() {
|
|
||||||
return latency;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* What trust hierarchy role does this device have?
|
|
||||||
*/
|
|
||||||
public final PeerRole role() {
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Known network paths to peer
|
|
||||||
*/
|
|
||||||
public final PeerPhysicalPath[] paths() {
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Physical network path to a peer
|
|
||||||
*/
|
|
||||||
public final class PeerPhysicalPath {
|
|
||||||
private InetSocketAddress address;
|
|
||||||
private long lastSend;
|
|
||||||
private long lastReceive;
|
|
||||||
private boolean fixed;
|
|
||||||
private boolean active;
|
|
||||||
private boolean preferred;
|
|
||||||
|
|
||||||
private PeerPhysicalPath() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address of endpoint
|
|
||||||
*/
|
|
||||||
public final InetSocketAddress address() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time of last send in milliseconds or 0 for never
|
|
||||||
*/
|
|
||||||
public final long lastSend() {
|
|
||||||
return lastSend;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time of last receive in milliseconds or 0 for never
|
|
||||||
*/
|
|
||||||
public final long lastReceive() {
|
|
||||||
return lastReceive;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is path fixed? (i.e. not learned, static)
|
|
||||||
*/
|
|
||||||
public final boolean isFixed() {
|
|
||||||
return fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is path active?
|
|
||||||
*/
|
|
||||||
public final boolean isActive() {
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is path preferred?
|
|
||||||
*/
|
|
||||||
public final boolean isPreferred() {
|
|
||||||
return preferred;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum PeerRole {
|
|
||||||
/**
|
|
||||||
* An ordinary node
|
|
||||||
*/
|
|
||||||
PEER_ROLE_LEAF,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* relay node
|
|
||||||
*/
|
|
||||||
PEER_ROLE_RELAY,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* root server
|
|
||||||
*/
|
|
||||||
PEER_ROLE_ROOT
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function return code: OK (0) or error results
|
|
||||||
*
|
|
||||||
* <p>Use {@link ResultCode#isFatal) to check for a fatal error. If a fatal error
|
|
||||||
* occurs, the node should be considered to not be working correctly. These
|
|
||||||
* indicate serious problems like an inaccessible data store or a compile
|
|
||||||
* problem.</p>
|
|
||||||
*/
|
|
||||||
public enum ResultCode {
|
|
||||||
/**
|
|
||||||
* Operation completed normally
|
|
||||||
*/
|
|
||||||
RESULT_OK(0),
|
|
||||||
|
|
||||||
// Fatal errors (> 0, < 1000)
|
|
||||||
/**
|
|
||||||
* Ran out of memory
|
|
||||||
*/
|
|
||||||
RESULT_FATAL_ERROR_OUT_OF_MEMORY(1),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data store is not writable or has failed
|
|
||||||
*/
|
|
||||||
RESULT_FATAL_ERROR_DATA_STORE_FAILED(2),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal error (e.g. unexpected exception indicating bug or build problem)
|
|
||||||
*/
|
|
||||||
RESULT_FATAL_ERROR_INTERNAL(3),
|
|
||||||
|
|
||||||
// non-fatal errors
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network ID not valid
|
|
||||||
*/
|
|
||||||
RESULT_ERROR_NETWORK_NOT_FOUND(1000);
|
|
||||||
|
|
||||||
private final int id;
|
|
||||||
ResultCode(int id) { this.id = id; }
|
|
||||||
public int getValue() { return id; }
|
|
||||||
|
|
||||||
public boolean isFatal(int id) {
|
|
||||||
return (id > 0 && id < 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public final class Version {
|
|
||||||
private Version() {}
|
|
||||||
|
|
||||||
public int major = 0;
|
|
||||||
public int minor = 0;
|
|
||||||
public int revision = 0;
|
|
||||||
public long featureFlags = 0;
|
|
||||||
}
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
import java.lang.Comparable;
|
|
||||||
import java.lang.Override;
|
|
||||||
import java.lang.String;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
public final class VirtualNetworkConfig implements Comparable<VirtualNetworkConfig> {
|
|
||||||
public static final int MAX_MULTICAST_SUBSCRIPTIONS = 4096;
|
|
||||||
public static final int ZT_MAX_ZT_ASSIGNED_ADDRESSES = 16;
|
|
||||||
|
|
||||||
private long nwid;
|
|
||||||
private long mac;
|
|
||||||
private String name;
|
|
||||||
private VirtualNetworkStatus status;
|
|
||||||
private VirtualNetworkType type;
|
|
||||||
private int mtu;
|
|
||||||
private boolean dhcp;
|
|
||||||
private boolean bridge;
|
|
||||||
private boolean broadcastEnabled;
|
|
||||||
private int portError;
|
|
||||||
private boolean enabled;
|
|
||||||
private long netconfRevision;
|
|
||||||
private MulticastGroup[] multicastSubscriptions;
|
|
||||||
private InetSocketAddress[] assignedAddresses;
|
|
||||||
|
|
||||||
private VirtualNetworkConfig() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(VirtualNetworkConfig cfg) {
|
|
||||||
boolean aaEqual = true;
|
|
||||||
if(assignedAddresses.length == cfg.assignedAddresses.length) {
|
|
||||||
for(int i = 0; i < assignedAddresses.length; ++i) {
|
|
||||||
if(!assignedAddresses[i].equals(cfg.assignedAddresses[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
aaEqual = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nwid == cfg.nwid &&
|
|
||||||
mac == cfg.mac &&
|
|
||||||
name.equals(cfg.name) &&
|
|
||||||
status.equals(cfg.status) &&
|
|
||||||
type.equals(cfg.type) &&
|
|
||||||
mtu == cfg.mtu &&
|
|
||||||
dhcp == cfg.dhcp &&
|
|
||||||
bridge == cfg.bridge &&
|
|
||||||
broadcastEnabled == cfg.broadcastEnabled &&
|
|
||||||
portError == cfg.portError &&
|
|
||||||
enabled == cfg.enabled &&
|
|
||||||
aaEqual;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(VirtualNetworkConfig cfg) {
|
|
||||||
if(cfg.nwid == this.nwid) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return this.nwid > cfg.nwid ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 64-bit ZeroTier network ID
|
|
||||||
*/
|
|
||||||
public final long networkId() {
|
|
||||||
return nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ethernet MAC (40 bits) that should be assigned to port
|
|
||||||
*/
|
|
||||||
public final long macAddress() {
|
|
||||||
return mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network name (from network configuration master)
|
|
||||||
*/
|
|
||||||
public final String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network configuration request status
|
|
||||||
*/
|
|
||||||
public final VirtualNetworkStatus networkStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network type
|
|
||||||
*/
|
|
||||||
public final VirtualNetworkType networkType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum interface MTU
|
|
||||||
*/
|
|
||||||
public final int mtu() {
|
|
||||||
return mtu;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the network this port belongs to indicates DHCP availability
|
|
||||||
*
|
|
||||||
* <p>This is a suggestion. The underlying implementation is free to ignore it
|
|
||||||
* for security or other reasons. This is simply a netconf parameter that
|
|
||||||
* means 'DHCP is available on this network.'</p>
|
|
||||||
*/
|
|
||||||
public final boolean isDhcpAvailable() {
|
|
||||||
return dhcp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this port is allowed to bridge to other networks
|
|
||||||
*
|
|
||||||
* <p>This is informational. If this is false, bridged packets will simply
|
|
||||||
* be dropped and bridging won't work.</p>
|
|
||||||
*/
|
|
||||||
public final boolean isBridgeEnabled() {
|
|
||||||
return bridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic
|
|
||||||
*/
|
|
||||||
public final boolean broadcastEnabled() {
|
|
||||||
return broadcastEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the network is in PORT_ERROR state, this is the error most recently returned by the port config callback
|
|
||||||
*/
|
|
||||||
public final int portError() {
|
|
||||||
return portError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this network enabled? If not, all frames to/from are dropped.
|
|
||||||
*/
|
|
||||||
public final boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network config revision as reported by netconf master
|
|
||||||
*
|
|
||||||
* <p>If this is zero, it means we're still waiting for our netconf.</p>
|
|
||||||
*/
|
|
||||||
public final long netconfRevision() {
|
|
||||||
return netconfRevision;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multicast group subscriptions
|
|
||||||
*/
|
|
||||||
public final MulticastGroup[] multicastSubscriptions() {
|
|
||||||
return multicastSubscriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZeroTier-assigned addresses (in {@link java.net.InetSocketAddress} objects)
|
|
||||||
*
|
|
||||||
* For IP, the port number of the sockaddr_XX structure contains the number
|
|
||||||
* of bits in the address netmask. Only the IP address and port are used.
|
|
||||||
* Other fields like interface number can be ignored.
|
|
||||||
*
|
|
||||||
* This is only used for ZeroTier-managed address assignments sent by the
|
|
||||||
* virtual network's configuration master.
|
|
||||||
*/
|
|
||||||
public final InetSocketAddress[] assignedAddresses() {
|
|
||||||
return assignedAddresses;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
|
|
||||||
public interface VirtualNetworkConfigListener {
|
|
||||||
/**
|
|
||||||
* Callback called to update virtual network port configuration
|
|
||||||
*
|
|
||||||
* <p>This can be called at any time to update the configuration of a virtual
|
|
||||||
* network port. The parameter after the network ID specifies whether this
|
|
||||||
* port is being brought up, updated, brought down, or permanently deleted.
|
|
||||||
*
|
|
||||||
* This in turn should be used by the underlying implementation to create
|
|
||||||
* and configure tap devices at the OS (or virtual network stack) layer.</P>
|
|
||||||
*
|
|
||||||
* This should not call {@link Node#multicastSubscribe} or other network-modifying
|
|
||||||
* methods, as this could cause a deadlock in multithreaded or interrupt
|
|
||||||
* driven environments.
|
|
||||||
*
|
|
||||||
* This must return 0 on success. It can return any OS-dependent error code
|
|
||||||
* on failure, and this results in the network being placed into the
|
|
||||||
* PORT_ERROR state.
|
|
||||||
*
|
|
||||||
* @param nwid network id
|
|
||||||
* @param op {@link VirtualNetworkConfigOperation} enum describing the configuration operation
|
|
||||||
* @param config {@link VirtualNetworkConfig} object with the new configuration
|
|
||||||
* @return 0 on success
|
|
||||||
*/
|
|
||||||
public int onNetworkConfigurationUpdated(
|
|
||||||
long nwid,
|
|
||||||
VirtualNetworkConfigOperation op,
|
|
||||||
VirtualNetworkConfig config);
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum VirtualNetworkConfigOperation {
|
|
||||||
/**
|
|
||||||
* Network is coming up (either for the first time or after service restart)
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_UP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network configuration has been updated
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network is going down (not permanently)
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network is going down permanently (leave/delete)
|
|
||||||
*/
|
|
||||||
VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public interface VirtualNetworkFrameListener {
|
|
||||||
/**
|
|
||||||
* Function to send a frame out to a virtual network port
|
|
||||||
*
|
|
||||||
* @param nwid ZeroTier One network ID
|
|
||||||
* @param srcMac source MAC address
|
|
||||||
* @param destMac destination MAC address
|
|
||||||
* @param ethertype
|
|
||||||
* @param vlanId
|
|
||||||
* @param frameData data to send
|
|
||||||
*/
|
|
||||||
public void onVirtualNetworkFrame(
|
|
||||||
long nwid,
|
|
||||||
long srcMac,
|
|
||||||
long destMac,
|
|
||||||
long etherType,
|
|
||||||
long vlanId,
|
|
||||||
byte[] frameData);
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
package com.zerotier.sdk;
|
|
||||||
|
|
||||||
public enum VirtualNetworkStatus {
|
|
||||||
/**
|
|
||||||
* Waiting for network configuration (also means revision == 0)
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_REQUESTING_CONFIGURATION,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration received and we are authorized
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_OK,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Netconf master told us 'nope'
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_ACCESS_DENIED,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Netconf master exists, but this virtual network does not
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_NOT_FOUND,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization of network failed or other internal error
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_PORT_ERROR,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZeroTier One version too old
|
|
||||||
*/
|
|
||||||
NETWORK_STATUS_CLIENT_TOO_OLD
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.GoogleAnalytics;
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 8/25/2015.
|
|
||||||
*/
|
|
||||||
public class AnalyticsApplication extends Application {
|
|
||||||
private Tracker mTracker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the default {@link Tracker} for this {@link Application}.
|
|
||||||
* @return tracker
|
|
||||||
*/
|
|
||||||
synchronized public Tracker getDefaultTracker() {
|
|
||||||
if (mTracker == null) {
|
|
||||||
SharedPreferences prefs = getSharedPreferences("user", MODE_PRIVATE);
|
|
||||||
|
|
||||||
String uuid = UUID.randomUUID().toString();
|
|
||||||
String savedUUID = prefs.getString("uuid", UUID.randomUUID().toString());
|
|
||||||
|
|
||||||
if(savedUUID.equals(uuid)) {
|
|
||||||
// this is a newly generated UUID. Save it
|
|
||||||
SharedPreferences.Editor e = prefs.edit();
|
|
||||||
e.putString("uuid", savedUUID);
|
|
||||||
e.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
|
|
||||||
// To enable debug logging use: adb shell setprop log.tag.GAv4 DEBUG
|
|
||||||
mTracker = analytics.newTracker(R.xml.app_tracker);
|
|
||||||
|
|
||||||
mTracker.set("&uid", savedUUID);
|
|
||||||
|
|
||||||
mTracker.send(new HitBuilders.ScreenViewBuilder()
|
|
||||||
.setNewSession()
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
return mTracker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package com.zerotier.one;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.GoogleAnalytics;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of Google Analytics trackers. Fetch the tracker you need using
|
|
||||||
* {@code AnalyticsTrackers.getInstance().get(...)}
|
|
||||||
* <p/>
|
|
||||||
* This code was generated by Android Studio but can be safely modified by
|
|
||||||
* hand at this point.
|
|
||||||
* <p/>
|
|
||||||
* TODO: Call {@link #initialize(Context)} from an entry point in your app
|
|
||||||
* before using this!
|
|
||||||
*/
|
|
||||||
public final class AnalyticsTrackers {
|
|
||||||
|
|
||||||
public enum Target {
|
|
||||||
APP,
|
|
||||||
// Add more trackers here if you need, and update the code in #get(Target) below
|
|
||||||
}
|
|
||||||
|
|
||||||
private static AnalyticsTrackers sInstance;
|
|
||||||
|
|
||||||
public static synchronized void initialize(Context context) {
|
|
||||||
if (sInstance != null) {
|
|
||||||
throw new IllegalStateException("Extra call to initialize analytics trackers");
|
|
||||||
}
|
|
||||||
|
|
||||||
sInstance = new AnalyticsTrackers(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized AnalyticsTrackers getInstance() {
|
|
||||||
if (sInstance == null) {
|
|
||||||
throw new IllegalStateException("Call initialize() before getInstance()");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Map<Target, Tracker> mTrackers = new HashMap<Target, Tracker>();
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't instantiate directly - use {@link #getInstance()} instead.
|
|
||||||
*/
|
|
||||||
private AnalyticsTrackers(Context context) {
|
|
||||||
mContext = context.getApplicationContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Tracker get(Target target) {
|
|
||||||
if (!mTrackers.containsKey(target)) {
|
|
||||||
Tracker tracker;
|
|
||||||
switch (target) {
|
|
||||||
case APP:
|
|
||||||
tracker = GoogleAnalytics.getInstance(mContext).newTracker(R.xml.app_tracker);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unhandled analytics target " + target);
|
|
||||||
}
|
|
||||||
mTrackers.put(target, tracker);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mTrackers.get(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class ErrorEvent {
|
|
||||||
ResultCode result;
|
|
||||||
|
|
||||||
public ErrorEvent(ResultCode rc) {
|
|
||||||
result = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getError() {
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.one.ui.JoinNetworkFragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class JoinNetworkEvent {
|
|
||||||
private long networkId;
|
|
||||||
|
|
||||||
public JoinNetworkEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class LeaveNetworkEvent {
|
|
||||||
long networkId;
|
|
||||||
|
|
||||||
public LeaveNetworkEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 8/4/2015.
|
|
||||||
*/
|
|
||||||
public class ManualDisconnectEvent {
|
|
||||||
public ManualDisconnectEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkInfoReplyEvent {
|
|
||||||
private VirtualNetworkConfig vnc;
|
|
||||||
|
|
||||||
public NetworkInfoReplyEvent(VirtualNetworkConfig vnc) {
|
|
||||||
this.vnc = vnc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VirtualNetworkConfig getNetworkInfo() {
|
|
||||||
return vnc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkListReplyEvent {
|
|
||||||
private VirtualNetworkConfig[] networks;
|
|
||||||
|
|
||||||
public NetworkListReplyEvent(VirtualNetworkConfig[] networks) {
|
|
||||||
this.networks = networks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VirtualNetworkConfig[] getNetworkList() {
|
|
||||||
return networks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import android.net.Network;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/24/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkReconfigureEvent {
|
|
||||||
public NetworkReconfigureEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkRemovedEvent {
|
|
||||||
private long networkId;
|
|
||||||
|
|
||||||
public NetworkRemovedEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/28/2015.
|
|
||||||
*/
|
|
||||||
public class NodeDestroyedEvent {
|
|
||||||
public NodeDestroyedEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/9/2015.
|
|
||||||
*/
|
|
||||||
public class NodeIDEvent {
|
|
||||||
private long nodeId;
|
|
||||||
|
|
||||||
public NodeIDEvent(long nodeId) {
|
|
||||||
this.nodeId = nodeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNodeId() {
|
|
||||||
return nodeId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.NodeStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/9/2015.
|
|
||||||
*/
|
|
||||||
public class NodeStatusEvent {
|
|
||||||
private NodeStatus status;
|
|
||||||
|
|
||||||
public NodeStatusEvent(NodeStatus status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeStatus getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class RequestNetworkInfoEvent {
|
|
||||||
private long networkId;
|
|
||||||
|
|
||||||
public RequestNetworkInfoEvent(long nwid) {
|
|
||||||
networkId = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNetworkId() {
|
|
||||||
return networkId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/23/2015.
|
|
||||||
*/
|
|
||||||
public class RequestNetworkListEvent {
|
|
||||||
public RequestNetworkListEvent() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 8/1/2015.
|
|
||||||
*/
|
|
||||||
public class RequestNodeStatusEvent {
|
|
||||||
public RequestNodeStatusEvent() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.zerotier.one.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/9/2015.
|
|
||||||
*/
|
|
||||||
public class StopEvent {
|
|
||||||
public StopEvent() {}
|
|
||||||
}
|
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class ARPTable {
|
|
||||||
public static final String TAG = "ARPTable";
|
|
||||||
|
|
||||||
private static final int REQUEST = 1;
|
|
||||||
private static final int REPLY = 2;
|
|
||||||
|
|
||||||
private final HashMap<InetAddress, Long> inetAddressToMacAddress;
|
|
||||||
private final HashMap<Long, InetAddress> macAddressToInetAdddress;
|
|
||||||
|
|
||||||
private static final long ENTRY_TIMEOUT = 120000L; // 2 minutes
|
|
||||||
|
|
||||||
private final ArrayList<ArpEntry> entries;
|
|
||||||
|
|
||||||
public ARPTable() {
|
|
||||||
entries = new ArrayList<ArpEntry>();
|
|
||||||
inetAddressToMacAddress = new HashMap<InetAddress, Long>();
|
|
||||||
macAddressToInetAdddress = new HashMap<Long, InetAddress>();
|
|
||||||
timeoutThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
timeoutThread.interrupt();
|
|
||||||
super.finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAddress(InetAddress addr, long mac) {
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
inetAddressToMacAddress.put(addr, mac);
|
|
||||||
}
|
|
||||||
synchronized (macAddressToInetAdddress) {
|
|
||||||
macAddressToInetAdddress.put(mac, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (entries) {
|
|
||||||
ArpEntry entry = new ArpEntry(mac, addr);
|
|
||||||
if(entries.contains(entry)) {
|
|
||||||
// update the entry time
|
|
||||||
int index = entries.indexOf(entry);
|
|
||||||
entries.get(index).updateTime();
|
|
||||||
} else {
|
|
||||||
entries.add(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateArpEntryTime(long mac) {
|
|
||||||
synchronized (entries) {
|
|
||||||
for(ArpEntry e : entries) {
|
|
||||||
if(mac == e.getMac()) {
|
|
||||||
e.updateTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateArpEntryTime(InetAddress addr) {
|
|
||||||
synchronized (entries) {
|
|
||||||
for(ArpEntry e : entries) {
|
|
||||||
if(addr.equals(e.getAddress())) {
|
|
||||||
e.updateTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MAC address for a given InetAddress
|
|
||||||
*
|
|
||||||
* @param addr address to get the MAC for
|
|
||||||
* @return MAC address as long. -1 if the address isn't known
|
|
||||||
*/
|
|
||||||
long getMacForAddress(InetAddress addr) {
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
if(inetAddressToMacAddress.containsKey(addr)) {
|
|
||||||
long mac = inetAddressToMacAddress.get(addr);
|
|
||||||
updateArpEntryTime(mac);
|
|
||||||
return mac;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the InetAddress for a given MAC address
|
|
||||||
*
|
|
||||||
* @param mac mac address to lookup.
|
|
||||||
* @return InetAddress if it's in the map. Otherwise null.
|
|
||||||
*/
|
|
||||||
InetAddress getAddressForMac(long mac) {
|
|
||||||
synchronized (macAddressToInetAdddress) {
|
|
||||||
if (macAddressToInetAdddress.containsKey(mac)) {
|
|
||||||
InetAddress addr = macAddressToInetAdddress.get(mac);
|
|
||||||
updateArpEntryTime(addr);
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasMacForAddress(InetAddress addr) {
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
return inetAddressToMacAddress.containsKey(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAddressForMac(long mac) {
|
|
||||||
synchronized (macAddressToInetAdddress) {
|
|
||||||
return macAddressToInetAdddress.containsKey(mac);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] longToBytes(long l) {
|
|
||||||
// allocate an 8 byte buffer. Long.SIZE returns number of bits so divide by 8
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE/8);
|
|
||||||
buffer.putLong(l);
|
|
||||||
return buffer.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getRequestPacket(long senderMac, InetAddress senderAddress, InetAddress destinationAddress) {
|
|
||||||
return getARPPacket(REQUEST, senderMac, 0, senderAddress, destinationAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getReplyPacket(long senderMac, InetAddress senderAddress, long destMac, InetAddress destAddress) {
|
|
||||||
return getARPPacket(REPLY, senderMac, destMac, senderAddress, destAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getARPPacket(int packetType, long senderMac, long destMac, InetAddress senderAddress, InetAddress destinationAddress) {
|
|
||||||
byte[] packet = new byte[28];
|
|
||||||
|
|
||||||
// Ethernet packet type
|
|
||||||
packet[0] = 0;
|
|
||||||
packet[1] = 1;
|
|
||||||
|
|
||||||
// IPV4 Protocol. 0x0800
|
|
||||||
packet[2] = 0x08;
|
|
||||||
packet[3] = 0;
|
|
||||||
|
|
||||||
// Hardware MAC address length
|
|
||||||
packet[4] = 6;
|
|
||||||
|
|
||||||
// IP address length
|
|
||||||
packet[5] = 4;
|
|
||||||
|
|
||||||
packet[6] = 0;
|
|
||||||
packet[7] = (byte)packetType;
|
|
||||||
|
|
||||||
byte[] senderMacBuffer = longToBytes(senderMac);
|
|
||||||
System.arraycopy(senderMacBuffer, 2, packet, 8, 6);
|
|
||||||
|
|
||||||
byte[] addrBuffer = senderAddress.getAddress();
|
|
||||||
System.arraycopy(addrBuffer, 0, packet, 14, 4);
|
|
||||||
|
|
||||||
byte[] destMacBuffer = longToBytes(destMac);
|
|
||||||
System.arraycopy(destMacBuffer, 2, packet, 18, 6);
|
|
||||||
|
|
||||||
byte[] destAddrBuffer = destinationAddress.getAddress();
|
|
||||||
System.arraycopy(destAddrBuffer, 0, packet, 24, 4);
|
|
||||||
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a reply is needed
|
|
||||||
*
|
|
||||||
* @param replyBuffer
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public ARPReplyData processARPPacket(byte[] replyBuffer) {
|
|
||||||
Log.d(TAG, "Processing ARP packet");
|
|
||||||
|
|
||||||
byte[] srcMacBuffer = new byte[8];
|
|
||||||
System.arraycopy(replyBuffer, 8, srcMacBuffer, 2, 6);
|
|
||||||
|
|
||||||
byte[] senderAddressBuffer = new byte[4];
|
|
||||||
System.arraycopy(replyBuffer, 14, senderAddressBuffer, 0, 4);
|
|
||||||
|
|
||||||
byte[] destMacBuffer = new byte[8];
|
|
||||||
System.arraycopy(replyBuffer, 18, destMacBuffer, 2, 6);
|
|
||||||
|
|
||||||
byte[] destAddressBuffer = new byte[4];
|
|
||||||
System.arraycopy(replyBuffer, 24, destAddressBuffer, 0, 4);
|
|
||||||
|
|
||||||
InetAddress senderAddress = null;
|
|
||||||
try {
|
|
||||||
senderAddress = InetAddress.getByAddress(senderAddressBuffer);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
InetAddress destAddress = null;
|
|
||||||
try {
|
|
||||||
destAddress = InetAddress.getByAddress(destAddressBuffer);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
long sourceMac = ByteBuffer.wrap(srcMacBuffer).getLong();
|
|
||||||
long destMac = ByteBuffer.wrap(destMacBuffer).getLong();
|
|
||||||
|
|
||||||
if(sourceMac != 0 && senderAddress != null) {
|
|
||||||
setAddress(senderAddress,sourceMac);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destMac != 0 && destAddress != null) {
|
|
||||||
setAddress(destAddress, destMac);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(replyBuffer[7] == 1) {
|
|
||||||
Log.d(TAG, "Reply needed");
|
|
||||||
|
|
||||||
ARPReplyData data = new ARPReplyData();
|
|
||||||
data.destMac = sourceMac;
|
|
||||||
data.destAddress = senderAddress;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ARPReplyData {
|
|
||||||
public long senderMac;
|
|
||||||
public InetAddress senderAddress;
|
|
||||||
public long destMac;
|
|
||||||
public InetAddress destAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ArpEntry {
|
|
||||||
private long mac;
|
|
||||||
private InetAddress address;
|
|
||||||
private long time;
|
|
||||||
|
|
||||||
ArpEntry(long mac, InetAddress address) {
|
|
||||||
this.mac = mac;
|
|
||||||
this.address = address;
|
|
||||||
updateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getMac() { return this.mac; }
|
|
||||||
public InetAddress getAddress() { return this.address; }
|
|
||||||
|
|
||||||
public void updateTime() {
|
|
||||||
this.time = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(ArpEntry e) {
|
|
||||||
// purposely do not check time
|
|
||||||
// mac & address alone determine equality
|
|
||||||
return (mac == e.mac) &&
|
|
||||||
(address.equals(e.address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Thread timeoutThread = new Thread("ARP Timeout Thread") {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
synchronized (entries) {
|
|
||||||
for (ArpEntry e : entries) {
|
|
||||||
if(e.time < (System.currentTimeMillis() + ENTRY_TIMEOUT) ) {
|
|
||||||
synchronized(macAddressToInetAdddress) {
|
|
||||||
macAddressToInetAdddress.remove(e.mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (inetAddressToMacAddress) {
|
|
||||||
inetAddressToMacAddress.remove(e.address);
|
|
||||||
}
|
|
||||||
|
|
||||||
entries.remove(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.DataStoreGetListener;
|
|
||||||
import com.zerotier.sdk.DataStorePutListener;
|
|
||||||
|
|
||||||
public class DataStore implements DataStoreGetListener, DataStorePutListener {
|
|
||||||
private static final String TAG = "DataStore";
|
|
||||||
private Context _ctx;
|
|
||||||
|
|
||||||
public DataStore(Context ctx) {
|
|
||||||
this._ctx = ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onDataStorePut(String name, byte[] buffer, boolean secure) {
|
|
||||||
Log.d(TAG, "Writing File: " + name);
|
|
||||||
try {
|
|
||||||
if(name.contains("/")) {
|
|
||||||
// filename has a directory separator.
|
|
||||||
int ix = name.lastIndexOf('/');
|
|
||||||
String path = name.substring(0, ix);
|
|
||||||
|
|
||||||
File f = new File(_ctx.getFilesDir(), path);
|
|
||||||
if(!f.exists()) {
|
|
||||||
f.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
File outputFile = new File(f, name.substring(name.lastIndexOf("/")+1));
|
|
||||||
FileOutputStream fos = new FileOutputStream(outputFile);
|
|
||||||
fos.write(buffer);
|
|
||||||
fos.flush();
|
|
||||||
fos.close();
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
FileOutputStream fos = _ctx.openFileOutput(name, Context.MODE_PRIVATE);
|
|
||||||
fos.write(buffer);
|
|
||||||
fos.flush();
|
|
||||||
fos.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException fnf) {
|
|
||||||
fnf.printStackTrace();
|
|
||||||
return -1;
|
|
||||||
} catch (IOException io) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
io.printStackTrace(pw);
|
|
||||||
Log.e(TAG, sw.toString());
|
|
||||||
return -2;
|
|
||||||
} catch(IllegalArgumentException ie) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
ie.printStackTrace(pw);
|
|
||||||
Log.e(TAG, sw.toString());
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onDelete(String name) {
|
|
||||||
Log.d(TAG, "Deleting File: " + name);
|
|
||||||
boolean deleted = false;
|
|
||||||
if(name.contains("/")) {
|
|
||||||
// filename has a directory separator.
|
|
||||||
|
|
||||||
File f = new File(_ctx.getFilesDir(), name);
|
|
||||||
if (!f.exists()) {
|
|
||||||
deleted = true;
|
|
||||||
} else {
|
|
||||||
deleted = f.delete();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deleted = _ctx.deleteFile(name);
|
|
||||||
}
|
|
||||||
return deleted ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long onDataStoreGet(String name, byte[] out_buffer,
|
|
||||||
long bufferIndex, long[] out_objectSize) {
|
|
||||||
Log.d(TAG, "Reading File: " + name);
|
|
||||||
try {
|
|
||||||
if(name.contains("/")) {
|
|
||||||
// filename has a directory separator.
|
|
||||||
int ix = name.lastIndexOf('/');
|
|
||||||
String path = name.substring(0, ix);
|
|
||||||
|
|
||||||
File f = new File(_ctx.getFilesDir(), path);
|
|
||||||
if(!f.exists()) {
|
|
||||||
f.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
File inputFile = new File(f, name.substring(name.lastIndexOf('/')+1));
|
|
||||||
if(!inputFile.exists()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInputStream fin = new FileInputStream(inputFile);
|
|
||||||
if(bufferIndex > 0) {
|
|
||||||
fin.skip(bufferIndex);
|
|
||||||
}
|
|
||||||
int read = fin.read(out_buffer);
|
|
||||||
fin.close();
|
|
||||||
return read;
|
|
||||||
} else {
|
|
||||||
FileInputStream fin = _ctx.openFileInput(name);
|
|
||||||
out_objectSize[0] = fin.getChannel().size();
|
|
||||||
if (bufferIndex > 0) {
|
|
||||||
fin.skip(bufferIndex);
|
|
||||||
}
|
|
||||||
int read = fin.read(out_buffer);
|
|
||||||
fin.close();
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException fnf) {
|
|
||||||
// Can't read a file that doesn't exist!
|
|
||||||
out_objectSize[0] = 0;
|
|
||||||
return -1;
|
|
||||||
} catch (IOException io) {
|
|
||||||
io.printStackTrace();
|
|
||||||
return -2;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/7/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkStateReceiver extends BroadcastReceiver {
|
|
||||||
private static String TAG = "NetworkStateReceiver";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context ctx, Intent intent) {
|
|
||||||
ConnectivityManager cm =
|
|
||||||
(ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
|
|
||||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
|
||||||
boolean isConnected = (activeNetwork != null &&
|
|
||||||
activeNetwork.isConnectedOrConnecting());
|
|
||||||
|
|
||||||
Intent i = new Intent(ctx, RuntimeService.class);
|
|
||||||
if(isConnected) {
|
|
||||||
Log.d(TAG, "Network State: Connected");
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.START_NETWORK_CHANGE);
|
|
||||||
ctx.startService(i);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Network State: Disconnected");
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.STOP_NETWORK_CHANGE);
|
|
||||||
ctx.startService(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import com.zerotier.one.util.InetAddressUtils;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/13/2015.
|
|
||||||
*/
|
|
||||||
public class Route {
|
|
||||||
InetAddress address;
|
|
||||||
int prefix;
|
|
||||||
|
|
||||||
public Route(InetAddress address, int prefix) {
|
|
||||||
this.address = address;
|
|
||||||
this.prefix = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean belongsToRoute(InetAddress otherAddr) {
|
|
||||||
InetAddress route = InetAddressUtils.addressToRoute(otherAddr, prefix);
|
|
||||||
|
|
||||||
return address.equals(route);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Route r) {
|
|
||||||
return address.equals(r.address) && prefix == r.prefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.one.events.ManualDisconnectEvent;
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
public class RuntimeService extends Service {
|
|
||||||
public static final String START_TYPE = "com.zerotier.one.service.RuntimeService.start_type";
|
|
||||||
public static final int START_NETWORK_CHANGE = 1;
|
|
||||||
public static final int START_BOOT = 2;
|
|
||||||
public static final int START_USER_INTERFACE = 3;
|
|
||||||
public static final int STOP_NETWORK_CHANGE = 4;
|
|
||||||
public static final int STOP_USER_INTERFACE = 5;
|
|
||||||
|
|
||||||
private static final String TAG = "RuntimeService";
|
|
||||||
private EventBus eventBus = EventBus.getDefault();
|
|
||||||
|
|
||||||
private boolean serviceStarted = false;
|
|
||||||
|
|
||||||
private NetworkStateReceiver nsReceiver = null;
|
|
||||||
|
|
||||||
public RuntimeService() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder onBind(Intent intent) {
|
|
||||||
// TODO: Return the communication channel to the service.
|
|
||||||
throw new UnsupportedOperationException("Not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
Log.d(TAG, "RuntimeService started");
|
|
||||||
|
|
||||||
if(nsReceiver == null) {
|
|
||||||
IntentFilter filter = new IntentFilter();
|
|
||||||
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
|
|
||||||
nsReceiver = new NetworkStateReceiver();
|
|
||||||
registerReceiver(nsReceiver, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(intent == null) {
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
|
|
||||||
int startMode = intent.getIntExtra(START_TYPE, 0);
|
|
||||||
// in each of the following cases, Prepare should always return null as the prepare call
|
|
||||||
// is called the first time the UI is started granting permission for ZeroTier to use
|
|
||||||
// the VPN API
|
|
||||||
switch (startMode) {
|
|
||||||
case START_NETWORK_CHANGE: {
|
|
||||||
Log.d(TAG, "Start Network change");
|
|
||||||
if(serviceStarted) {
|
|
||||||
// start ZeroTierOne service.
|
|
||||||
Log.d(TAG, "Start Network Change");
|
|
||||||
Intent i = ZeroTierOneService.prepare(this);
|
|
||||||
if(i == null) {
|
|
||||||
i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
startService(i);
|
|
||||||
serviceStarted = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Ignore Start Network Change: Service has not been manually started.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case START_BOOT: {
|
|
||||||
// if start on boot, start service
|
|
||||||
Log.d(TAG, "Start Boot");
|
|
||||||
Intent i = ZeroTierOneService.prepare(this);
|
|
||||||
if(i == null) {
|
|
||||||
i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
startService(i);
|
|
||||||
serviceStarted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case START_USER_INTERFACE: {
|
|
||||||
Log.d(TAG, "Start User Interface");
|
|
||||||
Intent i = ZeroTierOneService.prepare(this);
|
|
||||||
if(i == null) {
|
|
||||||
i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
startService(i);
|
|
||||||
serviceStarted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case STOP_NETWORK_CHANGE: {
|
|
||||||
Log.d(TAG, "Stop Network Change. Ignored.");
|
|
||||||
// Intent i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
// stopService(i);
|
|
||||||
// EventBus.getDefault().post(new StopEvent());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case STOP_USER_INTERFACE: {
|
|
||||||
Log.d(TAG, "Stop User Interface");
|
|
||||||
Intent i = new Intent(this, ZeroTierOneService.class);
|
|
||||||
stopService(i);
|
|
||||||
EventBus.getDefault().post(new ManualDisconnectEvent());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
Log.e(TAG, "Unknown start ID: " + startId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Broadcast receiver that listens for system bootup and starts
|
|
||||||
* the ZeroTier service
|
|
||||||
*/
|
|
||||||
public class StartupReceiver extends BroadcastReceiver {
|
|
||||||
private static final String TAG = "StartupReceiver";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context ctx, Intent intent) {
|
|
||||||
Log.i(TAG, "Received: " + intent.getAction()+ ". Starting ZeroTier One service.");
|
|
||||||
|
|
||||||
// TODO: Start service
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
|
||||||
|
|
||||||
boolean shouldStart = prefs.getBoolean("general_start_zerotier_on_boot", true);
|
|
||||||
if(shouldStart) {
|
|
||||||
Log.i(TAG, "Preferences set to start ZeroTier on boot");
|
|
||||||
Intent i = new Intent(ctx, RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.START_BOOT);
|
|
||||||
ctx.startService(i);
|
|
||||||
} else {
|
|
||||||
Log.i(TAG, "Preferences set to not start ZeroTier on boot");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,272 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.one.util.IPPacketUtils;
|
|
||||||
import com.zerotier.sdk.Node;
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkFrameListener;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/3/2015.
|
|
||||||
*/
|
|
||||||
public class TunTapAdapter implements VirtualNetworkFrameListener {
|
|
||||||
public static final String TAG = "TunTapAdapter";
|
|
||||||
|
|
||||||
private static final int ARP_PACKET = 0x0806;
|
|
||||||
private static final int IPV4_PACKET = 0x0800;
|
|
||||||
private static final int IPV6_PACKET = 0x86dd;
|
|
||||||
|
|
||||||
public static final long BROADCAST_MAC = 0xffffffffffffL;
|
|
||||||
|
|
||||||
private ARPTable arpTable;
|
|
||||||
private Node node;
|
|
||||||
private ZeroTierOneService ztService;
|
|
||||||
private ParcelFileDescriptor vpnSocket;
|
|
||||||
private FileInputStream in;
|
|
||||||
private FileOutputStream out;
|
|
||||||
|
|
||||||
private final HashMap<Route, Long> routeMap;
|
|
||||||
|
|
||||||
private Thread receiveThread;
|
|
||||||
|
|
||||||
public TunTapAdapter(ZeroTierOneService ztService) {
|
|
||||||
this.ztService = ztService;
|
|
||||||
arpTable = new ARPTable();
|
|
||||||
routeMap = new HashMap<Route, Long>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNode(Node node) {
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVpnSocket(ParcelFileDescriptor vpnSocket) {
|
|
||||||
this.vpnSocket = vpnSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileStreams(FileInputStream in, FileOutputStream out) {
|
|
||||||
this.in = in;
|
|
||||||
this.out = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addRouteAndNetwork(Route route, long networkId) {
|
|
||||||
synchronized (routeMap) {
|
|
||||||
routeMap.put(route, networkId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearRouteMap() {
|
|
||||||
synchronized (routeMap) {
|
|
||||||
routeMap.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startThreads() {
|
|
||||||
receiveThread = new Thread("Tunnel Receive Thread") {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, "TUN Receive Thread Started");
|
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(32767);
|
|
||||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
try {
|
|
||||||
while (!isInterrupted()) {
|
|
||||||
boolean idle = true;
|
|
||||||
int length = in.read(buffer.array());
|
|
||||||
if (length > 0) {
|
|
||||||
Log.d(TAG, "Sending packet to ZeroTier. " + length + " bytes.");
|
|
||||||
idle = false;
|
|
||||||
|
|
||||||
byte packet[] = new byte[length];
|
|
||||||
System.arraycopy(buffer.array(), 0, packet, 0, length);
|
|
||||||
|
|
||||||
InetAddress destAddress = IPPacketUtils.getDestIP(packet);
|
|
||||||
InetAddress sourceAddress = IPPacketUtils.getSourceIP(packet);
|
|
||||||
|
|
||||||
long nwid = networkIdForDestination(destAddress);
|
|
||||||
if (nwid == 0) {
|
|
||||||
Log.e(TAG, "Unable to find network ID for destination address: " + destAddress);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualNetworkConfig cfg = node.networkConfig(nwid);
|
|
||||||
InetAddress myAddress = cfg.assignedAddresses()[0].getAddress();
|
|
||||||
|
|
||||||
long srcMac = cfg.macAddress();
|
|
||||||
long bgt_dl[] = new long[1];
|
|
||||||
|
|
||||||
if (arpTable.hasMacForAddress(destAddress)) {
|
|
||||||
long destMac = arpTable.getMacForAddress(destAddress);
|
|
||||||
|
|
||||||
ResultCode rc = node.processVirtualNetworkFrame(
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
nwid,
|
|
||||||
srcMac,
|
|
||||||
destMac,
|
|
||||||
IPV4_PACKET,
|
|
||||||
0,
|
|
||||||
packet,
|
|
||||||
bgt_dl);
|
|
||||||
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error calling processVirtualNetworkFrame: " + rc.toString());
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Packet sent to ZT");
|
|
||||||
ztService.setNextBackgroundTaskDeadline(bgt_dl[0]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Unknown dest MAC address. Need to look it up. " + destAddress);
|
|
||||||
byte[] arpRequest = arpTable.getRequestPacket(srcMac, myAddress, destAddress);
|
|
||||||
|
|
||||||
ResultCode rc = node.processVirtualNetworkFrame(
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
nwid,
|
|
||||||
srcMac,
|
|
||||||
BROADCAST_MAC,
|
|
||||||
ARP_PACKET,
|
|
||||||
0,
|
|
||||||
arpRequest,
|
|
||||||
bgt_dl);
|
|
||||||
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error sending ARP packet: " + rc.toString());
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "ARP Request Sent!");
|
|
||||||
ztService.setNextBackgroundTaskDeadline(bgt_dl[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer.clear();
|
|
||||||
} else {
|
|
||||||
//Log.d(TAG, "No bytes read: " + length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idle) {
|
|
||||||
Thread.sleep(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error in TUN Receive: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// swallow InterruptedException
|
|
||||||
}
|
|
||||||
Log.d(TAG, "TUN Receive Thread ended");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
receiveThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void interrupt() {
|
|
||||||
if (receiveThread != null) {
|
|
||||||
receiveThread.interrupt();
|
|
||||||
try {
|
|
||||||
receiveThread.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// swallow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRunning() {
|
|
||||||
if (receiveThread == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return receiveThread.isAlive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onVirtualNetworkFrame(
|
|
||||||
long nwid,
|
|
||||||
long srcMac,
|
|
||||||
long destMac,
|
|
||||||
long etherType,
|
|
||||||
long vlanId,
|
|
||||||
byte[] frameData) {
|
|
||||||
Log.d(TAG, "Got Virtual Network Frame. Network ID: " + Long.toHexString(nwid) + " Source MAC: " + Long.toHexString(srcMac) +
|
|
||||||
" Dest MAC: " + Long.toHexString(destMac) + " Ether type: " + etherType + " VLAN ID: " + vlanId + " Frame Length: " + frameData.length);
|
|
||||||
|
|
||||||
if (vpnSocket == null) {
|
|
||||||
Log.e(TAG, "vpnSocket is null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in == null || out == null) {
|
|
||||||
Log.e(TAG, "no in/out streams");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (etherType == ARP_PACKET) {
|
|
||||||
Log.d(TAG, "Got ARP Packet");
|
|
||||||
|
|
||||||
ARPTable.ARPReplyData data = arpTable.processARPPacket(frameData);
|
|
||||||
|
|
||||||
if (data != null && data.destMac != 0 && data.destAddress != null) {
|
|
||||||
// We need to reply here.
|
|
||||||
long deadline[] = new long[1];
|
|
||||||
|
|
||||||
VirtualNetworkConfig cfg = node.networkConfig(nwid);
|
|
||||||
|
|
||||||
InetAddress myAddress = cfg.assignedAddresses()[0].getAddress();
|
|
||||||
|
|
||||||
byte[] replyPacket = arpTable.getReplyPacket(cfg.macAddress(), myAddress, data.destMac, data.destAddress);
|
|
||||||
ResultCode rc = node.processVirtualNetworkFrame(
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
nwid,
|
|
||||||
cfg.macAddress(),
|
|
||||||
srcMac,
|
|
||||||
ARP_PACKET,
|
|
||||||
0,
|
|
||||||
replyPacket,
|
|
||||||
deadline);
|
|
||||||
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error sending ARP packet: " + rc.toString());
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "ARP Reply Sent!");
|
|
||||||
ztService.setNextBackgroundTaskDeadline(deadline[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ((etherType == IPV4_PACKET) ||
|
|
||||||
(etherType == IPV6_PACKET)) {
|
|
||||||
// Got IPv4 or IPv6 packet!
|
|
||||||
Log.d(TAG, "Got IP packet. Length: " + frameData.length + " Bytes");
|
|
||||||
|
|
||||||
try {
|
|
||||||
InetAddress sourceAddress = IPPacketUtils.getSourceIP(frameData);
|
|
||||||
if (sourceAddress != null) {
|
|
||||||
arpTable.setAddress(sourceAddress, srcMac);
|
|
||||||
}
|
|
||||||
out.write(frameData);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error writing data to vpn socket: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Unknown Packet Type Received: 0x" + String.format("%02X%02X", frameData[12], frameData[13]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private long networkIdForDestination(InetAddress destination) {
|
|
||||||
synchronized (routeMap) {
|
|
||||||
for (Route r : routeMap.keySet()) {
|
|
||||||
if (r.belongsToRoute(destination)) {
|
|
||||||
return routeMap.get(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.zerotier.sdk.Node;
|
|
||||||
import com.zerotier.sdk.PacketSender;
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
|
|
||||||
import java.net.DatagramPacket;
|
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/3/2015.
|
|
||||||
*/
|
|
||||||
public class UdpCom implements PacketSender, Runnable {
|
|
||||||
private final static String TAG = "UdpCom";
|
|
||||||
|
|
||||||
Node node;
|
|
||||||
ZeroTierOneService ztService;
|
|
||||||
DatagramSocket svrSocket;
|
|
||||||
|
|
||||||
UdpCom(ZeroTierOneService service, DatagramSocket socket) {
|
|
||||||
svrSocket = socket;
|
|
||||||
this.ztService = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNode(Node node) {
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int onSendPacketRequested(
|
|
||||||
InetSocketAddress localAddress,
|
|
||||||
InetSocketAddress remoteAddress,
|
|
||||||
byte[] packetData,
|
|
||||||
int ttl) {
|
|
||||||
// TTL is ignored. No way to set it on a UDP packet in Java
|
|
||||||
if(svrSocket == null) {
|
|
||||||
Log.e(TAG, "Attempted to send packet on a null socket");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
DatagramPacket p = new DatagramPacket(packetData, packetData.length, remoteAddress);
|
|
||||||
Log.d(TAG, "onSendPacketRequested: Sent "+ p.getLength() + " bytes to " + remoteAddress.toString());
|
|
||||||
svrSocket.send(p);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
Log.d(TAG, "UDP Listen Thread Started.");
|
|
||||||
try {
|
|
||||||
long[] bgtask = new long[1];
|
|
||||||
byte[] buffer = new byte[16384];
|
|
||||||
while(!Thread.interrupted()) {
|
|
||||||
|
|
||||||
bgtask[0] = 0;
|
|
||||||
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
|
|
||||||
|
|
||||||
try {
|
|
||||||
svrSocket.receive(p);
|
|
||||||
if(p.getLength() > 0)
|
|
||||||
{
|
|
||||||
byte[] received = new byte[p.getLength()];
|
|
||||||
System.arraycopy(p.getData(), 0, received, 0, p.getLength());
|
|
||||||
Log.d(TAG, "Got " + p.getLength() + " Bytes From: " + p.getAddress().toString() +":" + p.getPort());
|
|
||||||
|
|
||||||
ResultCode rc = node.processWirePacket(System.currentTimeMillis(), null, new InetSocketAddress(p.getAddress(), p.getPort()), received, bgtask);
|
|
||||||
|
|
||||||
if(rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "procesWirePacket returned: " + rc.toString());
|
|
||||||
ztService.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
ztService.setNextBackgroundTaskDeadline( bgtask[0] );
|
|
||||||
}
|
|
||||||
} catch (SocketTimeoutException e) {
|
|
||||||
Log.d(TAG, "Socket Timeout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
Log.d(TAG, "UDP Listen Thread Ended.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,537 +0,0 @@
|
|||||||
package com.zerotier.one.service;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.net.VpnService;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.zerotier.one.events.ErrorEvent;
|
|
||||||
import com.zerotier.one.events.JoinNetworkEvent;
|
|
||||||
import com.zerotier.one.events.LeaveNetworkEvent;
|
|
||||||
import com.zerotier.one.events.ManualDisconnectEvent;
|
|
||||||
import com.zerotier.one.events.NetworkInfoReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkListReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkReconfigureEvent;
|
|
||||||
import com.zerotier.one.events.NetworkRemovedEvent;
|
|
||||||
import com.zerotier.one.events.NodeDestroyedEvent;
|
|
||||||
import com.zerotier.one.events.NodeIDEvent;
|
|
||||||
import com.zerotier.one.events.NodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.RequestNetworkInfoEvent;
|
|
||||||
import com.zerotier.one.events.RequestNetworkListEvent;
|
|
||||||
import com.zerotier.one.events.RequestNodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
import com.zerotier.one.util.InetAddressUtils;
|
|
||||||
import com.zerotier.one.util.NetworkIdUtils;
|
|
||||||
import com.zerotier.sdk.Event;
|
|
||||||
import com.zerotier.sdk.EventListener;
|
|
||||||
import com.zerotier.sdk.Node;
|
|
||||||
import com.zerotier.sdk.NodeException;
|
|
||||||
import com.zerotier.sdk.NodeStatus;
|
|
||||||
import com.zerotier.sdk.ResultCode;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfigListener;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfigOperation;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
public class ZeroTierOneService extends VpnService implements Runnable, EventListener, VirtualNetworkConfigListener {
|
|
||||||
|
|
||||||
private static final String TAG = "ZT1_Service";
|
|
||||||
|
|
||||||
public static final String ZT1_NETWORK_ID = "com.zerotier.one.network_id";
|
|
||||||
|
|
||||||
public static final int MSG_JOIN_NETWORK = 1;
|
|
||||||
public static final int MSG_LEAVE_NETWORK = 2;
|
|
||||||
|
|
||||||
private Thread vpnThread;
|
|
||||||
private UdpCom udpCom;
|
|
||||||
private Thread udpThread;
|
|
||||||
|
|
||||||
private TunTapAdapter tunTapAdapter;
|
|
||||||
|
|
||||||
private Node node;
|
|
||||||
private DataStore dataStore;
|
|
||||||
|
|
||||||
DatagramSocket svrSocket;
|
|
||||||
ParcelFileDescriptor vpnSocket;
|
|
||||||
FileInputStream in;
|
|
||||||
FileOutputStream out;
|
|
||||||
|
|
||||||
private final HashMap<Long, VirtualNetworkConfig> networkConfigs;
|
|
||||||
|
|
||||||
private EventBus eventBus = EventBus.getDefault();
|
|
||||||
|
|
||||||
private long nextBackgroundTaskDeadline = 0;
|
|
||||||
private long lastMulticastGroupCheck = 0;
|
|
||||||
|
|
||||||
protected void setNextBackgroundTaskDeadline(long deadline) {
|
|
||||||
synchronized (this) {
|
|
||||||
nextBackgroundTaskDeadline = deadline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZeroTierOneService() {
|
|
||||||
super();
|
|
||||||
dataStore = new DataStore(this);
|
|
||||||
networkConfigs = new HashMap<>();
|
|
||||||
eventBus.register(this);
|
|
||||||
|
|
||||||
Netcon.ZT_SDK_Wrapper wrapper = new Netcon.ZT_SDK_Wrapper();
|
|
||||||
|
|
||||||
|
|
||||||
wrapper.startOneService();
|
|
||||||
/*
|
|
||||||
if(wrapper.loadsymbols() == 4)
|
|
||||||
{
|
|
||||||
Log.e(TAG,"loadsymbols(): Symbol found");
|
|
||||||
//Toast t = Toast.makeText(this, "WORKED", Toast.LENGTH_SHORT);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log.e(TAG,"loadsymbols(): Symbol NOT found");
|
|
||||||
//Toast t = Toast.makeText(this, "DIDNT WORK", Toast.LENGTH_SHORT);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopZeroTier() {
|
|
||||||
if(udpThread != null && udpThread.isAlive()) {
|
|
||||||
udpThread.interrupt();
|
|
||||||
udpThread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(vpnThread != null && vpnThread.isAlive()) {
|
|
||||||
vpnThread.interrupt();
|
|
||||||
vpnThread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(svrSocket != null) {
|
|
||||||
svrSocket.close();
|
|
||||||
svrSocket = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node != null) {
|
|
||||||
eventBus.post(new NodeDestroyedEvent());
|
|
||||||
node.close();
|
|
||||||
node = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
stopZeroTier();
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRevoke() {
|
|
||||||
Intent i = new Intent(this, RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.STOP_USER_INTERFACE);
|
|
||||||
this.startService(i);
|
|
||||||
|
|
||||||
stopZeroTier();
|
|
||||||
try {
|
|
||||||
vpnSocket.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// swallow it
|
|
||||||
}
|
|
||||||
vpnSocket = null;
|
|
||||||
|
|
||||||
stopSelf();
|
|
||||||
|
|
||||||
Intent stopIntent = new Intent(this, RuntimeService.class);
|
|
||||||
stopService(stopIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "ZeroTierOne Service Started");
|
|
||||||
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
boolean autoRejoin = prefs.getBoolean("network_auto_rejoin_networks", true);
|
|
||||||
|
|
||||||
if(autoRejoin) {
|
|
||||||
// find all local network configs and join them
|
|
||||||
File networksFolder = new File(getFilesDir(), "networks.d");
|
|
||||||
if (networksFolder.exists()) {
|
|
||||||
File[] networks = networksFolder.listFiles();
|
|
||||||
for (File f : networks) {
|
|
||||||
if (f.getName().endsWith(".conf")) {
|
|
||||||
String filename = f.getName();
|
|
||||||
filename = filename.substring(0, filename.lastIndexOf('.'));
|
|
||||||
Log.d(TAG, "Loading network: " + filename);
|
|
||||||
ResultCode rc = node.join(NetworkIdUtils.hexStringToLong(filename));
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.d(TAG, "Error joining network: " + rc.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "This Node Address: " + Long.toHexString(node.address()));
|
|
||||||
|
|
||||||
while(!Thread.interrupted()) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
long dl = nextBackgroundTaskDeadline;
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
if (dl <= now) {
|
|
||||||
long[] returnDeadline = {0};
|
|
||||||
ResultCode rc = node.processBackgroundTasks(now, returnDeadline);
|
|
||||||
|
|
||||||
synchronized(this) {
|
|
||||||
nextBackgroundTaskDeadline = returnDeadline[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error on processBackgroundTasks: " + rc.toString());
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
long delay = (dl > now) ? (dl - now) : 100;
|
|
||||||
Thread.sleep(delay);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
break;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.e(TAG, ex.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.d(TAG, "ZeroTierOne Service Ended");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// EventBus events
|
|
||||||
//
|
|
||||||
|
|
||||||
public void onEvent(StopEvent e) {
|
|
||||||
stopZeroTier();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEvent(ManualDisconnectEvent e) {
|
|
||||||
stopZeroTier();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(JoinNetworkEvent e) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Join Network Event");
|
|
||||||
if(node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Remove this once multi-network support is in place
|
|
||||||
for(long nwid : networkConfigs.keySet()) {
|
|
||||||
onEventBackgroundThread(new LeaveNetworkEvent(nwid));
|
|
||||||
}
|
|
||||||
|
|
||||||
networkConfigs.clear();
|
|
||||||
|
|
||||||
ResultCode rc = node.join(e.getNetworkId());
|
|
||||||
if(rc != ResultCode.RESULT_OK) {
|
|
||||||
eventBus.post(new ErrorEvent(rc));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(LeaveNetworkEvent e) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Leave Network Event");
|
|
||||||
|
|
||||||
if(node != null) {
|
|
||||||
ResultCode rc = node.leave(e.getNetworkId());
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
eventBus.post(new ErrorEvent(rc));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String certsFile = "networks.d/" + Long.toHexString(e.getNetworkId()) + ".mcerts";
|
|
||||||
String confFile = "networks.d/" + Long.toHexString(e.getNetworkId()) + ".conf";
|
|
||||||
dataStore.onDelete(confFile);
|
|
||||||
dataStore.onDelete(certsFile);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(RequestNetworkInfoEvent e) {
|
|
||||||
/*
|
|
||||||
if(node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualNetworkConfig vnc = node.networkConfig(e.getNetworkId());
|
|
||||||
if(vnc != null) {
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(vnc));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(RequestNetworkListEvent e) {
|
|
||||||
/*
|
|
||||||
if(node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VirtualNetworkConfig[] networks = node.networks();
|
|
||||||
if(networks != null && networks.length > 0) {
|
|
||||||
eventBus.post(new NetworkListReplyEvent(networks));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventBackgroundThread(RequestNodeStatusEvent e) {
|
|
||||||
/*
|
|
||||||
if (node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeStatus ns = node.status();
|
|
||||||
|
|
||||||
eventBus.post(new NodeStatusEvent(ns));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventAsync(NetworkReconfigureEvent e) {
|
|
||||||
updateTunnelConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Event Listener Overrides
|
|
||||||
//
|
|
||||||
public void onEvent(Event e) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Event: " + e.toString());
|
|
||||||
|
|
||||||
if(node != null) {
|
|
||||||
NodeStatus status = node.status();
|
|
||||||
NodeStatusEvent nse = new NodeStatusEvent(status);
|
|
||||||
eventBus.post(nse);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTrace(String msg) {
|
|
||||||
Log.d(TAG, "Trace: " + msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Virtual Network Config Listener overrides
|
|
||||||
//
|
|
||||||
|
|
||||||
public int onNetworkConfigurationUpdated(
|
|
||||||
long nwid,
|
|
||||||
VirtualNetworkConfigOperation op,
|
|
||||||
VirtualNetworkConfig config) {
|
|
||||||
/*
|
|
||||||
Log.d(TAG, "Virtual Network Config Operation: " + op.toString());
|
|
||||||
switch(op) {
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_UP: {
|
|
||||||
Log.d(TAG, "Network Type:" + config.networkType().toString() + " " +
|
|
||||||
"Network Status: " + config.networkStatus().toString() + " " +
|
|
||||||
"Network Name: " + config.name() + " ");
|
|
||||||
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(config));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: {
|
|
||||||
Log.d(TAG, "Network Config Update!");
|
|
||||||
|
|
||||||
|
|
||||||
VirtualNetworkConfig cfg = null;
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
if (networkConfigs.containsKey(nwid)) {
|
|
||||||
cfg = networkConfigs.get(nwid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cfg == null) {
|
|
||||||
// we don't already have this network config
|
|
||||||
Log.d(TAG, "Adding new network.");
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
networkConfigs.put(nwid, config);
|
|
||||||
}
|
|
||||||
eventBus.post(new NetworkReconfigureEvent());
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(config));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!cfg.equals(config)) {
|
|
||||||
Log.d(TAG, "Updating network config");
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
networkConfigs.remove(nwid);
|
|
||||||
networkConfigs.put(nwid, config);
|
|
||||||
}
|
|
||||||
eventBus.post(new NetworkReconfigureEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
eventBus.post(new NetworkInfoReplyEvent(config));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN:
|
|
||||||
case VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY:
|
|
||||||
Log.d(TAG, "Network Down!");
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
if (networkConfigs.containsKey(nwid)) {
|
|
||||||
networkConfigs.remove(nwid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eventBus.post(new NetworkReconfigureEvent());
|
|
||||||
eventBus.post(new NetworkRemovedEvent(nwid));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Log.e(TAG, "Unknown Network Config Operation!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void shutdown() {
|
|
||||||
stopZeroTier();
|
|
||||||
this.stopSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This should ONLY be called from onEventAsync(NetworkReconfigureEvent)
|
|
||||||
*/
|
|
||||||
private void updateTunnelConfig() {
|
|
||||||
|
|
||||||
/*
|
|
||||||
synchronized (networkConfigs) {
|
|
||||||
if (networkConfigs.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tunTapAdapter.isRunning()) {
|
|
||||||
tunTapAdapter.interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
tunTapAdapter.clearRouteMap();
|
|
||||||
|
|
||||||
if (vpnSocket != null) {
|
|
||||||
try {
|
|
||||||
vpnSocket.close();
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
vpnSocket = null;
|
|
||||||
in = null;
|
|
||||||
out = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Builder builder = new Builder();
|
|
||||||
|
|
||||||
int highestMtu = 0;
|
|
||||||
|
|
||||||
for (VirtualNetworkConfig config : networkConfigs.values()) {
|
|
||||||
if (config.isEnabled()) {
|
|
||||||
long nwid = config.networkId();
|
|
||||||
|
|
||||||
InetSocketAddress addresses[] = config.assignedAddresses();
|
|
||||||
|
|
||||||
int adi = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < addresses.length; ++i) {
|
|
||||||
Log.d(TAG, "Adding VPN Address: " + addresses[i].getAddress() + " Mac: " + Long.toHexString(config.macAddress()));
|
|
||||||
|
|
||||||
byte[] addrBytes = addresses[i].getAddress().getAddress();
|
|
||||||
|
|
||||||
try {
|
|
||||||
adi = ByteBuffer.wrap(addrBytes).getInt();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Exception calculating multicast ADI: " + e.getMessage());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int routeSub = addresses[i].getPort();
|
|
||||||
InetAddress address = addresses[i].getAddress();
|
|
||||||
|
|
||||||
// TODO: Support IPv6
|
|
||||||
if(address instanceof Inet6Address) {
|
|
||||||
Log.d(TAG, "Got an IPV6 Address. Not adding it to the adapter");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
InetAddress route = InetAddressUtils.addressToRoute(address, routeSub);
|
|
||||||
if(route == null) {
|
|
||||||
Log.e(TAG, "NULL route calculated!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode rc = node.multicastSubscribe(nwid, TunTapAdapter.BROADCAST_MAC, adi);
|
|
||||||
if (rc != ResultCode.RESULT_OK) {
|
|
||||||
Log.e(TAG, "Error joining multicast group");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Joined multicast group");
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.addAddress(address, routeSub);
|
|
||||||
builder.addRoute(route, routeSub);
|
|
||||||
|
|
||||||
Route r = new Route(route, routeSub);
|
|
||||||
tunTapAdapter.addRouteAndNetwork(r, nwid);
|
|
||||||
|
|
||||||
|
|
||||||
int mtu = config.mtu();
|
|
||||||
if (mtu > highestMtu) {
|
|
||||||
highestMtu = mtu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.setMtu(highestMtu);
|
|
||||||
builder.setSession("ZeroTier One");
|
|
||||||
|
|
||||||
|
|
||||||
vpnSocket = builder.establish();
|
|
||||||
if(vpnSocket == null) {
|
|
||||||
Log.e(TAG, "vpnSocket is NULL after builder.establish()!!!!");
|
|
||||||
stopZeroTier();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
in = new FileInputStream(vpnSocket.getFileDescriptor());
|
|
||||||
out = new FileOutputStream(vpnSocket.getFileDescriptor());
|
|
||||||
|
|
||||||
tunTapAdapter.setVpnSocket(vpnSocket);
|
|
||||||
tunTapAdapter.setFileStreams(in, out);
|
|
||||||
tunTapAdapter.startThreads();
|
|
||||||
Log.i(TAG, "ZeroTier One Connected");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013 Maarten Pennings
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* If you use this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.inputmethodservice.Keyboard;
|
|
||||||
import android.inputmethodservice.KeyboardView;
|
|
||||||
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.InputType;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.View.OnFocusChangeListener;
|
|
||||||
import android.view.View.OnTouchListener;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When an activity hosts a keyboardView, this class allows several EditText's to register for it.
|
|
||||||
*
|
|
||||||
* @author Maarten Pennings
|
|
||||||
* @date 2012 December 23
|
|
||||||
*/
|
|
||||||
class HexKeyboard {
|
|
||||||
private final static String TAG = "HexKeyboard";
|
|
||||||
|
|
||||||
/** A link to the KeyboardView that is used to render this CustomKeyboard. */
|
|
||||||
private KeyboardView mKeyboardView;
|
|
||||||
/** A link to the activity that hosts the {@link #mKeyboardView}. */
|
|
||||||
private Activity mHostActivity;
|
|
||||||
|
|
||||||
/** The key (code) handler. */
|
|
||||||
private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
|
|
||||||
|
|
||||||
public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
|
|
||||||
public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL
|
|
||||||
public final static int CodePrev = 55000;
|
|
||||||
public final static int CodeAllLeft = 55001;
|
|
||||||
public final static int CodeLeft = 55002;
|
|
||||||
public final static int CodeRight = 55003;
|
|
||||||
public final static int CodeAllRight = 55004;
|
|
||||||
public final static int CodeNext = 55005;
|
|
||||||
public final static int CodeClear = 55006;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onKey(int primaryCode, int[] keyCodes) {
|
|
||||||
// NOTE We can say '<Key android:codes="49,50" ... >' in the xml file; all codes come in keyCodes, the first in this list in primaryCode
|
|
||||||
// Get the EditText and its Editable
|
|
||||||
View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
|
|
||||||
|
|
||||||
if( focusCurrent==null) return;
|
|
||||||
|
|
||||||
EditText edittext = (EditText) focusCurrent;
|
|
||||||
Editable editable = edittext.getText();
|
|
||||||
int start = edittext.getSelectionStart();
|
|
||||||
// Apply the key to the edittext
|
|
||||||
if( primaryCode==CodeCancel ) {
|
|
||||||
hideCustomKeyboard();
|
|
||||||
} else if( primaryCode==CodeDelete ) {
|
|
||||||
if( editable!=null && start>0 ) editable.delete(start - 1, start);
|
|
||||||
} else if( primaryCode==CodeClear ) {
|
|
||||||
if( editable!=null ) editable.clear();
|
|
||||||
} else if( primaryCode==CodeLeft ) {
|
|
||||||
if( start>0 ) edittext.setSelection(start - 1);
|
|
||||||
} else if( primaryCode==CodeRight ) {
|
|
||||||
if (start < edittext.length()) edittext.setSelection(start + 1);
|
|
||||||
} else if( primaryCode==CodeAllLeft ) {
|
|
||||||
edittext.setSelection(0);
|
|
||||||
} else if( primaryCode==CodeAllRight ) {
|
|
||||||
edittext.setSelection(edittext.length());
|
|
||||||
} else if( primaryCode==CodePrev ) {
|
|
||||||
View focusNew= edittext.focusSearch(View.FOCUS_LEFT);
|
|
||||||
if( focusNew!=null ) focusNew.requestFocus();
|
|
||||||
} else if( primaryCode==CodeNext ) {
|
|
||||||
View focusNew= edittext.focusSearch(View.FOCUS_RIGHT);
|
|
||||||
if( focusNew!=null ) focusNew.requestFocus();
|
|
||||||
} else { // insert character
|
|
||||||
editable.insert(start, Character.toString((char) primaryCode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPress(int arg0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRelease(int primaryCode) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onText(CharSequence text) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeDown() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeLeft() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeRight() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swipeUp() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a custom keyboard, that uses the KeyboardView (with resource id <var>viewid</var>) of the <var>host</var> activity,
|
|
||||||
* and load the keyboard layout from xml file <var>layoutid</var> (see {@link Keyboard} for description).
|
|
||||||
* Note that the <var>host</var> activity must have a <var>KeyboardView</var> in its layout (typically aligned with the bottom of the activity).
|
|
||||||
* Note that the keyboard layout xml file may include key codes for navigation; see the constants in this class for their values.
|
|
||||||
* Note that to enable EditText's to use this custom keyboard, call the {@link #registerEditText(int)}.
|
|
||||||
*
|
|
||||||
* @param host The hosting activity.
|
|
||||||
* @param viewid The id of the KeyboardView.
|
|
||||||
* @param layoutid The id of the xml file containing the keyboard layout.
|
|
||||||
*/
|
|
||||||
public HexKeyboard(Activity host, int viewid, int layoutid) {
|
|
||||||
mHostActivity= host;
|
|
||||||
mKeyboardView= (KeyboardView)mHostActivity.findViewById(viewid);
|
|
||||||
mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
|
|
||||||
mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview balloons
|
|
||||||
mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
|
|
||||||
// Hide the standard keyboard initially
|
|
||||||
mHostActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether the CustomKeyboard is visible. */
|
|
||||||
public boolean isCustomKeyboardVisible() {
|
|
||||||
return mKeyboardView.getVisibility() == View.VISIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make the CustomKeyboard visible, and hide the system keyboard for view v. */
|
|
||||||
public void showCustomKeyboard( View v ) {
|
|
||||||
mKeyboardView.setVisibility(View.VISIBLE);
|
|
||||||
mKeyboardView.setEnabled(true);
|
|
||||||
if( v!=null ) ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make the CustomKeyboard invisible. */
|
|
||||||
public void hideCustomKeyboard() {
|
|
||||||
mKeyboardView.setVisibility(View.GONE);
|
|
||||||
mKeyboardView.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register <var>EditText<var> with resource id <var>resid</var> (on the hosting activity) for using this custom keyboard.
|
|
||||||
*
|
|
||||||
* @param resid The resource id of the EditText that registers to the custom keyboard.
|
|
||||||
*/
|
|
||||||
public void registerEditText(int resid) {
|
|
||||||
// Find the EditText 'resid'
|
|
||||||
EditText edittext= (EditText)mHostActivity.findViewById(resid);
|
|
||||||
// Make the custom keyboard appear
|
|
||||||
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
|
|
||||||
// NOTE By setting the on focus listener, we can show the custom keyboard when the edit box gets focus, but also hide it when the edit box loses focus
|
|
||||||
@Override
|
|
||||||
public void onFocusChange(View v, boolean hasFocus) {
|
|
||||||
if (hasFocus) showCustomKeyboard(v);
|
|
||||||
else hideCustomKeyboard();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
edittext.setOnClickListener(new OnClickListener() {
|
|
||||||
// NOTE By setting the on click listener, we can show the custom keyboard again, by tapping on an edit box that already had focus (but that had the keyboard hidden).
|
|
||||||
@Override public void onClick(View v) {
|
|
||||||
showCustomKeyboard(v);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Disable standard keyboard hard way
|
|
||||||
// NOTE There is also an easy way: 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
|
|
||||||
edittext.setOnTouchListener(new OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
|
||||||
EditText edittext = (EditText) v;
|
|
||||||
int inType = edittext.getInputType(); // Backup the input type
|
|
||||||
edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
|
|
||||||
edittext.onTouchEvent(event); // Call native handler
|
|
||||||
edittext.setInputType(inType); // Restore input type
|
|
||||||
return true; // Consume touch event
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Disable spell check (hex strings look like words to Android)
|
|
||||||
edittext.setInputType(edittext.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/20/2015.
|
|
||||||
*/
|
|
||||||
public class JoinNetworkActivity extends SingleFragmentActivity {
|
|
||||||
public Fragment createFragment() {
|
|
||||||
return new JoinNetworkFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
|
|
||||||
import com.zerotier.one.AnalyticsApplication;
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
import com.zerotier.one.events.JoinNetworkEvent;
|
|
||||||
import com.zerotier.one.util.NetworkIdUtils;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/20/2015.
|
|
||||||
*/
|
|
||||||
public class JoinNetworkFragment extends Fragment {
|
|
||||||
public final static String TAG = "JoinNetwork";
|
|
||||||
|
|
||||||
private Tracker tracker = null;
|
|
||||||
|
|
||||||
private Button mJoinButton;
|
|
||||||
private EditText mNetworkIdTextView;
|
|
||||||
private ListView mRecentNetworksList;
|
|
||||||
|
|
||||||
EventBus eventBus = EventBus.getDefault();
|
|
||||||
|
|
||||||
HexKeyboard mHexKeyboard;
|
|
||||||
|
|
||||||
public JoinNetworkFragment() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Join Network");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Join Network");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
|
|
||||||
mHexKeyboard = new HexKeyboard(getActivity(), R.id.join_network_keyboard, R.xml.hex_keyboard);
|
|
||||||
mHexKeyboard.registerEditText(R.id.join_network_edit_text);
|
|
||||||
mHexKeyboard.hideCustomKeyboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
|
|
||||||
super.onCreateView(inflater, parent, savedInstanceState);
|
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_join_network, parent, false);
|
|
||||||
|
|
||||||
mNetworkIdTextView = (EditText)v.findViewById(R.id.join_network_edit_text);
|
|
||||||
mNetworkIdTextView.addTextChangedListener(new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
if (s.toString().length() == 16) {
|
|
||||||
mJoinButton.setEnabled(true);
|
|
||||||
} else {
|
|
||||||
mJoinButton.setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mJoinButton = (Button)v.findViewById(R.id.button_join_network);
|
|
||||||
mJoinButton.setEnabled(false);
|
|
||||||
mJoinButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, "Joining network " + mNetworkIdTextView.getText().toString());
|
|
||||||
String netIdString = mNetworkIdTextView.getText().toString();
|
|
||||||
long networkId = NetworkIdUtils.hexStringToLong(netIdString);
|
|
||||||
|
|
||||||
SharedPreferences prefs = getActivity().getSharedPreferences("recent_networks", Context.MODE_PRIVATE);
|
|
||||||
try {
|
|
||||||
String nws = prefs.getString("recent_networks", (new JSONArray()).toString());
|
|
||||||
JSONArray jArray = new JSONArray(nws);
|
|
||||||
ArrayList<String> array = new ArrayList<>();
|
|
||||||
|
|
||||||
// convert the JSON array to an actual array for ease of modification
|
|
||||||
for(int i = 0; i < jArray.length(); ++i) {
|
|
||||||
array.add(jArray.getString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean containsValue = false;
|
|
||||||
|
|
||||||
for(String id : array) {
|
|
||||||
if(id.equals(netIdString)) {
|
|
||||||
containsValue = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(containsValue) {
|
|
||||||
// remove the item
|
|
||||||
array.remove(netIdString);
|
|
||||||
} else {
|
|
||||||
// pop off the last item
|
|
||||||
if (array.size() > 4) {
|
|
||||||
array.remove(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert ID at the beginning of the list
|
|
||||||
array.add(0, mNetworkIdTextView.getText().toString());
|
|
||||||
|
|
||||||
// convert the list back to a JSON array
|
|
||||||
jArray = new JSONArray();
|
|
||||||
for(String id : array) {
|
|
||||||
jArray.put(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write JSON array to preferences
|
|
||||||
SharedPreferences.Editor e = prefs.edit();
|
|
||||||
e.putString("recent_networks", jArray.toString());
|
|
||||||
e.apply();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Exception setting recent networks: " + e.getMessage());
|
|
||||||
}
|
|
||||||
eventBus.post(new JoinNetworkEvent(networkId));
|
|
||||||
} catch (Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
Log.d(TAG, "Join Network: Error parsing network ID");
|
|
||||||
} finally {
|
|
||||||
getActivity().onBackPressed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mRecentNetworksList = (ListView) v.findViewById(R.id.recent_networks_list);
|
|
||||||
|
|
||||||
SharedPreferences prefs = getActivity().getSharedPreferences("recent_networks", Context.MODE_PRIVATE);
|
|
||||||
try {
|
|
||||||
String nws = prefs.getString("recent_networks", new JSONArray().toString());
|
|
||||||
JSONArray networks = new JSONArray(nws);
|
|
||||||
|
|
||||||
|
|
||||||
TextView recentNetworksText = (TextView) v.findViewById(R.id.recent_networks);
|
|
||||||
|
|
||||||
if (networks.length() == 0) {
|
|
||||||
mRecentNetworksList.setVisibility(View.GONE);
|
|
||||||
recentNetworksText.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
mRecentNetworksList.setVisibility(View.VISIBLE);
|
|
||||||
recentNetworksText.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
ArrayList<String> recentNetworks = new ArrayList<>();
|
|
||||||
for(int i = 0; i < networks.length(); ++i) {
|
|
||||||
recentNetworks.add(networks.getString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
final NetworkIDAdapter adapter = new NetworkIDAdapter(recentNetworks);
|
|
||||||
mRecentNetworksList.setAdapter(adapter);
|
|
||||||
|
|
||||||
mRecentNetworksList.setOnItemClickListener(new ListView.OnItemClickListener() {
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
mNetworkIdTextView.setText(adapter.getItem(position));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "JSON Error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class NetworkIDAdapter extends ArrayAdapter<String> {
|
|
||||||
public NetworkIDAdapter(ArrayList<String> config) {
|
|
||||||
super(getActivity(), 0, config);
|
|
||||||
Log.d(TAG, "Created network list item adapter");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
if(convertView == null) {
|
|
||||||
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_recent_network, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
String networkId = getItem(position);
|
|
||||||
TextView network = (TextView) convertView.findViewById(R.id.list_recent_network_id);
|
|
||||||
network.setText(networkId);
|
|
||||||
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/20/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkListActivity extends SingleFragmentActivity {
|
|
||||||
@Override
|
|
||||||
public Fragment createFragment() {
|
|
||||||
return new NetworkListFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,487 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
import com.zerotier.one.AnalyticsApplication;
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
import com.zerotier.one.events.LeaveNetworkEvent;
|
|
||||||
import com.zerotier.one.events.ManualDisconnectEvent;
|
|
||||||
import com.zerotier.one.events.NetworkInfoReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkListReplyEvent;
|
|
||||||
import com.zerotier.one.events.NetworkRemovedEvent;
|
|
||||||
import com.zerotier.one.events.NodeDestroyedEvent;
|
|
||||||
import com.zerotier.one.events.NodeIDEvent;
|
|
||||||
import com.zerotier.one.events.NodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.RequestNetworkListEvent;
|
|
||||||
import com.zerotier.one.events.RequestNodeStatusEvent;
|
|
||||||
import com.zerotier.one.events.StopEvent;
|
|
||||||
import com.zerotier.one.service.RuntimeService;
|
|
||||||
import com.zerotier.one.service.ZeroTierOneService;
|
|
||||||
import com.zerotier.sdk.NodeStatus;
|
|
||||||
import com.zerotier.sdk.VirtualNetworkConfig;
|
|
||||||
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import de.greenrobot.event.EventBus;
|
|
||||||
|
|
||||||
public class NetworkListFragment extends Fragment {
|
|
||||||
enum ConnectStatus {
|
|
||||||
CONNECTED,
|
|
||||||
DISCONNECTED
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tracker tracker = null;
|
|
||||||
|
|
||||||
public static final String TAG = "NetworkListFragment";
|
|
||||||
|
|
||||||
public static final int START_VPN = 2;
|
|
||||||
|
|
||||||
private ArrayList<VirtualNetworkConfig> mNetworkConfigs;
|
|
||||||
|
|
||||||
private EventBus eventBus;
|
|
||||||
private NetworkAdapter adapter;
|
|
||||||
private ListView listView;
|
|
||||||
private TextView nodeIdView;
|
|
||||||
private TextView nodeStatusView;
|
|
||||||
private Button connectButton;
|
|
||||||
private MenuItem joinNetworkMenu;
|
|
||||||
|
|
||||||
private ConnectStatus cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mandatory empty constructor for the fragment manager to instantiate the
|
|
||||||
* fragment (e.g. upon screen orientation changes).
|
|
||||||
*/
|
|
||||||
public NetworkListFragment() {
|
|
||||||
Log.d(TAG, "Network List Fragment created");
|
|
||||||
mNetworkConfigs = new ArrayList<VirtualNetworkConfig>();
|
|
||||||
eventBus = EventBus.getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
eventBus.register(this);
|
|
||||||
eventBus.post(new RequestNetworkListEvent());
|
|
||||||
eventBus.post(new RequestNodeStatusEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
eventBus.unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
|
|
||||||
super.onCreateView(inflater, parent, savedInstanceState);
|
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.network_list_fragment, parent, false);
|
|
||||||
|
|
||||||
listView = (ListView)v.findViewById(R.id.joined_networks_list);
|
|
||||||
|
|
||||||
adapter = new NetworkAdapter(mNetworkConfigs);
|
|
||||||
listView.setAdapter(adapter);
|
|
||||||
|
|
||||||
nodeIdView = (TextView) v.findViewById(R.id.node_id);
|
|
||||||
nodeStatusView = (TextView) v.findViewById(R.id.node_status);
|
|
||||||
connectButton = (Button) v.findViewById(R.id.connect_button);
|
|
||||||
|
|
||||||
if(cstatus == ConnectStatus.CONNECTED) {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_disconnect));
|
|
||||||
} else {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
}
|
|
||||||
|
|
||||||
connectButton.setOnClickListener(new Button.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (cstatus == ConnectStatus.CONNECTED) {
|
|
||||||
Intent i = new Intent(getActivity(), RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.STOP_USER_INTERFACE);
|
|
||||||
getActivity().startService(i);
|
|
||||||
cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
nodeStatusView.setText("OFFLINE");
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
sendStartServiceIntent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendStartServiceIntent() {
|
|
||||||
Intent i = ZeroTierOneService.prepare(getActivity());
|
|
||||||
if(i != null) {
|
|
||||||
startActivityForResult(i, START_VPN);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Intent is NULL. Already approved.");
|
|
||||||
startService();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
Log.d(TAG, "NetworkListFragment.onCreate");
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
|
|
||||||
|
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Network List");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
nodeStatusView.setText("OFFLINE");
|
|
||||||
mNetworkConfigs.clear();
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
|
|
||||||
eventBus.post(new RequestNetworkListEvent());
|
|
||||||
eventBus.post(new RequestNodeStatusEvent());
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
tracker.setScreenName("Network List");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
||||||
Log.d(TAG, "NetworkListFragment.onCreateOptionsMenu");
|
|
||||||
inflater.inflate(R.menu.menu_network_list, menu);
|
|
||||||
joinNetworkMenu = menu.findItem(R.id.menu_item_join_network);
|
|
||||||
joinNetworkMenu.setEnabled(false);
|
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
|
||||||
eventBus.post(new RequestNodeStatusEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.menu_item_join_network: {
|
|
||||||
Log.d(TAG, "Selected Join Network");
|
|
||||||
Intent i = new Intent(getActivity(), JoinNetworkActivity.class);
|
|
||||||
startActivity(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case R.id.menu_item_prefs: {
|
|
||||||
Log.d(TAG, "Selected Preferences");
|
|
||||||
Intent i = new Intent(getActivity(), PrefsActivity.class);
|
|
||||||
startActivity(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
|
|
||||||
switch(requestCode)
|
|
||||||
{
|
|
||||||
case START_VPN:
|
|
||||||
{
|
|
||||||
// Start ZeroTierOneService
|
|
||||||
startService();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity) {
|
|
||||||
super.onAttach(activity);
|
|
||||||
Log.d(TAG, "NetworkListFragment.onAttach");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetach() {
|
|
||||||
Log.d(TAG, "NetworkListFragment.onDetach");
|
|
||||||
super.onDetach();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NetworkListReplyEvent e) {
|
|
||||||
Log.d(TAG, "Got network list");
|
|
||||||
mNetworkConfigs.clear();
|
|
||||||
for(int i = 0; i < e.getNetworkList().length; ++i) {
|
|
||||||
mNetworkConfigs.add(e.getNetworkList()[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NetworkInfoReplyEvent e) {
|
|
||||||
Log.d(TAG, "Got Network Info");
|
|
||||||
VirtualNetworkConfig vnc = e.getNetworkInfo();
|
|
||||||
boolean hasNetworkWithId = false;
|
|
||||||
|
|
||||||
for(VirtualNetworkConfig c : mNetworkConfigs) {
|
|
||||||
if(c.networkId() == vnc.networkId()) {
|
|
||||||
hasNetworkWithId = true;
|
|
||||||
int index = mNetworkConfigs.indexOf(c);
|
|
||||||
mNetworkConfigs.set(index, vnc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!hasNetworkWithId) {
|
|
||||||
mNetworkConfigs.add(vnc);
|
|
||||||
}
|
|
||||||
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NetworkRemovedEvent e) {
|
|
||||||
Log.d(TAG, "Removing network: " + Long.toHexString(e.getNetworkId()));
|
|
||||||
for(VirtualNetworkConfig c : mNetworkConfigs) {
|
|
||||||
if(c.networkId() == e.getNetworkId()) {
|
|
||||||
mNetworkConfigs.remove(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sortNetworkListAndNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NodeIDEvent e) {
|
|
||||||
long nodeId = e.getNodeId();
|
|
||||||
String nodeHex = Long.toHexString(nodeId);
|
|
||||||
while(nodeHex.length() < 10) {
|
|
||||||
nodeHex = "0" + nodeHex;
|
|
||||||
}
|
|
||||||
nodeIdView.setText(nodeHex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NodeStatusEvent e) {
|
|
||||||
NodeStatus status = e.getStatus();
|
|
||||||
if(status.isOnline()) {
|
|
||||||
nodeStatusView.setText("ONLINE");
|
|
||||||
if(joinNetworkMenu != null) {
|
|
||||||
joinNetworkMenu.setEnabled(true);
|
|
||||||
}
|
|
||||||
cstatus = ConnectStatus.CONNECTED;
|
|
||||||
if(connectButton != null) {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_disconnect));
|
|
||||||
}
|
|
||||||
if(nodeIdView != null) {
|
|
||||||
nodeIdView.setText(Long.toHexString(status.getAddres()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setOfflineState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEventMainThread(NodeDestroyedEvent e) {
|
|
||||||
setOfflineState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setOfflineState() {
|
|
||||||
if(nodeStatusView != null) {
|
|
||||||
nodeStatusView.setText("OFFLINE");
|
|
||||||
}
|
|
||||||
if(joinNetworkMenu != null) {
|
|
||||||
joinNetworkMenu.setEnabled(false);
|
|
||||||
}
|
|
||||||
cstatus = ConnectStatus.DISCONNECTED;
|
|
||||||
if(connectButton != null) {
|
|
||||||
connectButton.setText(getResources().getText(R.string.button_connect));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sortNetworkListAndNotify() {
|
|
||||||
Collections.sort(mNetworkConfigs);
|
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
listView.invalidateViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startService() {
|
|
||||||
Intent i = new Intent(getActivity(), RuntimeService.class);
|
|
||||||
i.putExtra(RuntimeService.START_TYPE, RuntimeService.START_USER_INTERFACE);
|
|
||||||
getActivity().startService(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NetworkAdapter extends ArrayAdapter<VirtualNetworkConfig> {
|
|
||||||
|
|
||||||
public NetworkAdapter(ArrayList<VirtualNetworkConfig> config) {
|
|
||||||
super(getActivity(), 0, config);
|
|
||||||
Log.d(TAG, "Created network list item adapter");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
if(!listView.getItemsCanFocus()) {
|
|
||||||
listView.setItemsCanFocus(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(convertView == null) {
|
|
||||||
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_network, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualNetworkConfig vnc = getItem(position);
|
|
||||||
TextView networkId = (TextView)convertView.findViewById(R.id.network_list_network_id);
|
|
||||||
networkId.setText(Long.toHexString(vnc.networkId()));
|
|
||||||
|
|
||||||
TextView networkName = (TextView) convertView.findViewById(R.id.network_list_network_name);
|
|
||||||
networkName.setText(vnc.name());
|
|
||||||
|
|
||||||
|
|
||||||
TextView networkStatus = (TextView)convertView.findViewById(R.id.network_status_textview);
|
|
||||||
|
|
||||||
CharSequence statusText;
|
|
||||||
switch(vnc.networkStatus()) {
|
|
||||||
case NETWORK_STATUS_OK:
|
|
||||||
statusText = getResources().getText(R.string.network_status_ok);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_ACCESS_DENIED:
|
|
||||||
statusText = getResources().getText(R.string.network_status_access_denied);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_CLIENT_TOO_OLD:
|
|
||||||
statusText = getResources().getText(R.string.network_status_client_too_old);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_NOT_FOUND:
|
|
||||||
statusText = getResources().getText(R.string.network_status_not_found);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_PORT_ERROR:
|
|
||||||
statusText = getResources().getText(R.string.network_status_port_error);
|
|
||||||
break;
|
|
||||||
case NETWORK_STATUS_REQUESTING_CONFIGURATION:
|
|
||||||
statusText = getResources().getText(R.string.network_status_requesting_configuration);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
statusText = getResources().getText(R.string.network_status_unknown);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
networkStatus.setText(statusText);
|
|
||||||
|
|
||||||
TextView networkType = (TextView)convertView.findViewById(R.id.network_type_textview);
|
|
||||||
switch(vnc.networkType()) {
|
|
||||||
case NETWORK_TYPE_PUBLIC:
|
|
||||||
networkType.setText(getResources().getText(R.string.network_type_public));
|
|
||||||
break;
|
|
||||||
case NETWORK_TYPE_PRIVATE:
|
|
||||||
networkType.setText(getResources().getText(R.string.network_type_private));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
networkType.setText(getResources().getText(R.string.network_type_unknown));
|
|
||||||
}
|
|
||||||
|
|
||||||
String mac = Long.toHexString(vnc.macAddress());
|
|
||||||
while(mac.length() < 12) {
|
|
||||||
mac = "0" + mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder displayMac = new StringBuilder();
|
|
||||||
displayMac.append(mac.charAt(0));
|
|
||||||
displayMac.append(mac.charAt(1));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(2));
|
|
||||||
displayMac.append(mac.charAt(3));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(4));
|
|
||||||
displayMac.append(mac.charAt(5));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(6));
|
|
||||||
displayMac.append(mac.charAt(7));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(8));
|
|
||||||
displayMac.append(mac.charAt(9));
|
|
||||||
displayMac.append(':');
|
|
||||||
displayMac.append(mac.charAt(10));
|
|
||||||
displayMac.append(mac.charAt(11));
|
|
||||||
|
|
||||||
TextView macView = (TextView)convertView.findViewById(R.id.network_mac_textview);
|
|
||||||
macView.setText(displayMac.toString());
|
|
||||||
|
|
||||||
TextView mtuView = (TextView) convertView.findViewById(R.id.network_mtu_textview);
|
|
||||||
mtuView.setText(Integer.toString(vnc.mtu()));
|
|
||||||
|
|
||||||
TextView broadcastEnabledView = (TextView) convertView.findViewById(R.id.network_broadcast_textview);
|
|
||||||
broadcastEnabledView.setText(vnc.broadcastEnabled() ? "Enabled" : "Disabled");
|
|
||||||
|
|
||||||
TextView bridgingEnabledView = (TextView) convertView.findViewById(R.id.network_bridging_textview);
|
|
||||||
bridgingEnabledView.setText(vnc.isBridgeEnabled() ? "Enabled" : "Disabled");
|
|
||||||
|
|
||||||
InetSocketAddress[] addresses = vnc.assignedAddresses();
|
|
||||||
StringBuilder addrText = new StringBuilder();
|
|
||||||
for(InetSocketAddress addr : addresses) {
|
|
||||||
InetAddress ipaddr = addr.getAddress();
|
|
||||||
if(ipaddr instanceof Inet6Address) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String address = addr.toString();
|
|
||||||
if(address.startsWith("/")) {
|
|
||||||
address = address.substring(1);
|
|
||||||
}
|
|
||||||
int lastSlashPosition = address.lastIndexOf(':');
|
|
||||||
address = address.substring(0, lastSlashPosition) + "/" + address.substring(lastSlashPosition+1, address.length());
|
|
||||||
addrText.append(address);
|
|
||||||
addrText.append('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView addressesView = (TextView) convertView.findViewById(R.id.network_ipaddresses_textview);
|
|
||||||
addressesView.setText(addrText.toString());
|
|
||||||
|
|
||||||
Button leaveButton = (Button) convertView.findViewById(R.id.network_leave_button);
|
|
||||||
leaveButton.setOnClickListener(new LeaveButtonClickListener(vnc.networkId()));
|
|
||||||
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LeaveButtonClickListener implements Button.OnClickListener {
|
|
||||||
|
|
||||||
private long nwid;
|
|
||||||
|
|
||||||
public LeaveButtonClickListener(long nwid) {
|
|
||||||
this.nwid = nwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Log.d(TAG, "Leave Button Pressed for network: " + Long.toHexString(nwid));
|
|
||||||
EventBus.getDefault().post(new LeaveNetworkEvent(nwid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/7/2015.
|
|
||||||
*/
|
|
||||||
public class PrefsActivity extends SingleFragmentActivity {
|
|
||||||
@Override
|
|
||||||
public Fragment createFragment() {
|
|
||||||
return new PrefsFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.PreferenceFragment;
|
|
||||||
|
|
||||||
import com.google.android.gms.analytics.HitBuilders;
|
|
||||||
import com.google.android.gms.analytics.Tracker;
|
|
||||||
import com.zerotier.one.AnalyticsApplication;
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
import com.zerotier.one.service.ZeroTierOneService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 7/7/2015.
|
|
||||||
*/
|
|
||||||
public class PrefsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
|
||||||
private Tracker tracker = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
|
||||||
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Preferences");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
if(tracker == null) {
|
|
||||||
tracker = ((AnalyticsApplication) getActivity().getApplication()).getDefaultTracker();
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker.setScreenName("Preferences");
|
|
||||||
tracker.send(new HitBuilders.ScreenViewBuilder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
|
||||||
if(key.equals("network_use_cellular_data")) {
|
|
||||||
if(sharedPreferences.getBoolean("network_use_cellular_data", false)) {
|
|
||||||
Intent i = new Intent(getActivity(), ZeroTierOneService.class);
|
|
||||||
getActivity().startService(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package com.zerotier.one.ui;
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.app.FragmentManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import com.zerotier.one.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/16/2015.
|
|
||||||
*/
|
|
||||||
public abstract class SingleFragmentActivity extends AppCompatActivity {
|
|
||||||
protected abstract Fragment createFragment();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_fragment);
|
|
||||||
|
|
||||||
FragmentManager fm = getFragmentManager();
|
|
||||||
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
|
|
||||||
|
|
||||||
if(fragment == null) {
|
|
||||||
fragment = createFragment();
|
|
||||||
fm.beginTransaction()
|
|
||||||
.add(R.id.fragmentContainer, fragment)
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package com.zerotier.one.util;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/19/2015.
|
|
||||||
*/
|
|
||||||
public class IPPacketUtils {
|
|
||||||
private static final String TAG = "IPPacketUtils";
|
|
||||||
|
|
||||||
public static InetAddress getSourceIP(byte[] data) {
|
|
||||||
byte[] addrBuffer = new byte[4];
|
|
||||||
System.arraycopy(data, 12, addrBuffer, 0, 4);
|
|
||||||
try {
|
|
||||||
return InetAddress.getByAddress(addrBuffer);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
Log.e(TAG, "Error creating InetAddress: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InetAddress getDestIP(byte[] data) {
|
|
||||||
byte[] addrBuffer = new byte[4];
|
|
||||||
System.arraycopy(data, 16, addrBuffer, 0, 4);
|
|
||||||
try {
|
|
||||||
return InetAddress.getByAddress(addrBuffer);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
Log.e(TAG, "Error creating InetAddress: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the 1's complement checksum of a region of bytes
|
|
||||||
*
|
|
||||||
* @param buffer
|
|
||||||
* @param startValue
|
|
||||||
* @param startByte
|
|
||||||
* @param endByte
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static long calculateChecksum(byte[] buffer, long startValue, int startByte, int endByte) {
|
|
||||||
|
|
||||||
int length = endByte - startByte;
|
|
||||||
int i = startByte;
|
|
||||||
long sum = startValue;
|
|
||||||
long data;
|
|
||||||
|
|
||||||
// Handle all pairs
|
|
||||||
while (length > 1) {
|
|
||||||
data = (((buffer[i] << 8) & 0xFF00) | ((buffer[i + 1]) & 0xFF));
|
|
||||||
sum += data;
|
|
||||||
// 1's complement carry bit correction in 16-bits (detecting sign extension)
|
|
||||||
if ((sum & 0xFFFF0000) > 0) {
|
|
||||||
sum = sum & 0xFFFF;
|
|
||||||
sum += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 2;
|
|
||||||
length -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle remaining byte in odd length buffers
|
|
||||||
if (length > 0) {
|
|
||||||
sum += (buffer[i] << 8 & 0xFF00);
|
|
||||||
// 1's complement carry bit correction in 16-bits (detecting sign extension)
|
|
||||||
if ((sum & 0xFFFF0000) > 0) {
|
|
||||||
sum = sum & 0xFFFF;
|
|
||||||
sum += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final 1's complement value correction to 16-bits
|
|
||||||
sum = ~sum;
|
|
||||||
sum = sum & 0xFFFF;
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package com.zerotier.one.util;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 6/13/2015.
|
|
||||||
*/
|
|
||||||
public class InetAddressUtils {
|
|
||||||
public static final String TAG = "InetAddressUtils";
|
|
||||||
|
|
||||||
public static byte[] addressToNetmask(InetAddress addr, int prefix) {
|
|
||||||
int numAddressBytes = addr.getAddress().length;
|
|
||||||
if(numAddressBytes > 4) {
|
|
||||||
throw new UnsupportedOperationException("IPv6 is not yet supported");
|
|
||||||
}
|
|
||||||
int numAddressBits = numAddressBytes * 8;
|
|
||||||
|
|
||||||
byte[] maskBytes = new byte[numAddressBytes];
|
|
||||||
for(int i = 0; i < numAddressBytes; ++i) {
|
|
||||||
maskBytes[i] = (byte)255;
|
|
||||||
}
|
|
||||||
int mask = ByteBuffer.wrap(maskBytes).getInt();
|
|
||||||
|
|
||||||
mask = mask >> (numAddressBits - prefix);
|
|
||||||
mask = mask << (numAddressBits - prefix);
|
|
||||||
|
|
||||||
return ByteBuffer.allocate(4).putInt(mask).array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InetAddress addressToRoute(InetAddress addr, int prefix) {
|
|
||||||
byte[] maskBytes = addressToNetmask(addr, prefix);
|
|
||||||
byte[] routeBytes = new byte[maskBytes.length];
|
|
||||||
InetAddress route = null;
|
|
||||||
try {
|
|
||||||
for(int i = 0; i < maskBytes.length; ++i) {
|
|
||||||
routeBytes[i] = (byte)(addr.getAddress()[i] & maskBytes[i]);
|
|
||||||
}
|
|
||||||
route = InetAddress.getByAddress(routeBytes);
|
|
||||||
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
Log.e(TAG, "Uknown Host Exception calculating route");
|
|
||||||
}
|
|
||||||
|
|
||||||
return route;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.zerotier.one.util;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Grant on 5/26/2015.
|
|
||||||
*/
|
|
||||||
public class NetworkIdUtils {
|
|
||||||
/**
|
|
||||||
* Long will not parse a 64-bit hex string when the highest bit is 1 for some reasoon. So
|
|
||||||
* for converting network IDs in hex to a long, we must use big integer.
|
|
||||||
*
|
|
||||||
* @param hexString
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static long hexStringToLong(String hexString) {
|
|
||||||
BigInteger value = new BigInteger(hexString, 16);
|
|
||||||
return value.longValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,8 +7,6 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* 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 */; };
|
7C04632B1DE363BA003E2B0E /* ManagedRoute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */; };
|
||||||
7C04632C1DE363C9003E2B0E /* 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 */; };
|
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 */; };
|
7C5B40971DCC14E300C43410 /* picotcp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228D21DCC11A8006A2661 /* picotcp.cpp */; };
|
||||||
7C5B40981DCC14E300C43410 /* lwip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228CF1DCC1193006A2661 /* lwip.cpp */; };
|
7C5B40981DCC14E300C43410 /* lwip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228CF1DCC1193006A2661 /* lwip.cpp */; };
|
||||||
7C7AF0241DFA1B8600AABE75 /* ManagedRoute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0463291DE363BA003E2B0E /* ManagedRoute.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 */; };
|
7C7AF0261DFA22F300AABE75 /* ethernet.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5851DBACE7E006585E7 /* ethernet.c */; };
|
||||||
7C7D52831DBEADD200896C93 /* intercept.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52791DBEADD200896C93 /* intercept.c */; };
|
7C7D52831DBEADD200896C93 /* intercept.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52791DBEADD200896C93 /* intercept.c */; };
|
||||||
7C7D52841DBEADD200896C93 /* proxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527A1DBEADD200896C93 /* proxy.cpp */; };
|
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 */; };
|
7C7F164A1DBEB76F00C7AFFD /* service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527D1DBEADD200896C93 /* service.cpp */; };
|
||||||
7C7F164B1DBEB76F00C7AFFD /* sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527F1DBEADD200896C93 /* sockets.c */; };
|
7C7F164B1DBEB76F00C7AFFD /* sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527F1DBEADD200896C93 /* sockets.c */; };
|
||||||
7C7F164C1DBEB76F00C7AFFD /* tap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52801DBEADD200896C93 /* tap.cpp */; };
|
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 */; };
|
7C7F164F1DBEB7AB00C7AFFD /* OneService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5821DBACB3E006585E7 /* OneService.cpp */; };
|
||||||
7C7F16501DBEB7AB00C7AFFD /* C25519.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5121DBAC872006585E7 /* C25519.cpp */; };
|
7C7F16501DBEB7AB00C7AFFD /* C25519.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5121DBAC872006585E7 /* C25519.cpp */; };
|
||||||
7C7F16511DBEB7AB00C7AFFD /* CertificateOfMembership.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5141DBAC872006585E7 /* CertificateOfMembership.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 */; };
|
7C7F16851DBEB89600C7AFFD /* sys.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B471DB99E7900BD3F7F /* sys.c */; };
|
||||||
7C7F16861DBEB89600C7AFFD /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
|
7C7F16861DBEB89600C7AFFD /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
|
||||||
7C7F16871DBEB89600C7AFFD /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4C1DB99E7900BD3F7F /* udp.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 */; };
|
7C7F16891DBEB8B300C7AFFD /* http_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC003571D1217A1003E68DC /* http_parser.c */; };
|
||||||
7C969B4D1DB99E7900BD3F7F /* def.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3C1DB99E7900BD3F7F /* def.c */; };
|
7C969B4D1DB99E7900BD3F7F /* def.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3C1DB99E7900BD3F7F /* def.c */; };
|
||||||
7C969B4E1DB99E7900BD3F7F /* dns.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3D1DB99E7900BD3F7F /* dns.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 */; };
|
7C969BD11DB99F9E00BD3F7F /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
|
||||||
7C969BD21DB99F9E00BD3F7F /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4C1DB99E7900BD3F7F /* udp.c */; };
|
7C969BD21DB99F9E00BD3F7F /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4C1DB99E7900BD3F7F /* udp.c */; };
|
||||||
7C969C7C1DBAA61700BD3F7F /* tcpip.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969C7B1DBAA61700BD3F7F /* tcpip.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, ); }; };
|
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 */; };
|
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 */; };
|
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 */; };
|
7CC005211D1324B3003E68DC /* http_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CC003571D1217A1003E68DC /* http_parser.c */; };
|
||||||
7CD785601E08C7B500E03BF0 /* lwip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228CF1DCC1193006A2661 /* lwip.cpp */; };
|
7CD785601E08C7B500E03BF0 /* lwip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2228CF1DCC1193006A2661 /* lwip.cpp */; };
|
||||||
7CD785611E08C7B500E03BF0 /* rpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527B1DBEADD200896C93 /* rpc.c */; };
|
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 */; };
|
7CD785631E08C7B500E03BF0 /* sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527F1DBEADD200896C93 /* sockets.c */; };
|
||||||
7CD785641E08C7B500E03BF0 /* tap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52801DBEADD200896C93 /* tap.cpp */; };
|
7CD785641E08C7B500E03BF0 /* tap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D52801DBEADD200896C93 /* tap.cpp */; };
|
||||||
7CD785661E08C7B500E03BF0 /* ManagedRoute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7AF0231DFA1B5C00AABE75 /* ManagedRoute.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 */; };
|
7CD785691E08C7B500E03BF0 /* OneService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5821DBACB3E006585E7 /* OneService.cpp */; };
|
||||||
7CD7856A1E08C7B500E03BF0 /* C25519.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5121DBAC872006585E7 /* C25519.cpp */; };
|
7CD7856A1E08C7B500E03BF0 /* C25519.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5121DBAC872006585E7 /* C25519.cpp */; };
|
||||||
7CD7856B1E08C7B500E03BF0 /* CertificateOfMembership.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5141DBAC872006585E7 /* CertificateOfMembership.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 */; };
|
7CD7859B1E08C7E200E03BF0 /* sys.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B471DB99E7900BD3F7F /* sys.c */; };
|
||||||
7CD7859C1E08C7E200E03BF0 /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
|
7CD7859C1E08C7E200E03BF0 /* timeouts.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4B1DB99E7900BD3F7F /* timeouts.c */; };
|
||||||
7CD7859D1E08C7E200E03BF0 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B4C1DB99E7900BD3F7F /* udp.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 */; };
|
7CD7859F1E08C87A00E03BF0 /* proxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C7D527A1DBEADD200896C93 /* proxy.cpp */; };
|
||||||
7CD785A01E08C87A00E03BF0 /* def.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3C1DB99E7900BD3F7F /* def.c */; };
|
7CD785A01E08C87A00E03BF0 /* def.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3C1DB99E7900BD3F7F /* def.c */; };
|
||||||
7CD785A11E08C87A00E03BF0 /* dns.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C969B3D1DB99E7900BD3F7F /* dns.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 */; };
|
7CEAF5841DBACB3E006585E7 /* OneService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5821DBACB3E006585E7 /* OneService.cpp */; };
|
||||||
7CEAF5861DBACE7E006585E7 /* ethernet.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5851DBACE7E006585E7 /* ethernet.c */; };
|
7CEAF5861DBACE7E006585E7 /* ethernet.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5851DBACE7E006585E7 /* ethernet.c */; };
|
||||||
7CEAF5881DBACEC3006585E7 /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAF5871DBACEC3006585E7 /* err.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 */; };
|
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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference 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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */ = {
|
7CC003101D12166B003E68DC /* ext */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7C0463251DE362BD003E2B0E /* json.c */,
|
|
||||||
7C0463261DE362BD003E2B0E /* json.h */,
|
|
||||||
7CC0035A1D1217B2003E68DC /* lz4.c */,
|
|
||||||
7CC0035B1D1217B2003E68DC /* lz4.h */,
|
|
||||||
7CC003571D1217A1003E68DC /* http_parser.c */,
|
7CC003571D1217A1003E68DC /* http_parser.c */,
|
||||||
7CC003581D1217A1003E68DC /* http_parser.h */,
|
7CC003581D1217A1003E68DC /* http_parser.h */,
|
||||||
);
|
);
|
||||||
@@ -673,15 +645,11 @@
|
|||||||
7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */,
|
7C0463291DE363BA003E2B0E /* ManagedRoute.cpp */,
|
||||||
7C7AF0231DFA1B5C00AABE75 /* ManagedRoute.cpp */,
|
7C7AF0231DFA1B5C00AABE75 /* ManagedRoute.cpp */,
|
||||||
7C04632A1DE363BA003E2B0E /* ManagedRoute.hpp */,
|
7C04632A1DE363BA003E2B0E /* ManagedRoute.hpp */,
|
||||||
7CEAF58E1DBAD10A006585E7 /* BackgroundResolver.cpp */,
|
|
||||||
7CEAF5891DBAD0BF006585E7 /* DeferredPackets.cpp */,
|
|
||||||
7CEAF58A1DBAD0BF006585E7 /* DeferredPackets.hpp */,
|
|
||||||
7CEAF5821DBACB3E006585E7 /* OneService.cpp */,
|
7CEAF5821DBACB3E006585E7 /* OneService.cpp */,
|
||||||
7CEAF5831DBACB3E006585E7 /* OneService.hpp */,
|
7CEAF5831DBACB3E006585E7 /* OneService.hpp */,
|
||||||
7CEAF50D1DBAC872006585E7 /* Address.hpp */,
|
7CEAF50D1DBAC872006585E7 /* Address.hpp */,
|
||||||
7CEAF50E1DBAC872006585E7 /* Array.hpp */,
|
7CEAF50E1DBAC872006585E7 /* Array.hpp */,
|
||||||
7CEAF50F1DBAC872006585E7 /* AtomicCounter.hpp */,
|
7CEAF50F1DBAC872006585E7 /* AtomicCounter.hpp */,
|
||||||
7CEAF5101DBAC872006585E7 /* BinarySemaphore.hpp */,
|
|
||||||
7CEAF5111DBAC872006585E7 /* Buffer.hpp */,
|
7CEAF5111DBAC872006585E7 /* Buffer.hpp */,
|
||||||
7CEAF5121DBAC872006585E7 /* C25519.cpp */,
|
7CEAF5121DBAC872006585E7 /* C25519.cpp */,
|
||||||
7CEAF5131DBAC872006585E7 /* C25519.hpp */,
|
7CEAF5131DBAC872006585E7 /* C25519.hpp */,
|
||||||
@@ -983,9 +951,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7C7AF0261DFA22F300AABE75 /* ethernet.c in Sources */,
|
7C7AF0261DFA22F300AABE75 /* ethernet.c in Sources */,
|
||||||
7C7AF0251DFA223100AABE75 /* BackgroundResolver.cpp in Sources */,
|
|
||||||
7C04632B1DE363BA003E2B0E /* ManagedRoute.cpp in Sources */,
|
7C04632B1DE363BA003E2B0E /* ManagedRoute.cpp in Sources */,
|
||||||
7C0463271DE362BD003E2B0E /* json.c in Sources */,
|
|
||||||
7CEAF5531DBAC872006585E7 /* Multicaster.cpp in Sources */,
|
7CEAF5531DBAC872006585E7 /* Multicaster.cpp in Sources */,
|
||||||
7C2228D41DCC11A8006A2661 /* picotcp.cpp in Sources */,
|
7C2228D41DCC11A8006A2661 /* picotcp.cpp in Sources */,
|
||||||
7CEAF50B1DBAC841006585E7 /* PortMapper.cpp in Sources */,
|
7CEAF50B1DBAC841006585E7 /* PortMapper.cpp in Sources */,
|
||||||
@@ -995,7 +961,6 @@
|
|||||||
7C969B691DB99E8E00BD3F7F /* icmp.c in Sources */,
|
7C969B691DB99E8E00BD3F7F /* icmp.c in Sources */,
|
||||||
7C2228D11DCC1193006A2661 /* lwip.cpp in Sources */,
|
7C2228D11DCC1193006A2661 /* lwip.cpp in Sources */,
|
||||||
7CEAF5521DBAC872006585E7 /* InetAddress.cpp in Sources */,
|
7CEAF5521DBAC872006585E7 /* InetAddress.cpp in Sources */,
|
||||||
7CEAF58B1DBAD0BF006585E7 /* DeferredPackets.cpp in Sources */,
|
|
||||||
7CEAF55C1DBAC872006585E7 /* Salsa20.cpp in Sources */,
|
7CEAF55C1DBAC872006585E7 /* Salsa20.cpp in Sources */,
|
||||||
7CEAF5071DBAC841006585E7 /* Arp.cpp in Sources */,
|
7CEAF5071DBAC841006585E7 /* Arp.cpp in Sources */,
|
||||||
7C7D52861DBEADD200896C93 /* service.cpp in Sources */,
|
7C7D52861DBEADD200896C93 /* service.cpp in Sources */,
|
||||||
@@ -1047,7 +1012,6 @@
|
|||||||
7CEAF54D1DBAC872006585E7 /* Cluster.cpp in Sources */,
|
7CEAF54D1DBAC872006585E7 /* Cluster.cpp in Sources */,
|
||||||
7C969B521DB99E7900BD3F7F /* mem.c in Sources */,
|
7C969B521DB99E7900BD3F7F /* mem.c in Sources */,
|
||||||
7C969B6C1DB99E8E00BD3F7F /* ip4_frag.c in Sources */,
|
7C969B6C1DB99E8E00BD3F7F /* ip4_frag.c in Sources */,
|
||||||
7CC0035C1D1217B2003E68DC /* lz4.c in Sources */,
|
|
||||||
7CEAF55F1DBAC872006585E7 /* Switch.cpp in Sources */,
|
7CEAF55F1DBAC872006585E7 /* Switch.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@@ -1057,10 +1021,8 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7C7AF0241DFA1B8600AABE75 /* ManagedRoute.cpp in Sources */,
|
7C7AF0241DFA1B8600AABE75 /* ManagedRoute.cpp in Sources */,
|
||||||
7C9D4ED51DF246F200EF20CD /* json.c in Sources */,
|
|
||||||
7C2228D51DCC11B8006A2661 /* picotcp.cpp in Sources */,
|
7C2228D51DCC11B8006A2661 /* picotcp.cpp in Sources */,
|
||||||
7C2228D61DCC11B8006A2661 /* lwip.cpp in Sources */,
|
7C2228D61DCC11B8006A2661 /* lwip.cpp in Sources */,
|
||||||
7C7F16881DBEB8B300C7AFFD /* lz4.c in Sources */,
|
|
||||||
7C7F16891DBEB8B300C7AFFD /* http_parser.c in Sources */,
|
7C7F16891DBEB8B300C7AFFD /* http_parser.c in Sources */,
|
||||||
7C7F16721DBEB88700C7AFFD /* autoip.c in Sources */,
|
7C7F16721DBEB88700C7AFFD /* autoip.c in Sources */,
|
||||||
7C7F16731DBEB88700C7AFFD /* dhcp.c in Sources */,
|
7C7F16731DBEB88700C7AFFD /* dhcp.c in Sources */,
|
||||||
@@ -1090,8 +1052,6 @@
|
|||||||
7C7F166F1DBEB88700C7AFFD /* err.c in Sources */,
|
7C7F166F1DBEB88700C7AFFD /* err.c in Sources */,
|
||||||
7C7F16701DBEB88700C7AFFD /* ethernet.c in Sources */,
|
7C7F16701DBEB88700C7AFFD /* ethernet.c in Sources */,
|
||||||
7C7F16711DBEB88700C7AFFD /* tcpip.c in Sources */,
|
7C7F16711DBEB88700C7AFFD /* tcpip.c in Sources */,
|
||||||
7C7F164D1DBEB7AB00C7AFFD /* BackgroundResolver.cpp in Sources */,
|
|
||||||
7C7F164E1DBEB7AB00C7AFFD /* DeferredPackets.cpp in Sources */,
|
|
||||||
7C7F164F1DBEB7AB00C7AFFD /* OneService.cpp in Sources */,
|
7C7F164F1DBEB7AB00C7AFFD /* OneService.cpp in Sources */,
|
||||||
7C7F16501DBEB7AB00C7AFFD /* C25519.cpp in Sources */,
|
7C7F16501DBEB7AB00C7AFFD /* C25519.cpp in Sources */,
|
||||||
7C7F16511DBEB7AB00C7AFFD /* CertificateOfMembership.cpp in Sources */,
|
7C7F16511DBEB7AB00C7AFFD /* CertificateOfMembership.cpp in Sources */,
|
||||||
@@ -1133,7 +1093,6 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7C04632C1DE363C9003E2B0E /* ManagedRoute.cpp in Sources */,
|
7C04632C1DE363C9003E2B0E /* ManagedRoute.cpp in Sources */,
|
||||||
7C0463281DE362D9003E2B0E /* json.c in Sources */,
|
|
||||||
7C5B40971DCC14E300C43410 /* picotcp.cpp in Sources */,
|
7C5B40971DCC14E300C43410 /* picotcp.cpp in Sources */,
|
||||||
7C5B40981DCC14E300C43410 /* lwip.cpp in Sources */,
|
7C5B40981DCC14E300C43410 /* lwip.cpp in Sources */,
|
||||||
7C7D528B1DBEADE600896C93 /* intercept.c in Sources */,
|
7C7D528B1DBEADE600896C93 /* intercept.c in Sources */,
|
||||||
@@ -1146,8 +1105,6 @@
|
|||||||
7C969BCE1DB99F9E00BD3F7F /* tcp_in.c in Sources */,
|
7C969BCE1DB99F9E00BD3F7F /* tcp_in.c in Sources */,
|
||||||
7C969BCF1DB99F9E00BD3F7F /* tcp_out.c in Sources */,
|
7C969BCF1DB99F9E00BD3F7F /* tcp_out.c in Sources */,
|
||||||
7C969BD01DB99F9E00BD3F7F /* tcp.c in Sources */,
|
7C969BD01DB99F9E00BD3F7F /* tcp.c in Sources */,
|
||||||
7CEAF58F1DBAD10A006585E7 /* BackgroundResolver.cpp in Sources */,
|
|
||||||
7CEAF58C1DBAD0E1006585E7 /* DeferredPackets.cpp in Sources */,
|
|
||||||
7CEAF58D1DBAD0E1006585E7 /* OneService.cpp in Sources */,
|
7CEAF58D1DBAD0E1006585E7 /* OneService.cpp in Sources */,
|
||||||
7CEAF5881DBACEC3006585E7 /* err.c in Sources */,
|
7CEAF5881DBACEC3006585E7 /* err.c in Sources */,
|
||||||
7CEAF5861DBACE7E006585E7 /* ethernet.c in Sources */,
|
7CEAF5861DBACE7E006585E7 /* ethernet.c in Sources */,
|
||||||
@@ -1200,7 +1157,6 @@
|
|||||||
7C969BCD1DB99F9E00BD3F7F /* sys.c in Sources */,
|
7C969BCD1DB99F9E00BD3F7F /* sys.c in Sources */,
|
||||||
7C969BD11DB99F9E00BD3F7F /* timeouts.c in Sources */,
|
7C969BD11DB99F9E00BD3F7F /* timeouts.c in Sources */,
|
||||||
7C969BD21DB99F9E00BD3F7F /* udp.c in Sources */,
|
7C969BD21DB99F9E00BD3F7F /* udp.c in Sources */,
|
||||||
7CC004D01D131E37003E68DC /* lz4.c in Sources */,
|
|
||||||
7CC004D11D131E37003E68DC /* http_parser.c in Sources */,
|
7CC004D11D131E37003E68DC /* http_parser.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@@ -1235,7 +1191,6 @@
|
|||||||
7CD7859B1E08C7E200E03BF0 /* sys.c in Sources */,
|
7CD7859B1E08C7E200E03BF0 /* sys.c in Sources */,
|
||||||
7CD7859C1E08C7E200E03BF0 /* timeouts.c in Sources */,
|
7CD7859C1E08C7E200E03BF0 /* timeouts.c in Sources */,
|
||||||
7CD7859D1E08C7E200E03BF0 /* udp.c in Sources */,
|
7CD7859D1E08C7E200E03BF0 /* udp.c in Sources */,
|
||||||
7CD7859E1E08C7E200E03BF0 /* json.c in Sources */,
|
|
||||||
7CD785871E08C7C300E03BF0 /* err.c in Sources */,
|
7CD785871E08C7C300E03BF0 /* err.c in Sources */,
|
||||||
7CD785881E08C7C300E03BF0 /* ethernet.c in Sources */,
|
7CD785881E08C7C300E03BF0 /* ethernet.c in Sources */,
|
||||||
7CD785891E08C7C300E03BF0 /* tcpip.c in Sources */,
|
7CD785891E08C7C300E03BF0 /* tcpip.c in Sources */,
|
||||||
@@ -1245,8 +1200,6 @@
|
|||||||
7CD785631E08C7B500E03BF0 /* sockets.c in Sources */,
|
7CD785631E08C7B500E03BF0 /* sockets.c in Sources */,
|
||||||
7CD785641E08C7B500E03BF0 /* tap.cpp in Sources */,
|
7CD785641E08C7B500E03BF0 /* tap.cpp in Sources */,
|
||||||
7CD785661E08C7B500E03BF0 /* ManagedRoute.cpp in Sources */,
|
7CD785661E08C7B500E03BF0 /* ManagedRoute.cpp in Sources */,
|
||||||
7CD785671E08C7B500E03BF0 /* BackgroundResolver.cpp in Sources */,
|
|
||||||
7CD785681E08C7B500E03BF0 /* DeferredPackets.cpp in Sources */,
|
|
||||||
7CD785691E08C7B500E03BF0 /* OneService.cpp in Sources */,
|
7CD785691E08C7B500E03BF0 /* OneService.cpp in Sources */,
|
||||||
7CD7856A1E08C7B500E03BF0 /* C25519.cpp in Sources */,
|
7CD7856A1E08C7B500E03BF0 /* C25519.cpp in Sources */,
|
||||||
7CD7856B1E08C7B500E03BF0 /* CertificateOfMembership.cpp in Sources */,
|
7CD7856B1E08C7B500E03BF0 /* CertificateOfMembership.cpp in Sources */,
|
||||||
@@ -1274,7 +1227,6 @@
|
|||||||
7CD785811E08C7B500E03BF0 /* OSUtils.cpp in Sources */,
|
7CD785811E08C7B500E03BF0 /* OSUtils.cpp in Sources */,
|
||||||
7CD785821E08C7B500E03BF0 /* PortMapper.cpp in Sources */,
|
7CD785821E08C7B500E03BF0 /* PortMapper.cpp in Sources */,
|
||||||
7CD785831E08C7B500E03BF0 /* ControlPlane.cpp in Sources */,
|
7CD785831E08C7B500E03BF0 /* ControlPlane.cpp in Sources */,
|
||||||
7CC005201D1324B3003E68DC /* lz4.c in Sources */,
|
|
||||||
7CC005211D1324B3003E68DC /* http_parser.c in Sources */,
|
7CC005211D1324B3003E68DC /* http_parser.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ INCLUDES=
|
|||||||
DEFS=
|
DEFS=
|
||||||
ARCH_FLAGS=-arch x86_64
|
ARCH_FLAGS=-arch x86_64
|
||||||
CFLAGS=
|
CFLAGS=
|
||||||
CXXFLAGS=$(CFLAGS) -fno-rtti
|
CXXFLAGS=$(CFLAGS) -fno-rtti -std=c++11 -DZT_SDK
|
||||||
|
|
||||||
include objects.mk
|
include objects.mk
|
||||||
|
|
||||||
@@ -91,18 +91,18 @@ CODESIGN_INSTALLER_CERT=
|
|||||||
# Debug output for ZeroTier service
|
# Debug output for ZeroTier service
|
||||||
ifeq ($(ZT_DEBUG),1)
|
ifeq ($(ZT_DEBUG),1)
|
||||||
DEFS+=-DZT_TRACE
|
DEFS+=-DZT_TRACE
|
||||||
CFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
|
CFLAGS+=-Wall -Werror -g -pthread $(INCLUDES) $(DEFS)
|
||||||
CXXFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
|
CXXFLAGS+=-Wall -Werror -g -pthread $(INCLUDES) $(DEFS)
|
||||||
LDFLAGS=-ldl
|
LDFLAGS=-ldl
|
||||||
STRIP?=echo
|
STRIP?=echo
|
||||||
# The following line enables optimization for the crypto code, since
|
# The following line enables optimization for the crypto code, since
|
||||||
# C25519 in particular is almost UNUSABLE in -O0 even on a 3ghz box!
|
# 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
|
else
|
||||||
CFLAGS?=-O3 -fstack-protector
|
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?= -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
|
LDFLAGS=-ldl -pie -Wl,-z,relro,-z,now
|
||||||
STRIP?=strip
|
STRIP?=strip
|
||||||
STRIP+=--strip-all
|
STRIP+=--strip-all
|
||||||
|
|||||||
12
make-mac.mk
12
make-mac.mk
@@ -27,7 +27,7 @@ INCLUDES=
|
|||||||
DEFS=
|
DEFS=
|
||||||
ARCH_FLAGS=-arch x86_64
|
ARCH_FLAGS=-arch x86_64
|
||||||
CFLAGS=
|
CFLAGS=
|
||||||
CXXFLAGS=$(CFLAGS) -fno-rtti
|
CXXFLAGS=$(CFLAGS) -fno-rtti -std=c++11 -DZT_SDK
|
||||||
|
|
||||||
include objects.mk
|
include objects.mk
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ INCLUDES+= -Iext \
|
|||||||
# --------------------------------- ZT Config ----------------------------------
|
# --------------------------------- 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
|
# Disable codesign since open source users will not have ZeroTier's certs
|
||||||
CODESIGN=echo
|
CODESIGN=echo
|
||||||
@@ -254,14 +254,18 @@ osx_static_lib: lwip $(OBJS)
|
|||||||
else
|
else
|
||||||
osx_static_lib: pico $(OBJS)
|
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
|
$(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 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
|
endif
|
||||||
|
|
||||||
# Builds zts_* library tests
|
# Builds zts_* library tests
|
||||||
osx_static_lib_tests:
|
osx_static_lib_tests:
|
||||||
mkdir -p $(TEST_OBJDIR)
|
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.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.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.udpclient4.c -o $(TEST_OBJDIR)/$(OSTYPE).zts.udpclient4.out -Lbuild -lzt -ldl
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# ---------------------------------- Android -----------------------------------
|
# ---------------------------------- Android -----------------------------------
|
||||||
|
|||||||
66
objects.mk
66
objects.mk
@@ -1,32 +1,36 @@
|
|||||||
OBJS=\
|
OBJS=\
|
||||||
zerotierone/ext/json-parser/json.o \
|
zto/controller/EmbeddedNetworkController.o \
|
||||||
zerotierone/ext/http-parser/http_parser.o \
|
zto/controller/JSONDB.o \
|
||||||
zerotierone/ext/lz4/lz4.o \
|
zto/node/C25519.o \
|
||||||
zerotierone/node/C25519.o \
|
zto/node/Capability.o \
|
||||||
zerotierone/node/CertificateOfMembership.o \
|
zto/node/CertificateOfMembership.o \
|
||||||
zerotierone/node/Cluster.o \
|
zto/node/CertificateOfOwnership.o \
|
||||||
zerotierone/node/DeferredPackets.o \
|
zto/node/Cluster.o \
|
||||||
zerotierone/node/Identity.o \
|
zto/node/Identity.o \
|
||||||
zerotierone/node/IncomingPacket.o \
|
zto/node/IncomingPacket.o \
|
||||||
zerotierone/node/InetAddress.o \
|
zto/node/InetAddress.o \
|
||||||
zerotierone/node/Multicaster.o \
|
zto/node/Membership.o \
|
||||||
zerotierone/node/Network.o \
|
zto/node/Multicaster.o \
|
||||||
zerotierone/node/NetworkConfig.o \
|
zto/node/Network.o \
|
||||||
zerotierone/node/Node.o \
|
zto/node/NetworkConfig.o \
|
||||||
zerotierone/node/OutboundMulticast.o \
|
zto/node/Node.o \
|
||||||
zerotierone/node/Packet.o \
|
zto/node/OutboundMulticast.o \
|
||||||
zerotierone/node/Path.o \
|
zto/node/Packet.o \
|
||||||
zerotierone/node/Peer.o \
|
zto/node/Path.o \
|
||||||
zerotierone/node/Poly1305.o \
|
zto/node/Peer.o \
|
||||||
zerotierone/node/Salsa20.o \
|
zto/node/Poly1305.o \
|
||||||
zerotierone/node/SelfAwareness.o \
|
zto/node/Revocation.o \
|
||||||
zerotierone/node/SHA512.o \
|
zto/node/Salsa20.o \
|
||||||
zerotierone/node/Switch.o \
|
zto/node/SelfAwareness.o \
|
||||||
zerotierone/node/Topology.o \
|
zto/node/SHA512.o \
|
||||||
zerotierone/node/Utils.o \
|
zto/node/Switch.o \
|
||||||
zerotierone/osdep/BackgroundResolver.o \
|
zto/node/Tag.o \
|
||||||
zerotierone/osdep/ManagedRoute.o \
|
zto/node/Topology.o \
|
||||||
zerotierone/osdep/Http.o \
|
zto/node/Utils.o \
|
||||||
zerotierone/osdep/OSUtils.o \
|
zto/osdep/ManagedRoute.o \
|
||||||
zerotierone/service/ClusterGeoIpService.o \
|
zto/osdep/Http.o \
|
||||||
zerotierone/service/ControlPlane.o
|
zto/osdep/OSUtils.o \
|
||||||
|
zto/service/ClusterGeoIpService.o \
|
||||||
|
zto/service/SoftwareUpdater.o \
|
||||||
|
zto/ext/http-parser/http_parser.o
|
||||||
|
|
||||||
|
|||||||
41
src/debug.h
41
src/debug.h
@@ -26,16 +26,20 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifndef _SDK_DEBUG_H_
|
#ifndef _SDK_DEBUG_H_
|
||||||
#define _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_ERROR 1 // Errors
|
||||||
#define MSG_TRANSFER 2 // RX/TX specific statements
|
#define MSG_TRANSFER 2 // RX/TX specific statements
|
||||||
#define MSG_INFO 3 // Information which is generally useful to any developer
|
#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_EXTRA 4 // If nothing in your world makes sense
|
||||||
|
#define MSG_FLOW 5 // High-level flow messages
|
||||||
|
|
||||||
#define __SHOW_FILENAMES__ true
|
#define __SHOW_FILENAMES__ true
|
||||||
#define __SHOW_COLOR__ true
|
#define __SHOW_COLOR__ true
|
||||||
@@ -79,6 +83,12 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#define THREAD_ID (long)getpid()
|
||||||
|
#elif __APPLE__
|
||||||
|
#define THREAD_ID (long)syscall(SYS_thread_selfid)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
@@ -87,10 +97,11 @@ extern "C" {
|
|||||||
|
|
||||||
//#if defined(SDK_DEBUG)
|
//#if defined(SDK_DEBUG)
|
||||||
#if DEBUG_LEVEL >= MSG_ERROR
|
#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
|
#else
|
||||||
#define DEBUG_ERROR(fmt, args...)
|
#define DEBUG_ERROR(fmt, args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DEBUG_LEVEL >= MSG_INFO
|
#if DEBUG_LEVEL >= MSG_INFO
|
||||||
#if defined(__ANDROID__)
|
#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))
|
#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_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))
|
#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
|
#else
|
||||||
#define DEBUG_INFO(fmt, args...) fprintf(stderr, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##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_INFO : %14s:%4d:%25s: " fmt "\n" RESET, __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: %14s:%4d:%25s: " fmt "\n" RESET, __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 : %14s:%4d:" fmt "\n", __FILENAME__, __LINE__, ##args)
|
#define DEBUG_BLANK(fmt, args...) fprintf(stderr, "ZT_INFO [%ld] : %14s:%4d:" fmt "\n", THREAD_ID, __FILENAME__, __LINE__, ##args)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DEBUG_INFO(fmt, args...)
|
#define DEBUG_INFO(fmt, args...)
|
||||||
#define DEBUG_BLANK(fmt, args...)
|
#define DEBUG_BLANK(fmt, args...)
|
||||||
|
#define DEBUG_ATTN(fmt, args...)
|
||||||
|
#define DEBUG_STACK(fmt, args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DEBUG_LEVEL >= MSG_TRANSFER
|
#if DEBUG_LEVEL >= MSG_TRANSFER
|
||||||
#if defined(__ANDROID__)
|
#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))
|
#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
|
#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
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DEBUG_TRANS(fmt, args...)
|
#define DEBUG_TRANS(fmt, args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DEBUG_LEVEL >= MSG_EXTRA
|
#if DEBUG_LEVEL >= MSG_EXTRA
|
||||||
#if defined(__ANDROID__)
|
#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))
|
#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
|
#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
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EXTRA(fmt, args...)
|
#define DEBUG_EXTRA(fmt, args...)
|
||||||
#endif
|
#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
|
//#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
22
src/defs.h
22
src/defs.h
@@ -25,18 +25,15 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// --- lwIP
|
#define SDK_MTU 1200//ZT_MAX_MTU // 2800, usually
|
||||||
#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)
|
|
||||||
|
|
||||||
// --- 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
|
#define MAX_PICO_FRAME_RX_BUF_SZ ZT_MAX_MTU * 128
|
||||||
|
|
||||||
// --- jip
|
// General
|
||||||
|
|
||||||
// --- General
|
|
||||||
|
|
||||||
// TCP Buffer sizes
|
// TCP Buffer sizes
|
||||||
#define DEFAULT_TCP_TX_BUF_SZ 1024 * 1024
|
#define DEFAULT_TCP_TX_BUF_SZ 1024 * 1024
|
||||||
#define DEFAULT_TCP_RX_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)
|
// UDP Buffer sizes (should be about the size of your MTU)
|
||||||
#define DEFAULT_UDP_TX_BUF_SZ ZT_MAX_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)
|
||||||
72
src/sdk.h
72
src/sdk.h
@@ -28,6 +28,17 @@
|
|||||||
#ifndef _ZT_SDK_H
|
#ifndef _ZT_SDK_H
|
||||||
#define _ZT_SDK_H 1
|
#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)
|
#if defined(SDK_SERVICE)
|
||||||
// Sanity checks for compilation
|
// Sanity checks for compilation
|
||||||
#if !defined(SDK_LWIP) && !defined(SDK_PICOTCP)
|
#if !defined(SDK_LWIP) && !defined(SDK_PICOTCP)
|
||||||
@@ -44,22 +55,37 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define SETSOCKOPT_SIG int fd, int level, int optname, const void *optval, socklen_t optlen
|
#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
|
#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 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 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 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 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
|
#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 SEND_SIG int fd, const void *buf, size_t len, int flags
|
||||||
#define WRITE_SIG int fd, const void *buf, size_t len
|
#define WRITE_SIG int fd, const void *buf, size_t len
|
||||||
#define READ_SIG int fd, 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 SOCKET_SIG int socket_family, int socket_type, int protocol
|
||||||
#define CONNECT_SIG int fd, const struct sockaddr *addr, socklen_t addrlen
|
#define CONNECT_SIG int fd, const struct sockaddr *addr, socklen_t addrlen
|
||||||
#define BIND_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" {
|
extern "C" {
|
||||||
#endif
|
#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 load_symbols();
|
||||||
extern void zts_init_rpc(const char *path, const char *nwid);
|
extern void zts_init_rpc(const char *path, const char *nwid);
|
||||||
extern char *api_netpath;
|
extern char *api_netpath;
|
||||||
extern char *debug_logfile;
|
extern char *debug_logfile;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// ------------------------- Ancient INTERCEPT-related cruft --------------------
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Function pointers to original system calls
|
// Function pointers to original system calls
|
||||||
// - These are used when we detect that either the intercept is not
|
// - These are used when we detect that either the intercept is not
|
||||||
// available or that ZeroTier hasn't administered the given socket
|
// 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 (*realclose)(CLOSE_SIG);
|
||||||
extern int (*realgetsockname)(GETSOCKNAME_SIG);
|
extern int (*realgetsockname)(GETSOCKNAME_SIG);
|
||||||
|
|
||||||
// Direct call
|
// ------------------------------------------------------------------------------
|
||||||
// - Skips intercept
|
// ---------------------------- Direct API call section -------------------------
|
||||||
// - 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_*
|
|
||||||
|
|
||||||
// SOCKS5 Proxy Controls
|
// SOCKS5 Proxy Controls
|
||||||
int zts_start_proxy_server(const char *homepath, const char * nwid, struct sockaddr_storage * addr);
|
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_stop_proxy_server(const char *nwid);
|
||||||
int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage *addr);
|
int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage *addr);
|
||||||
bool zts_proxy_is_running(const char *nwid);
|
bool zts_proxy_is_running(const char *nwid);
|
||||||
|
|
||||||
// ZT Service Controls
|
// ZT Service Controls
|
||||||
void zts_start_service(const char *path);
|
void zts_start_service(const char *path);
|
||||||
void *zts_start_core_service(void *thread_id);
|
void *zts_start_core_service(void *thread_id);
|
||||||
void zts_stop_service();
|
void zts_stop_service();
|
||||||
|
void zts_stop();
|
||||||
bool zts_service_is_running();
|
bool zts_service_is_running();
|
||||||
void zts_join_network(const char * nwid);
|
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_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_ipv4_address(const char *nwid, char *addrstr);
|
||||||
void zts_get_ipv6_address(const char *nwid, char *addrstr);
|
void zts_get_ipv6_address(const char *nwid, char *addrstr);
|
||||||
bool zts_has_address(const char *nwid);
|
bool zts_has_address(const char *nwid);
|
||||||
int zts_get_device_id();
|
int zts_get_device_id(char *devID);
|
||||||
bool zts_is_relayed();
|
int zts_get_device_id_from_file(const char *filepath, char *devID);
|
||||||
char *zts_get_homepath();
|
char *zts_get_homepath();
|
||||||
|
void zts_get_6plane_addr(char *addr, const char *nwid, const char *devID);
|
||||||
// ZT Intercept/RPC Controls
|
void zts_get_rfc4193_addr(char *addr, const char *nwid, const char *devID);
|
||||||
// TODO: Remove any?
|
// BSD-like socket API
|
||||||
//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);
|
|
||||||
|
|
||||||
int zts_socket(SOCKET_SIG);
|
int zts_socket(SOCKET_SIG);
|
||||||
int zts_connect(CONNECT_SIG);
|
int zts_connect(CONNECT_SIG);
|
||||||
int zts_bind(BIND_SIG);
|
int zts_bind(BIND_SIG);
|
||||||
@@ -165,12 +184,10 @@ int zts_getsockname(GETSOCKNAME_SIG);
|
|||||||
int zts_getpeername(GETPEERNAME_SIG);
|
int zts_getpeername(GETPEERNAME_SIG);
|
||||||
int zts_close(CLOSE_SIG);
|
int zts_close(CLOSE_SIG);
|
||||||
int zts_fcntl(FCNTL_SIG);
|
int zts_fcntl(FCNTL_SIG);
|
||||||
|
|
||||||
ssize_t zts_sendto(SENDTO_SIG);
|
ssize_t zts_sendto(SENDTO_SIG);
|
||||||
ssize_t zts_sendmsg(SENDMSG_SIG);
|
ssize_t zts_sendmsg(SENDMSG_SIG);
|
||||||
ssize_t zts_recvfrom(RECVFROM_SIG);
|
ssize_t zts_recvfrom(RECVFROM_SIG);
|
||||||
ssize_t zts_recvmsg(RECVMSG_SIG);
|
ssize_t zts_recvmsg(RECVMSG_SIG);
|
||||||
|
|
||||||
#if defined(__UNITY_3D__)
|
#if defined(__UNITY_3D__)
|
||||||
ssize_t zts_recv(int fd, void *buf, int len);
|
ssize_t zts_recv(int fd, void *buf, int len);
|
||||||
ssize_t zts_send(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);
|
void zt_leave_network(const char * nwid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Android JNI Direct-call API
|
// ------------------------------------------------------------------------------
|
||||||
|
// --------------------- Direct API call section (for Android) ------------------
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
|
||||||
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
|
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
// ZT SERVICE CONTROLS
|
// ZT SERVICE CONTROLS
|
||||||
@@ -226,7 +246,7 @@ ssize_t zts_recvmsg(RECVMSG_SIG);
|
|||||||
|
|
||||||
|
|
||||||
// Prototypes for redefinition of syscalls
|
// Prototypes for redefinition of syscalls
|
||||||
// - Implemented in SDK_Intercept.c
|
// - Implemented in intercept.c
|
||||||
#if defined(SDK_INTERCEPT)
|
#if defined(SDK_INTERCEPT)
|
||||||
int socket(SOCKET_SIG);
|
int socket(SOCKET_SIG);
|
||||||
int connect(CONNECT_SIG);
|
int connect(CONNECT_SIG);
|
||||||
|
|||||||
122
src/service.cpp
122
src/service.cpp
@@ -45,29 +45,29 @@
|
|||||||
#include "OneService.hpp"
|
#include "OneService.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "OSUtils.hpp"
|
#include "OSUtils.hpp"
|
||||||
|
#include "InetAddress.hpp"
|
||||||
|
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
#include "debug.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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 -----------------------------
|
// --------------------------------- Base zts_* API -----------------------------
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
@@ -123,7 +123,7 @@ int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage * ad
|
|||||||
// Basic ZT service controls
|
// Basic ZT service controls
|
||||||
// Will also spin up a SOCKS5 proxy server if USE_SOCKS_PROXY is set
|
// Will also spin up a SOCKS5 proxy server if USE_SOCKS_PROXY is set
|
||||||
void zts_join_network(const char * nwid) {
|
void zts_join_network(const char * nwid) {
|
||||||
DEBUG_INFO();
|
DEBUG_ERROR();
|
||||||
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
|
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
|
||||||
if(!ZeroTier::OSUtils::mkdir(netDir)) {
|
if(!ZeroTier::OSUtils::mkdir(netDir)) {
|
||||||
DEBUG_ERROR("unable to create: %s", netDir.c_str());
|
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
|
zts_start_proxy_server(homeDir.c_str(), nwid, NULL); // NULL addr for default
|
||||||
#endif
|
#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) {
|
void zts_leave_network(const char * nwid) {
|
||||||
if(zt1Service)
|
if(zt1Service)
|
||||||
zt1Service->leave(nwid);
|
zt1Service->leave(nwid);
|
||||||
}
|
}
|
||||||
//
|
// Check whether the service is running
|
||||||
bool zts_service_is_running() {
|
bool zts_service_is_running() {
|
||||||
return !zt1Service ? false : zt1Service->isRunning();
|
return !zt1Service ? false : zt1Service->isRunning();
|
||||||
}
|
}
|
||||||
//
|
// Stop the service
|
||||||
void zts_stop_service() {
|
void zts_stop_service() {
|
||||||
if(zt1Service)
|
if(zt1Service)
|
||||||
zt1Service->terminate();
|
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
|
// 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.
|
// Now only returns first assigned address per network. Shouldn't normally be a problem.
|
||||||
|
|
||||||
// Get IPV4 Address for this device on given network
|
// Get IPV4 Address for this device on given network
|
||||||
|
|
||||||
bool zts_has_address(const char *nwid)
|
bool zts_has_address(const char *nwid)
|
||||||
{
|
{
|
||||||
char ipv4_addr[64], ipv6_addr[64];
|
char ipv4_addr[64], ipv6_addr[64];
|
||||||
@@ -172,8 +196,6 @@ bool zts_has_address(const char *nwid)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void zts_get_ipv4_address(const char *nwid, char *addrstr)
|
void zts_get_ipv4_address(const char *nwid, char *addrstr)
|
||||||
{
|
{
|
||||||
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
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);
|
memcpy(addrstr, "-1.-1.-1.-1/-1", 14);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get device ID
|
// Get device ID (from running service)
|
||||||
int zts_get_device_id()
|
int zts_get_device_id(char *devID) {
|
||||||
{
|
if(zt1Service) {
|
||||||
// zt->node->status
|
char id[10];
|
||||||
/* TODO */ return 0;
|
sprintf(id, "%lx",zt1Service->getNode()->address());
|
||||||
|
memcpy(devID, id, 10);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
//
|
// Get device ID (from file)
|
||||||
bool zts_is_relayed() {
|
int zts_get_device_id_from_file(const char *filepath, char *devID) {
|
||||||
// TODO
|
std::string fname("identity.public");
|
||||||
// zt1Service->getNode()->peers()
|
std::string fpath(filepath);
|
||||||
return false;
|
|
||||||
|
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
|
// Return the home path for this instance of ZeroTier
|
||||||
char *zts_get_homepath() {
|
char *zts_get_homepath() {
|
||||||
return (char*)givenHomeDir.c_str();
|
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 -------------------------
|
// ----------------------------- .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) {
|
//void init_service_and_rpc(int key, const char * path, const char * nwid) {
|
||||||
// rpcEnabled = true;
|
|
||||||
// rpcNWID = nwid;
|
// rpcNWID = nwid;
|
||||||
// init_service(key, path);
|
// 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
|
// Construct path for network config and supporting service files
|
||||||
if (homeDir.length()) {
|
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;
|
std::string ptmp;
|
||||||
if (homeDir[0] == ZT_PATH_SEPARATOR)
|
if (homeDir[0] == ZT_PATH_SEPARATOR)
|
||||||
ptmp.push_back(ZT_PATH_SEPARATOR);
|
ptmp.push_back(ZT_PATH_SEPARATOR);
|
||||||
@@ -504,17 +548,7 @@ void *zts_start_core_service(void *thread_id) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//chdir(current_dir); // Return to previous current working directory (at the request of Unity3D)
|
|
||||||
#if defined(__UNITY_3D__)
|
|
||||||
DEBUG_INFO("starting service...");
|
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
|
// Generate random port for new service instance
|
||||||
unsigned int randp = 0;
|
unsigned int randp = 0;
|
||||||
|
|||||||
@@ -73,6 +73,7 @@
|
|||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
#include "Constants.hpp" // For Tap's MTU
|
#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 no path, construct one or get it fron system env vars
|
||||||
if(!api_netpath) {
|
if(!api_netpath) {
|
||||||
rpc_mutex_init();
|
rpc_mutex_init();
|
||||||
|
// Provided by user
|
||||||
#if defined(SDK_BUNDLED)
|
#if defined(SDK_BUNDLED)
|
||||||
// Get the path/nwid from the user application
|
// Get the path/nwid from the user application
|
||||||
// netpath = [path + "/nc_" + nwid]
|
// netpath = [path + "/nc_" + nwid]
|
||||||
char *fullpath = (char *)malloc(strlen(path)+strlen(nwid)+1+4);
|
char *fullpath = (char *)malloc(strlen(path)+strlen(nwid)+1+4);
|
||||||
if(fullpath) {
|
if(fullpath) {
|
||||||
|
zts_join_network_soft(path, nwid);
|
||||||
strcpy(fullpath, path);
|
strcpy(fullpath, path);
|
||||||
strcat(fullpath, "/nc_");
|
strcat(fullpath, "/nc_");
|
||||||
strcat(fullpath, nwid);
|
strcat(fullpath, nwid);
|
||||||
api_netpath = fullpath;
|
api_netpath = fullpath;
|
||||||
}
|
}
|
||||||
|
// Provided by Env
|
||||||
#else
|
#else
|
||||||
// Get path/nwid from environment variables
|
// Get path/nwid from environment variables
|
||||||
if (!api_netpath) {
|
if (!api_netpath) {
|
||||||
@@ -191,7 +195,7 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
ssize_t zts_sendto(SENDTO_SIG) // Used as internal implementation
|
ssize_t zts_sendto(SENDTO_SIG) // Used as internal implementation
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUG_EXTRA("fd=%d", fd);
|
//DEBUG_EXTRA("fd=%d", fd);
|
||||||
if(len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
|
if(len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
|
||||||
errno = EMSGSIZE; // Msg is too large
|
errno = EMSGSIZE; // Msg is too large
|
||||||
return -1;
|
return -1;
|
||||||
@@ -232,7 +236,7 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
ssize_t zts_sendmsg(SENDMSG_SIG)
|
ssize_t zts_sendmsg(SENDMSG_SIG)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUG_EXTRA("fd=%d",fd);
|
//DEBUG_EXTRA("fd=%d",fd);
|
||||||
char * p, * buf;
|
char * p, * buf;
|
||||||
size_t tot_len = 0;
|
size_t tot_len = 0;
|
||||||
size_t err;
|
size_t err;
|
||||||
@@ -280,7 +284,7 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
|
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 payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
|
||||||
int rxbytes = zts_recvfrom(fd, &buffer, len, flags, &addr, sizeof(struct sockaddr_storage));
|
int rxbytes = zts_recvfrom(fd, &buffer, len, flags, &addr, sizeof(struct sockaddr_storage));
|
||||||
if(rxbytes > 0)
|
if(rxbytes > 0)
|
||||||
@@ -304,19 +308,42 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
ssize_t zts_recvfrom(RECVFROM_SIG)
|
ssize_t zts_recvfrom(RECVFROM_SIG)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int payload_offset, tmpsz = 0; // payload size
|
int read_chunk_sz = 0, payload_offset, tmpsz=0, pnum=0; // payload size
|
||||||
char tmpbuf[ZT_MAX_MTU];
|
char tmpbuf[SDK_MTU];
|
||||||
if(read(fd, tmpbuf, ZT_MAX_MTU) > 0) {
|
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?
|
// TODO: case for address size mismatch?
|
||||||
memcpy(addr, tmpbuf, *addrlen);
|
memcpy(addr, tmpbuf, *addrlen);
|
||||||
memcpy(&tmpsz, tmpbuf + sizeof(struct sockaddr_storage), sizeof(tmpsz));
|
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);
|
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 {
|
else {
|
||||||
perror("read:\n");
|
return -1;
|
||||||
}
|
}
|
||||||
return tmpsz;
|
return read_chunk_sz;
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
@@ -332,7 +359,7 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
ssize_t zts_recvmsg(RECVMSG_SIG)
|
ssize_t zts_recvmsg(RECVMSG_SIG)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUG_EXTRA("fd=%d", fd);
|
//DEBUG_EXTRA("fd=%d", fd);
|
||||||
ssize_t err, n, tot_len = 0;
|
ssize_t err, n, tot_len = 0;
|
||||||
char *buf, *p;
|
char *buf, *p;
|
||||||
struct iovec *iov = msg->msg_iov;
|
struct iovec *iov = msg->msg_iov;
|
||||||
@@ -541,7 +568,7 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
get_api_netpath();
|
get_api_netpath();
|
||||||
DEBUG_INFO("fd=%d", fd);
|
//DEBUG_INFO("fd=%d", fd);
|
||||||
struct connect_st rpc_st;
|
struct connect_st rpc_st;
|
||||||
rpc_st.fd = fd;
|
rpc_st.fd = fd;
|
||||||
memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
|
memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
|
||||||
|
|||||||
@@ -25,6 +25,10 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
#include "src/debug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
#include "sdkutils.hpp"
|
#include "sdkutils.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -479,52 +479,52 @@ namespace ZeroTier {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SDK_IPV6)
|
#if defined(SDK_IPV6)
|
||||||
inline struct netif * __netif_add(NETIF_ADD_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _netif_add(netif,state,init,input); }
|
inline struct netif * __netif_add(NETIF_ADD_SIG) throw() { Mutex::Lock _l(_lock); return _netif_add(netif,state,init,input); }
|
||||||
inline void __nd6_tmr(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); _nd6_tmr(); }
|
inline void __nd6_tmr(void) throw() { /**/ Mutex::Lock _l(_lock); _nd6_tmr(); }
|
||||||
inline void __netif_ip6_addr_set_state(NETIF_IP6_ADDR_SET_STATE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); _netif_ip6_addr_set_state(netif, addr_idx, state); }
|
inline void __netif_ip6_addr_set_state(NETIF_IP6_ADDR_SET_STATE_SIG) throw() { Mutex::Lock _l(_lock); _netif_ip6_addr_set_state(netif, addr_idx, state); }
|
||||||
inline void __netif_create_ip6_linklocal_address(NETIF_CREATE_IP6_LINKLOCAL_ADDRESS_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); _netif_create_ip6_linklocal_address(netif, from_mac_48bit); }
|
inline void __netif_create_ip6_linklocal_address(NETIF_CREATE_IP6_LINKLOCAL_ADDRESS_SIG) throw() { Mutex::Lock _l(_lock); _netif_create_ip6_linklocal_address(netif, from_mac_48bit); }
|
||||||
inline err_t __ethip6_output(ETHIP6_OUTPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _ethip6_output(netif,q,ip6addr); }
|
inline err_t __ethip6_output(ETHIP6_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _ethip6_output(netif,q,ip6addr); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void __netif_init(void) throw() { Mutex::Lock _l(_lock); _netif_init(); }
|
inline void __netif_init(void) throw() { Mutex::Lock _l(_lock); _netif_init(); }
|
||||||
// inline void __netif_set_addr(NETIF_SET_ADDR_SIG) throw() { Mutex::Lock _l(_lock); _netif_set_addr(netif, ipaddr, netmask, gw); }
|
// inline void __netif_set_addr(NETIF_SET_ADDR_SIG) throw() { Mutex::Lock _l(_lock); _netif_set_addr(netif, ipaddr, netmask, gw); }
|
||||||
inline void __lwip_init() throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _lwip_init(); }
|
inline void __lwip_init() throw() { Mutex::Lock _l(_lock); return _lwip_init(); }
|
||||||
inline err_t __tcp_write(TCP_WRITE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_write(pcb,arg,len,apiflags); }
|
inline err_t __tcp_write(TCP_WRITE_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_write(pcb,arg,len,apiflags); }
|
||||||
inline void __tcp_sent(TCP_SENT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_sent(pcb,sent); }
|
inline void __tcp_sent(TCP_SENT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_sent(pcb,sent); }
|
||||||
inline struct tcp_pcb * __tcp_new(TCP_NEW_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_new(); }
|
inline struct tcp_pcb * __tcp_new(TCP_NEW_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_new(); }
|
||||||
inline struct udp_pcb * __udp_new(UDP_NEW_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_new(); }
|
inline struct udp_pcb * __udp_new(UDP_NEW_SIG) throw() { Mutex::Lock _l(_lock); return _udp_new(); }
|
||||||
inline err_t __udp_connect(UDP_CONNECT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_connect(pcb,ipaddr,port); }
|
inline err_t __udp_connect(UDP_CONNECT_SIG) throw() { Mutex::Lock _l(_lock); return _udp_connect(pcb,ipaddr,port); }
|
||||||
inline err_t __udp_send(UDP_SEND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_send(pcb,p); }
|
inline err_t __udp_send(UDP_SEND_SIG) throw() { Mutex::Lock _l(_lock); return _udp_send(pcb,p); }
|
||||||
inline err_t __udp_sendto(UDP_SENDTO_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_sendto(pcb,p,dst_ip,dst_port); }
|
inline err_t __udp_sendto(UDP_SENDTO_SIG) throw() { Mutex::Lock _l(_lock); return _udp_sendto(pcb,p,dst_ip,dst_port); }
|
||||||
inline void __udp_recv(UDP_RECV_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_recv(pcb,recv,recv_arg); }
|
inline void __udp_recv(UDP_RECV_SIG) throw() { Mutex::Lock _l(_lock); return _udp_recv(pcb,recv,recv_arg); }
|
||||||
inline err_t __udp_bind(UDP_BIND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_bind(pcb,ipaddr,port); }
|
inline err_t __udp_bind(UDP_BIND_SIG) throw() { Mutex::Lock _l(_lock); return _udp_bind(pcb,ipaddr,port); }
|
||||||
inline void __udp_remove(UDP_REMOVE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _udp_remove(pcb); }
|
inline void __udp_remove(UDP_REMOVE_SIG) throw() { Mutex::Lock _l(_lock); return _udp_remove(pcb); }
|
||||||
inline u16_t __tcp_sndbuf(TCP_SNDBUF_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_sndbuf(pcb); }
|
inline u16_t __tcp_sndbuf(TCP_SNDBUF_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_sndbuf(pcb); }
|
||||||
inline err_t __tcp_connect(TCP_CONNECT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_connect(pcb,ipaddr,port,connected); }
|
inline err_t __tcp_connect(TCP_CONNECT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_connect(pcb,ipaddr,port,connected); }
|
||||||
inline void __tcp_recv(TCP_RECV_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_recv(pcb,recv); }
|
inline void __tcp_recv(TCP_RECV_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_recv(pcb,recv); }
|
||||||
inline void __tcp_recved(TCP_RECVED_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_recved(pcb,len); }
|
inline void __tcp_recved(TCP_RECVED_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_recved(pcb,len); }
|
||||||
inline void __tcp_err(TCP_ERR_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_err(pcb,err); }
|
inline void __tcp_err(TCP_ERR_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_err(pcb,err); }
|
||||||
inline void __tcp_poll(TCP_POLL_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_poll(pcb,poll,interval); }
|
inline void __tcp_poll(TCP_POLL_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_poll(pcb,poll,interval); }
|
||||||
inline void __tcp_arg(TCP_ARG_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _tcp_arg(pcb,arg); }
|
inline void __tcp_arg(TCP_ARG_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_arg(pcb,arg); }
|
||||||
inline err_t __tcp_close(TCP_CLOSE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_close(pcb); }
|
inline err_t __tcp_close(TCP_CLOSE_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_close(pcb); }
|
||||||
inline void __tcp_abort(TCP_ABORT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_abort(pcb); }
|
inline void __tcp_abort(TCP_ABORT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_abort(pcb); }
|
||||||
inline err_t __tcp_output(TCP_OUTPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_output(pcb); }
|
inline err_t __tcp_output(TCP_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_output(pcb); }
|
||||||
inline void __tcp_accept(TCP_ACCEPT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_accept(pcb,accept); }
|
inline void __tcp_accept(TCP_ACCEPT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_accept(pcb,accept); }
|
||||||
inline struct tcp_pcb * __tcp_listen(TCP_LISTEN_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_listen(pcb); }
|
inline struct tcp_pcb * __tcp_listen(TCP_LISTEN_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_listen(pcb); }
|
||||||
inline struct tcp_pcb * __tcp_listen_with_backlog(TCP_LISTEN_WITH_BACKLOG_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_listen_with_backlog(pcb,backlog); }
|
inline struct tcp_pcb * __tcp_listen_with_backlog(TCP_LISTEN_WITH_BACKLOG_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_listen_with_backlog(pcb,backlog); }
|
||||||
inline err_t __tcp_bind(TCP_BIND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_bind(pcb,ipaddr,port); }
|
inline err_t __tcp_bind(TCP_BIND_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_bind(pcb,ipaddr,port); }
|
||||||
inline void __etharp_tmr(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _etharp_tmr(); }
|
inline void __etharp_tmr(void) throw() { Mutex::Lock _l(_lock); return _etharp_tmr(); }
|
||||||
inline void __tcp_tmr(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _tcp_tmr(); }
|
inline void __tcp_tmr(void) throw() { Mutex::Lock _l(_lock); return _tcp_tmr(); }
|
||||||
inline u8_t __pbuf_free(PBUF_FREE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pbuf_free(p); }
|
inline u8_t __pbuf_free(PBUF_FREE_SIG) throw() { Mutex::Lock _l(_lock); return _pbuf_free(p); }
|
||||||
inline struct pbuf * __pbuf_alloc(PBUF_ALLOC_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock_mem); return _pbuf_alloc(layer,length,type); }
|
inline struct pbuf * __pbuf_alloc(PBUF_ALLOC_SIG) throw() { Mutex::Lock _l(_lock_mem); return _pbuf_alloc(layer,length,type); }
|
||||||
inline u16_t __lwip_htons(LWIP_HTONS_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _lwip_htons(x); }
|
inline u16_t __lwip_htons(LWIP_HTONS_SIG) throw() { Mutex::Lock _l(_lock); return _lwip_htons(x); }
|
||||||
inline u16_t __lwip_ntohs(LWIP_NTOHS_SIG) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); return _lwip_ntohs(x); }
|
inline u16_t __lwip_ntohs(LWIP_NTOHS_SIG) throw() { Mutex::Lock _l(_lock); return _lwip_ntohs(x); }
|
||||||
//inline err_t __etharp_output(ETHARP_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _etharp_output(netif,q,ipaddr); }
|
//inline err_t __etharp_output(ETHARP_OUTPUT_SIG) throw() { Mutex::Lock _l(_lock); return _etharp_output(netif,q,ipaddr); }
|
||||||
inline err_t __ethernet_input(ETHERNET_INPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _ethernet_input(p,netif); }
|
inline err_t __ethernet_input(ETHERNET_INPUT_SIG) throw() { Mutex::Lock _l(_lock); return _ethernet_input(p,netif); }
|
||||||
inline void __tcp_input(TCP_INPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _tcp_input(p,inp); }
|
inline void __tcp_input(TCP_INPUT_SIG) throw() { Mutex::Lock _l(_lock); return _tcp_input(p,inp); }
|
||||||
inline err_t __ip_input(IP_INPUT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _ip_input(p,inp); }
|
inline err_t __ip_input(IP_INPUT_SIG) throw() { Mutex::Lock _l(_lock); return _ip_input(p,inp); }
|
||||||
inline void __netif_set_default(NETIF_SET_DEFAULT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _netif_set_default(netif); }
|
inline void __netif_set_default(NETIF_SET_DEFAULT_SIG) throw() { Mutex::Lock _l(_lock); return _netif_set_default(netif); }
|
||||||
inline void __netif_set_up(NETIF_SET_UP_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _netif_set_up(netif); }
|
inline void __netif_set_up(NETIF_SET_UP_SIG) throw() { Mutex::Lock _l(_lock); return _netif_set_up(netif); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|||||||
@@ -40,21 +40,6 @@
|
|||||||
|
|
||||||
namespace ZeroTier {
|
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
|
// Reference to the tap interface
|
||||||
// This is needed due to the fact that there's a lot going on in 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
|
// 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)
|
void pico_loop(NetconEthernetTap *tap)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
while(tap->_run)
|
while(tap->_run)
|
||||||
{
|
{
|
||||||
tap->_phy.poll(50); // in ms
|
tap->_phy.poll(ZT_PHY_POLL_INTERVAL); // in ms
|
||||||
//usleep(50);
|
|
||||||
tap->picostack->__pico_stack_tick();
|
tap->picostack->__pico_stack_tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RX packets from network onto internal buffer
|
// RX packets from [ZT->STACK] onto RXBUF
|
||||||
// Also notifies the tap service that data can be read
|
// Also notify the tap service that data can be read:
|
||||||
|
// [RXBUF -> (ZTSOCK->APP)]
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
// | |
|
// | |
|
||||||
@@ -144,8 +128,7 @@ namespace ZeroTier {
|
|||||||
// After this step, buffer will be emptied periodically by pico_handleRead()
|
// After this step, buffer will be emptied periodically by pico_handleRead()
|
||||||
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
// TODO: Verify
|
DEBUG_INFO();
|
||||||
// DEBUG_INFO("picosock=%p", s);
|
|
||||||
Connection *conn = tap->getConnection(s);
|
Connection *conn = tap->getConnection(s);
|
||||||
if(conn) {
|
if(conn) {
|
||||||
int r;
|
int r;
|
||||||
@@ -158,11 +141,9 @@ namespace ZeroTier {
|
|||||||
do {
|
do {
|
||||||
int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz;
|
int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz;
|
||||||
if(avail) {
|
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), SDK_MTU, (void *)&peer.ip4.addr, &port);
|
||||||
r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), ZT_MAX_MTU, (void *)&peer.ip4.addr, &port);
|
|
||||||
// DEBUG_ATTN("received packet (%d byte) from %08X:%u", r, long_be2(peer.ip4.addr), short_be(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);
|
tap->_phy.setNotifyWritable(conn->sock, true);
|
||||||
//DEBUG_EXTRA("read=%d", r);
|
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
conn->rxsz += r;
|
conn->rxsz += r;
|
||||||
}
|
}
|
||||||
@@ -175,7 +156,7 @@ namespace ZeroTier {
|
|||||||
DEBUG_ERROR("invalid connection");
|
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
|
// Also notifies the tap service that data can be read
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
@@ -190,6 +171,8 @@ namespace ZeroTier {
|
|||||||
//
|
//
|
||||||
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
|
DEBUG_INFO();
|
||||||
|
|
||||||
Connection *conn = tap->getConnection(s);
|
Connection *conn = tap->getConnection(s);
|
||||||
if(conn) {
|
if(conn) {
|
||||||
|
|
||||||
@@ -199,16 +182,15 @@ namespace ZeroTier {
|
|||||||
struct pico_ip6 ip6;
|
struct pico_ip6 ip6;
|
||||||
} peer;
|
} peer;
|
||||||
|
|
||||||
char tmpbuf[ZT_MAX_MTU];
|
char tmpbuf[SDK_MTU];
|
||||||
int tot = 0;
|
|
||||||
unsigned char *addr_pos, *sz_pos, *payload_pos;
|
unsigned char *addr_pos, *sz_pos, *payload_pos;
|
||||||
struct sockaddr_in addr_in;
|
struct sockaddr_in addr_in;
|
||||||
addr_in.sin_addr.s_addr = peer.ip4.addr;
|
addr_in.sin_addr.s_addr = peer.ip4.addr;
|
||||||
addr_in.sin_port = port;
|
addr_in.sin_port = port;
|
||||||
|
|
||||||
// RX
|
// RX
|
||||||
int r = tap->picostack->__pico_socket_recvfrom(s, tmpbuf, ZT_MAX_MTU, (void *)&peer.ip4.addr, &port);
|
int r = tap->picostack->__pico_socket_recvfrom(s, tmpbuf, SDK_MTU, (void *)&peer.ip4.addr, &port);
|
||||||
DEBUG_EXTRA("read=%d", r);
|
DEBUG_FLOW(" [ RXBUF <- STACK] Receiving (%d) from stack, copying to receving buffer", r);
|
||||||
|
|
||||||
// Mutex::Lock _l2(tap->_rx_buf_m);
|
// Mutex::Lock _l2(tap->_rx_buf_m);
|
||||||
// struct sockaddr_in6 addr_in6;
|
// struct sockaddr_in6 addr_in6;
|
||||||
@@ -216,23 +198,25 @@ namespace ZeroTier {
|
|||||||
// addr_in6.sin6_port = Utils::ntoh(s->remote_port);
|
// 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));
|
// 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
|
if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
|
||||||
DEBUG_INFO("UDP RX buffer full. Discarding oldest payload segment");
|
//DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment");
|
||||||
memmove(conn->rxbuf, conn->rxbuf + ZT_MAX_MTU, DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU);
|
memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU);
|
||||||
addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU); // TODO:
|
addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - SDK_MTU); // TODO:
|
||||||
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
|
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
|
||||||
conn->rxsz -= ZT_MAX_MTU;
|
conn->rxsz -= SDK_MTU;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
addr_pos = conn->rxbuf + conn->rxsz; // where we'll prepend the size of the address
|
addr_pos = conn->rxbuf + conn->rxsz; // where we'll prepend the size of the address
|
||||||
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
|
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));
|
memcpy(addr_pos, &addr_in, sizeof(struct sockaddr_storage));
|
||||||
|
|
||||||
// Adjust buffer size
|
// Adjust buffer size
|
||||||
if(r) {
|
if(r) {
|
||||||
conn->rxsz += ZT_MAX_MTU;
|
conn->rxsz += SDK_MTU;
|
||||||
memcpy(sz_pos, &r, sizeof(r));
|
memcpy(sz_pos, &r, sizeof(r));
|
||||||
tap->phyOnUnixWritable(conn->sock, NULL, true);
|
tap->phyOnUnixWritable(conn->sock, NULL, true);
|
||||||
//tap->_phy.setNotifyWritable(conn->sock, false);
|
//tap->_phy.setNotifyWritable(conn->sock, false);
|
||||||
@@ -241,6 +225,8 @@ namespace ZeroTier {
|
|||||||
DEBUG_ERROR("unable to read from picosock=%p", s);
|
DEBUG_ERROR("unable to read from picosock=%p", s);
|
||||||
}
|
}
|
||||||
memcpy(payload_pos, tmpbuf, r); // write payload to app's socket
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +243,7 @@ namespace ZeroTier {
|
|||||||
|
|
||||||
// Only called from a locked context, no need to lock anything
|
// Only called from a locked context, no need to lock anything
|
||||||
if(conn->txsz > 0) {
|
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) {
|
if((r = tap->picostack->__pico_socket_write(s, &conn->txbuf, max_write_len)) < 0) {
|
||||||
DEBUG_ERROR("unable to write to picosock=%p", s);
|
DEBUG_ERROR("unable to write to picosock=%p", s);
|
||||||
return;
|
return;
|
||||||
@@ -276,6 +262,7 @@ namespace ZeroTier {
|
|||||||
// Main callback for TCP connections
|
// Main callback for TCP connections
|
||||||
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
|
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
|
DEBUG_INFO();
|
||||||
int err;
|
int err;
|
||||||
Mutex::Lock _l(picotap->_tcpconns_m);
|
Mutex::Lock _l(picotap->_tcpconns_m);
|
||||||
Connection *conn = picotap->getConnection(s);
|
Connection *conn = picotap->getConnection(s);
|
||||||
@@ -365,7 +352,7 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
int pico_eth_send(struct pico_device *dev, void *buf, int len)
|
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;
|
struct pico_eth_hdr *ethhdr;
|
||||||
ethhdr = (struct pico_eth_hdr *)buf;
|
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()
|
// 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)
|
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
|
// 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
|
// must enqueue each frame into a memory structure shared by both threads. This structure will
|
||||||
Mutex::Lock _l(tap->_pico_frame_rxbuf_m);
|
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
|
// assemble new eth header
|
||||||
struct pico_eth_hdr ethhdr;
|
struct pico_eth_hdr ethhdr;
|
||||||
from.copyTo(ethhdr.saddr, 6);
|
from.copyTo(ethhdr.saddr, 6);
|
||||||
to.copyTo(ethhdr.daddr, 6);
|
to.copyTo(ethhdr.daddr, 6);
|
||||||
ethhdr.proto = Utils::hton((uint16_t)etherType);
|
ethhdr.proto = Utils::hton((uint16_t)etherType);
|
||||||
int newlen = len+sizeof(struct pico_eth_hdr);
|
int newlen = len + sizeof(int) + sizeof(struct pico_eth_hdr);
|
||||||
//
|
|
||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot, &newlen, sizeof(newlen)); // size of frame
|
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), ðhdr, sizeof(ethhdr)); // new eth header
|
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), ðhdr, sizeof(ethhdr)); // new eth header
|
||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
|
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);
|
tap->pico_frame_rxbuf_tot += newlen;
|
||||||
// DEBUG_INFO("RX frame buffer %3f full", (float)pico_frame_rxbuf_tot / (float)(1024 * 1024));
|
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Move FRAME(sz=%d) into FBUF(sz=%d), data_len=%d", newlen, picotap->pico_frame_rxbuf_tot, len);
|
||||||
// DEBUG_INFO("len=%d", 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), ðhdr, 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
|
// A maximum of 'loop_score' frames can be processed in each call
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
@@ -427,22 +440,28 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
int pico_eth_poll(struct pico_device *dev, int loop_score)
|
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
|
// OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA
|
||||||
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
|
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
|
||||||
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
|
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
|
||||||
unsigned char frame[ZT_MAX_MTU];
|
unsigned char frame[SDK_MTU];
|
||||||
uint32_t len;
|
int len;
|
||||||
|
while (picotap->pico_frame_rxbuf_tot > 0 && loop_score > 0) {
|
||||||
while (picotap->pico_frame_rxbuf_tot > 0) {
|
DEBUG_INFO(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot);
|
||||||
memset(frame, 0, sizeof(frame));
|
memset(frame, 0, sizeof(frame));
|
||||||
len = 0;
|
len = 0;
|
||||||
memcpy(&len, picotap->pico_frame_rxbuf, sizeof(len)); // get frame len
|
memcpy(&len, picotap->pico_frame_rxbuf, sizeof(len)); // get frame len
|
||||||
memcpy(frame, picotap->pico_frame_rxbuf + sizeof(len), len); // get frame data
|
if(len >= 0) {
|
||||||
memmove(picotap->pico_frame_rxbuf, picotap->pico_frame_rxbuf + sizeof(len) + len, ZT_MAX_MTU-(sizeof(len) + len));
|
DEBUG_FLOW(" [ FBUF -> STACK] Moving FRAME of size (%d) from FBUF(sz=%d) into stack",len, picotap->pico_frame_rxbuf_tot-len);
|
||||||
picotap->picostack->__pico_stack_recv(dev, (uint8_t*)frame, len);
|
memcpy(frame, picotap->pico_frame_rxbuf + sizeof(len), len-(sizeof(len)) ); // get frame data
|
||||||
picotap->pico_frame_rxbuf_tot-=(sizeof(len) + len);
|
memmove(picotap->pico_frame_rxbuf, picotap->pico_frame_rxbuf + len, MAX_PICO_FRAME_RX_BUF_SZ-len); // shift buffer
|
||||||
// DEBUG_EXTRA("RX frame buffer %3f full", (float)(picotap->pico_frame_rxbuf_tot) / (float)(MAX_PICO_FRAME_RX_BUF_SZ));
|
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--;
|
loop_score--;
|
||||||
}
|
}
|
||||||
return loop_score;
|
return loop_score;
|
||||||
@@ -475,10 +494,28 @@ namespace ZeroTier {
|
|||||||
*uptr = newConn;
|
*uptr = newConn;
|
||||||
newConn->type = socket_rpc->socket_type;
|
newConn->type = socket_rpc->socket_type;
|
||||||
newConn->sock = sock;
|
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->local_addr = NULL;
|
||||||
// newConn->peer_addr = NULL;
|
// newConn->peer_addr = NULL;
|
||||||
newConn->picosock = psock;
|
newConn->picosock = psock;
|
||||||
picotap->_Connections.push_back(newConn);
|
picotap->_Connections.push_back(newConn);
|
||||||
|
memset(newConn->rxbuf, 0, DEFAULT_UDP_RX_BUF_SZ);
|
||||||
return newConn;
|
return newConn;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -496,13 +533,13 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
void pico_handleWrite(Connection *conn)
|
void pico_handleWrite(Connection *conn)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
//DEBUG_INFO();
|
||||||
if(!conn || !conn->picosock) {
|
if(!conn || !conn->picosock) {
|
||||||
DEBUG_ERROR(" invalid connection");
|
DEBUG_ERROR(" invalid connection");
|
||||||
return;
|
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) {
|
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);
|
DEBUG_ERROR("unable to write to picosock=%p, r=%d", (conn->picosock), r);
|
||||||
return;
|
return;
|
||||||
@@ -542,16 +579,15 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
if(conn->type == SOCK_DGRAM) {
|
if(conn->type == SOCK_DGRAM) {
|
||||||
max = DEFAULT_UDP_TX_BUF_SZ;
|
max = DEFAULT_UDP_TX_BUF_SZ;
|
||||||
DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
//DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
||||||
(float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
|
// (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
|
// Instructs the stack to connect to a remote host
|
||||||
void pico_handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
|
void pico_handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
//DEBUG_INFO();
|
||||||
if(conn->picosock) {
|
if(conn->picosock) {
|
||||||
struct sockaddr_in *addr = (struct sockaddr_in *) &connect_rpc->addr;
|
struct sockaddr_in *addr = (struct sockaddr_in *) &connect_rpc->addr;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -562,7 +598,7 @@ namespace ZeroTier {
|
|||||||
char ipv4_str[INET_ADDRSTRLEN];
|
char ipv4_str[INET_ADDRSTRLEN];
|
||||||
inet_ntop(AF_INET, &(in4->sin_addr), 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));
|
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);
|
ret = picotap->picostack->__pico_socket_connect(conn->picosock, &zaddr, addr->sin_port);
|
||||||
#elif defined(SDK_IPV6) // "fd56:5799:d8f6:1238:8c99:9322:30ce:418a"
|
#elif defined(SDK_IPV6) // "fd56:5799:d8f6:1238:8c99:9322:30ce:418a"
|
||||||
struct pico_ip6 zaddr;
|
struct pico_ip6 zaddr;
|
||||||
@@ -570,7 +606,7 @@ namespace ZeroTier {
|
|||||||
char ipv6_str[INET6_ADDRSTRLEN];
|
char ipv6_str[INET6_ADDRSTRLEN];
|
||||||
inet_ntop(AF_INET6, &(in6->sin6_addr), 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);
|
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);
|
ret = picotap->picostack->__pico_socket_connect(conn->picosock, &zaddr, addr->sin_port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -661,6 +697,7 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Feeds data into the local app socket from the I/O buffer associated with the "connection"
|
// Feeds data into the local app socket from the I/O buffer associated with the "connection"
|
||||||
|
// [ (APP<-ZTSOCK) <- RXBUF ]
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
// | |
|
// | |
|
||||||
@@ -669,42 +706,53 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
|
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
|
||||||
{
|
{
|
||||||
|
DEBUG_INFO();
|
||||||
if(!lwip_invoked) {
|
if(!lwip_invoked) {
|
||||||
|
// The stack thread writes to RXBUF as well
|
||||||
picotap->_tcpconns_m.lock();
|
picotap->_tcpconns_m.lock();
|
||||||
picotap->_rx_buf_m.lock();
|
picotap->_rx_buf_m.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_ATTN();
|
int tot = 0, n = -1;
|
||||||
|
|
||||||
Connection *conn = picotap->getConnection(sock);
|
Connection *conn = picotap->getConnection(sock);
|
||||||
if(conn && conn->rxsz) {
|
if(conn && conn->rxsz) {
|
||||||
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ;
|
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) {
|
if(conn->type==SOCK_DGRAM) {
|
||||||
n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, ZT_MAX_MTU);
|
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] attempting write, RXBUF(%d)", conn->rxsz);
|
||||||
DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
|
// 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);
|
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
|
||||||
memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int));
|
memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int));
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
memcpy(&addr, conn->rxbuf, addr_sz_offset);
|
memcpy(&addr, conn->rxbuf, addr_sz_offset);
|
||||||
// adjust buffer
|
// adjust buffer
|
||||||
if(conn->rxsz-n > 0) // If more remains on buffer
|
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Copying data from receiving buffer to ZT-controlled app socket (n=%d, payload_sz=%d)", n, payload_sz);
|
||||||
memcpy(conn->rxbuf, conn->rxbuf+ZT_MAX_MTU, conn->rxsz - ZT_MAX_MTU);
|
if(conn->rxsz-n > 0) { // If more remains on buffer
|
||||||
conn->rxsz -= ZT_MAX_MTU;
|
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) {
|
if(conn->type==SOCK_STREAM) {
|
||||||
n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, conn->rxsz);
|
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
|
if(conn->rxsz-n > 0) // If more remains on buffer
|
||||||
memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n);
|
memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n);
|
||||||
conn->rxsz -= n;
|
conn->rxsz -= n;
|
||||||
}
|
}
|
||||||
if(n) {
|
if(n) {
|
||||||
if(conn->type==SOCK_STREAM) {
|
if(conn->type==SOCK_STREAM) {
|
||||||
DEBUG_TRANS("[TCP RX] <--- :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
//DEBUG_TRANS("[TCP RX] <--- :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
||||||
(float)conn->txsz / max, (float)conn->rxsz / max, conn->sock, n);
|
// (float)conn->txsz / max, (float)conn->rxsz / max, conn->sock, n);
|
||||||
}
|
}
|
||||||
if(conn->rxsz == 0) {
|
if(conn->rxsz == 0) {
|
||||||
picotap->_phy.setNotifyWritable(sock, false);
|
picotap->_phy.setNotifyWritable(sock, false);
|
||||||
@@ -717,13 +765,12 @@ namespace ZeroTier {
|
|||||||
picotap->_phy.setNotifyWritable(sock, false);
|
picotap->_phy.setNotifyWritable(sock, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
picotap->_phy.whack();
|
//picotap->_phy.whack();
|
||||||
check_buffer_states(conn);
|
|
||||||
|
|
||||||
if(!lwip_invoked) {
|
if(!lwip_invoked) {
|
||||||
picotap->_tcpconns_m.unlock();
|
picotap->_tcpconns_m.unlock();
|
||||||
picotap->_rx_buf_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
|
// Closes a pico_socket
|
||||||
|
|||||||
@@ -265,31 +265,31 @@ namespace ZeroTier {
|
|||||||
dlclose(_libref);
|
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 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_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_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_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_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_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_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_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 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 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_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_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_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 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 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_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_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_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_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_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_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 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 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_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
|
} // namespace ZeroTier
|
||||||
|
|||||||
20
src/tap.cpp
20
src/tap.cpp
@@ -63,7 +63,7 @@ namespace ZeroTier {
|
|||||||
int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno)
|
int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno)
|
||||||
{
|
{
|
||||||
//#if !defined(USE_SOCKS_PROXY)
|
//#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);
|
int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
|
||||||
char retmsg[sz];
|
char retmsg[sz];
|
||||||
memset(&retmsg, 0, sizeof(retmsg));
|
memset(&retmsg, 0, sizeof(retmsg));
|
||||||
@@ -328,7 +328,7 @@ void NetconEthernetTap::closeConnection(PhySocket *sock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) {
|
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) {
|
||||||
DEBUG_EXTRA("physock=%p", sock);
|
//DEBUG_EXTRA("physock=%p", sock);
|
||||||
Mutex::Lock _l(_tcpconns_m);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
//closeConnection(sock);
|
//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)
|
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;
|
uint64_t CANARY_num;
|
||||||
pid_t pid, tid;
|
pid_t pid, tid;
|
||||||
ssize_t wlen = len;
|
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);
|
// DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
|
||||||
|
|
||||||
if(cmd == RPC_SOCKET) {
|
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
|
// Create new lwip socket and associate it with this sock
|
||||||
struct socket_st socket_rpc;
|
struct socket_st socket_rpc;
|
||||||
memcpy(&socket_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct socket_st));
|
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);
|
// DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
case RPC_BIND:
|
case RPC_BIND:
|
||||||
DEBUG_INFO("RPC_BIND, physock=%p", sock);
|
//DEBUG_INFO("RPC_BIND, physock=%p", sock);
|
||||||
struct bind_st bind_rpc;
|
struct bind_st bind_rpc;
|
||||||
memcpy(&bind_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct bind_st));
|
memcpy(&bind_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct bind_st));
|
||||||
handleBind(sock, rpcSock, uptr, &bind_rpc);
|
handleBind(sock, rpcSock, uptr, &bind_rpc);
|
||||||
break;
|
break;
|
||||||
case RPC_LISTEN:
|
case RPC_LISTEN:
|
||||||
DEBUG_INFO("RPC_LISTEN, physock=%p", sock);
|
//DEBUG_INFO("RPC_LISTEN, physock=%p", sock);
|
||||||
struct listen_st listen_rpc;
|
struct listen_st listen_rpc;
|
||||||
memcpy(&listen_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct listen_st));
|
memcpy(&listen_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct listen_st));
|
||||||
handleListen(sock, rpcSock, uptr, &listen_rpc);
|
handleListen(sock, rpcSock, uptr, &listen_rpc);
|
||||||
break;
|
break;
|
||||||
case RPC_GETSOCKNAME:
|
case RPC_GETSOCKNAME:
|
||||||
DEBUG_INFO("RPC_GETSOCKNAME, physock=%p", sock);
|
//DEBUG_INFO("RPC_GETSOCKNAME, physock=%p", sock);
|
||||||
struct getsockname_st getsockname_rpc;
|
struct getsockname_st getsockname_rpc;
|
||||||
memcpy(&getsockname_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st));
|
memcpy(&getsockname_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st));
|
||||||
handleGetsockname(sock, rpcSock, uptr, &getsockname_rpc);
|
handleGetsockname(sock, rpcSock, uptr, &getsockname_rpc);
|
||||||
break;
|
break;
|
||||||
case RPC_GETPEERNAME:
|
case RPC_GETPEERNAME:
|
||||||
DEBUG_INFO("RPC_GETPEERNAME, physock=%p", sock);
|
//DEBUG_INFO("RPC_GETPEERNAME, physock=%p", sock);
|
||||||
struct getsockname_st getpeername_rpc;
|
struct getsockname_st getpeername_rpc;
|
||||||
memcpy(&getpeername_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st));
|
memcpy(&getpeername_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct getsockname_st));
|
||||||
handleGetpeername(sock, rpcSock, uptr, &getpeername_rpc);
|
handleGetpeername(sock, rpcSock, uptr, &getpeername_rpc);
|
||||||
break;
|
break;
|
||||||
case RPC_CONNECT:
|
case RPC_CONNECT:
|
||||||
DEBUG_INFO("RPC_CONNECT, physock=%p", sock);
|
//DEBUG_INFO("RPC_CONNECT, physock=%p", sock);
|
||||||
struct connect_st connect_rpc;
|
struct connect_st connect_rpc;
|
||||||
memcpy(&connect_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct connect_st));
|
memcpy(&connect_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct connect_st));
|
||||||
handleConnect(sock, rpcSock, conn, &connect_rpc);
|
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
|
// 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)
|
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);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
#if defined(SDK_PICOTCP)
|
#if defined(SDK_PICOTCP)
|
||||||
pico_handleConnect(sock, rpcSock, conn, connect_rpc);
|
pico_handleConnect(sock, rpcSock, conn, connect_rpc);
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
|
|
||||||
int atoi(const char *str);
|
int atoi(const char *str);
|
||||||
@@ -19,6 +19,12 @@ int main(int argc , char *argv[])
|
|||||||
printf("usage: client <addr> <port> <netpath> <nwid>\n");
|
printf("usage: client <addr> <port> <netpath> <nwid>\n");
|
||||||
return 1;
|
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]);
|
zts_init_rpc(argv[3],argv[4]);
|
||||||
|
|
||||||
int sock, port = atoi(argv[2]);
|
int sock, port = atoi(argv[2]);
|
||||||
@@ -4,13 +4,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
|
|
||||||
void error(char *msg) {
|
void error(char *msg) {
|
||||||
@@ -24,10 +23,18 @@ int main(int argc, char *argv[]) {
|
|||||||
struct hostent *server;
|
struct hostent *server;
|
||||||
char buffer[256] = "This is a string from client!";
|
char buffer[256] = "This is a string from client!";
|
||||||
|
|
||||||
if (argc < 3) {
|
if(argc < 3) {
|
||||||
fprintf(stderr, "Usage: %s \n", argv[0]);
|
printf("usage: client <addr> <port> <netpath> <nwid>\n");
|
||||||
exit(0);
|
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]);
|
portno = atoi(argv[2]);
|
||||||
|
|
||||||
printf("\nIPv6 TCP Client Started...\n");
|
printf("\nIPv6 TCP Client Started...\n");
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
|
|
||||||
int atoi(const char *str);
|
int atoi(const char *str);
|
||||||
@@ -13,9 +13,15 @@ int atoi(const char *str);
|
|||||||
int main(int argc , char *argv[])
|
int main(int argc , char *argv[])
|
||||||
{
|
{
|
||||||
if(argc < 3) {
|
if(argc < 3) {
|
||||||
printf("usage: client <port> <netpath> <nwid>\n");
|
printf("usage: server <port> <netpath> <nwid>\n");
|
||||||
return 1;
|
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]);
|
zts_init_rpc(argv[2],argv[3]);
|
||||||
|
|
||||||
int sock, client_sock, c, read_size, port = atoi(argv[1]);
|
int sock, client_sock, c, read_size, port = atoi(argv[1]);
|
||||||
@@ -29,9 +29,15 @@ int main(int argc, char *argv[]) {
|
|||||||
char client_addr_ipv6[100];
|
char client_addr_ipv6[100];
|
||||||
|
|
||||||
if(argc < 3) {
|
if(argc < 3) {
|
||||||
printf("usage: client <port> <netpath> <nwid>\n");
|
printf("usage: server <port> <netpath> <nwid>\n");
|
||||||
return 1;
|
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]);
|
zts_init_rpc(argv[2],argv[3]);
|
||||||
|
|
||||||
printf("\nIPv6 TCP Server Started...\n");
|
printf("\nIPv6 TCP Server Started...\n");
|
||||||
@@ -9,15 +9,12 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
|
|
||||||
#define BUFSIZE 1024
|
#define BUFSIZE 1024
|
||||||
|
|
||||||
/*
|
|
||||||
* error - wrapper for perror
|
|
||||||
*/
|
|
||||||
void error(char *msg) {
|
void error(char *msg) {
|
||||||
perror(msg);
|
perror(msg);
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -36,6 +33,14 @@ int main(int argc, char **argv) {
|
|||||||
fprintf(stderr,"usage: %s <hostname> <port>\n", argv[0]);
|
fprintf(stderr,"usage: %s <hostname> <port>\n", argv[0]);
|
||||||
exit(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];
|
hostname = argv[1];
|
||||||
portno = atoi(argv[2]);
|
portno = atoi(argv[2]);
|
||||||
|
|
||||||
@@ -80,7 +85,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
/* print the server's reply */
|
/* print the server's reply */
|
||||||
memset(buf, 0, sizeof(buf));
|
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)
|
//if (n < 0)
|
||||||
// printf("ERROR in recvfrom: %d", n);
|
// printf("ERROR in recvfrom: %d", n);
|
||||||
printf("Echo from server: %s", buf);
|
printf("Echo from server: %s", buf);
|
||||||
65
tests/zts/zts.udpclient6.c
Executable file
65
tests/zts/zts.udpclient6.c
Executable 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;
|
||||||
|
}
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
|
|
||||||
#define MAXBUF 1024*1024
|
#define MAXBUF 1024*1024
|
||||||
@@ -21,32 +21,34 @@ void echo(int sock) {
|
|||||||
socklen_t len = sizeof(remote);
|
socklen_t len = sizeof(remote);
|
||||||
long count = 0;
|
long count = 0;
|
||||||
|
|
||||||
while (1) {
|
while(1) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
//usleep(50);
|
|
||||||
count++;
|
count++;
|
||||||
// read a datagram from the socket (put result in bufin)
|
// read a datagram from the socket
|
||||||
n=recvfrom(sock,bufin,MAXBUF,0,(struct sockaddr *)&remote,&len);
|
n=zts_recvfrom(sock,bufin,MAXBUF,0,(struct sockaddr *)&remote,&len);
|
||||||
// print out the address of the sender
|
// print out the address of the sender
|
||||||
printf("DGRAM from %s:%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
|
printf("DGRAM from %s:%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
|
||||||
|
|
||||||
if (n<0) {
|
if (n<0) {
|
||||||
perror("Error receiving data");
|
perror("Error receiving data");
|
||||||
} else {
|
} 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);
|
// 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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if(argc < 3) {
|
if(argc < 3) {
|
||||||
printf("usage: client <port> <netpath> <nwid>\n");
|
printf("usage: client <port> <netpath> <nwid>\n");
|
||||||
return 1;
|
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]);
|
zts_init_rpc(argv[2],argv[3]);
|
||||||
|
|
||||||
int sock, port = atoi(argv[1]);
|
int sock, port = atoi(argv[1]);
|
||||||
@@ -55,7 +57,7 @@ int main(int argc, char *argv[]) {
|
|||||||
struct sockaddr_in skaddr2;
|
struct sockaddr_in skaddr2;
|
||||||
|
|
||||||
// Create socket
|
// 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");
|
printf("error creating socket\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -64,28 +66,14 @@ int main(int argc, char *argv[]) {
|
|||||||
skaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
skaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
skaddr.sin_port = htons(port);
|
skaddr.sin_port = htons(port);
|
||||||
// Bind to address
|
// 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");
|
printf("error binding\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// find out what port we were assigned
|
// find out what port we were assigned
|
||||||
len = sizeof( skaddr2 );
|
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
|
// RX
|
||||||
echo(sock);
|
echo(sock);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
68
tests/zts/zts.udpserver6.c
Executable file
68
tests/zts/zts.udpserver6.c
Executable 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;
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
'\" -*- coding: utf-8 -*-
|
|
||||||
@@ -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
@@ -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
@@ -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
|
|
||||||
@@ -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:
|
|
||||||
@@ -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:
|
|
||||||
@@ -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
Reference in New Issue
Block a user