Compare commits

...
43 Commits
Author SHA1 Message Date
Adam Ierymenko a0acc82e99 1.14.1 (#2362)
* Bump version in most places.

* Update official release steps for desktop

* Version bump a bunch of Rust packages.

* Windows fix for disabling MT properly.

* Release notes.
2024-09-12 18:48:34 -04:00
Adam Ierymenko 98e532de20 Merge pull request #2244 from zerotier/lel-amri-fix-mac-handling-in-rules-parser
Fix mac handling in rules parser
2024-09-11 14:56:10 -04:00
Adam Ierymenko e1ee3eb494 Merge branch 'dev' into lel-amri-fix-mac-handling-in-rules-parser 2024-09-11 12:13:32 -04:00
Adam Ierymenko 4a485df0c7 Merge pull request #2234 from zerotier/jh-zerotier-multithreaded
Add multi-core concurrent packet processing
2024-09-11 10:17:22 -04:00
Travis LaDuke 2522d29fdc Merge pull request #2360 from laduke/dev
retain build artifacts from build action
2024-09-10 13:55:29 -07:00
travisladuke 560d6fba1b tar mac and linux binary
to keep the execute permission bit
2024-09-10 13:45:50 -07:00
travisladuke 223ec0c59d retain build artifacts
cleaned up all the github action deprecation warnings.
save zerotier-one binary for mac, windows, and linux
2024-09-10 13:36:59 -07:00
Adam Ierymenko 6bc785e771 Merge branch 'dev' into jh-zerotier-multithreaded 2024-09-10 13:10:45 -04:00
Adam Ierymenko fb8cbb69aa Merge pull request #2354 from zerotier/jh-misc-multipath-patches
Multipath improvements
2024-09-10 13:08:37 -04:00
Adam Ierymenko 861147b845 Merge branch 'dev' into jh-zerotier-multithreaded 2024-09-09 16:22:48 -04:00
Adam Ierymenko 763caaebab Merge pull request #2161 from parona-source/execstack
Append noexecstack to linker flags instead of assembler flags
2024-09-09 16:22:14 -04:00
Adam Ierymenko 276259394a Merge branch 'dev' into jh-zerotier-multithreaded 2024-09-09 16:19:37 -04:00
Adam Ierymenko 46c0d1a732 Merge pull request #2320 from zerotier/report-os-arch
Report os arch
2024-09-09 16:13:47 -04:00
Adam Ierymenko 31d2dcec17 Merge pull request #2263 from fedepell/patch-1
Update README.md minimal compilers
2024-09-09 16:04:35 -04:00
Adam Ierymenko c9234ee027 Merge branch 'dev' into patch-1 2024-09-09 16:03:41 -04:00
Adam Ierymenko 9a8d715666 Merge branch 'report-os-arch' of github.com:/zerotier/ZeroTierOne into report-os-arch 2024-09-09 14:36:43 -04:00
Adam Ierymenko 8d474e1395 Add ios differentiation, and .clangd that works w/Zed and clangd. 2024-09-09 14:36:22 -04:00
Adam Ierymenko 52e3d9b804 Merge branch 'dev' into report-os-arch 2024-09-09 14:26:53 -04:00
Joseph Henry 8f5cc4ed33 Completely remove vestigial RX code 2024-09-06 15:19:06 -07:00
Joseph Henry 059d05f41f Comment out vestigial test code (improves mt performance) 2024-09-06 09:52:39 -07:00
Joseph Henry c86b91c5f0 Fix condition where settings may be applied with multithreading is disabled 2024-09-04 12:14:20 -07:00
Joseph Henry e42848d37d Fix bug for when no multithreaded config is given 2024-09-04 11:00:23 -07:00
Joseph Henry bf7dddbd84 Fix issues that prevent user multipath preferences from being respected 2024-08-29 10:09:19 -07:00
Joseph Henry 95983ba168 Build fix for FreeBSD 2024-08-26 12:54:36 -07:00
Joseph Henry c97943d69d Add packet mux source file to Windows project 2024-08-22 15:28:25 -07:00
Joseph Henry b813ea70a5 Simplify packet critical path. Plus more platform fixes 2024-08-22 12:59:06 -07:00
Joseph Henry e734019216 More platform-related build fixes 2024-08-21 14:06:25 -07:00
Joseph Henry b7d9290de9 Fix build issue on macOS 2024-08-21 11:22:07 -07:00
Joseph Henry b1a30ae4ff Switch to local.conf-based config of multithreading 2024-08-20 13:39:15 -07:00
Joseph Henry 8283a6d6d4 Merge branch 'dev' into jh-zerotier-multithreaded 2024-08-18 15:08:42 -07:00
Joseph Henry 36adae3d82 Add packet multiplexer 2024-08-18 15:07:18 -07:00
Joseph Henry 64634c916c Fix build for macOS, tune to prevent packet re-ordering 2024-07-03 08:49:07 -07:00
Adam Ierymenko e2840b0eb8 undo stuff from other branch 2024-06-24 18:54:05 -04:00
Adam Ierymenko f4edb092b7 Merge branch 'dev' into rusty-tcp-relay 2024-06-24 18:53:25 -04:00
Adam Ierymenko 8caede300c Add OS_ARCH to network config metadata. 2024-06-24 18:02:58 -04:00
Adam Ierymenko f79af92599 Add Rust tcp-proxy base, add .clangd 2024-06-17 11:02:13 -04:00
Federico Pellegrin 280cc77e23 Update README.md minimal compilers
Update the minimal compilers in documentation. As `std=c++17` is used the minimal got quite bumped from last update. For gcc 7.x would seem possibly enough, but some of the dependencies (eg. libpqxx) need 8.x at least, so setting that as documented minimum.
2024-03-25 05:06:22 +01:00
Joseph Henry b9d0cf9c89 Don't pass result of void function to string constructor 2024-03-05 12:14:12 -08:00
Joseph Henry 80cfc2bd26 Merge branch 'dev' into fix-mac-handling-in-rules-parser 2024-03-05 11:26:33 -08:00
Joseph Henry 43b141547e Merge branch 'dev' into fix-mac-handling-in-rules-parser 2024-03-05 10:48:58 -08:00
Joseph Henry 683d332abc Add multi-core concurrent packet processing 2024-02-23 09:57:39 -08:00
Léo El Amri 1aa31e0414 Fix how MAC addresses are handled by the rules parser
It wasn't ignoring separator characters such as the colon and hyphen.
The rules compiler automatically add a colon to separate bytes, which is
not compatible with how they are parsed.
2023-11-15 16:51:03 +01:00
Alfred Wingate e171384c19 Append noexecstack to linker flags instead of assembler flags
* Better compatibility with LLVM toolchain where clang -c doesn't
  support the flag, but the linker does. LLD already defaults to
  noexecstack, but adding it in the linker phase will avoid errors about
  unsupported options.

Signed-off-by: Alfred Wingate <parona@protonmail.com>
2023-10-29 14:03:26 +02:00
39 changed files with 1420 additions and 710 deletions

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
CompileFlags:
Add:
- "-std=c++17"
- "-I../ext"
- "-I../ext/prometheus-cpp-lite-1.0/core/include"
- "-I../ext/prometheus-cpp-lite-1.0/simpleapi/include"
+33 -15
View File
@@ -9,13 +9,12 @@ jobs:
git config --global core.autocrlf input
# git config --global core.eol lf
- name: checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: x86_64-unknown-linux-gnu
override: true
targets: x86_64-unknown-linux-gnu
components: rustfmt, clippy
- name: Set up cargo cache
@@ -33,6 +32,14 @@ jobs:
run: |
make selftest
./zerotier-selftest
- name: 'Tar files' # keeps permissions (execute)
run: tar -cvf zerotier-one.tar zerotier-one
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: zerotier-one-ubuntu-x64
path: zerotier-one.tar
retention-days: 7
build_macos:
runs-on: macos-latest
@@ -42,20 +49,18 @@ jobs:
git config --global core.autocrlf input
# git config --global core.eol lf
- name: checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Rust aarch64
uses: actions-rs/toolchain@v1
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: aarch64-apple-darwin
override: true
components: rustfmt, clippy
- name: Install Rust x86_64
uses: actions-rs/toolchain@v1
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: x86_64-apple-darwin
override: true
components: rustfmt, clippy
- name: Set up cargo cache
uses: Swatinem/rust-cache@v2
@@ -65,13 +70,21 @@ jobs:
shared-key: ${{ runner.os }}-cargo-
workspaces: |
rustybits/
- name: make
run: make
- name: selftest
run: |
make selftest
./zerotier-selftest
- name: 'Tar files' # keeps permissions (execute)
run: tar -cvf zerotier-one.tar zerotier-one
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: zerotier-one-mac
path: zerotier-one.tar
retention-days: 7
build_windows:
runs-on: windows-latest
@@ -81,13 +94,12 @@ jobs:
git config --global core.autocrlf true
# git config --global core.eol lf
- name: checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: aarch64-apple-darwin
override: true
components: rustfmt, clippy
- name: Set up cargo cache
uses: Swatinem/rust-cache@v2
@@ -99,7 +111,13 @@ jobs:
rustybits/
- name: setup msbuild
uses: microsoft/setup-msbuild@v1.1.3
uses: microsoft/setup-msbuild@v2
- name: msbuild
run: |
msbuild windows\ZeroTierOne.sln /m /p:Configuration=Release /property:Platform=x64 /t:ZeroTierOne
msbuild windows\ZeroTierOne.sln /m /p:Configuration=Release /property:Platform=x64 /t:ZeroTierOne
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: zerotier-one-windows
path: windows/Build
retention-days: 7
+1
View File
@@ -124,6 +124,7 @@ attic/world/mkworld
workspace/
workspace2/
zeroidc/target/
tcp-proxy/target
#snapcraft specifics
/parts/
+1
View File
@@ -14,6 +14,7 @@ The version must be incremented in all of the following files:
/debian/changelog
/ext/installfiles/mac/ZeroTier One.pkgproj
/ext/installfiles/windows/ZeroTier One.aip
../DesktopUI/mac-app-template/ZeroTier.app/Contents/Info.plist
The final .AIP file can only be edited on Windows with [Advanced Installer Enterprise](http://www.advancedinstaller.com/). In addition to incrementing the version be sure that a new product code is generated. (The "upgrade code" GUID on the other hand must never change.)
+1 -1
View File
@@ -58,7 +58,7 @@ To build on Mac and Linux just type `make`. On FreeBSD and OpenBSD `gmake` (GNU
- Xcode command line tools for macOS 10.13 or newer are required.
- Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*.
- **Linux**
- The minimum compiler versions required are GCC/G++ 4.9.3 or CLANG/CLANG++ 3.4.2. (Install `clang` on CentOS 7 as G++ is too old.)
- The minimum compiler versions required are GCC/G++ 8.x or CLANG/CLANG++ 5.x.
- Linux makefiles automatically detect and prefer clang/clang++ if present as it produces smaller and slightly faster binaries in most cases. You can override by supplying CC and CXX variables on the make command line.
- Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*.
- **Windows**
+16
View File
@@ -1,6 +1,22 @@
ZeroTier Release Notes
======
# 2024-09-12 -- Version 1.14.1
* Multithreaded packet I/O support! Currently this is just for Linux and must
be enabled in local.conf. It will likely make the largest difference on small
multi-core devices where CPU is a bottleneck and high throughput is desired.
It may be enabled by default in the future but we want it to be thoroughly
tested. It's a little harder than it seems at first glance due to the need
to keep packets in sequence and balance load.
* Several multipath bug fixes.
* Updated the versions on a number of libraries related to OIDC support and HTTP.
* MacOS .app now shows the correct version in its Info.plist manifest.
* Sanitize MAC addresses in JSON format rules parser.
* Some basic information about the platform (OS, CPU architecture) is now reported
to network controllers when networks are joined so it can be displayed to
network admins and in the future used in policy checking and inventory operations.
# 2024-05-02 -- Version 1.14.0
* Linux I/O performance improvements under heavy load
+4 -2
View File
@@ -315,12 +315,14 @@ static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule)
return true;
} else if (t == "MATCH_MAC_SOURCE") {
rule.t |= ZT_NETWORK_RULE_MATCH_MAC_SOURCE;
const std::string mac(OSUtils::jsonString(r["mac"],"0"));
std::string mac(OSUtils::jsonString(r["mac"],"0"));
Utils::cleanMac(mac);
Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6);
return true;
} else if (t == "MATCH_MAC_DEST") {
rule.t |= ZT_NETWORK_RULE_MATCH_MAC_DEST;
const std::string mac(OSUtils::jsonString(r["mac"],"0"));
std::string mac(OSUtils::jsonString(r["mac"],"0"));
Utils::cleanMac(mac);
Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6);
return true;
} else if (t == "MATCH_IPV4_SOURCE") {
+6
View File
@@ -1,3 +1,9 @@
zerotier-one (1.14.1) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Wed, 11 Sep 2024 01:00:00 -0700
zerotier-one (1.14.0) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
+1 -1
View File
@@ -701,7 +701,7 @@
<key>USE_HFS+_COMPRESSION</key>
<false/>
<key>VERSION</key>
<string>1.14.0</string>
<string>1.14.1</string>
</dict>
<key>TYPE</key>
<integer>0</integer>
+1 -1
View File
@@ -364,7 +364,7 @@ override CFLAGS+=-fPIC -fPIE
override CXXFLAGS+=-fPIC -fPIE
# Non-executable stack
override ASFLAGS+=--noexecstack
override LDFLAGS+=-Wl,-z,noexecstack
.PHONY: all
all: one
+26 -15
View File
@@ -373,6 +373,7 @@ SharedPtr<Path> Bond::getAppropriatePath(int64_t now, int32_t flowId)
*/
if (_policy == ZT_BOND_POLICY_ACTIVE_BACKUP) {
if (_abPathIdx != ZT_MAX_PEER_NETWORK_PATHS && _paths[_abPathIdx].p) {
//fprintf(stderr, "trying to send via (_abPathIdx=%d) %s\n", _abPathIdx, pathToStr(_paths[_abPathIdx].p).c_str());
return _paths[_abPathIdx].p;
}
}
@@ -1032,6 +1033,13 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
bool satisfiedUpDelay = (now - _paths[i].lastAliveToggle) >= _upDelay;
// How long since the last QoS was received (Must be less than ZT_PEER_PATH_EXPIRATION since the remote peer's _qosSendInterval isn't known)
bool acceptableQoSAge = (_paths[i].lastQoSReceived == 0 && inTrial) || ((now - _paths[i].lastQoSReceived) < ZT_PEER_EXPIRED_PATH_TRIAL_PERIOD);
// Allow active-backup to operate without the receipt of QoS records
// This may be expanded to the other modes as an option
if (_policy == ZT_BOND_POLICY_ACTIVE_BACKUP) {
acceptableQoSAge = true;
}
currEligibility = _paths[i].allowed() && ((acceptableAge && satisfiedUpDelay && acceptableQoSAge) || inTrial);
if (currEligibility) {
@@ -1043,12 +1051,11 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
*/
if (currEligibility != _paths[i].eligible) {
if (currEligibility == 0) {
log("link %s is no longer eligible", pathToStr(_paths[i].p).c_str());
log("link %s is no longer eligible (reason: allowed=%d, age=%d, ud=%d, qos=%d, trial=%d)", pathToStr(_paths[i].p).c_str(), _paths[i].allowed(), acceptableAge, satisfiedUpDelay, acceptableQoSAge, inTrial);
}
if (currEligibility == 1) {
log("link %s is eligible", pathToStr(_paths[i].p).c_str());
}
debug("\t[%d] allowed=%d, age=%d, qa=%d, ud=%d, trial=%d", i, _paths[i].allowed(), acceptableAge, acceptableQoSAge, satisfiedUpDelay, inTrial);
dumpPathStatus(now, i);
if (currEligibility) {
rebuildBond = true;
@@ -1496,7 +1503,8 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
{
int prevActiveBackupPathIdx = _abPathIdx;
int nonPreferredPathIdx = ZT_MAX_PEER_NETWORK_PATHS;
bool bFoundPrimaryLink = false;
bool foundPathOnPrimaryLink = false;
bool foundPreferredPath = false;
if (_abPathIdx != ZT_MAX_PEER_NETWORK_PATHS && ! _paths[_abPathIdx].p) {
_abPathIdx = ZT_MAX_PEER_NETWORK_PATHS;
@@ -1559,15 +1567,16 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
if (! _paths[i].preferred()) {
// Found path on primary link, take note in case we don't find a preferred path
nonPreferredPathIdx = i;
bFoundPrimaryLink = true;
foundPathOnPrimaryLink = true;
}
if (_paths[i].preferred()) {
_abPathIdx = i;
bFoundPrimaryLink = true;
foundPathOnPrimaryLink = true;
if (_paths[_abPathIdx].p) {
SharedPtr<Link> abLink = RR->bc->getLinkBySocket(_policyAlias, _paths[_abPathIdx].p->localSocket());
if (abLink) {
log("found preferred primary link %s", pathToStr(_paths[_abPathIdx].p).c_str());
log("found preferred primary link (_abPathIdx=%d), %s", _abPathIdx, pathToStr(_paths[_abPathIdx].p).c_str());
foundPreferredPath = true;
}
break; // Found preferred path on primary link
}
@@ -1575,8 +1584,8 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
}
}
}
if (bFoundPrimaryLink && (nonPreferredPathIdx != ZT_MAX_PEER_NETWORK_PATHS)) {
log("found non-preferred primary link");
if (!foundPreferredPath && foundPathOnPrimaryLink && (nonPreferredPathIdx != ZT_MAX_PEER_NETWORK_PATHS)) {
log("found non-preferred primary link (_abPathIdx=%d)", _abPathIdx);
_abPathIdx = nonPreferredPathIdx;
}
}
@@ -1614,10 +1623,10 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
}
if (_paths[(*it)].p && ! _paths[(*it)].eligible) {
SharedPtr<Link> link = RR->bc->getLinkBySocket(_policyAlias, _paths[(*it)].p->localSocket());
it = _abFailoverQueue.erase(it);
if (link) {
log("link %s is ineligible, removing from failover queue (%zu links remain in queue)", pathToStr(_paths[_abPathIdx].p).c_str(), _abFailoverQueue.size());
log("link %s is ineligible, removing from failover queue (%zu links remain in queue)", pathToStr(_paths[(*it)].p).c_str(), _abFailoverQueue.size());
}
it = _abFailoverQueue.erase(it);
continue;
}
else {
@@ -1684,7 +1693,7 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
}
}
if (! bFoundPathInQueue) {
_abFailoverQueue.push_front(i);
_abFailoverQueue.push_back(i);
log("add link %s to failover queue (%zu links in queue)", pathToStr(_paths[i].p).c_str(), _abFailoverQueue.size());
addPathToBond(i, 0);
}
@@ -1734,13 +1743,14 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
}
}
if (! bFoundPathInQueue) {
_abFailoverQueue.push_front(i);
_abFailoverQueue.push_back(i);
log("add link %s to failover queue (%zu links in queue)", pathToStr(_paths[i].p).c_str(), _abFailoverQueue.size());
addPathToBond(i, 0);
}
}
}
}
/*
// Sort queue based on performance
if (! _abFailoverQueue.empty()) {
for (int i = 0; i < _abFailoverQueue.size(); i++) {
@@ -1752,7 +1762,7 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
}
_abFailoverQueue[hole_position] = value_to_insert;
}
}
}*/
/**
* Short-circuit if we have no queued paths
@@ -1902,7 +1912,7 @@ void Bond::setBondParameters(int policy, SharedPtr<Bond> templateBond, bool useT
* Policy defaults
*/
_abPathIdx = ZT_MAX_PEER_NETWORK_PATHS;
_abLinkSelectMethod = ZT_BOND_RESELECTION_POLICY_OPTIMIZE;
_abLinkSelectMethod = ZT_BOND_RESELECTION_POLICY_ALWAYS;
_rrPacketsSentOnCurrLink = 0;
_rrIdx = 0;
_packetsPerLink = 64;
@@ -2021,7 +2031,8 @@ void Bond::dumpInfo(int64_t now, bool force)
_lastSummaryDump = now;
float overhead = (_overheadBytes / (timeSinceLastDump / 1000.0f) / 1000.0f);
_overheadBytes = 0;
log("bond: bp=%d, fi=%" PRIu64 ", mi=%d, ud=%d, dd=%d, flows=%zu, leaf=%d, overhead=%f KB/s, links=(%d/%d)",
log("bond: ready=%d, bp=%d, fi=%" PRIu64 ", mi=%d, ud=%d, dd=%d, flows=%zu, leaf=%d, overhead=%f KB/s, links=(%d/%d)",
isReady(),
_policy,
_failoverInterval,
_monitorInterval,
+2
View File
@@ -1144,6 +1144,7 @@ class Bond {
__attribute__((format(printf, 2, 3)))
#endif
{
//if (_peerId != 0x0 && _peerId != 0x0) { return; }
#ifdef ZT_TRACE
time_t rawtime;
struct tm* timeinfo;
@@ -1175,6 +1176,7 @@ class Bond {
__attribute__((format(printf, 2, 3)))
#endif
{
//if (_peerId != 0x0 && _peerId != 0x0) { return; }
#ifdef ZT_DEBUG
time_t rawtime;
struct tm* timeinfo;
+66
View File
@@ -202,6 +202,72 @@
#define ZT_PACKED_STRUCT(D) D __attribute__((packed))
#endif
#if defined(_WIN32)
#define ZT_PLATFORM_NAME "windows" // Windows
#elif defined(_WIN64)
#define ZT_PLATFORM_NAME "windows" // Windows
#elif defined(__CYGWIN__)
#define ZT_PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window)
#elif defined(__ANDROID__)
#define ZT_PLATFORM_NAME "android" // Android (implies Linux, so it must come first)
#elif defined(__linux__)
#define ZT_PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other
#elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__)
#include <sys/param.h>
#if defined(BSD)
#define ZT_PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD
#endif
#elif defined(__hpux)
#define ZT_PLATFORM_NAME "hp-ux" // HP-UX
#elif defined(_AIX)
#define ZT_PLATFORM_NAME "aix" // IBM AIX
#elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
#include <TargetConditionals.h>
#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR == 1
#define ZT_PLATFORM_NAME "ios_sim" // Apple iOS
#elif defined(TARGET_OS_IPAD) && TARGET_OS_IPAD == 1
#define ZT_PLATFORM_NAME "ios_ipad"
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1
#define ZT_PLATFORM_NAME "ios_iphone" // Apple iOS
#elif defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1
#define ZT_PLATFORM_NAME "macos" // Apple OSX
#endif
#elif defined(__sun) && defined(__SVR4)
#define ZT_PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana
#else
#define ZT_PLATFORM_NAME "unknown"
#endif
#ifndef ZT_PLATFORM_NAME
#define ZT_PLATFORM_NAME "unknown"
#endif
#if defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64) || defined(_M_AMD64)
#define ZT_ARCH_NAME "x86_64"
#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_X86_) || defined(_M_IX86) || defined(__X86__) || defined(__I86__) || defined(_M_I86)
#define ZT_ARCH_NAME "x86"
#elif defined(__aarch64__) || defined(__AARCH64EL__) || defined(_M_ARM64)
#define ZT_ARCH_NAME "arm64"
#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARMT) || defined(__arm) || defined(__thumb__)
#define ZT_ARCH_NAME "arm"
#elif defined(__loongarch__) || defined(_LOONGARCH_ARCH)
#define ZT_ARCH_NAME "loongarch"
#elif defined(__mips__) || defined(__MIPS__)
#define ZT_ARCH_NAME "mips"
#elif defined(__riscv) || defined(__riscv_xlen)
#define ZT_ARCH_NAME "riscv"
#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__) || defined (_M_PPC)
#define ZT_ARCH_NAME "powerpc"
#elif defined(__s390__) || defined(__s390x__) || defined(__zarch__)
#define ZT_ARCH_NAME "s390"
#else
#define ZT_ARCH_NAME "unknown"
#endif
#ifndef ZT_ARCH_NAME
#define ZT_ARCH_NAME "unknown"
#endif
#define ZT_TARGET_NAME (ZT_PLATFORM_NAME "/" ZT_ARCH_NAME)
/**
* Length of a ZeroTier address in bytes
*/
+59 -60
View File
@@ -38,6 +38,7 @@
#include "Path.hpp"
#include "Bond.hpp"
#include "Metrics.hpp"
#include "PacketMultiplexer.hpp"
namespace ZeroTier {
@@ -334,7 +335,6 @@ bool IncomingPacket::_doACK(const RuntimeEnvironment* RR, void* tPtr, const Shar
bool IncomingPacket::_doQOS_MEASUREMENT(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr<Peer>& peer)
{
Metrics::pkt_qos_in++;
SharedPtr<Bond> bond = peer->bond();
if (! peer->rateGateQoS(RR->node->now(), _path)) {
return true;
}
@@ -793,66 +793,65 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar
{
Metrics::pkt_frame_in++;
int32_t _flowId = ZT_QOS_NO_FLOW;
if (peer->flowHashingSupported()) {
if (size() > ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD) {
const unsigned int etherType = at<uint16_t>(ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE);
const unsigned int frameLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
const uint8_t *const frameData = reinterpret_cast<const uint8_t *>(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
if (etherType == ZT_ETHERTYPE_IPV4 && (frameLen >= 20)) {
uint16_t srcPort = 0;
uint16_t dstPort = 0;
uint8_t proto = (reinterpret_cast<const uint8_t *>(frameData)[9]);
const unsigned int headerLen = 4 * (reinterpret_cast<const uint8_t *>(frameData)[0] & 0xf);
switch(proto) {
case 0x01: // ICMP
//flowId = 0x01;
break;
// All these start with 16-bit source and destination port in that order
case 0x06: // TCP
case 0x11: // UDP
case 0x84: // SCTP
case 0x88: // UDPLite
if (frameLen > (headerLen + 4)) {
unsigned int pos = headerLen + 0;
srcPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
srcPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
pos++;
dstPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
dstPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
_flowId = dstPort ^ srcPort ^ proto;
}
break;
}
if (size() > ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD) {
const unsigned int etherType = at<uint16_t>(ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE);
const unsigned int frameLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
const uint8_t *const frameData = reinterpret_cast<const uint8_t *>(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
if (etherType == ZT_ETHERTYPE_IPV4 && (frameLen >= 20)) {
uint16_t srcPort = 0;
uint16_t dstPort = 0;
uint8_t proto = (reinterpret_cast<const uint8_t *>(frameData)[9]);
const unsigned int headerLen = 4 * (reinterpret_cast<const uint8_t *>(frameData)[0] & 0xf);
switch(proto) {
case 0x01: // ICMP
//flowId = 0x01;
break;
// All these start with 16-bit source and destination port in that order
case 0x06: // TCP
case 0x11: // UDP
case 0x84: // SCTP
case 0x88: // UDPLite
if (frameLen > (headerLen + 4)) {
unsigned int pos = headerLen + 0;
srcPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
srcPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
pos++;
dstPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
dstPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
_flowId = dstPort ^ srcPort ^ proto;
}
break;
}
}
if (etherType == ZT_ETHERTYPE_IPV6 && (frameLen >= 40)) {
uint16_t srcPort = 0;
uint16_t dstPort = 0;
unsigned int pos;
unsigned int proto;
_ipv6GetPayload((const uint8_t *)frameData, frameLen, pos, proto);
switch(proto) {
case 0x3A: // ICMPv6
//flowId = 0x3A;
break;
// All these start with 16-bit source and destination port in that order
case 0x06: // TCP
case 0x11: // UDP
case 0x84: // SCTP
case 0x88: // UDPLite
if (frameLen > (pos + 4)) {
srcPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
srcPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
pos++;
dstPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
dstPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
_flowId = dstPort ^ srcPort ^ proto;
}
break;
default:
break;
}
if (etherType == ZT_ETHERTYPE_IPV6 && (frameLen >= 40)) {
uint16_t srcPort = 0;
uint16_t dstPort = 0;
unsigned int pos;
unsigned int proto;
_ipv6GetPayload((const uint8_t *)frameData, frameLen, pos, proto);
switch(proto) {
case 0x3A: // ICMPv6
//flowId = 0x3A;
break;
// All these start with 16-bit source and destination port in that order
case 0x06: // TCP
case 0x11: // UDP
case 0x84: // SCTP
case 0x88: // UDPLite
if (frameLen > (pos + 4)) {
srcPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
srcPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
pos++;
dstPort = (reinterpret_cast<const uint8_t *>(frameData)[pos++]) << 8;
dstPort |= (reinterpret_cast<const uint8_t *>(frameData)[pos]);
_flowId = dstPort ^ srcPort ^ proto;
}
break;
default:
break;
}
}
}
@@ -869,7 +868,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar
const unsigned int frameLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
const uint8_t *const frameData = reinterpret_cast<const uint8_t *>(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
if (network->filterIncomingPacket(tPtr,peer,RR->identity.address(),sourceMac,network->mac(),frameData,frameLen,etherType,0) > 0) {
RR->node->putFrame(tPtr,nwid,network->userPtr(),sourceMac,network->mac(),etherType,0,(const void *)frameData,frameLen);
RR->pm->putFrame(tPtr,nwid,network->userPtr(),sourceMac,network->mac(),etherType,0,(const void *)frameData,frameLen, _flowId);
}
}
} else {
@@ -942,7 +941,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const
}
// fall through -- 2 means accept regardless of bridging checks or other restrictions
case 2:
RR->node->putFrame(tPtr,nwid,network->userPtr(),from,to,etherType,0,(const void *)frameData,frameLen);
RR->pm->putFrame(tPtr,nwid,network->userPtr(),from,to,etherType,0,(const void *)frameData,frameLen, flowId);
break;
}
}
+1
View File
@@ -1313,6 +1313,7 @@ void Network::requestConfiguration(void *tPtr)
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS);
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_OS_ARCH,ZT_TARGET_NAME);
RR->t->networkConfigRequestSent(tPtr,*this,ctrl);
+3 -1
View File
@@ -105,6 +105,8 @@ namespace ZeroTier {
// Network config version
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION "v"
// Network config version
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_OS_ARCH "o"
// Protocol version (see Packet.hpp)
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION "pv"
// Software vendor
@@ -687,7 +689,7 @@ public:
/**
* Time current authentication expires or 0 if external authentication is disabled
*
*
* Not used if authVersion >= 1
*/
uint64_t authenticationExpiryTime;
+17 -2
View File
@@ -35,6 +35,7 @@
#include "Network.hpp"
#include "Trace.hpp"
#include "Metrics.hpp"
#include "PacketMultiplexer.hpp"
// FIXME: remove this suppression and actually fix warnings
#ifdef __GNUC__
@@ -119,9 +120,10 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
const unsigned long mcs = sizeof(Multicaster) + (((sizeof(Multicaster) & 0xf) != 0) ? (16 - (sizeof(Multicaster) & 0xf)) : 0);
const unsigned long topologys = sizeof(Topology) + (((sizeof(Topology) & 0xf) != 0) ? (16 - (sizeof(Topology) & 0xf)) : 0);
const unsigned long sas = sizeof(SelfAwareness) + (((sizeof(SelfAwareness) & 0xf) != 0) ? (16 - (sizeof(SelfAwareness) & 0xf)) : 0);
const unsigned long bc = sizeof(Bond) + (((sizeof(Bond) & 0xf) != 0) ? (16 - (sizeof(Bond) & 0xf)) : 0);
const unsigned long bcs = sizeof(Bond) + (((sizeof(Bond) & 0xf) != 0) ? (16 - (sizeof(Bond) & 0xf)) : 0);
const unsigned long pms = sizeof(PacketMultiplexer) + (((sizeof(PacketMultiplexer) & 0xf) != 0) ? (16 - (sizeof(PacketMultiplexer) & 0xf)) : 0);
m = reinterpret_cast<char *>(::malloc(16 + ts + sws + mcs + topologys + sas + bc));
m = reinterpret_cast<char *>(::malloc(16 + ts + sws + mcs + topologys + sas + bcs + pms));
if (!m) {
throw std::bad_alloc();
}
@@ -141,6 +143,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
RR->sa = new (m) SelfAwareness(RR);
m += sas;
RR->bc = new (m) Bond(RR);
m += bcs;
RR->pm = new (m) PacketMultiplexer(RR);
} catch ( ... ) {
if (RR->sa) {
RR->sa->~SelfAwareness();
@@ -160,6 +164,9 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
if (RR->bc) {
RR->bc->~Bond();
}
if (RR->pm) {
RR->pm->~PacketMultiplexer();
}
::free(m);
throw;
}
@@ -191,6 +198,9 @@ Node::~Node()
if (RR->bc) {
RR->bc->~Bond();
}
if (RR->pm) {
RR->pm->~PacketMultiplexer();
}
::free(RR->rtmem);
}
@@ -230,6 +240,11 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
}
}
void Node::initMultithreading(unsigned int concurrency, bool cpuPinningEnabled)
{
RR->pm->setUpPostDecodeReceiveThreads(concurrency, cpuPinningEnabled);
}
// Closure used to ping upstream and active/online peers
class _PingPeersThatNeedPing
{
+4 -1
View File
@@ -283,7 +283,10 @@ public:
return _lowBandwidthMode;
}
private:
void initMultithreading(unsigned int concurrency, bool cpuPinningEnabled);
public:
RuntimeEnvironment _RR;
RuntimeEnvironment *RR;
void *_uPtr; // _uptr (lower case) is reserved in Visual Studio :P
+122
View File
@@ -0,0 +1,122 @@
/*
* Copyright (c)2013-2021 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2026-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
#include "PacketMultiplexer.hpp"
#include "Node.hpp"
#include "RuntimeEnvironment.hpp"
#include "Constants.hpp"
#include <stdio.h>
#include <stdlib.h>
namespace ZeroTier {
PacketMultiplexer::PacketMultiplexer(const RuntimeEnvironment* renv)
{
RR = renv;
};
void PacketMultiplexer::putFrame(void* tPtr, uint64_t nwid, void** nuptr, const MAC& source, const MAC& dest, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len, unsigned int flowId)
{
#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__WINDOWS__)
RR->node->putFrame(tPtr,nwid,nuptr,source,dest,etherType,vlanId,(const void *)data,len);
return;
#endif
if (!_enabled) {
RR->node->putFrame(tPtr,nwid,nuptr,source,dest,etherType,vlanId,(const void *)data,len);
return;
}
PacketRecord* packet;
_rxPacketVector_m.lock();
if (_rxPacketVector.empty()) {
packet = new PacketRecord;
}
else {
packet = _rxPacketVector.back();
_rxPacketVector.pop_back();
}
_rxPacketVector_m.unlock();
packet->tPtr = tPtr;
packet->nwid = nwid;
packet->nuptr = nuptr;
packet->source = source.toInt();
packet->dest = dest.toInt();
packet->etherType = etherType;
packet->vlanId = vlanId;
packet->len = len;
packet->flowId = flowId;
memcpy(packet->data, data, len);
int bucket = flowId % _concurrency;
_rxPacketQueues[bucket]->postLimit(packet, 2048);
}
void PacketMultiplexer::setUpPostDecodeReceiveThreads(unsigned int concurrency, bool cpuPinningEnabled)
{
#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__WINDOWS__)
return;
#endif
_enabled = true;
_concurrency = concurrency;
bool _enablePinning = cpuPinningEnabled;
for (unsigned int i = 0; i < _concurrency; ++i) {
fprintf(stderr, "Reserved queue for thread %d\n", i);
_rxPacketQueues.push_back(new BlockingQueue<PacketRecord*>());
}
// Each thread picks from its own queue to feed into the core
for (unsigned int i = 0; i < _concurrency; ++i) {
_rxThreads.push_back(std::thread([this, i, _enablePinning]() {
fprintf(stderr, "Created post-decode packet ingestion thread %d\n", i);
PacketRecord* packet = nullptr;
for (;;) {
if (! _rxPacketQueues[i]->get(packet)) {
break;
}
if (! packet) {
break;
}
// fprintf(stderr, "popped packet from queue %d\n", i);
MAC sourceMac = MAC(packet->source);
MAC destMac = MAC(packet->dest);
RR->node->putFrame(packet->tPtr, packet->nwid, packet->nuptr, sourceMac, destMac, packet->etherType, 0, (const void*)packet->data, packet->len);
{
Mutex::Lock l(_rxPacketVector_m);
_rxPacketVector.push_back(packet);
}
/*
if (ZT_ResultCode_isFatal(err)) {
char tmp[256];
OSUtils::ztsnprintf(tmp, sizeof(tmp), "error processing packet: %d", (int)err);
Mutex::Lock _l(_termReason_m);
_termReason = ONE_UNRECOVERABLE_ERROR;
_fatalErrorMessage = tmp;
this->terminate();
break;
}
*/
}
}));
}
}
} // namespace ZeroTier
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (c)2013-2021 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2026-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
#ifndef ZT_PACKET_MULTIPLEXER_HPP
#define ZT_PACKET_MULTIPLEXER_HPP
#include "../osdep/BlockingQueue.hpp"
#include "MAC.hpp"
#include "Mutex.hpp"
#include "RuntimeEnvironment.hpp"
#include <thread>
#include <vector>
namespace ZeroTier {
struct PacketRecord {
void* tPtr;
uint64_t nwid;
void** nuptr;
uint64_t source;
uint64_t dest;
unsigned int etherType;
unsigned int vlanId;
uint8_t data[ZT_MAX_MTU];
unsigned int len;
unsigned int flowId;
};
class PacketMultiplexer {
public:
const RuntimeEnvironment* RR;
PacketMultiplexer(const RuntimeEnvironment* renv);
void setUpPostDecodeReceiveThreads(unsigned int concurrency, bool cpuPinningEnabled);
void putFrame(void* tPtr, uint64_t nwid, void** nuptr, const MAC& source, const MAC& dest, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len, unsigned int flowId);
std::vector<BlockingQueue<PacketRecord*>*> _rxPacketQueues;
unsigned int _concurrency;
// pool
std::vector<PacketRecord*> _rxPacketVector;
std::vector<std::thread> _rxPacketThreads;
Mutex _rxPacketVector_m, _rxPacketThreads_m;
std::vector<std::thread> _rxThreads;
unsigned int _rxThreadCount;
bool _enabled;
};
} // namespace ZeroTier
#endif // ZT_PACKET_MULTIPLEXER_HPP
Loaded 20 of 39 files, more files were not shown because too many files have changed in this diff. Show more