diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa07e94fc..30fa484c9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -131,49 +131,18 @@ set(
zt_go_native
)
-if(WIN32)
- set(libs ${libs} wsock32 ws2_32 rpcrt4 iphlpapi)
-else(WIN32)
- set(libs ${libs} pthread)
-endif(WIN32)
-
-#if(WIN32)
-# add_subdirectory("windows/WinUI")
-# add_subdirectory("windows/copyutil")
-# add_definitions(-DNOMINMAX)
-#endif(WIN32)
-
#if(WIN32)
# set(libs ${libs} wsock32 ws2_32 rpcrt4 iphlpapi)
-# set(src
-# ${src}
-# "windows/ZeroTierOne/ServiceBase.cpp"
-# "windows/ZeroTierOne/ServiceInstaller.cpp"
-# "windows/ZeroTierOne/ZeroTierOneService.cpp"
-# "windows/ZeroTierOne/ZeroTierOne.rc"
-# )
-# set(headers
-# ${headers}
-# "windows/ZeroTierOne/ServiceBase.h"
-# "windows/ZeroTierOne/ServiceInstaller.h"
-# "windows/ZeroTierOne/ZeroTierOneService.h"
-# )
#else(WIN32)
-# set(libs ${libs} pthread resolv)
+# set(libs ${libs} pthread)
#endif(WIN32)
#if(BUILD_CENTRAL_CONTROLLER)
# set(libs ${libs} rabbitmq-static ${PostgreSQL_LIBRARIES})
#endif(BUILD_CENTRAL_CONTROLLER)
-#add_executable(${PROJECT_NAME} ${src} ${headers})
-#target_link_libraries(${PROJECT_NAME} ${libs})
-#target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})
-
-add_custom_command(
- OUTPUT zerotier
+add_custom_target(zerotier ALL
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/go
- COMMAND go build -trimpath -ldflags -s -o ../build/zerotier cmd/zerotier/zerotier.go
- DEPENDS zt_osdep zt_core zt_go_native
+ COMMAND rm -f ../build/zerotier && go build -trimpath -ldflags -s -o ../build/zerotier cmd/zerotier/zerotier.go
)
-add_custom_target(build_zerotier ALL DEPENDS zerotier)
+add_dependencies(zerotier zt_osdep zt_core zt_go_native)
diff --git a/go/cmd/zerotier/zerotier.go b/go/cmd/zerotier/zerotier.go
index b3d698871..0c12c8a84 100644
--- a/go/cmd/zerotier/zerotier.go
+++ b/go/cmd/zerotier/zerotier.go
@@ -20,6 +20,7 @@ import (
"os"
"path"
"runtime"
+ "runtime/debug"
"strings"
"zerotier/cmd/zerotier/cli"
@@ -63,6 +64,18 @@ func authTokenRequired(authToken string) {
}
func main() {
+ // Reduce Go's threads to 1-2 depending on whether this is single core or
+ // multi-core. Note that I/O threads are in C++ and are separate and Go
+ // code only does service control and CLI stuff, so this reduces memory
+ // use and competition with I/O but shouldn't impact throughput. We also
+ // crank up the GC to reduce memory usage a little bit.
+ if runtime.NumCPU() >= 2 {
+ runtime.GOMAXPROCS(2)
+ } else {
+ runtime.GOMAXPROCS(1)
+ }
+ debug.SetGCPercent(25)
+
globalOpts := flag.NewFlagSet("global", flag.ContinueOnError)
hflag := globalOpts.Bool("h", false, "") // support -h to be canonical with other Unix utilities
jflag := globalOpts.Bool("j", false, "")
diff --git a/go/pkg/zerotier/node.go b/go/pkg/zerotier/node.go
index 47222f105..dbee8a74b 100644
--- a/go/pkg/zerotier/node.go
+++ b/go/pkg/zerotier/node.go
@@ -89,6 +89,8 @@ type Node struct {
networksLock sync.RWMutex
interfaceAddresses map[string]net.IP // physical external IPs on the machine
interfaceAddressesLock sync.Mutex
+ online uint32
+ running uint32
basePath string
peersPath string
networksPath string
@@ -102,8 +104,6 @@ type Node struct {
id *Identity
namedSocketApiServer *http.Server
tcpApiServer *http.Server
- online uint32
- running uint32
runWaitGroup sync.WaitGroup
}
diff --git a/node/Constants.hpp b/node/Constants.hpp
index c8f806a8f..168fb7059 100644
--- a/node/Constants.hpp
+++ b/node/Constants.hpp
@@ -79,7 +79,7 @@
/**
* Maximum delay between timer task checks (should be a fraction of smallest housekeeping interval)
*/
-#define ZT_MAX_TIMER_TASK_INTERVAL 3000
+#define ZT_MAX_TIMER_TASK_INTERVAL 5000
/**
* How often most internal cleanup and housekeeping tasks are performed
@@ -92,7 +92,7 @@
* Note that this affects how frequently we re-request network configurations
* from network controllers if we haven't received one yet.
*/
-#define ZT_NETWORK_HOUSEKEEPING_PERIOD 12000
+#define ZT_NETWORK_HOUSEKEEPING_PERIOD 15000
/**
* Delay between WHOIS retries in ms
@@ -139,7 +139,12 @@
/**
* Timeout for overall peer activity (measured from last receive)
*/
-#define ZT_PEER_ACTIVITY_TIMEOUT ((ZT_PEER_PING_PERIOD * 2) + 5000)
+#define ZT_PEER_ALIVE_TIMEOUT ((ZT_PEER_PING_PERIOD * 2) + 5000)
+
+/**
+ * Timeout for overall peer activity (measured from last receive)
+ */
+#define ZT_PEER_ACTIVITY_TIMEOUT (ZT_PEER_PING_PERIOD + 5000)
/**
* Maximum interval between sort/prioritize of paths for a peer
diff --git a/node/Node.cpp b/node/Node.cpp
index 1d27dba88..37a2622ab 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -170,15 +170,21 @@ struct _processBackgroundTasks_ping_eachPeer
Node *parent;
void *tPtr;
bool online;
+ std::vector
rootsNotOnline;
ZT_ALWAYS_INLINE void operator()(const SharedPtr &peer,const bool isRoot)
{
peer->ping(tPtr,now,isRoot);
- if ((isRoot)&&((now - peer->lastReceive()) <= (ZT_PEER_PING_PERIOD + 5000)))
- online = true;
+ if (isRoot) {
+ if (peer->active(now)) {
+ online = true;
+ } else {
+ rootsNotOnline.push_back(peer->address());
+ }
+ }
}
};
-static uint16_t junk = 0;
+static uint8_t junk = 0; // junk payload for keepalive packets
struct _processBackgroundTasks_path_keepalive
{
int64_t now;
@@ -215,6 +221,15 @@ ZT_ResultCode Node::processBackgroundTasks(void *tPtr, int64_t now, volatile int
}
RR->topology->rankRoots(now);
+
+ if (pf.online) {
+ // If we have at least one online root, request whois for roots not online.
+ // This will give us updated locators for these roots which may contain new
+ // IP addresses. It will also auto-discover IPs for roots that were not added
+ // with an initial bootstrap address.
+ for (std::vector::const_iterator r(pf.rootsNotOnline.begin()); r != pf.rootsNotOnline.end(); ++r)
+ RR->sw->requestWhois(tPtr,now,*r);
+ }
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
@@ -286,7 +301,7 @@ ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr)
if (*nw) {
unsigned long newNetworksSize = (unsigned long)_networks.size();
std::vector< SharedPtr > newNetworks;
- uint64_t newNetworksMask;
+ uint64_t newNetworksMask,id;
std::vector< SharedPtr >::const_iterator i;
try_larger_network_hashtable:
@@ -296,7 +311,7 @@ try_larger_network_hashtable:
newNetworksMask = (uint64_t)(newNetworksSize - 1);
for(i=_networks.begin();i!=_networks.end();++i) {
- const uint64_t id = (*i)->id();
+ id = (*i)->id();
nw = &(newNetworks[(unsigned long)((id + (id >> 32U)) & newNetworksMask)]);
if (*nw)
goto try_larger_network_hashtable;
diff --git a/node/Peer.hpp b/node/Peer.hpp
index f2b2a8faa..b993cd858 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -185,10 +185,15 @@ public:
*/
ZT_ALWAYS_INLINE int64_t lastReceive() const { return _lastReceive; }
+ /**
+ * @return True if we've heard from this peer in less than ZT_PEER_ALIVE_TIMEOUT
+ */
+ ZT_ALWAYS_INLINE bool alive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ALIVE_TIMEOUT); }
+
/**
* @return True if we've heard from this peer in less than ZT_PEER_ACTIVITY_TIMEOUT
*/
- ZT_ALWAYS_INLINE bool alive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
+ ZT_ALWAYS_INLINE bool active(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
/**
* @return Latency in milliseconds of best/aggregate path or 0xffff if unknown
diff --git a/node/Topology.cpp b/node/Topology.cpp
index 49070cb36..b69fea236 100644
--- a/node/Topology.cpp
+++ b/node/Topology.cpp
@@ -22,12 +22,12 @@ struct _RootSortComparisonOperator
ZT_ALWAYS_INLINE bool operator()(const SharedPtr &a,const SharedPtr &b)
{
const int64_t now = _now;
- if (a->alive(now)) {
- if (b->alive(now))
+ if (a->active(now)) {
+ if (b->active(now))
return (a->latency() < b->latency());
return true;
}
- return a->bootstrap() >= b->bootstrap();
+ return a->lastReceive() < b->lastReceive();
}
const int64_t _now;
};
diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp
index 663980beb..8591fe7e0 100644
--- a/osdep/OSUtils.cpp
+++ b/osdep/OSUtils.cpp
@@ -11,27 +11,26 @@
*/
/****/
-#include
-#include
-#include
-#include
+#include
+#include
+#include
+#include
#include
-#include
#include "../node/Constants.hpp"
#include "../node/Utils.hpp"
#ifdef __UNIX_LIKE__
#include
-#include
#include
-#include
-#include
-#include
#include
#include
#endif
+#ifdef __GCC__
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
#ifdef __WINDOWS__
#include
#include
@@ -40,8 +39,6 @@
#include
#endif
-#include
-
#include "OSUtils.hpp"
namespace ZeroTier {
@@ -122,64 +119,6 @@ std::vector OSUtils::listDirectory(const char *path,bool includeDir
return r;
}
-long OSUtils::cleanDirectory(const char *path,const int64_t olderThan)
-{
- long cleaned = 0;
-
-#ifdef __WINDOWS__
- HANDLE hFind;
- WIN32_FIND_DATAA ffd;
- LARGE_INTEGER date,adjust;
- adjust.QuadPart = 11644473600000 * 10000;
- char tmp[4096];
- if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) {
- do {
- if ((strcmp(ffd.cFileName,"."))&&(strcmp(ffd.cFileName,".."))&&((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
- date.HighPart = ffd.ftLastWriteTime.dwHighDateTime;
- date.LowPart = ffd.ftLastWriteTime.dwLowDateTime;
- if (date.QuadPart > 0) {
- date.QuadPart -= adjust.QuadPart;
- if ((int64_t)((date.QuadPart / 10000000) * 1000) < olderThan) {
- ztsnprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName);
- if (DeleteFileA(tmp))
- ++cleaned;
- }
- }
- }
- } while (FindNextFileA(hFind,&ffd));
- FindClose(hFind);
- }
-#else
- struct dirent de;
- struct dirent *dptr;
- struct stat st;
- char tmp[4096];
- DIR *d = opendir(path);
- if (!d)
- return -1;
- dptr = (struct dirent *)0;
- for(;;) {
- if (readdir_r(d,&de,&dptr))
- break;
- if (dptr) {
- if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))&&(dptr->d_type == DT_REG)) {
- ztsnprintf(tmp,sizeof(tmp),"%s/%s",path,dptr->d_name);
- if (stat(tmp,&st) == 0) {
- int64_t mt = (int64_t)(st.st_mtime);
- if ((mt > 0)&&((mt * 1000) < olderThan)) {
- if (unlink(tmp) == 0)
- ++cleaned;
- }
- }
- }
- } else break;
- }
- closedir(d);
-#endif
-
- return cleaned;
-}
-
bool OSUtils::rmDashRf(const char *path)
{
#ifdef __WINDOWS__
diff --git a/osdep/OSUtils.hpp b/osdep/OSUtils.hpp
index bf6ca4f5f..1de747e3e 100644
--- a/osdep/OSUtils.hpp
+++ b/osdep/OSUtils.hpp
@@ -132,16 +132,6 @@ public:
*/
static std::vector listDirectory(const char *path,bool includeDirectories = false);
- /**
- * Clean a directory of files whose last modified time is older than this
- *
- * This ignores directories, symbolic links, and other special files.
- *
- * @param olderThan Last modified older than timestamp (ms since epoch)
- * @return Number of cleaned files or negative on fatal error
- */
- static long cleanDirectory(const char *path,const int64_t olderThan);
-
/**
* Delete a directory and all its files and subdirectories recursively
*