More Go boilerplate.
This commit is contained in:
parent
ae2120eb96
commit
ed2024285d
7 changed files with 154 additions and 11 deletions
|
@ -2,11 +2,11 @@ cmake_minimum_required(VERSION 2.8)
|
|||
project(zt_go_native)
|
||||
|
||||
set(src
|
||||
GoNode.cpp
|
||||
GoGlue.cpp
|
||||
)
|
||||
|
||||
set(headers
|
||||
GoNode.h
|
||||
GoGlue.h
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${src} ${headers})
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "GoNode.h"
|
||||
#include "GoGlue.h"
|
||||
|
||||
#include "../../node/Constants.hpp"
|
||||
#include "../../node/InetAddress.hpp"
|
||||
#include "../../node/Node.hpp"
|
||||
#include "../../node/Utils.hpp"
|
||||
#include "../../node/MAC.hpp"
|
||||
#include "../../node/Address.hpp"
|
||||
#include "../../osdep/OSUtils.hpp"
|
||||
#include "../../osdep/BlockingQueue.hpp"
|
||||
#include "../../osdep/EthernetTap.hpp"
|
||||
|
@ -55,6 +57,7 @@
|
|||
#include <vector>
|
||||
#include <array>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#define SETSOCKOPT_FLAG_TYPE BOOL
|
||||
|
@ -90,10 +93,18 @@ struct ZT_GoNode_Impl
|
|||
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::atomic_bool run;
|
||||
|
||||
std::map< ZT_SOCKET,ZT_GoNodeThread > threads;
|
||||
std::mutex threads_l;
|
||||
|
||||
std::map< uint64_t,std::shared_ptr<EthernetTap> > taps;
|
||||
std::mutex taps_l;
|
||||
|
||||
BlockingQueue<ZT_GoNodeEvent> eq;
|
||||
|
||||
std::thread backgroundTaskThread;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -273,10 +284,10 @@ static void ZT_GoNode_DNSResolver(
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 *),
|
||||
int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize)
|
||||
)
|
||||
int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize))
|
||||
{
|
||||
try {
|
||||
struct ZT_Node_Callbacks cb;
|
||||
|
@ -296,6 +307,18 @@ extern "C" ZT_GoNode *ZT_GoNode_new(
|
|||
gn->goPathCheckFunc = goPathCheckFunc;
|
||||
gn->goPathLookupFunc = goPathLookupFunc;
|
||||
gn->goStateObjectGetFunc = goStateObjectGetFunc;
|
||||
gn->path = workingPath;
|
||||
gn->run = true;
|
||||
|
||||
gn->backgroundTaskThread = std::thread([gn] {
|
||||
while (gn->run) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
const int64_t now = OSUtils::now();
|
||||
if (now >= gn->nextBackgroundTaskDeadline)
|
||||
gn->node->processBackgroundTasks(nullptr,now,&(gn->nextBackgroundTaskDeadline));
|
||||
}
|
||||
});
|
||||
|
||||
return gn;
|
||||
} catch ( ... ) {
|
||||
fprintf(stderr,"FATAL: unable to create new instance of Node (out of memory?)" ZT_EOL_S);
|
||||
|
@ -305,6 +328,8 @@ extern "C" ZT_GoNode *ZT_GoNode_new(
|
|||
|
||||
extern "C" void ZT_GoNode_delete(ZT_GoNode *gn)
|
||||
{
|
||||
gn->run = false;
|
||||
|
||||
ZT_GoNodeEvent sd;
|
||||
sd.type = ZT_GONODE_EVENT_SHUTDOWN;
|
||||
gn->eq.post(sd);
|
||||
|
@ -321,6 +346,14 @@ extern "C" void ZT_GoNode_delete(ZT_GoNode *gn)
|
|||
for(auto t=th.begin();t!=th.end();++t)
|
||||
t->join();
|
||||
|
||||
gn->taps_l.lock();
|
||||
for(auto t=gn->taps.begin();t!=gn->taps.end();++t)
|
||||
gn->node->leave(t->first,nullptr,nullptr);
|
||||
gn->taps.clear();
|
||||
gn->taps_l.unlock();
|
||||
|
||||
gn->backgroundTaskThread.join();
|
||||
|
||||
delete gn->node;
|
||||
delete gn;
|
||||
}
|
||||
|
@ -491,3 +524,39 @@ extern "C" int 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)
|
||||
{
|
||||
ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
|
||||
gn->node->processVirtualNetworkFrame(tptr,OSUtils::now(),nwid,from.toInt(),to.toInt(),etherType,vlanId,data,len,&(gn->nextBackgroundTaskDeadline));
|
||||
}
|
||||
|
||||
extern "C" ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid)
|
||||
{
|
||||
try {
|
||||
std::lock_guard<std::mutex> l(gn->taps_l);
|
||||
auto existingTap = gn->taps.find(nwid);
|
||||
if (existingTap != gn->taps.end())
|
||||
return (ZT_GoTap *)existingTap->second.get();
|
||||
char tmp[256];
|
||||
OSUtils::ztsnprintf(tmp,sizeof(tmp),"ZeroTier Network %.16llx",(unsigned long long)nwid);
|
||||
std::shared_ptr<EthernetTap> tap(EthernetTap::newInstance(nullptr,gn->path.c_str(),MAC(Address(gn->node->address()),nwid),ZT_DEFAULT_MTU,0,nwid,tmp,&tapFrameHandler,gn));
|
||||
if (!tap)
|
||||
return nullptr;
|
||||
gn->taps[nwid] = tap;
|
||||
gn->node->join(nwid,tap.get(),nullptr);
|
||||
return (ZT_GoTap *)tap.get();
|
||||
} catch ( ... ) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid)
|
||||
{
|
||||
std::lock_guard<std::mutex> l(gn->taps_l);
|
||||
auto existingTap = gn->taps.find(nwid);
|
||||
if (existingTap != gn->taps.end()) {
|
||||
gn->node->leave(nwid,nullptr,nullptr);
|
||||
gn->taps.erase(existingTap);
|
||||
}
|
||||
}
|
|
@ -20,6 +20,14 @@
|
|||
|
||||
#include "../../include/ZeroTierCore.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* A pointer to an instance of EthernetTap */
|
||||
typedef void ZT_GoTap;
|
||||
|
||||
/* ZT_GoNode is a C struct and functions that wraps ZT_Node for use via cgo. It
|
||||
* performs UDP and other direct I/O in C for performance but otherwise lets
|
||||
* the Go code control the node's behavior. */
|
||||
struct ZT_GoNode_Impl;
|
||||
typedef struct ZT_GoNode_Impl ZT_GoNode;
|
||||
|
||||
|
@ -65,6 +73,7 @@ struct ZT_GoNodeEvent_Impl
|
|||
|
||||
/* Network configuration update event */
|
||||
struct {
|
||||
ZT_GoTap *tap;
|
||||
int op; /* ZT_VirtualNetworkConfigOperation */
|
||||
ZT_VirtualNetworkConfig conf;
|
||||
} nconf;
|
||||
|
@ -73,27 +82,63 @@ struct ZT_GoNodeEvent_Impl
|
|||
|
||||
typedef struct ZT_GoNodeEvent_Impl ZT_GoNodeEvent;
|
||||
|
||||
#ifndef __cplusplus
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
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 *),
|
||||
int (*goStateObjectGetFunc)(ZT_GoNode *,ZT_Node *,int objType,const uint64_t id[2],void *buf,unsigned int bufSize)
|
||||
);
|
||||
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);
|
||||
|
||||
ZT_Node *ZT_GoNode_getNode(ZT_GoNode *gn);
|
||||
|
||||
/* This can be called more than once to start multiple listener threads */
|
||||
int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char *ip,const int 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_waitForEvent(ZT_GoNode *gn,ZT_GoNodeEvent *ev);
|
||||
|
||||
#ifndef __cplusplus
|
||||
ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid);
|
||||
|
||||
void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void ZT_GoTap_setEnabled(ZT_GoTap *tap,int enabled);
|
||||
|
||||
int ZT_GoTap_addIp(ZT_GoTap *tap,int af,const void *ip,int port);
|
||||
|
||||
int ZT_GoTap_removeIp(ZT_GoTap *tap,int af,const void *ip,int port);
|
||||
|
||||
/* The buf buffer is filled with tuplies of:
|
||||
* uint8_t family
|
||||
* uint8_t ip[4 or 16]
|
||||
* uint16_t port (big-endian byte order)
|
||||
*
|
||||
* This function returns the number of such tuples in the result.
|
||||
* If the buffer isn't big enough results are incomplete.
|
||||
*/
|
||||
int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize);
|
||||
|
||||
const char *ZT_GoTap_deviceName(ZT_GoTap *tap);
|
||||
|
||||
void ZT_GoTap_setFriendlyName(ZT_GoTap *tap,const char *friendlyName);
|
||||
|
||||
void ZT_GoTap_setMtu(ZT_GoTap *tap,unsigned int mtu);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue