|
@@ -24,6 +24,7 @@
|
|
|
#include "../osdep/EthernetTap.hpp"
|
|
|
|
|
|
#ifndef __WINDOWS__
|
|
|
+
|
|
|
#include <unistd.h>
|
|
|
#include <sys/socket.h>
|
|
|
#include <sys/un.h>
|
|
@@ -32,11 +33,16 @@
|
|
|
#include <ifaddrs.h>
|
|
|
#include <net/if.h>
|
|
|
#include <netinet/in.h>
|
|
|
-#if __has_include(<netinet/in6_var.h>)
|
|
|
+
|
|
|
+#ifdef __BSD__
|
|
|
+
|
|
|
#include <netinet6/in6_var.h>
|
|
|
+
|
|
|
#endif
|
|
|
+
|
|
|
#include <arpa/inet.h>
|
|
|
#include <errno.h>
|
|
|
+
|
|
|
#ifdef __LINUX__
|
|
|
#ifndef IPV6_DONTFRAG
|
|
|
#define IPV6_DONTFRAG 62
|
|
@@ -71,7 +77,7 @@ struct ZT_GoNodeThread
|
|
|
int port;
|
|
|
int af;
|
|
|
bool primary;
|
|
|
- std::atomic<bool> run;
|
|
|
+ std::atomic< bool > run;
|
|
|
std::thread thr;
|
|
|
};
|
|
|
|
|
@@ -82,10 +88,10 @@ struct ZT_GoNode_Impl
|
|
|
volatile int64_t nextBackgroundTaskDeadline;
|
|
|
|
|
|
String path;
|
|
|
- std::atomic<bool> run;
|
|
|
+ std::atomic< bool > run;
|
|
|
|
|
|
- Map< ZT_SOCKET,ZT_GoNodeThread > threads;
|
|
|
- Map< uint64_t,std::shared_ptr<EthernetTap> > taps;
|
|
|
+ Map< ZT_SOCKET, ZT_GoNodeThread > threads;
|
|
|
+ Map< uint64_t, std::shared_ptr< EthernetTap > > taps;
|
|
|
|
|
|
std::mutex threads_l;
|
|
|
std::mutex taps_l;
|
|
@@ -97,14 +103,14 @@ static const String defaultHomePath(OSUtils::platformDefaultHomePath());
|
|
|
const char *const ZT_PLATFORM_DEFAULT_HOMEPATH = defaultHomePath.c_str();
|
|
|
|
|
|
// These are implemented in Go code.
|
|
|
-extern "C" int goPathCheckFunc(void *,const ZT_Identity *,int,const void *,int);
|
|
|
-extern "C" int goPathLookupFunc(void *,uint64_t,int,const ZT_Identity *,int *,uint8_t [16],int *);
|
|
|
-extern "C" void goStateObjectPutFunc(void *,int,const uint64_t [2],const void *,int);
|
|
|
-extern "C" int goStateObjectGetFunc(void *,int,const uint64_t [2],void **);
|
|
|
-extern "C" void goVirtualNetworkConfigFunc(void *,ZT_GoTap *,uint64_t,int,const ZT_VirtualNetworkConfig *);
|
|
|
-extern "C" void goZtEvent(void *,int,const void *);
|
|
|
-extern "C" void goHandleTapAddedMulticastGroup(void *,ZT_GoTap *,uint64_t,uint64_t,uint32_t);
|
|
|
-extern "C" void goHandleTapRemovedMulticastGroup(void *,ZT_GoTap *,uint64_t,uint64_t,uint32_t);
|
|
|
+extern "C" int goPathCheckFunc(void *, const ZT_Identity *, int, const void *, int);
|
|
|
+extern "C" int goPathLookupFunc(void *, uint64_t, int, const ZT_Identity *, int *, uint8_t [16], int *);
|
|
|
+extern "C" void goStateObjectPutFunc(void *, int, const uint64_t [2], const void *, int);
|
|
|
+extern "C" int goStateObjectGetFunc(void *, int, const uint64_t [2], void **);
|
|
|
+extern "C" void goVirtualNetworkConfigFunc(void *, ZT_GoTap *, uint64_t, int, const ZT_VirtualNetworkConfig *);
|
|
|
+extern "C" void goZtEvent(void *, int, const void *);
|
|
|
+extern "C" void goHandleTapAddedMulticastGroup(void *, ZT_GoTap *, uint64_t, uint64_t, uint32_t);
|
|
|
+extern "C" void goHandleTapRemovedMulticastGroup(void *, ZT_GoTap *, uint64_t, uint64_t, uint32_t);
|
|
|
|
|
|
static void ZT_GoNode_VirtualNetworkConfigFunction(
|
|
|
ZT_Node *node,
|
|
@@ -115,7 +121,7 @@ static void ZT_GoNode_VirtualNetworkConfigFunction(
|
|
|
enum ZT_VirtualNetworkConfigOperation op,
|
|
|
const ZT_VirtualNetworkConfig *cfg)
|
|
|
{
|
|
|
- goVirtualNetworkConfigFunc(reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,reinterpret_cast<ZT_GoTap *>(*nptr),nwid,op,cfg);
|
|
|
+ goVirtualNetworkConfigFunc(reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr, reinterpret_cast<ZT_GoTap *>(*nptr), nwid, op, cfg);
|
|
|
}
|
|
|
|
|
|
static void ZT_GoNode_VirtualNetworkFrameFunction(
|
|
@@ -132,7 +138,7 @@ static void ZT_GoNode_VirtualNetworkFrameFunction(
|
|
|
unsigned int len)
|
|
|
{
|
|
|
if (*nptr)
|
|
|
- reinterpret_cast<EthernetTap *>(*nptr)->put(MAC(srcMac),MAC(destMac),etherType,data,len);
|
|
|
+ reinterpret_cast<EthernetTap *>(*nptr)->put(MAC(srcMac), MAC(destMac), etherType, data, len);
|
|
|
}
|
|
|
|
|
|
static void ZT_GoNode_EventCallback(
|
|
@@ -142,7 +148,7 @@ static void ZT_GoNode_EventCallback(
|
|
|
enum ZT_Event et,
|
|
|
const void *data)
|
|
|
{
|
|
|
- goZtEvent(reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,et,data);
|
|
|
+ goZtEvent(reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr, et, data);
|
|
|
}
|
|
|
|
|
|
static void ZT_GoNode_StatePutFunction(
|
|
@@ -162,7 +168,9 @@ static void ZT_GoNode_StatePutFunction(
|
|
|
len);
|
|
|
}
|
|
|
|
|
|
-static void _freeFunc(void *p) { if (p) free(p); }
|
|
|
+static void _freeFunc(void *p)
|
|
|
+{ if (p) free(p); }
|
|
|
+
|
|
|
static int ZT_GoNode_StateGetFunction(
|
|
|
ZT_Node *node,
|
|
|
void *uptr,
|
|
@@ -180,29 +188,29 @@ static int ZT_GoNode_StateGetFunction(
|
|
|
data);
|
|
|
}
|
|
|
|
|
|
-static ZT_INLINE void doUdpSend(ZT_SOCKET sock,const struct sockaddr_storage *addr,const void *data,const unsigned int len,const unsigned int ipTTL)
|
|
|
+static ZT_INLINE void doUdpSend(ZT_SOCKET sock, const struct sockaddr_storage *addr, const void *data, const unsigned int len, const unsigned int ipTTL)
|
|
|
{
|
|
|
- switch(addr->ss_family) {
|
|
|
+ switch (addr->ss_family) {
|
|
|
case AF_INET:
|
|
|
- if (unlikely((ipTTL > 0)&&(ipTTL < 255))) {
|
|
|
+ if (unlikely((ipTTL > 0) && (ipTTL < 255))) {
|
|
|
#ifdef __WINDOWS__
|
|
|
DWORD tmp = (DWORD)ipTTL;
|
|
|
#else
|
|
|
int tmp = (int)ipTTL;
|
|
|
#endif
|
|
|
- setsockopt(sock,IPPROTO_IP,IP_TTL,&tmp,sizeof(tmp));
|
|
|
- sendto(sock,data,len,MSG_DONTWAIT,(const sockaddr *)addr,sizeof(struct sockaddr_in));
|
|
|
+ setsockopt(sock, IPPROTO_IP, IP_TTL, &tmp, sizeof(tmp));
|
|
|
+ sendto(sock, data, len, MSG_DONTWAIT, (const sockaddr *)addr, sizeof(struct sockaddr_in));
|
|
|
tmp = 255;
|
|
|
- setsockopt(sock,IPPROTO_IP,IP_TTL,&tmp,sizeof(tmp));
|
|
|
+ setsockopt(sock, IPPROTO_IP, IP_TTL, &tmp, sizeof(tmp));
|
|
|
} else {
|
|
|
- sendto(sock,data,len,MSG_DONTWAIT,(const sockaddr *)addr,sizeof(struct sockaddr_in));
|
|
|
+ sendto(sock, data, len, MSG_DONTWAIT, (const sockaddr *)addr, sizeof(struct sockaddr_in));
|
|
|
}
|
|
|
break;
|
|
|
case AF_INET6:
|
|
|
// The ipTTL option isn't currently used with IPv6. It's only used
|
|
|
// with IPv4 "firewall opener" / "NAT buster" preamble packets as part
|
|
|
// of IPv4 NAT traversal.
|
|
|
- sendto(sock,data,len,MSG_DONTWAIT,(const sockaddr *)addr,sizeof(struct sockaddr_in6));
|
|
|
+ sendto(sock, data, len, MSG_DONTWAIT, (const sockaddr *)addr, sizeof(struct sockaddr_in6));
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -218,13 +226,13 @@ static int ZT_GoNode_WirePacketSendFunction(
|
|
|
unsigned int ipTTL)
|
|
|
{
|
|
|
if (likely(localSocket > 0)) {
|
|
|
- doUdpSend((ZT_SOCKET)localSocket,addr,data,len,ipTTL);
|
|
|
+ doUdpSend((ZT_SOCKET)localSocket, addr, data, len, ipTTL);
|
|
|
} else {
|
|
|
ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
|
|
|
- std::lock_guard<std::mutex> l(gn->threads_l);
|
|
|
- for(auto t=gn->threads.begin();t!=gn->threads.end();++t) {
|
|
|
- if ((t->second.af == addr->ss_family)&&(t->second.primary)) {
|
|
|
- doUdpSend(t->first,addr,data,len,ipTTL);
|
|
|
+ std::lock_guard< std::mutex > l(gn->threads_l);
|
|
|
+ for (auto t = gn->threads.begin(); t != gn->threads.end(); ++t) {
|
|
|
+ if ((t->second.af == addr->ss_family) && (t->second.primary)) {
|
|
|
+ doUdpSend(t->first, addr, data, len, ipTTL);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -241,7 +249,7 @@ static int ZT_GoNode_PathCheckFunction(
|
|
|
int64_t localSocket,
|
|
|
const struct sockaddr_storage *sa)
|
|
|
{
|
|
|
- switch(sa->ss_family) {
|
|
|
+ switch (sa->ss_family) {
|
|
|
case AF_INET:
|
|
|
return goPathCheckFunc(
|
|
|
reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
|
|
@@ -282,15 +290,15 @@ static int ZT_GoNode_PathLookupFunction(
|
|
|
&port
|
|
|
);
|
|
|
if (result != 0) {
|
|
|
- switch(family) {
|
|
|
+ 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);
|
|
|
+ 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);
|
|
|
+ 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;
|
|
|
}
|
|
@@ -298,7 +306,7 @@ static int ZT_GoNode_PathLookupFunction(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath,uintptr_t userPtr)
|
|
|
+extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath, uintptr_t userPtr)
|
|
|
{
|
|
|
try {
|
|
|
struct ZT_Node_Callbacks cb;
|
|
@@ -315,7 +323,7 @@ extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath,uintptr_t userPtr)
|
|
|
ZT_GoNode_Impl *gn = new ZT_GoNode_Impl;
|
|
|
const int64_t now = OSUtils::now();
|
|
|
gn->goUserPtr = reinterpret_cast<void *>(userPtr);
|
|
|
- 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->path = workingPath;
|
|
|
gn->run = true;
|
|
@@ -327,28 +335,28 @@ extern "C" ZT_GoNode *ZT_GoNode_new(const char *workingPath,uintptr_t userPtr)
|
|
|
const int64_t now = OSUtils::now();
|
|
|
|
|
|
if (now >= gn->nextBackgroundTaskDeadline)
|
|
|
- gn->node->processBackgroundTasks(nullptr,now,&(gn->nextBackgroundTaskDeadline));
|
|
|
+ gn->node->processBackgroundTasks(nullptr, now, &(gn->nextBackgroundTaskDeadline));
|
|
|
|
|
|
if ((now - lastCheckedTaps) > 10000) {
|
|
|
lastCheckedTaps = now;
|
|
|
- std::vector<MulticastGroup> added,removed;
|
|
|
- std::lock_guard<std::mutex> tl(gn->taps_l);
|
|
|
- for(auto t=gn->taps.begin();t!=gn->taps.end();++t) {
|
|
|
+ std::vector< MulticastGroup > added, removed;
|
|
|
+ std::lock_guard< std::mutex > tl(gn->taps_l);
|
|
|
+ for (auto t = gn->taps.begin(); t != gn->taps.end(); ++t) {
|
|
|
added.clear();
|
|
|
removed.clear();
|
|
|
- t->second->scanMulticastGroups(added,removed);
|
|
|
- for(auto g=added.begin();g!=added.end();++g)
|
|
|
- goHandleTapAddedMulticastGroup(gn,(ZT_GoTap *)t->second.get(),t->first,g->mac().toInt(),g->adi());
|
|
|
- for(auto g=removed.begin();g!=removed.end();++g)
|
|
|
- goHandleTapRemovedMulticastGroup(gn,(ZT_GoTap *)t->second.get(),t->first,g->mac().toInt(),g->adi());
|
|
|
+ t->second->scanMulticastGroups(added, removed);
|
|
|
+ for (auto g = added.begin(); g != added.end(); ++g)
|
|
|
+ goHandleTapAddedMulticastGroup(gn, (ZT_GoTap *)t->second.get(), t->first, g->mac().toInt(), g->adi());
|
|
|
+ for (auto g = removed.begin(); g != removed.end(); ++g)
|
|
|
+ goHandleTapRemovedMulticastGroup(gn, (ZT_GoTap *)t->second.get(), t->first, g->mac().toInt(), g->adi());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return gn;
|
|
|
- } catch ( ... ) {
|
|
|
- fprintf(stderr,"FATAL: unable to create new instance of Node (out of memory?)" ZT_EOL_S);
|
|
|
+ } catch (...) {
|
|
|
+ fprintf(stderr, "FATAL: unable to create new instance of Node (out of memory?)" ZT_EOL_S);
|
|
|
exit(1);
|
|
|
}
|
|
|
}
|
|
@@ -358,17 +366,17 @@ extern "C" void ZT_GoNode_delete(ZT_GoNode *gn)
|
|
|
gn->run = false;
|
|
|
|
|
|
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;
|
|
|
- shutdown(t->first,SHUT_RDWR);
|
|
|
+ shutdown(t->first, SHUT_RDWR);
|
|
|
close(t->first);
|
|
|
t->second.thr.join();
|
|
|
}
|
|
|
gn->threads_l.unlock();
|
|
|
|
|
|
gn->taps_l.lock();
|
|
|
- for(auto t=gn->taps.begin();t!=gn->taps.end();++t)
|
|
|
- gn->node->leave(t->first,nullptr,nullptr);
|
|
|
+ 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();
|
|
|
|
|
@@ -385,17 +393,17 @@ extern "C" ZT_Node *ZT_GoNode_getNode(ZT_GoNode *gn)
|
|
|
return gn->node;
|
|
|
}
|
|
|
|
|
|
-static void setCommonUdpSocketSettings(ZT_SOCKET udpSock,const char *dev)
|
|
|
+static void setCommonUdpSocketSettings(ZT_SOCKET udpSock, const char *dev)
|
|
|
{
|
|
|
int bufSize = 1048576;
|
|
|
while (bufSize > 131072) {
|
|
|
- if (setsockopt(udpSock,SOL_SOCKET,SO_RCVBUF,(const char *)&bufSize,sizeof(bufSize)) == 0)
|
|
|
+ if (setsockopt(udpSock, SOL_SOCKET, SO_RCVBUF, (const char *)&bufSize, sizeof(bufSize)) == 0)
|
|
|
break;
|
|
|
bufSize -= 131072;
|
|
|
}
|
|
|
bufSize = 1048576;
|
|
|
while (bufSize > 131072) {
|
|
|
- if (setsockopt(udpSock,SOL_SOCKET,SO_SNDBUF,(const char *)&bufSize,sizeof(bufSize)) == 0)
|
|
|
+ if (setsockopt(udpSock, SOL_SOCKET, SO_SNDBUF, (const char *)&bufSize, sizeof(bufSize)) == 0)
|
|
|
break;
|
|
|
bufSize -= 131072;
|
|
|
}
|
|
@@ -404,15 +412,15 @@ static void setCommonUdpSocketSettings(ZT_SOCKET udpSock,const char *dev)
|
|
|
|
|
|
#ifdef SO_REUSEPORT
|
|
|
fl = SETSOCKOPT_FLAG_TRUE;
|
|
|
- setsockopt(udpSock,SOL_SOCKET,SO_REUSEPORT,(void *)&fl,sizeof(fl));
|
|
|
+ setsockopt(udpSock, SOL_SOCKET, SO_REUSEPORT, (void *)&fl, sizeof(fl));
|
|
|
#endif
|
|
|
#ifndef __LINUX__ // linux wants just SO_REUSEPORT
|
|
|
fl = SETSOCKOPT_FLAG_TRUE;
|
|
|
- setsockopt(udpSock,SOL_SOCKET,SO_REUSEADDR,(void *)&fl,sizeof(fl));
|
|
|
+ setsockopt(udpSock, SOL_SOCKET, SO_REUSEADDR, (void *)&fl, sizeof(fl));
|
|
|
#endif
|
|
|
|
|
|
fl = SETSOCKOPT_FLAG_TRUE;
|
|
|
- setsockopt(udpSock,SOL_SOCKET,SO_BROADCAST,(void *)&fl,sizeof(fl));
|
|
|
+ setsockopt(udpSock, SOL_SOCKET, SO_BROADCAST, (void *)&fl, sizeof(fl));
|
|
|
|
|
|
#ifdef IP_DONTFRAG
|
|
|
fl = SETSOCKOPT_FLAG_FALSE;
|
|
@@ -428,54 +436,54 @@ static void setCommonUdpSocketSettings(ZT_SOCKET udpSock,const char *dev)
|
|
|
setsockopt(udpSock,SOL_SOCKET,SO_BINDTODEVICE,dev,strlen(dev));
|
|
|
#endif
|
|
|
#if defined(__BSD__) && defined(IP_BOUND_IF)
|
|
|
- if ((dev)&&(strlen(dev))) {
|
|
|
+ if ((dev) && (strlen(dev))) {
|
|
|
int idx = if_nametoindex(dev);
|
|
|
if (idx != 0)
|
|
|
- setsockopt(udpSock,IPPROTO_IP,IP_BOUND_IF,(void *)&idx,sizeof(idx));
|
|
|
+ setsockopt(udpSock, IPPROTO_IP, IP_BOUND_IF, (void *)&idx, sizeof(idx));
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-extern "C" int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port,const int primary)
|
|
|
+extern "C" int ZT_GoNode_phyStartListen(ZT_GoNode *gn, const char *dev, const char *ip, const int port, const int primary)
|
|
|
{
|
|
|
- if (strchr(ip,':')) {
|
|
|
+ if (strchr(ip, ':')) {
|
|
|
struct sockaddr_in6 in6;
|
|
|
- memset(&in6,0,sizeof(in6));
|
|
|
+ memset(&in6, 0, sizeof(in6));
|
|
|
in6.sin6_family = AF_INET6;
|
|
|
- if (inet_pton(AF_INET6,ip,&(in6.sin6_addr)) <= 0)
|
|
|
+ if (inet_pton(AF_INET6, ip, &(in6.sin6_addr)) <= 0)
|
|
|
return errno;
|
|
|
in6.sin6_port = htons((uint16_t)port);
|
|
|
|
|
|
- ZT_SOCKET udpSock = socket(AF_INET6,SOCK_DGRAM,0);
|
|
|
+ ZT_SOCKET udpSock = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
|
if (udpSock == ZT_INVALID_SOCKET)
|
|
|
return errno;
|
|
|
- setCommonUdpSocketSettings(udpSock,dev);
|
|
|
+ setCommonUdpSocketSettings(udpSock, dev);
|
|
|
SETSOCKOPT_FLAG_TYPE fl = SETSOCKOPT_FLAG_TRUE;
|
|
|
- setsockopt(udpSock,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&fl,sizeof(fl));
|
|
|
+ setsockopt(udpSock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&fl, sizeof(fl));
|
|
|
#ifdef IPV6_DONTFRAG
|
|
|
fl = SETSOCKOPT_FLAG_FALSE;
|
|
|
setsockopt(udpSock,IPPROTO_IPV6,IPV6_DONTFRAG,&fl,sizeof(fl));
|
|
|
#endif
|
|
|
|
|
|
- if (bind(udpSock,reinterpret_cast<const struct sockaddr *>(&in6),sizeof(in6)) != 0)
|
|
|
+ if (bind(udpSock, reinterpret_cast<const struct sockaddr *>(&in6), sizeof(in6)) != 0)
|
|
|
return errno;
|
|
|
|
|
|
{
|
|
|
- std::lock_guard<std::mutex> l(gn->threads_l);
|
|
|
+ std::lock_guard< std::mutex > l(gn->threads_l);
|
|
|
ZT_GoNodeThread &gnt = gn->threads[udpSock];
|
|
|
gnt.ip = ip;
|
|
|
gnt.port = port;
|
|
|
gnt.af = AF_INET6;
|
|
|
gnt.primary = (primary != 0);
|
|
|
gnt.run = true;
|
|
|
- gnt.thr = std::thread([udpSock,gn,&gnt] {
|
|
|
+ gnt.thr = std::thread([udpSock, gn, &gnt] {
|
|
|
struct sockaddr_in6 in6;
|
|
|
socklen_t salen;
|
|
|
while (gnt.run) {
|
|
|
salen = sizeof(in6);
|
|
|
void *buf = ZT_getBuffer();
|
|
|
if (buf) {
|
|
|
- int s = (int)recvfrom(udpSock,buf,16384,0,reinterpret_cast<struct sockaddr *>(&in6),&salen);
|
|
|
+ int s = (int)recvfrom(udpSock, buf, 16384, 0, reinterpret_cast<struct sockaddr *>(&in6), &salen);
|
|
|
if (s > 0) {
|
|
|
ZT_Node_processWirePacket(
|
|
|
reinterpret_cast<ZT_Node *>(gn->node),
|
|
@@ -497,40 +505,40 @@ extern "C" int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char
|
|
|
}
|
|
|
} else {
|
|
|
struct sockaddr_in in;
|
|
|
- memset(&in,0,sizeof(in));
|
|
|
+ memset(&in, 0, sizeof(in));
|
|
|
in.sin_family = AF_INET;
|
|
|
- if (inet_pton(AF_INET,ip,&(in.sin_addr)) <= 0)
|
|
|
+ if (inet_pton(AF_INET, ip, &(in.sin_addr)) <= 0)
|
|
|
return errno;
|
|
|
in.sin_port = htons((uint16_t)port);
|
|
|
|
|
|
- ZT_SOCKET udpSock = socket(AF_INET,SOCK_DGRAM,0);
|
|
|
+ ZT_SOCKET udpSock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
if (udpSock == ZT_INVALID_SOCKET)
|
|
|
return errno;
|
|
|
- setCommonUdpSocketSettings(udpSock,dev);
|
|
|
+ setCommonUdpSocketSettings(udpSock, dev);
|
|
|
#ifdef SO_NO_CHECK
|
|
|
SETSOCKOPT_FLAG_TYPE fl = SETSOCKOPT_FLAG_TRUE;
|
|
|
setsockopt(udpSock,SOL_SOCKET,SO_NO_CHECK,&fl,sizeof(fl));
|
|
|
#endif
|
|
|
|
|
|
- if (bind(udpSock,reinterpret_cast<const struct sockaddr *>(&in),sizeof(in)) != 0)
|
|
|
+ if (bind(udpSock, reinterpret_cast<const struct sockaddr *>(&in), sizeof(in)) != 0)
|
|
|
return errno;
|
|
|
|
|
|
{
|
|
|
- std::lock_guard<std::mutex> l(gn->threads_l);
|
|
|
+ std::lock_guard< std::mutex > l(gn->threads_l);
|
|
|
ZT_GoNodeThread &gnt = gn->threads[udpSock];
|
|
|
gnt.ip = ip;
|
|
|
gnt.port = port;
|
|
|
gnt.af = AF_INET6;
|
|
|
gnt.primary = (primary != 0);
|
|
|
gnt.run = true;
|
|
|
- gnt.thr = std::thread([udpSock,gn,&gnt] {
|
|
|
+ gnt.thr = std::thread([udpSock, gn, &gnt] {
|
|
|
struct sockaddr_in in4;
|
|
|
socklen_t salen;
|
|
|
while (gnt.run) {
|
|
|
salen = sizeof(in4);
|
|
|
void *buf = ZT_getBuffer();
|
|
|
if (buf) {
|
|
|
- int s = (int)recvfrom(udpSock,buf,sizeof(buf),0,reinterpret_cast<struct sockaddr *>(&in4),&salen);
|
|
|
+ int s = (int)recvfrom(udpSock, buf, sizeof(buf), 0, reinterpret_cast<struct sockaddr *>(&in4), &salen);
|
|
|
if (s > 0) {
|
|
|
ZT_Node_processWirePacket(
|
|
|
reinterpret_cast<ZT_Node *>(gn->node),
|
|
@@ -555,14 +563,14 @@ extern "C" int ZT_GoNode_phyStartListen(ZT_GoNode *gn,const char *dev,const char
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-extern "C" int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char *ip,const int port)
|
|
|
+extern "C" int ZT_GoNode_phyStopListen(ZT_GoNode *gn, const char *dev, const char *ip, const int port)
|
|
|
{
|
|
|
{
|
|
|
- std::lock_guard<std::mutex> l(gn->threads_l);
|
|
|
- for(auto t=gn->threads.begin();t!=gn->threads.end();) {
|
|
|
- if ((t->second.ip == ip)&&(t->second.port == port)) {
|
|
|
+ std::lock_guard< std::mutex > l(gn->threads_l);
|
|
|
+ for (auto t = gn->threads.begin(); t != gn->threads.end();) {
|
|
|
+ if ((t->second.ip == ip) && (t->second.port == port)) {
|
|
|
t->second.run = false;
|
|
|
- shutdown(t->first,SHUT_RDWR);
|
|
|
+ shutdown(t->first, SHUT_RDWR);
|
|
|
close(t->first);
|
|
|
t->second.thr.join();
|
|
|
gn->threads.erase(t++);
|
|
@@ -572,7 +580,7 @@ extern "C" int ZT_GoNode_phyStopListen(ZT_GoNode *gn,const char *dev,const char
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-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_Node_processVirtualNetworkFrame(
|
|
|
reinterpret_cast<ZT_Node *>(reinterpret_cast<ZT_GoNode *>(uptr)->node),
|
|
@@ -589,69 +597,69 @@ static void tapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,
|
|
|
&(reinterpret_cast<ZT_GoNode *>(uptr)->nextBackgroundTaskDeadline));
|
|
|
}
|
|
|
|
|
|
-extern "C" ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn,uint64_t nwid,const ZT_Fingerprint *const controllerFingerprint)
|
|
|
+extern "C" ZT_GoTap *ZT_GoNode_join(ZT_GoNode *gn, uint64_t nwid, const ZT_Fingerprint *const controllerFingerprint)
|
|
|
{
|
|
|
try {
|
|
|
- std::lock_guard<std::mutex> l(gn->taps_l);
|
|
|
+ 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));
|
|
|
+ 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,controllerFingerprint,tap.get(),nullptr);
|
|
|
+ gn->node->join(nwid, controllerFingerprint, tap.get(), nullptr);
|
|
|
return (ZT_GoTap *)tap.get();
|
|
|
- } catch ( ... ) {
|
|
|
+ } catch (...) {
|
|
|
return nullptr;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-extern "C" void ZT_GoNode_leave(ZT_GoNode *gn,uint64_t nwid)
|
|
|
+extern "C" void ZT_GoNode_leave(ZT_GoNode *gn, uint64_t nwid)
|
|
|
{
|
|
|
- std::lock_guard<std::mutex> l(gn->taps_l);
|
|
|
+ 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->node->leave(nwid, nullptr, nullptr);
|
|
|
gn->taps.erase(existingTap);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-extern "C" void ZT_GoTap_setEnabled(ZT_GoTap *tap,int enabled)
|
|
|
+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 netmaskBits)
|
|
|
+extern "C" int ZT_GoTap_addIp(ZT_GoTap *tap, int af, const void *ip, int netmaskBits)
|
|
|
{
|
|
|
- switch(af) {
|
|
|
+ switch (af) {
|
|
|
case AF_INET:
|
|
|
- return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip,4,(unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
+ return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip, 4, (unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
case AF_INET6:
|
|
|
- return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip,16,(unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
+ return (reinterpret_cast<EthernetTap *>(tap)->addIp(InetAddress(ip, 16, (unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-extern "C" int ZT_GoTap_removeIp(ZT_GoTap *tap,int af,const void *ip,int netmaskBits)
|
|
|
+extern "C" int ZT_GoTap_removeIp(ZT_GoTap *tap, int af, const void *ip, int netmaskBits)
|
|
|
{
|
|
|
- switch(af) {
|
|
|
+ switch (af) {
|
|
|
case AF_INET:
|
|
|
- return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip,4,(unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
+ return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip, 4, (unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
case AF_INET6:
|
|
|
- return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip,16,(unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
+ return (reinterpret_cast<EthernetTap *>(tap)->removeIp(InetAddress(ip, 16, (unsigned int)netmaskBits)) ? 1 : 0);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-extern "C" int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize)
|
|
|
+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) {
|
|
|
+ for (auto ip = ips.begin(); ip != ips.end(); ++ip) {
|
|
|
if ((p + 6) > bufSize)
|
|
|
break;
|
|
|
const uint8_t *const ipd = reinterpret_cast<const uint8_t *>(ip->rawIpData());
|
|
@@ -665,7 +673,7 @@ extern "C" int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize)
|
|
|
} else if (ip->isV6()) {
|
|
|
if ((p + 18) <= bufSize) {
|
|
|
b[p++] = AF_INET6;
|
|
|
- for(int j=0;j<16;++j)
|
|
|
+ for (int j = 0; j < 16; ++j)
|
|
|
b[p++] = ipd[j];
|
|
|
b[p++] = (uint8_t)ip->netmaskBits();
|
|
|
}
|
|
@@ -674,36 +682,41 @@ extern "C" int ZT_GoTap_ips(ZT_GoTap *tap,void *buf,unsigned int bufSize)
|
|
|
return (int)p;
|
|
|
}
|
|
|
|
|
|
-extern "C" void ZT_GoTap_deviceName(ZT_GoTap *tap,char nbuf[256])
|
|
|
+extern "C" void ZT_GoTap_deviceName(ZT_GoTap *tap, char nbuf[256])
|
|
|
{
|
|
|
- Utils::scopy(nbuf,256,reinterpret_cast<EthernetTap *>(tap)->deviceName().c_str());
|
|
|
+ Utils::scopy(nbuf, 256, reinterpret_cast<EthernetTap *>(tap)->deviceName().c_str());
|
|
|
}
|
|
|
|
|
|
-extern "C" void ZT_GoTap_setFriendlyName(ZT_GoTap *tap,const char *friendlyName)
|
|
|
+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)
|
|
|
+extern "C" void ZT_GoTap_setMtu(ZT_GoTap *tap, unsigned int mtu)
|
|
|
{
|
|
|
reinterpret_cast<EthernetTap *>(tap)->setMtu(mtu);
|
|
|
}
|
|
|
|
|
|
-extern "C" int ZT_isTemporaryV6Address(const char *ifname,const struct sockaddr_storage *a)
|
|
|
+#if defined(IFA_F_SECONDARY) && !defined(IFA_F_TEMPORARY)
|
|
|
+#define IFA_F_TEMPORARY IFA_F_SECONDARY
|
|
|
+#endif
|
|
|
+
|
|
|
+extern "C" int ZT_isTemporaryV6Address(const char *ifname, const struct sockaddr_storage *a)
|
|
|
{
|
|
|
-#ifdef IN6_IFF_TEMPORARY
|
|
|
+#if defined(IN6_IFF_TEMPORARY) && defined(SIOCGIFAFLAG_IN6)
|
|
|
static ZT_SOCKET s_tmpV6Socket = ZT_INVALID_SOCKET;
|
|
|
static std::mutex s_lock;
|
|
|
- std::lock_guard<std::mutex> l(s_lock);
|
|
|
+ std::lock_guard< std::mutex > l(s_lock);
|
|
|
if (s_tmpV6Socket == ZT_INVALID_SOCKET) {
|
|
|
- s_tmpV6Socket = socket(AF_INET6,SOCK_DGRAM,0);
|
|
|
+ s_tmpV6Socket = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
|
if (s_tmpV6Socket <= 0)
|
|
|
return 0;
|
|
|
}
|
|
|
struct in6_ifreq ifr;
|
|
|
- strncpy(ifr.ifr_name,ifname,sizeof(ifr.ifr_name));
|
|
|
- memcpy(&(ifr.ifr_addr),a,sizeof(sockaddr_in6));
|
|
|
- if (ioctl(s_tmpV6Socket,SIOCGIFAFLAG_IN6,&ifr) < 0) {
|
|
|
+ memset(&ifr, 0, sizeof(ifr));
|
|
|
+ strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
|
|
+ memcpy(&(ifr.ifr_addr), a, sizeof(sockaddr_in6));
|
|
|
+ if (ioctl(s_tmpV6Socket, SIOCGIFAFLAG_IN6, &ifr) < 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
return ((ifr.ifr_ifru.ifru_flags6 & IN6_IFF_TEMPORARY) != 0) ? 1 : 0;
|