mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-05-16 15:32:57 +00:00
Go code!
This commit is contained in:
parent
e0ddbc2f28
commit
b34aa10bf8
@ -20,7 +20,6 @@
|
|||||||
#include "../../node/MAC.hpp"
|
#include "../../node/MAC.hpp"
|
||||||
#include "../../node/Address.hpp"
|
#include "../../node/Address.hpp"
|
||||||
#include "../../osdep/OSUtils.hpp"
|
#include "../../osdep/OSUtils.hpp"
|
||||||
#include "../../osdep/BlockingQueue.hpp"
|
|
||||||
#include "../../osdep/EthernetTap.hpp"
|
#include "../../osdep/EthernetTap.hpp"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -89,10 +88,6 @@ struct ZT_GoNode_Impl
|
|||||||
Node *node;
|
Node *node;
|
||||||
volatile int64_t nextBackgroundTaskDeadline;
|
volatile int64_t nextBackgroundTaskDeadline;
|
||||||
|
|
||||||
int (*goPathCheckFunc)(ZT_GoNode *,ZT_Node *,uint64_t ztAddress,const void *);
|
|
||||||
int (*goPathLookupFunc)(ZT_GoNode *,ZT_Node *,int desiredAddressFamily,void *);
|
|
||||||
int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize);
|
|
||||||
|
|
||||||
std::string path;
|
std::string path;
|
||||||
std::atomic_bool run;
|
std::atomic_bool run;
|
||||||
|
|
||||||
@ -102,12 +97,19 @@ struct ZT_GoNode_Impl
|
|||||||
std::map< uint64_t,std::shared_ptr<EthernetTap> > taps;
|
std::map< uint64_t,std::shared_ptr<EthernetTap> > taps;
|
||||||
std::mutex taps_l;
|
std::mutex taps_l;
|
||||||
|
|
||||||
BlockingQueue<ZT_GoNodeEvent> eq;
|
|
||||||
|
|
||||||
std::thread backgroundTaskThread;
|
std::thread backgroundTaskThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/* These functions are implemented in Go in pkg/ztnode/node-callbacks.go */
|
||||||
|
extern "C" int goPathCheckFunc(ZT_GoNode *,uint64_t,int,const void *,int);
|
||||||
|
extern "C" int goPathLookupFunc(ZT_GoNode *,uint64_t,int,int *,uint8_t [16],int *);
|
||||||
|
extern "C" void goStateObjectPutFunc(ZT_GoNode *,int,const uint64_t [2],const void *,int);
|
||||||
|
extern "C" int goStateObjectGetFunc(ZT_GoNode *,int,const uint64_t [2],void *,unsigned int);
|
||||||
|
extern "C" void goDNSResolverFunc(ZT_GoNode *,const uint8_t *,int,const char *,uintptr_t);
|
||||||
|
extern "C" int goVirtualNetworkConfigFunc(ZT_GoNode *,ZT_GoTap *,uint64_t,int,const ZT_VirtualNetworkConfig *);
|
||||||
|
extern "C" void goZtEvent(ZT_GoNode *,int,const void *);
|
||||||
|
|
||||||
static int ZT_GoNode_VirtualNetworkConfigFunction(
|
static int ZT_GoNode_VirtualNetworkConfigFunction(
|
||||||
ZT_Node *node,
|
ZT_Node *node,
|
||||||
@ -118,13 +120,7 @@ static int ZT_GoNode_VirtualNetworkConfigFunction(
|
|||||||
enum ZT_VirtualNetworkConfigOperation op,
|
enum ZT_VirtualNetworkConfigOperation op,
|
||||||
const ZT_VirtualNetworkConfig *cfg)
|
const ZT_VirtualNetworkConfig *cfg)
|
||||||
{
|
{
|
||||||
ZT_GoNodeEvent ev;
|
return goVirtualNetworkConfigFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoTap *>(*nptr),nwid,op,cfg);
|
||||||
ev.type = ZT_GONODE_EVENT_NETWORK_CONFIG_UPDATE;
|
|
||||||
ev.data.nconf.op = op;
|
|
||||||
if (cfg)
|
|
||||||
ev.data.nconf.conf = *cfg;
|
|
||||||
reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ZT_GoNode_VirtualNetworkFrameFunction(
|
static void ZT_GoNode_VirtualNetworkFrameFunction(
|
||||||
@ -151,10 +147,7 @@ static void ZT_GoNode_EventCallback(
|
|||||||
enum ZT_Event et,
|
enum ZT_Event et,
|
||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
ZT_GoNodeEvent ev;
|
goZtEvent(reinterpret_cast<ZT_GoNode *>(uptr),et,data);
|
||||||
ev.type = ZT_GONODE_EVENT_ZTEVENT;
|
|
||||||
ev.data.zt.type = et;
|
|
||||||
reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ZT_GoNode_StatePutFunction(
|
static void ZT_GoNode_StatePutFunction(
|
||||||
@ -166,18 +159,7 @@ static void ZT_GoNode_StatePutFunction(
|
|||||||
const void *data,
|
const void *data,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
if (len < ZT_MAX_STATE_OBJECT_SIZE) { // sanity check
|
goStateObjectPutFunc(reinterpret_cast<ZT_GoNode *>(uptr),objType,id,data,len);
|
||||||
ZT_GoNodeEvent ev;
|
|
||||||
ev.type = (len >= 0) ? ZT_GONODE_EVENT_STATE_PUT : ZT_GONODE_EVENT_STATE_DELETE;
|
|
||||||
if (len > 0) {
|
|
||||||
memcpy(ev.data.sobj.data,data,len);
|
|
||||||
ev.data.sobj.len = (unsigned int)len;
|
|
||||||
}
|
|
||||||
ev.data.sobj.objType = objType;
|
|
||||||
ev.data.sobj.id[0] = id[0];
|
|
||||||
ev.data.sobj.id[1] = id[1];
|
|
||||||
reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ZT_GoNode_StateGetFunction(
|
static int ZT_GoNode_StateGetFunction(
|
||||||
@ -189,7 +171,12 @@ static int ZT_GoNode_StateGetFunction(
|
|||||||
void *buf,
|
void *buf,
|
||||||
unsigned int buflen)
|
unsigned int buflen)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<ZT_GoNode *>(uptr)->goStateObjectGetFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoNode *>(uptr)->node,(int)objType,id,buf,buflen);
|
return goStateObjectGetFunc(
|
||||||
|
reinterpret_cast<ZT_GoNode *>(uptr),
|
||||||
|
(int)objType,
|
||||||
|
id,
|
||||||
|
buf,
|
||||||
|
buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZT_ALWAYS_INLINE void doUdpSend(ZT_SOCKET sock,const struct sockaddr_storage *addr,const void *data,const unsigned int len,const unsigned int ipTTL)
|
static ZT_ALWAYS_INLINE void doUdpSend(ZT_SOCKET sock,const struct sockaddr_storage *addr,const void *data,const unsigned int len,const unsigned int ipTTL)
|
||||||
@ -254,7 +241,23 @@ static int ZT_GoNode_PathCheckFunction(
|
|||||||
int64_t localSocket,
|
int64_t localSocket,
|
||||||
const struct sockaddr_storage *sa)
|
const struct sockaddr_storage *sa)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<ZT_GoNode *>(uptr)->goPathCheckFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoNode *>(uptr)->node,ztAddress,sa);
|
switch(sa->ss_family) {
|
||||||
|
case AF_INET:
|
||||||
|
return goPathCheckFunc(
|
||||||
|
reinterpret_cast<ZT_GoNode *>(uptr),
|
||||||
|
ztAddress,
|
||||||
|
AF_INET,
|
||||||
|
&(reinterpret_cast<const struct sockaddr_in *>(sa)->sin_addr.s_addr),
|
||||||
|
Utils::ntoh((uint16_t)reinterpret_cast<const struct sockaddr_in *>(sa)->sin_port));
|
||||||
|
case AF_INET6:
|
||||||
|
return goPathCheckFunc(
|
||||||
|
reinterpret_cast<ZT_GoNode *>(uptr),
|
||||||
|
ztAddress,
|
||||||
|
AF_INET6,
|
||||||
|
reinterpret_cast<const struct sockaddr_in6 *>(sa)->sin6_addr.s6_addr,
|
||||||
|
Utils::ntoh((uint16_t)reinterpret_cast<const struct sockaddr_in6 *>(sa)->sin6_port));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ZT_GoNode_PathLookupFunction(
|
static int ZT_GoNode_PathLookupFunction(
|
||||||
@ -265,7 +268,32 @@ static int ZT_GoNode_PathLookupFunction(
|
|||||||
int desiredAddressFamily,
|
int desiredAddressFamily,
|
||||||
struct sockaddr_storage *sa)
|
struct sockaddr_storage *sa)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<ZT_GoNode *>(uptr)->goPathLookupFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoNode *>(uptr)->node,desiredAddressFamily,sa);
|
int family = 0;
|
||||||
|
uint8_t ip[16];
|
||||||
|
int port = 0;
|
||||||
|
const int result = goPathLookupFunc(
|
||||||
|
reinterpret_cast<ZT_GoNode *>(uptr),
|
||||||
|
ztAddress,
|
||||||
|
desiredAddressFamily,
|
||||||
|
&family,
|
||||||
|
ip,
|
||||||
|
&port
|
||||||
|
);
|
||||||
|
if (result != 0) {
|
||||||
|
switch(family) {
|
||||||
|
case AF_INET:
|
||||||
|
reinterpret_cast<struct sockaddr_in *>(sa)->sin_family = AF_INET;
|
||||||
|
memcpy(&(reinterpret_cast<struct sockaddr_in *>(sa)->sin_addr.s_addr),ip,4);
|
||||||
|
reinterpret_cast<struct sockaddr_in *>(sa)->sin_port = Utils::hton((uint16_t)port);
|
||||||
|
return 1;
|
||||||
|
case AF_INET6:
|
||||||
|
reinterpret_cast<struct sockaddr_in6 *>(sa)->sin6_family = AF_INET6;
|
||||||
|
memcpy(reinterpret_cast<struct sockaddr_in6 *>(sa)->sin6_addr.s6_addr,ip,16);
|
||||||
|
reinterpret_cast<struct sockaddr_in6 *>(sa)->sin6_port = Utils::hton((uint16_t)port);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ZT_GoNode_DNSResolver(
|
static void ZT_GoNode_DNSResolver(
|
||||||
@ -277,19 +305,14 @@ static void ZT_GoNode_DNSResolver(
|
|||||||
const char *name,
|
const char *name,
|
||||||
uintptr_t requestId)
|
uintptr_t requestId)
|
||||||
{
|
{
|
||||||
ZT_GoNodeEvent ev;
|
uint8_t t[256];
|
||||||
ev.type = ZT_GONODE_EVENT_DNS_GET_TXT;
|
for(unsigned int i=0;(i<numTypes)&&(i<256);++i) t[i] = (uint8_t)types[i];
|
||||||
Utils::scopy(ev.data.dns.dnsName,sizeof(ev.data.dns.dnsName),name);
|
goDNSResolverFunc(reinterpret_cast<ZT_GoNode *>(uptr),t,(int)numTypes,name,requestId);
|
||||||
reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
/****************************************************************************/
|
||||||
|
|
||||||
extern "C" ZT_GoNode *ZT_GoNode_new(
|
extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath)
|
||||||
const char *workingPath,
|
|
||||||
int (*goPathCheckFunc)(ZT_GoNode *,ZT_Node *,uint64_t ztAddress,const void *),
|
|
||||||
int (*goPathLookupFunc)(ZT_GoNode *,ZT_Node *,int desiredAddressFamily,void *),
|
|
||||||
int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize))
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
struct ZT_Node_Callbacks cb;
|
struct ZT_Node_Callbacks cb;
|
||||||
@ -307,9 +330,6 @@ extern "C" ZT_GoNode *ZT_GoNode_new(
|
|||||||
const int64_t now = OSUtils::now();
|
const int64_t now = OSUtils::now();
|
||||||
gn->node = new Node(reinterpret_cast<void *>(gn),nullptr,&cb,now);
|
gn->node = new Node(reinterpret_cast<void *>(gn),nullptr,&cb,now);
|
||||||
gn->nextBackgroundTaskDeadline = now;
|
gn->nextBackgroundTaskDeadline = now;
|
||||||
gn->goPathCheckFunc = goPathCheckFunc;
|
|
||||||
gn->goPathLookupFunc = goPathLookupFunc;
|
|
||||||
gn->goStateObjectGetFunc = goStateObjectGetFunc;
|
|
||||||
gn->path = workingPath;
|
gn->path = workingPath;
|
||||||
gn->run = true;
|
gn->run = true;
|
||||||
|
|
||||||
@ -333,10 +353,6 @@ extern "C" void ZT_GoNode_delete(ZT_GoNode *gn)
|
|||||||
{
|
{
|
||||||
gn->run = false;
|
gn->run = false;
|
||||||
|
|
||||||
ZT_GoNodeEvent sd;
|
|
||||||
sd.type = ZT_GONODE_EVENT_SHUTDOWN;
|
|
||||||
gn->eq.post(sd);
|
|
||||||
|
|
||||||
gn->threads_l.lock();
|
gn->threads_l.lock();
|
||||||
for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
|
for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
|
||||||
t->second.run = false;
|
t->second.run = false;
|
||||||
@ -358,11 +374,6 @@ extern "C" void ZT_GoNode_delete(ZT_GoNode *gn)
|
|||||||
delete gn;
|
delete gn;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" ZT_Node *ZT_GoNode_getNode(ZT_GoNode *gn)
|
|
||||||
{
|
|
||||||
return gn->node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets flags and socket options common to both IPv4 and IPv6 UDP sockets
|
// Sets flags and socket options common to both IPv4 and IPv6 UDP sockets
|
||||||
static void setCommonUdpSocketSettings(ZT_SOCKET udpSock,const char *dev)
|
static void setCommonUdpSocketSettings(ZT_SOCKET udpSock,const char *dev)
|
||||||
{
|
{
|
||||||
@ -521,11 +532,6 @@ extern "C" int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ZT_GoNode_waitForEvent(ZT_GoNode *gn,ZT_GoNodeEvent *ev)
|
|
||||||
{
|
|
||||||
gn->eq.get(*ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
static void tapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
||||||
{
|
{
|
||||||
ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
|
ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
|
||||||
@ -561,3 +567,78 @@ extern "C" void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid)
|
|||||||
gn->taps.erase(existingTap);
|
gn->taps.erase(existingTap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
extern "C" void ZT_GoTap_setEnabled(ZT_GoTap *tap,int enabled)
|
||||||
|
{
|
||||||
|
reinterpret_cast<EthernetTap *>(tap)->setEnabled(enabled != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int ZT_GoTap_addIp(ZT_GoTap *tap,int af,const void *ip,int port)
|
||||||
|
{
|
||||||
|
switch(af) {
|
||||||
|
case AF_INET:
|
||||||
|
return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip,4,(unsigned int)port)) ? 1 : 0);
|
||||||
|
case AF_INET6:
|
||||||
|
return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip,16,(unsigned int)port)) ? 1 : 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int ZT_GoTap_removeIp(ZT_GoTap *tap,int af,const void *ip,int port)
|
||||||
|
{
|
||||||
|
switch(af) {
|
||||||
|
case AF_INET:
|
||||||
|
return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip,4,(unsigned int)port)) ? 1 : 0);
|
||||||
|
case AF_INET6:
|
||||||
|
return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip,16,(unsigned int)port)) ? 1 : 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize)
|
||||||
|
{
|
||||||
|
auto ips = reinterpret_cast<EthernetTap *>(tap)->ips();
|
||||||
|
unsigned int p = 0;
|
||||||
|
uint8_t *const b = reinterpret_cast<uint8_t *>(buf);
|
||||||
|
for(auto ip=ips.begin();ip!=ips.end();++ip) {
|
||||||
|
if ((p + 7) > bufSize)
|
||||||
|
break;
|
||||||
|
const uint8_t *const ipd = reinterpret_cast<const uint8_t *>(ip->rawIpData());
|
||||||
|
const unsigned int port = ip->port();
|
||||||
|
if (ip->isV4()) {
|
||||||
|
b[p++] = AF_INET;
|
||||||
|
b[p++] = ipd[0];
|
||||||
|
b[p++] = ipd[1];
|
||||||
|
b[p++] = ipd[2];
|
||||||
|
b[p++] = ipd[3];
|
||||||
|
b[p++] = (uint8_t)((port >> 8) & 0xff);
|
||||||
|
b[p++] = (uint8_t)(port & 0xff);
|
||||||
|
} else if (ip->isV6()) {
|
||||||
|
if ((p + 19) <= bufSize) {
|
||||||
|
b[p++] = AF_INET6;
|
||||||
|
for(int j=0;j<16;++j)
|
||||||
|
b[p++] = ipd[j];
|
||||||
|
b[p++] = (uint8_t)((port >> 8) & 0xff);
|
||||||
|
b[p++] = (uint8_t)(port & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (int)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ZT_GoTap_deviceName(ZT_GoTap *tap,char nbuf[256])
|
||||||
|
{
|
||||||
|
Utils::scopy(nbuf,256,reinterpret_cast<EthernetTap *>(tap)->deviceName().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ZT_GoTap_setFriendlyName(ZT_GoTap *tap,const char *friendlyName)
|
||||||
|
{
|
||||||
|
reinterpret_cast<EthernetTap *>(tap)->setFriendlyName(friendlyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ZT_GoTap_setMtu(ZT_GoTap *tap,unsigned int mtu)
|
||||||
|
{
|
||||||
|
reinterpret_cast<EthernetTap *>(tap)->setMtu(mtu);
|
||||||
|
}
|
||||||
|
@ -31,57 +31,6 @@ typedef void ZT_GoTap;
|
|||||||
struct ZT_GoNode_Impl;
|
struct ZT_GoNode_Impl;
|
||||||
typedef struct ZT_GoNode_Impl ZT_GoNode;
|
typedef struct ZT_GoNode_Impl ZT_GoNode;
|
||||||
|
|
||||||
#define ZT_GONODE_EVENT_SHUTDOWN 0
|
|
||||||
#define ZT_GONODE_EVENT_ZTEVENT 1
|
|
||||||
#define ZT_GONODE_EVENT_DNS_GET_TXT 2
|
|
||||||
#define ZT_GONODE_EVENT_STATE_PUT 3
|
|
||||||
#define ZT_GONODE_EVENT_STATE_DELETE 4
|
|
||||||
#define ZT_GONODE_EVENT_NETWORK_CONFIG_UPDATE 5
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variant type for async core generated events pulled via waitForEvent
|
|
||||||
*/
|
|
||||||
struct ZT_GoNodeEvent_Impl
|
|
||||||
{
|
|
||||||
#ifdef __cplusplus
|
|
||||||
inline ZT_GoNodeEvent_Impl() { memset(reinterpret_cast<void *>(this),0,sizeof(ZT_GoNodeEvent_Impl)); }
|
|
||||||
inline ZT_GoNodeEvent_Impl(const ZT_GoNodeEvent_Impl &ev) { memcpy(reinterpret_cast<void *>(this),reinterpret_cast<const void *>(&ev),sizeof(ZT_GoNodeEvent_Impl)); }
|
|
||||||
inline ZT_GoNodeEvent_Impl &operator=(const ZT_GoNodeEvent_Impl &ev) { memcpy(reinterpret_cast<void *>(this),reinterpret_cast<const void *>(&ev),sizeof(ZT_GoNodeEvent_Impl)); return *this; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int type;
|
|
||||||
|
|
||||||
union {
|
|
||||||
/* ZeroTier event of ZT_Event type */
|
|
||||||
struct {
|
|
||||||
int type;
|
|
||||||
} zt;
|
|
||||||
|
|
||||||
/* DNS resolution request */
|
|
||||||
struct {
|
|
||||||
uintptr_t requestId;
|
|
||||||
char dnsName[256];
|
|
||||||
} dns;
|
|
||||||
|
|
||||||
/* State object put or delete request */
|
|
||||||
struct {
|
|
||||||
uint8_t data[ZT_MAX_STATE_OBJECT_SIZE];
|
|
||||||
unsigned int len;
|
|
||||||
int objType;
|
|
||||||
uint64_t id[2];
|
|
||||||
} sobj;
|
|
||||||
|
|
||||||
/* Network configuration update event */
|
|
||||||
struct {
|
|
||||||
ZT_GoTap *tap;
|
|
||||||
int op; /* ZT_VirtualNetworkConfigOperation */
|
|
||||||
ZT_VirtualNetworkConfig conf;
|
|
||||||
} nconf;
|
|
||||||
} data;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct ZT_GoNodeEvent_Impl ZT_GoNodeEvent;
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -90,11 +39,10 @@ extern "C" {
|
|||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
ZT_GoNode *ZT_GoNode_new(
|
|
||||||
const char *workingPath,
|
/****************************************************************************/
|
||||||
int (*goPathCheckFunc)(ZT_GoNode *,ZT_Node *,uint64_t ztAddress,const void *),
|
|
||||||
int (*goPathLookupFunc)(ZT_GoNode *,ZT_Node *,int desiredAddressFamily,void *),
|
ZT_GoNode *ZT_GoNode_new(const char *workingPath);
|
||||||
int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize));
|
|
||||||
|
|
||||||
void ZT_GoNode_delete(ZT_GoNode *gn);
|
void ZT_GoNode_delete(ZT_GoNode *gn);
|
||||||
|
|
||||||
@ -106,8 +54,6 @@ int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char *ip,const
|
|||||||
/* Close all listener threads for a given local IP and port */
|
/* Close all listener threads for a given local IP and port */
|
||||||
int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port);
|
int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port);
|
||||||
|
|
||||||
void ZT_GoNode_waitForEvent(ZT_GoNode *gn,ZT_GoNodeEvent *ev);
|
|
||||||
|
|
||||||
ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid);
|
ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid);
|
||||||
|
|
||||||
void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid);
|
void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid);
|
||||||
@ -130,7 +76,7 @@ int ZT_GoTap_removeIp(ZT_GoTap *tap,int af,const void *ip,int port);
|
|||||||
*/
|
*/
|
||||||
int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize);
|
int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize);
|
||||||
|
|
||||||
const char *ZT_GoTap_deviceName(ZT_GoTap *tap);
|
void ZT_GoTap_deviceName(ZT_GoTap *tap,char nbuf[256]);
|
||||||
|
|
||||||
void ZT_GoTap_setFriendlyName(ZT_GoTap *tap,const char *friendlyName);
|
void ZT_GoTap_setFriendlyName(ZT_GoTap *tap,const char *friendlyName);
|
||||||
|
|
||||||
|
25
go/pkg/zerotier/errors.go
Normal file
25
go/pkg/zerotier/errors.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c)2019 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2023-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
// Err is a basic string error type for ZeroTier
|
||||||
|
type Err string
|
||||||
|
|
||||||
|
func (e Err) Error() string { return (string)(e) }
|
||||||
|
|
||||||
|
// Simple ZeroTier Errors
|
||||||
|
const (
|
||||||
|
ErrInvalidMACAddress Err = "invalid MAC address"
|
||||||
|
ErrInvalidParameter Err = "invalid parameter"
|
||||||
|
)
|
63
go/pkg/zerotier/mac.go
Normal file
63
go/pkg/zerotier/mac.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c)2019 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2023-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MAC represents an Ethernet hardware address
|
||||||
|
type MAC uint64
|
||||||
|
|
||||||
|
// NewMACFromString decodes a MAC address in canonical colon-separated hex format
|
||||||
|
func NewMACFromString(s string) (MAC, error) {
|
||||||
|
ss := strings.Split(s, ":")
|
||||||
|
if len(ss) != 6 {
|
||||||
|
return MAC(0), ErrInvalidMACAddress
|
||||||
|
}
|
||||||
|
var m uint64
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
m <<= 8
|
||||||
|
c, _ := strconv.ParseUint(ss[i], 16, 64)
|
||||||
|
if c > 0xff {
|
||||||
|
return MAC(0), ErrInvalidMACAddress
|
||||||
|
}
|
||||||
|
m |= (c & 0xff)
|
||||||
|
}
|
||||||
|
return MAC(m), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns this MAC address in canonical human-readable form
|
||||||
|
func (m MAC) String() string {
|
||||||
|
return fmt.Sprintf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (m>>40)&0xff, (m>>32)&0xff, (m>>24)&0xff, (m>>16)&0xff, (m>>8)&0xff, m&0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON marshals this MAC as a string
|
||||||
|
func (m MAC) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(m.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON unmarshals this MAC from a string
|
||||||
|
func (m *MAC) UnmarshalJSON(j []byte) error {
|
||||||
|
var s string
|
||||||
|
err := json.Unmarshal(j, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m, err = NewMACFromString(s)
|
||||||
|
return err
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
package ztnode
|
package zerotier
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
20
go/pkg/zerotier/multicastgroup.go
Normal file
20
go/pkg/zerotier/multicastgroup.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c)2019 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2023-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
// MulticastGroup represents a normal Ethernet multicast or broadcast address plus 32 additional ZeroTier-specific bits
|
||||||
|
type MulticastGroup struct {
|
||||||
|
MAC MAC
|
||||||
|
ADI uint32
|
||||||
|
}
|
74
go/pkg/zerotier/network.go
Normal file
74
go/pkg/zerotier/network.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c)2019 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2023-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkConfig represents the network's current state
|
||||||
|
type NetworkConfig struct {
|
||||||
|
// ID is this network's 64-bit globally unique identifier
|
||||||
|
ID uint64
|
||||||
|
|
||||||
|
// MAC is the Ethernet MAC address of this device on this network
|
||||||
|
MAC MAC
|
||||||
|
|
||||||
|
// Name is a short human-readable name set by the controller
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Status is a status code indicating this network's authorization status
|
||||||
|
Status int
|
||||||
|
|
||||||
|
// LastUpdated is the time this network's configuration was last updated from the controller
|
||||||
|
LastUpdated time.Time
|
||||||
|
|
||||||
|
// Type is this network's type
|
||||||
|
Type int
|
||||||
|
|
||||||
|
// MTU is the Ethernet MTU for this network
|
||||||
|
MTU int
|
||||||
|
|
||||||
|
// CanBridge is true if this network is allowed to bridge in other devices with different Ethernet addresses
|
||||||
|
CanBridge bool
|
||||||
|
|
||||||
|
// AllowsBroadcast is true if the broadcast (ff:ff:ff:ff:ff:ff) address works (excluding IPv4 ARP which is handled via a special path)
|
||||||
|
AllowsBroadcast bool
|
||||||
|
|
||||||
|
// IPs are static IPs assigned by the network controller to this device
|
||||||
|
IPs []net.IPNet
|
||||||
|
|
||||||
|
// Routes are static routes assigned by the network controller to this device
|
||||||
|
Routes []Route
|
||||||
|
|
||||||
|
// MulticastSubscriptions are this device's current multicast subscriptions
|
||||||
|
MulticastSubscriptions []MulticastGroup
|
||||||
|
|
||||||
|
// PortType is a human-readable description of this port's implementation type or name
|
||||||
|
PortType string
|
||||||
|
|
||||||
|
// PortDeviceName is the OS-specific device name (e.g. tun0 or feth1856) for this network's virtual port
|
||||||
|
PortDeviceName string
|
||||||
|
|
||||||
|
// PortErrorCode is an OS-specific error code returned by the virtual NIC driver
|
||||||
|
PortErrorCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network is a currently joined network
|
||||||
|
type Network struct {
|
||||||
|
config atomic.Value
|
||||||
|
tap atomic.Value
|
||||||
|
}
|
180
go/pkg/zerotier/node-callbacks.go
Normal file
180
go/pkg/zerotier/node-callbacks.go
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c)2019 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2023-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
//#cgo CFLAGS: -O3
|
||||||
|
//#define ZT_CGO 1
|
||||||
|
//#include <stdint.h>
|
||||||
|
//#include <stdlib.h>
|
||||||
|
//#include <string.h>
|
||||||
|
//#include "../../native/GoGlue.h"
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
afInet = C.AF_INET
|
||||||
|
afInet6 = C.AF_INET6
|
||||||
|
|
||||||
|
networkStatusRequestingConfiguration = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
|
||||||
|
networkStatusOK = C.ZT_NETWORK_STATUS_OK
|
||||||
|
networkStatusAccessDenied = C.ZT_NETWORK_STATUS_ACCESS_DENIED
|
||||||
|
networkStatusNotFound = C.ZT_NETWORK_STATUS_NOT_FOUND
|
||||||
|
networkStatusPortError = C.ZT_NETWORK_STATUS_PORT_ERROR
|
||||||
|
networkStatusClientTooOld = C.ZT_NETWORK_STATUS_CLIENT_TOO_OLD
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
nodesByUserPtr map[uintptr]*Node
|
||||||
|
nodesByUserPtrLock sync.RWMutex
|
||||||
|
)
|
||||||
|
|
||||||
|
//export goPathCheckFunc
|
||||||
|
func goPathCheckFunc(gn unsafe.Pointer, ztAddress C.uint64_t, af C.int, ip unsafe.Pointer, port C.int) C.int {
|
||||||
|
nodesByUserPtrLock.RLock()
|
||||||
|
node := nodesByUserPtr[uintptr(gn)]
|
||||||
|
nodesByUserPtrLock.RUnlock()
|
||||||
|
if node != nil && node.pathCheck(uint64(ztAddress), int(af), nil, int(port)) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goPathLookupFunc
|
||||||
|
func goPathLookupFunc(gn unsafe.Pointer, ztAddress C.uint64_t, desiredAddressFamily int, familyP, ipP, portP unsafe.Pointer) C.int {
|
||||||
|
nodesByUserPtrLock.RLock()
|
||||||
|
node := nodesByUserPtr[uintptr(gn)]
|
||||||
|
nodesByUserPtrLock.RUnlock()
|
||||||
|
if node == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ip, port := node.pathLookup(uint64(ztAddress))
|
||||||
|
ip4 := ip.To4()
|
||||||
|
if len(ip4) == 4 {
|
||||||
|
*((*C.int)(familyP)) = afInet
|
||||||
|
copy((*[4]byte)(ipP)[:], ip4)
|
||||||
|
*((*C.int)(portP)) = C.int(port)
|
||||||
|
} else if len(ip) == 16 {
|
||||||
|
*((*C.int)(familyP)) = afInet6
|
||||||
|
copy((*[16]byte)(ipP)[:], ip)
|
||||||
|
*((*C.int)(portP)) = C.int(port)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goStateObjectPutFunc
|
||||||
|
func goStateObjectPutFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, len C.int) {
|
||||||
|
nodesByUserPtrLock.RLock()
|
||||||
|
node := nodesByUserPtr[uintptr(gn)]
|
||||||
|
nodesByUserPtrLock.RUnlock()
|
||||||
|
if node == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len < 0 {
|
||||||
|
node.stateObjectDelete(int(objType), *((*[2]uint64)(id)))
|
||||||
|
} else {
|
||||||
|
node.stateObjectPut(int(objType), *((*[2]uint64)(id)), C.GoBytes(data, len))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goStateObjectGetFunc
|
||||||
|
func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, bufSize C.uint) C.int {
|
||||||
|
nodesByUserPtrLock.RLock()
|
||||||
|
node := nodesByUserPtr[uintptr(gn)]
|
||||||
|
nodesByUserPtrLock.RUnlock()
|
||||||
|
if node == nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
tmp, found := node.stateObjectGet(int(objType), *((*[2]uint64)(id)))
|
||||||
|
if found && len(tmp) < int(bufSize) {
|
||||||
|
if len(tmp) > 0 {
|
||||||
|
C.memcpy(data, unsafe.Pointer(&(tmp[0])), C.ulong(len(tmp)))
|
||||||
|
}
|
||||||
|
return C.int(len(tmp))
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goDNSResolverFunc
|
||||||
|
func goDNSResolverFunc(gn unsafe.Pointer, dnsRecordTypes unsafe.Pointer, numDNSRecordTypes C.int, name unsafe.Pointer, requestID C.uintptr_t) {
|
||||||
|
nodesByUserPtrLock.RLock()
|
||||||
|
node := nodesByUserPtr[uintptr(gn)]
|
||||||
|
nodesByUserPtrLock.RUnlock()
|
||||||
|
if node == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
recordTypes := C.GoBytes(dnsRecordTypes, numDNSRecordTypes)
|
||||||
|
recordName := C.GoString((*C.char)(name))
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
recordNameCStrCopy := C.CString(recordName)
|
||||||
|
for _, rt := range recordTypes {
|
||||||
|
switch rt {
|
||||||
|
case C.ZT_DNS_RECORD_TXT:
|
||||||
|
recs, _ := net.LookupTXT(recordName)
|
||||||
|
for _, rec := range recs {
|
||||||
|
if len(rec) > 0 {
|
||||||
|
rnCS := C.CString(rec)
|
||||||
|
C.ZT_Node_processDNSResult(unsafe.Pointer(node.zn), nil, requestID, recordNameCStrCopy, C.ZT_DNS_RECORD_TXT, unsafe.Pointer(rnCS), C.uint(len(rec)), 0)
|
||||||
|
C.free(unsafe.Pointer(rnCS))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
C.ZT_Node_processDNSResult(unsafe.Pointer(node.zn), nil, requestID, recordNameCStrCopy, C.ZT_DNS_RECORD__END_OF_RESULTS, nil, 0, 0)
|
||||||
|
C.free(unsafe.Pointer(recordNameCStrCopy))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goVirtualNetworkConfigFunc
|
||||||
|
func goVirtualNetworkConfigFunc(gn, tapP unsafe.Pointer, nwid C.uint64_t, op C.int, conf unsafe.Pointer) C.int {
|
||||||
|
nodesByUserPtrLock.RLock()
|
||||||
|
node := nodesByUserPtr[uintptr(gn)]
|
||||||
|
nodesByUserPtrLock.RUnlock()
|
||||||
|
if node == nil {
|
||||||
|
return 255
|
||||||
|
}
|
||||||
|
return C.int(node.handleNetworkConfigUpdate(int(op), (*C.ZT_VirtualNetworkConfig)(conf)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goZtEvent
|
||||||
|
func goZtEvent(gn unsafe.Pointer, eventType C.int, data unsafe.Pointer) {
|
||||||
|
nodesByUserPtrLock.RLock()
|
||||||
|
node := nodesByUserPtr[uintptr(gn)]
|
||||||
|
nodesByUserPtrLock.RUnlock()
|
||||||
|
if node == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch eventType {
|
||||||
|
case C.ZT_EVENT_OFFLINE:
|
||||||
|
atomic.StoreUint32(&node.online, 0)
|
||||||
|
case C.ZT_EVENT_ONLINE:
|
||||||
|
atomic.StoreUint32(&node.online, 1)
|
||||||
|
case C.ZT_EVENT_TRACE:
|
||||||
|
node.handleTrace(C.GoString((*C.char)(data)))
|
||||||
|
case C.ZT_EVENT_USER_MESSAGE:
|
||||||
|
um := (*C.ZT_UserMessage)(data)
|
||||||
|
node.handleUserMessage(uint64(um.origin), uint64(um.typeId), C.GoBytes(um.data, C.int(um.length)))
|
||||||
|
case C.ZT_EVENT_REMOTE_TRACE:
|
||||||
|
rt := (*C.ZT_RemoteTrace)(data)
|
||||||
|
node.handleRemoteTrace(uint64(rt.origin), C.GoBytes(unsafe.Pointer(rt.data), C.int(rt.len)))
|
||||||
|
}
|
||||||
|
}
|
128
go/pkg/zerotier/node.go
Normal file
128
go/pkg/zerotier/node.go
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c)2019 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2023-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
//#cgo CFLAGS: -O3
|
||||||
|
//#cgo LDFLAGS: ${SRCDIR}/../../../build/node/libzt_core.a ${SRCDIR}/../../../build/go/native/libzt_go_native.a -lc++
|
||||||
|
//#define ZT_CGO 1
|
||||||
|
//#include <stdint.h>
|
||||||
|
//#include "../../native/GoGlue.h"
|
||||||
|
//#if __has_include("../../../version.h")
|
||||||
|
//#include "../../../version.h"
|
||||||
|
//#else
|
||||||
|
//#define ZEROTIER_ONE_VERSION_MAJOR 255
|
||||||
|
//#define ZEROTIER_ONE_VERSION_MINOR 255
|
||||||
|
//#define ZEROTIER_ONE_VERSION_REVISION 255
|
||||||
|
//#define ZEROTIER_ONE_VERSION_BUILD 255
|
||||||
|
//#endif
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CoreVersionMajor is the major version of the ZeroTier core
|
||||||
|
CoreVersionMajor int = C.ZEROTIER_ONE_VERSION_MAJOR
|
||||||
|
|
||||||
|
// CoreVersionMinor is the minor version of the ZeroTier core
|
||||||
|
CoreVersionMinor int = C.ZEROTIER_ONE_VERSION_MINOR
|
||||||
|
|
||||||
|
// CoreVersionRevision is the revision of the ZeroTier core
|
||||||
|
CoreVersionRevision int = C.ZEROTIER_ONE_VERSION_REVISION
|
||||||
|
|
||||||
|
// CoreVersionBuild is the build version of the ZeroTier core
|
||||||
|
CoreVersionBuild int = C.ZEROTIER_ONE_VERSION_BUILD
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tap is an instance of an EthernetTap object
|
||||||
|
type Tap struct {
|
||||||
|
tap *C.ZT_GoTap
|
||||||
|
networkStatus uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node is an instance of a ZeroTier node
|
||||||
|
type Node struct {
|
||||||
|
gn *C.ZT_GoNode
|
||||||
|
zn *C.ZT_Node
|
||||||
|
|
||||||
|
taps map[uint64]*Tap
|
||||||
|
tapsLock sync.RWMutex
|
||||||
|
|
||||||
|
online uint32
|
||||||
|
running uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNode creates and initializes a new instance of the ZeroTier node service
|
||||||
|
func NewNode() *Node {
|
||||||
|
n := new(Node)
|
||||||
|
|
||||||
|
gnRawAddr := uintptr(unsafe.Pointer(n.gn))
|
||||||
|
nodesByUserPtrLock.Lock()
|
||||||
|
nodesByUserPtr[gnRawAddr] = n
|
||||||
|
nodesByUserPtrLock.Unlock()
|
||||||
|
runtime.SetFinalizer(n, func(obj interface{}) { // make sure this always happens
|
||||||
|
nodesByUserPtrLock.Lock()
|
||||||
|
delete(nodesByUserPtr, gnRawAddr)
|
||||||
|
nodesByUserPtrLock.Unlock()
|
||||||
|
})
|
||||||
|
|
||||||
|
n.running = 1
|
||||||
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes this Node and frees its underlying C++ Node structures
|
||||||
|
func (n *Node) Close() {
|
||||||
|
if atomic.SwapUint32(&n.running, 0) != 0 {
|
||||||
|
C.ZT_GoNode_delete(n.gn)
|
||||||
|
nodesByUserPtrLock.Lock()
|
||||||
|
delete(nodesByUserPtr, uintptr(unsafe.Pointer(n.gn)))
|
||||||
|
nodesByUserPtrLock.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) pathCheck(ztAddress uint64, af int, ip net.IP, port int) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) pathLookup(ztAddress uint64) (net.IP, int) {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) stateObjectPut(objType int, id [2]uint64, data []byte) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) stateObjectDelete(objType int, id [2]uint64) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) stateObjectGet(objType int, id [2]uint64) ([]byte, bool) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) handleTrace(traceMessage string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) handleUserMessage(originAddress, messageTypeID uint64, data []byte) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) handleRemoteTrace(originAddress uint64, dictData []byte) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) handleNetworkConfigUpdate(op int, config *C.ZT_VirtualNetworkConfig) int {
|
||||||
|
return 0
|
||||||
|
}
|
28
go/pkg/zerotier/route.go
Normal file
28
go/pkg/zerotier/route.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c)2019 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2023-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
package zerotier
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
// Route represents a route in a host's routing table
|
||||||
|
type Route struct {
|
||||||
|
// Target for this route
|
||||||
|
Target net.IPNet
|
||||||
|
|
||||||
|
// Via is how to reach this target (null/empty if the target IP range is local to this virtual LAN)
|
||||||
|
Via net.IP
|
||||||
|
|
||||||
|
// Metric is an interface metric that can affect route priority (behavior can be OS-specific)
|
||||||
|
Metric int
|
||||||
|
}
|
@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c)2019 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* Use of this software is governed by the Business Source License included
|
|
||||||
* in the LICENSE.TXT file in the project's root directory.
|
|
||||||
*
|
|
||||||
* Change Date: 2023-01-01
|
|
||||||
*
|
|
||||||
* On the date above, in accordance with the Business Source License, use
|
|
||||||
* of this software will be governed by version 2.0 of the Apache License.
|
|
||||||
*/
|
|
||||||
/****/
|
|
||||||
|
|
||||||
package ztnode
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// errTypeName returns the type name of an error minus any leading * character.
|
|
||||||
func errTypeName(err error) string {
|
|
||||||
if err == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
et := reflect.TypeOf(err)
|
|
||||||
if et.Kind() == reflect.Ptr {
|
|
||||||
return et.Elem().Name()
|
|
||||||
}
|
|
||||||
return et.Name()
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Err indicates a general LF error such as an invalid parameter or state.
|
|
||||||
type Err string
|
|
||||||
|
|
||||||
func (e Err) Error() string { return (string)(e) }
|
|
||||||
|
|
||||||
// General errors
|
|
||||||
const (
|
|
||||||
ErrInvalidPublicKey Err = "invalid public key"
|
|
||||||
ErrInvalidPrivateKey Err = "invalid private key"
|
|
||||||
ErrInvalidParameter Err = "invalid parameter"
|
|
||||||
ErrInvalidObject Err = "invalid object"
|
|
||||||
ErrUnsupportedType Err = "unsupported type"
|
|
||||||
ErrUnsupportedCurve Err = "unsupported ECC curve (for this purpose)"
|
|
||||||
ErrOutOfRange Err = "parameter out of range"
|
|
||||||
ErrWharrgarblFailed Err = "Wharrgarbl proof of work algorithm failed (out of memory?)"
|
|
||||||
ErrIO Err = "I/O error"
|
|
||||||
ErrIncorrectKey Err = "incorrect key"
|
|
||||||
ErrAlreadyConnected Err = "already connected"
|
|
||||||
ErrRecordNotFound Err = "record not found"
|
|
||||||
ErrRecordIsNewer Err = "record is newer than timestamp"
|
|
||||||
ErrPulseSpanExeceeded Err = "pulse is more than one year after record"
|
|
||||||
ErrDuplicateRecord Err = "duplicate record"
|
|
||||||
ErrPrivateKeyRequired Err = "private key required"
|
|
||||||
ErrInvalidMessageSize Err = "message size invalid"
|
|
||||||
ErrQueryRequiresSelectors Err = "query requires at least one selector"
|
|
||||||
ErrQueryInvalidSortOrder Err = "invalid sort order value"
|
|
||||||
ErrAlreadyMounted Err = "mount point already mounted"
|
|
||||||
)
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// ErrRecord indicates an error related to an invalid record or a record failing a check.
|
|
||||||
type ErrRecord string
|
|
||||||
|
|
||||||
func (e ErrRecord) Error() string { return (string)(e) }
|
|
||||||
|
|
||||||
// Errs indicating that a record is invalid
|
|
||||||
const (
|
|
||||||
ErrRecordInvalid ErrRecord = "record invalid"
|
|
||||||
ErrRecordOwnerSignatureCheckFailed ErrRecord = "owner signature check failed"
|
|
||||||
ErrRecordInsufficientWork ErrRecord = "insufficient work to pay for this record"
|
|
||||||
ErrRecordNotApproved ErrRecord = "record not currently approved (via proof of work and/or certificates)"
|
|
||||||
ErrRecordInsufficientLinks ErrRecord = "insufficient links"
|
|
||||||
ErrRecordTooManyLinks ErrRecord = "too many links"
|
|
||||||
ErrRecordInvalidLinks ErrRecord = "links must be sorted and unique"
|
|
||||||
ErrRecordTooManySelectors ErrRecord = "too many selectors"
|
|
||||||
ErrRecordUnsupportedAlgorithm ErrRecord = "unsupported algorithm or type"
|
|
||||||
ErrRecordTooLarge ErrRecord = "record too large"
|
|
||||||
ErrRecordValueTooLarge ErrRecord = "record value too large"
|
|
||||||
ErrRecordViolatesSpecialRelativity ErrRecord = "record timestamp too far in the future"
|
|
||||||
ErrRecordTooOld ErrRecord = "record older than network timestamp floor"
|
|
||||||
ErrRecordCertificateInvalid ErrRecord = "certificate invalid"
|
|
||||||
ErrRecordCertificateRequired ErrRecord = "certificate required"
|
|
||||||
ErrRecordProhibited ErrRecord = "record administratively prohibited"
|
|
||||||
)
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// ErrDatabase contains information about a database related problem.
|
|
||||||
type ErrDatabase struct {
|
|
||||||
// ErrCode is the error code returned by the C database module.
|
|
||||||
ErrCode int
|
|
||||||
|
|
||||||
// ErrMessage is an error message supplied by the C code or by Go (optional)
|
|
||||||
ErrMessage string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ErrDatabase) Error() string {
|
|
||||||
return fmt.Sprintf("database error: %d (%s)", e.ErrCode, e.ErrMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// ErrAPI (response) indicates an error and is returned with non-200 responses.
|
|
||||||
type ErrAPI struct {
|
|
||||||
Code int `` // HTTP response code
|
|
||||||
Message string `json:",omitempty"` // Message indicating the reason for the error
|
|
||||||
ErrTypeName string `json:",omitempty"` // Name of LF native error or empty if HTTP or transport error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error implements the error interface, making APIError an 'error' in the Go sense.
|
|
||||||
func (e ErrAPI) Error() string {
|
|
||||||
if len(e.ErrTypeName) > 0 {
|
|
||||||
return fmt.Sprintf("%d:%s:%s", e.Code, e.ErrTypeName, e.Message)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%d:%s", e.Code, e.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
*/
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c)2019 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* Use of this software is governed by the Business Source License included
|
|
||||||
* in the LICENSE.TXT file in the project's root directory.
|
|
||||||
*
|
|
||||||
* Change Date: 2023-01-01
|
|
||||||
*
|
|
||||||
* On the date above, in accordance with the Business Source License, use
|
|
||||||
* of this software will be governed by version 2.0 of the Apache License.
|
|
||||||
*/
|
|
||||||
/****/
|
|
||||||
|
|
||||||
package ztnode
|
|
||||||
|
|
||||||
//#cgo CFLAGS: -O3
|
|
||||||
//#cgo LDFLAGS: ${SRCDIR}/../../../build/node/libzt_core.a ${SRCDIR}/../../../build/go/native/libzt_go_native.a -lc++
|
|
||||||
//#define ZT_CGO 1
|
|
||||||
//#include <stdint.h>
|
|
||||||
//#include "../../native/GoGlue.h"
|
|
||||||
//#if __has_include("../../../version.h")
|
|
||||||
//#include "../../../version.h"
|
|
||||||
//#else
|
|
||||||
//#define ZEROTIER_ONE_VERSION_MAJOR 255
|
|
||||||
//#define ZEROTIER_ONE_VERSION_MINOR 255
|
|
||||||
//#define ZEROTIER_ONE_VERSION_REVISION 255
|
|
||||||
//#define ZEROTIER_ONE_VERSION_BUILD 255
|
|
||||||
//#endif
|
|
||||||
import "C"
|
|
||||||
import "sync"
|
|
||||||
|
|
||||||
const (
|
|
||||||
// CoreVersionMajor is the major version of the ZeroTier core
|
|
||||||
CoreVersionMajor int = C.ZEROTIER_ONE_VERSION_MAJOR
|
|
||||||
|
|
||||||
// CoreVersionMinor is the minor version of the ZeroTier core
|
|
||||||
CoreVersionMinor int = C.ZEROTIER_ONE_VERSION_MINOR
|
|
||||||
|
|
||||||
// CoreVersionRevision is the revision of the ZeroTier core
|
|
||||||
CoreVersionRevision int = C.ZEROTIER_ONE_VERSION_REVISION
|
|
||||||
|
|
||||||
// CoreVersionBuild is the build version of the ZeroTier core
|
|
||||||
CoreVersionBuild int = C.ZEROTIER_ONE_VERSION_BUILD
|
|
||||||
)
|
|
||||||
|
|
||||||
// Node is an instance of a ZeroTier node
|
|
||||||
type Node struct {
|
|
||||||
gn *C.ZT_GoNode
|
|
||||||
zn *C.ZT_Node
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
nodesByUserPtr map[uintptr]*Node
|
|
||||||
nodesByUserPtrLock sync.Mutex
|
|
||||||
)
|
|
@ -983,7 +983,7 @@ typedef struct
|
|||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route metric (not currently used)
|
* Route metric
|
||||||
*/
|
*/
|
||||||
uint16_t metric;
|
uint16_t metric;
|
||||||
} ZT_VirtualNetworkRoute;
|
} ZT_VirtualNetworkRoute;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user