mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-01 00:45:27 +00:00
More Go boilerplate.
This commit is contained in:
parent
ae2120eb96
commit
ed2024285d
@ -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
|
||||
|
@ -1851,6 +1851,7 @@ ZT_SDK_API void ZT_Node_processDNSResult(
|
||||
* @param node Node instance
|
||||
* @param nwid 64-bit ZeroTier network ID
|
||||
* @param uptr An arbitrary pointer to associate with this network (default: NULL)
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr);
|
||||
@ -1868,6 +1869,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *upt
|
||||
* @param node Node instance
|
||||
* @param nwid 64-bit network ID
|
||||
* @param uptr Target pointer is set to uptr (if not NULL)
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr,void *tptr);
|
||||
@ -2015,6 +2017,17 @@ ZT_SDK_API ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t
|
||||
*/
|
||||
ZT_SDK_API ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node);
|
||||
|
||||
/**
|
||||
* Set the network-associated user-defined pointer for a given network
|
||||
*
|
||||
* This will have no effect if the network ID is not recognized.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param nwid Network ID
|
||||
* @param ptr New network-associated pointer
|
||||
*/
|
||||
ZT_SDK_API void ZT_Node_setNetworkUserPtr(ZT_Node *node,uint64_t nwid,void *ptr);
|
||||
|
||||
/**
|
||||
* Free a query result buffer
|
||||
*
|
||||
|
@ -41,8 +41,8 @@ public:
|
||||
((((uint64_t)d) & 0xffULL) << 16) |
|
||||
((((uint64_t)e) & 0xffULL) << 8) |
|
||||
(((uint64_t)f) & 0xffULL) ) {}
|
||||
ZT_ALWAYS_INLINE MAC(const void *bits,unsigned int len) { setTo(bits,len); }
|
||||
ZT_ALWAYS_INLINE MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); }
|
||||
ZT_ALWAYS_INLINE MAC(const void *bits,unsigned int len) { setTo(bits,len); }
|
||||
ZT_ALWAYS_INLINE MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); }
|
||||
ZT_ALWAYS_INLINE MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {}
|
||||
|
||||
/**
|
||||
|
@ -598,6 +598,14 @@ ZT_VirtualNetworkList *Node::networks() const
|
||||
return nl;
|
||||
}
|
||||
|
||||
void Node::setNetworkUserPtr(uint64_t nwid,void *ptr)
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
const SharedPtr<Network> *const nw = _networks.get(nwid);
|
||||
if (nw)
|
||||
*((*nw)->userPtr()) = ptr;
|
||||
}
|
||||
|
||||
void Node::freeQueryResult(void *qr)
|
||||
{
|
||||
if (qr)
|
||||
@ -1011,6 +1019,13 @@ ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_setNetworkUserPtr(ZT_Node *node,uint64_t nwid,void *ptr)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setNetworkUserPtr(nwid,ptr);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
|
||||
void ZT_Node_freeQueryResult(ZT_Node *node,void *qr)
|
||||
{
|
||||
try {
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
ZT_PeerList *peers() const;
|
||||
ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const;
|
||||
ZT_VirtualNetworkList *networks() const;
|
||||
void setNetworkUserPtr(uint64_t nwid,void *ptr);
|
||||
void freeQueryResult(void *qr);
|
||||
int addLocalInterfaceAddress(const struct sockaddr_storage *addr);
|
||||
void clearLocalInterfaceAddresses();
|
||||
|
Loading…
x
Reference in New Issue
Block a user