diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 5cecf3400..7a866b479 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,6 +1,13 @@ ZeroTier Release Notes ====== +## 2025-12-22 -- Version 1.16.1 + + * Metrics collection is now disabled by default. It can be enabled via the `enableMetrics` setting in `local.conf`. + * Fix for an issue where metrics were not being recorded while running in daemon mode. + * Fix debug dumpfile being written to the root directory. + * Minor bug fixes in Mac and BSD tun/tap code. + ## 2025-08-21 -- Version 1.16.0 * License Changes diff --git a/debian/changelog b/debian/changelog index 84b78f697..57d6b2ac4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +zerotier-one (1.16.1) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 12 Dec 2025 01:00:00 -0700 + zerotier-one (1.16.0-2) unstable; urgency=medium * Fix build settings to include controller. diff --git a/ext/installfiles/mac/ZeroTier One.pkgproj b/ext/installfiles/mac/ZeroTier One.pkgproj index 56ae6ea28..5abe96455 100755 --- a/ext/installfiles/mac/ZeroTier One.pkgproj +++ b/ext/installfiles/mac/ZeroTier One.pkgproj @@ -702,7 +702,7 @@ USE_HFS+_COMPRESSION VERSION - 1.16.0 + 1.16.1 TYPE 0 diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip index b787dac15..8a84ad434 100644 --- a/ext/installfiles/windows/ZeroTier One.aip +++ b/ext/installfiles/windows/ZeroTier One.aip @@ -21,10 +21,10 @@ - + - + @@ -62,7 +62,7 @@ - + @@ -515,7 +515,7 @@ - + diff --git a/ext/installfiles/windows/ZeroTier One.back.aip b/ext/installfiles/windows/ZeroTier One.back.aip deleted file mode 100644 index 9ad818277..000000000 --- a/ext/installfiles/windows/ZeroTier One.back.aip +++ /dev/null @@ -1,558 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ext/prometheus-cpp-lite-1.0/core/include/prometheus/save_to_file.h b/ext/prometheus-cpp-lite-1.0/core/include/prometheus/save_to_file.h index 26bd0c95c..d181b1358 100644 --- a/ext/prometheus-cpp-lite-1.0/core/include/prometheus/save_to_file.h +++ b/ext/prometheus-cpp-lite-1.0/core/include/prometheus/save_to_file.h @@ -50,6 +50,16 @@ namespace prometheus { public: SaveToFile() = default; + void stop() { + must_die = true; + worker_thread.join(); + } + + void restart() { + must_die = false; + worker_thread = std::thread(&SaveToFile::worker_function, this); + } + ~SaveToFile() { must_die = true; worker_thread.join(); diff --git a/one.cpp b/one.cpp index 0e2ac4cfa..a066f4e65 100644 --- a/one.cpp +++ b/one.cpp @@ -1196,12 +1196,13 @@ static int cli(int argc, char** argv) return 0; } - snprintf((char*)path, sizeof(path), "%s%szerotier_dump.txt", (char*)path, ZT_PATH_SEPARATOR_S); + char dumpfile[PATH_MAX]; + snprintf(dumpfile, sizeof(dumpfile), "%s%szerotier_dump.txt", (char*)path, ZT_PATH_SEPARATOR_S); - fprintf(stdout, "Writing dump to: %s\n", path); - int fd = open((char*)path, O_CREAT | O_RDWR, 0664); + fprintf(stdout, "Writing dump to: %s\n", dumpfile); + int fd = open(dumpfile, O_CREAT | O_WRONLY | O_TRUNC, 0664); if (fd == -1) { - fprintf(stderr, "Error creating file.\n"); + perror("Error creating file"); return 1; } write(fd, dump.str().c_str(), dump.str().size()); @@ -1278,9 +1279,9 @@ static int cli(int argc, char** argv) return 0; } - BOOL err = WriteFile(file, dump.str().c_str(), dump.str().size(), NULL, NULL); - if (err = FALSE) { - fprintf(stderr, "Error writing file"); + BOOL ok = WriteFile(file, dump.str().c_str(), dump.str().size(), NULL, NULL); + if (ok == FALSE) { + fprintf(stderr, "Error writing file\n"); return 1; } CloseHandle(file); @@ -1346,12 +1347,15 @@ static int cli(int argc, char** argv) } close(sock); char cwd[16384]; - getcwd(cwd, sizeof(cwd)); - snprintf(cwd, sizeof(cwd), "%s%szerotier_dump.txt", cwd, ZT_PATH_SEPARATOR_S); - fprintf(stdout, "Writing dump to: %s\n", cwd); - int fd = open(cwd, O_CREAT | O_RDWR, 0664); + if (getcwd(cwd, sizeof(cwd)) == nullptr) { + strcpy(cwd, "."); + } + char dumpfile[sizeof(cwd) + 32]; + snprintf(dumpfile, sizeof(dumpfile), "%s%szerotier_dump.txt", cwd, ZT_PATH_SEPARATOR_S); + fprintf(stdout, "Writing dump to: %s\n", dumpfile); + int fd = open(dumpfile, O_CREAT | O_WRONLY | O_TRUNC, 0664); if (fd == -1) { - fprintf(stderr, "Error creating file.\n"); + perror("Error creating file"); return 1; } write(fd, dump.str().c_str(), dump.str().size()); @@ -2330,14 +2334,18 @@ int main(int argc, char** argv) } #endif // !ZT_ONE_NO_ROOT_CHECK if (runAsDaemon) { + prometheus::simpleapi::saver.stop(); + long p = (long)fork(); if (p < 0) { fprintf(stderr, "%s: could not fork" ZT_EOL_S, argv[0]); return 1; } else if (p > 0) - return 0; // forked + _Exit(0); // forked // else p == 0, so we are daemonized + + prometheus::simpleapi::saver.restart(); } #endif // __UNIX_LIKE__ diff --git a/osdep/BSDEthernetTap.cpp b/osdep/BSDEthernetTap.cpp index 36e70ca7c..82ac07d1a 100644 --- a/osdep/BSDEthernetTap.cpp +++ b/osdep/BSDEthernetTap.cpp @@ -339,7 +339,7 @@ std::vector BSDEthernetTap::ips() const freeifaddrs(ifa); std::sort(r.begin(), r.end()); - std::unique(r.begin(), r.end()); + r.erase(std::unique(r.begin(), r.end()), r.end()); _ifaddrs = r; @@ -394,7 +394,7 @@ void BSDEthernetTap::scanMulticastGroups(std::vector& added, std newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); std::sort(newGroups.begin(), newGroups.end()); - std::unique(newGroups.begin(), newGroups.end()); + newGroups.erase(std::unique(newGroups.begin(), newGroups.end()), newGroups.end()); for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) diff --git a/osdep/MacKextEthernetTap.cpp b/osdep/MacKextEthernetTap.cpp index 707858fd9..399742929 100644 --- a/osdep/MacKextEthernetTap.cpp +++ b/osdep/MacKextEthernetTap.cpp @@ -607,7 +607,7 @@ void MacKextEthernetTap::scanMulticastGroups(std::vector& added, newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); std::sort(newGroups.begin(), newGroups.end()); - std::unique(newGroups.begin(), newGroups.end()); + newGroups.erase(std::unique(newGroups.begin(), newGroups.end()), newGroups.end()); for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) diff --git a/osdep/NetBSDEthernetTap.cpp b/osdep/NetBSDEthernetTap.cpp index 666a387f6..aa923bdb3 100644 --- a/osdep/NetBSDEthernetTap.cpp +++ b/osdep/NetBSDEthernetTap.cpp @@ -316,7 +316,7 @@ std::vector NetBSDEthernetTap::ips() const freeifaddrs(ifa); std::sort(r.begin(), r.end()); - std::unique(r.begin(), r.end()); + r.erase(std::unique(r.begin(), r.end()), r.end()); return r; } @@ -367,7 +367,7 @@ void NetBSDEthernetTap::scanMulticastGroups(std::vector& added, newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); std::sort(newGroups.begin(), newGroups.end()); - std::unique(newGroups.begin(), newGroups.end()); + newGroups.erase(std::unique(newGroups.begin(), newGroups.end()), newGroups.end()); for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) diff --git a/service/OneService.cpp b/service/OneService.cpp index 41d790516..227b575f7 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -988,7 +988,6 @@ class OneServiceImpl : public OneService { _ports[1] = 0; _ports[2] = 0; - prometheus::simpleapi::saver.set_registry(prometheus::simpleapi::registry_ptr); prometheus::simpleapi::saver.set_delay(std::chrono::seconds(5)); prometheus::simpleapi::saver.set_out_file(_homePath + ZT_PATH_SEPARATOR + "metrics.prom"); @@ -2610,8 +2609,8 @@ class OneServiceImpl : public OneService { _controlPlaneV6.set_pre_routing_handler(authCheck); #if ZT_DEBUG == 1 - _controlPlane.set_logger([](const httplib::Request& req, const httplib::Response& res) { fprintf(stderr, "%s", http_log(req, res).c_str()); }); - _controlPlaneV6.set_logger([](const httplib::Request& req, const httplib::Response& res) { fprintf(stderr, "%s", http_log(req, res).c_str()); }); + //_controlPlane.set_logger([](const httplib::Request& req, const httplib::Response& res) { fprintf(stderr, "%s", http_log(req, res).c_str()); }); + //_controlPlaneV6.set_logger([](const httplib::Request& req, const httplib::Response& res) { fprintf(stderr, "%s", http_log(req, res).c_str()); }); #endif if (_primaryPort == 0) { fprintf(stderr, "unable to determine local control port"); @@ -2931,6 +2930,15 @@ class OneServiceImpl : public OneService { _allowManagementFrom.push_back(nw); } } + + bool enableMetrics = OSUtils::jsonBool(settings["enableMetrics"], false); + if (enableMetrics) { + prometheus::simpleapi::saver.set_registry(prometheus::simpleapi::registry_ptr); + } + else { + std::shared_ptr registry; + prometheus::simpleapi::saver.set_registry(registry); + } } #if ZT_VAULT_SUPPORT diff --git a/service/README.md b/service/README.md index 94e920a58..5ecbb4e1f 100644 --- a/service/README.md +++ b/service/README.md @@ -41,7 +41,7 @@ Settings available in `local.conf` (this is not valid JSON, and JSON does not al "allowManagementFrom": [ "NETWORK/bits", ...] |null, /* If non-NULL, allow JSON/HTTP management from this IP network. Default is 127.0.0.1 only. */ "bind": [ "ip",... ], /* If present and non-null, bind to these IPs instead of to each interface (wildcard IP allowed) */ "allowTcpFallbackRelay": true|false, /* Allow or disallow establishment of TCP relay connections (true by default) */ - "multipathMode": 0|1|2 /* multipath mode: none (0), random (1), proportional (2) */ + "enableMetrics": true|false /* If true, enable the collection of metrics in metrics.prom. */ } } ``` diff --git a/version.h b/version.h index 3cfa04ffa..b0e5bb00e 100644 --- a/version.h +++ b/version.h @@ -22,7 +22,7 @@ /** * Revision */ -#define ZEROTIER_ONE_VERSION_REVISION 0 +#define ZEROTIER_ONE_VERSION_REVISION 1 /** * Build version diff --git a/zerotier-one.spec b/zerotier-one.spec index ffb010c24..be57e7723 100644 --- a/zerotier-one.spec +++ b/zerotier-one.spec @@ -1,5 +1,5 @@ Name: zerotier-one -Version: 1.16.0 +Version: 1.16.1 Release: 1%{?dist} Summary: ZeroTier network virtualization service @@ -155,6 +155,9 @@ chmod 0755 $RPM_BUILD_ROOT/etc/init.d/zerotier-one %endif %changelog +* Fri Dec 12 2025 Adam Ierymenko - 1.16.1 +- see https://github.com/zerotier/ZeroTierOne for release notes + * Wed Oct 23 2024 Adam Ierymenko - 1.14.2 - see https://github.com/zerotier/ZeroTierOne for release notes