Go code!
This commit is contained in:
parent
e0ddbc2f28
commit
b34aa10bf8
15 changed files with 668 additions and 300 deletions
|
@ -20,7 +20,6 @@
|
|||
#include "../../node/MAC.hpp"
|
||||
#include "../../node/Address.hpp"
|
||||
#include "../../osdep/OSUtils.hpp"
|
||||
#include "../../osdep/BlockingQueue.hpp"
|
||||
#include "../../osdep/EthernetTap.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -89,10 +88,6 @@ struct ZT_GoNode_Impl
|
|||
Node *node;
|
||||
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::atomic_bool run;
|
||||
|
||||
|
@ -102,12 +97,19 @@ struct ZT_GoNode_Impl
|
|||
std::map< uint64_t,std::shared_ptr<EthernetTap> > taps;
|
||||
std::mutex taps_l;
|
||||
|
||||
BlockingQueue<ZT_GoNodeEvent> eq;
|
||||
|
||||
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(
|
||||
ZT_Node *node,
|
||||
|
@ -118,13 +120,7 @@ static int ZT_GoNode_VirtualNetworkConfigFunction(
|
|||
enum ZT_VirtualNetworkConfigOperation op,
|
||||
const ZT_VirtualNetworkConfig *cfg)
|
||||
{
|
||||
ZT_GoNodeEvent ev;
|
||||
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;
|
||||
return goVirtualNetworkConfigFunc(reinterpret_cast<ZT_GoNode *>(uptr),reinterpret_cast<ZT_GoTap *>(*nptr),nwid,op,cfg);
|
||||
}
|
||||
|
||||
static void ZT_GoNode_VirtualNetworkFrameFunction(
|
||||
|
@ -151,10 +147,7 @@ static void ZT_GoNode_EventCallback(
|
|||
enum ZT_Event et,
|
||||
const void *data)
|
||||
{
|
||||
ZT_GoNodeEvent ev;
|
||||
ev.type = ZT_GONODE_EVENT_ZTEVENT;
|
||||
ev.data.zt.type = et;
|
||||
reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
|
||||
goZtEvent(reinterpret_cast<ZT_GoNode *>(uptr),et,data);
|
||||
}
|
||||
|
||||
static void ZT_GoNode_StatePutFunction(
|
||||
|
@ -166,18 +159,7 @@ static void ZT_GoNode_StatePutFunction(
|
|||
const void *data,
|
||||
int len)
|
||||
{
|
||||
if (len < ZT_MAX_STATE_OBJECT_SIZE) { // sanity check
|
||||
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);
|
||||
}
|
||||
goStateObjectPutFunc(reinterpret_cast<ZT_GoNode *>(uptr),objType,id,data,len);
|
||||
}
|
||||
|
||||
static int ZT_GoNode_StateGetFunction(
|
||||
|
@ -189,7 +171,12 @@ static int ZT_GoNode_StateGetFunction(
|
|||
void *buf,
|
||||
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)
|
||||
|
@ -254,7 +241,23 @@ static int ZT_GoNode_PathCheckFunction(
|
|||
int64_t localSocket,
|
||||
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(
|
||||
|
@ -265,7 +268,32 @@ static int ZT_GoNode_PathLookupFunction(
|
|||
int desiredAddressFamily,
|
||||
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(
|
||||
|
@ -277,19 +305,14 @@ static void ZT_GoNode_DNSResolver(
|
|||
const char *name,
|
||||
uintptr_t requestId)
|
||||
{
|
||||
ZT_GoNodeEvent ev;
|
||||
ev.type = ZT_GONODE_EVENT_DNS_GET_TXT;
|
||||
Utils::scopy(ev.data.dns.dnsName,sizeof(ev.data.dns.dnsName),name);
|
||||
reinterpret_cast<ZT_GoNode *>(uptr)->eq.post(ev);
|
||||
uint8_t t[256];
|
||||
for(unsigned int i=0;(i<numTypes)&&(i<256);++i) t[i] = (uint8_t)types[i];
|
||||
goDNSResolverFunc(reinterpret_cast<ZT_GoNode *>(uptr),t,(int)numTypes,name,requestId);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/****************************************************************************/
|
||||
|
||||
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))
|
||||
extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath)
|
||||
{
|
||||
try {
|
||||
struct ZT_Node_Callbacks cb;
|
||||
|
@ -307,9 +330,6 @@ extern "C" ZT_GoNode *ZT_GoNode_new(
|
|||
const int64_t now = OSUtils::now();
|
||||
gn->node = new Node(reinterpret_cast<void *>(gn),nullptr,&cb,now);
|
||||
gn->nextBackgroundTaskDeadline = now;
|
||||
gn->goPathCheckFunc = goPathCheckFunc;
|
||||
gn->goPathLookupFunc = goPathLookupFunc;
|
||||
gn->goStateObjectGetFunc = goStateObjectGetFunc;
|
||||
gn->path = workingPath;
|
||||
gn->run = true;
|
||||
|
||||
|
@ -333,10 +353,6 @@ 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);
|
||||
|
||||
gn->threads_l.lock();
|
||||
for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
|
||||
t->second.run = false;
|
||||
|
@ -358,11 +374,6 @@ extern "C" void ZT_GoNode_delete(ZT_GoNode *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
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue