This commit is contained in:
Joseph Henry 2020-11-19 14:39:40 -08:00
commit 24162fd490
10 changed files with 183 additions and 125 deletions

View file

@ -1,6 +1,28 @@
ZeroTier Release Notes ZeroTier Release Notes
====== ======
# 2020-11-19 -- Version 1.6.0
Version 1.6.0 is a major release that incorporates back-ported features from the 2.0 branch, which is still under development. It also fixes a number of issues.
New features and improvements (including those listed under 1.5.0):
* **Apple Silicon** (MacOS ARM64) native support via universal binary. ZeroTier now requires the very latest Xcode to build.
* **Linux performance improvements** for up to 25% faster tun/tap I/O performance on multi-core systems.
* **Multipath support** with modes modeled after the Linux kernel's bonding driver. This includes active-passive and active-active modes with fast failover and load balancing. See section 2.1.5 of the manual.
* **DNS configuration** push from network controllers to end nodes, with locally configurable permissions for whether or not push is allowed.
* **AES-GMAC-SIV** encryption mode, which is both somewhat more secure and significantly faster than the old Salsa20/12-Poly1305 mode on hardware that supports AES acceleration. This includes virtually all X86-64 chips and most ARM64. This mode is based on AES-SIV and has been audited by Trail of Bits to ensure that it is equivalent security-wise.
Bug fixes:
* **Managed route assignment fixes** to eliminate missing routes on Linux and what we believe to be the source of sporadic high CPU usage on MacOS.
* **Hang on shutdown** issues should be fixed.
* **Sporadic multicast outages** should be fixed.
Known remaining issues:
* AES hardware acceleration is not yet supported on 32-bit ARM, PowerPC (32 or 64), or MIPS (32 or 64) systems. Currently supported are X86-64 and ARM64/AARCH64 with crypto extensions.
# 2020-10-05 -- Version 1.5.0 (actually 1.6.0-beta1) # 2020-10-05 -- Version 1.5.0 (actually 1.6.0-beta1)
Version 1.6.0 (1.5.0 is a beta!) is a significant release that incorporates a number of back-ported fixes and features from the ZeroTier 2.0 tree. Version 1.6.0 (1.5.0 is a beta!) is a significant release that incorporates a number of back-ported fixes and features from the ZeroTier 2.0 tree.

6
debian/changelog vendored
View file

@ -1,3 +1,9 @@
zerotier-one (1.6.0) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Thu, 19 Nov 2020 01:00:00 -0700
zerotier-one (1.5.0) unstable; urgency=medium zerotier-one (1.5.0) unstable; urgency=medium
* Version 1.5.0 is actually 1.6.0-beta1 * Version 1.5.0 is actually 1.6.0-beta1

View file

@ -689,7 +689,7 @@
<key>USE_HFS+_COMPRESSION</key> <key>USE_HFS+_COMPRESSION</key>
<false/> <false/>
<key>VERSION</key> <key>VERSION</key>
<string>1.5.0</string> <string>1.6.0</string>
</dict> </dict>
<key>TYPE</key> <key>TYPE</key>
<integer>0</integer> <integer>0</integer>

View file

@ -3,7 +3,7 @@ CXX=clang++
INCLUDES= INCLUDES=
DEFS= DEFS=
LIBS= LIBS=
ARCH_FLAGS=-msse -msse2 -arch x86_64 -arch arm64e ARCH_FLAGS=-msse -msse2 -arch x86_64 -arch arm64
CODESIGN=echo CODESIGN=echo
PRODUCTSIGN=echo PRODUCTSIGN=echo
@ -67,6 +67,7 @@ endif
# Debug mode -- dump trace output, build binary with -g # Debug mode -- dump trace output, build binary with -g
ifeq ($(ZT_DEBUG),1) ifeq ($(ZT_DEBUG),1)
ZT_TRACE=1 ZT_TRACE=1
ARCH_FLAGS=
CFLAGS+=-Wall -g $(INCLUDES) $(DEFS) $(ARCH_FLAGS) CFLAGS+=-Wall -g $(INCLUDES) $(DEFS) $(ARCH_FLAGS)
STRIP=echo STRIP=echo
# The following line enables optimization for the crypto code, since # The following line enables optimization for the crypto code, since
@ -92,10 +93,10 @@ CXXFLAGS=$(CFLAGS) -std=c++11 -stdlib=libc++
all: one macui all: one macui
ext/x64-salsa2012-asm/salsa2012.o: ext/x64-salsa2012-asm/salsa2012.o:
as -o ext/x64-salsa2012-asm/salsa2012.o ext/x64-salsa2012-asm/salsa2012.s as -arch x86_64 -o ext/x64-salsa2012-asm/salsa2012.o ext/x64-salsa2012-asm/salsa2012.s
mac-agent: FORCE mac-agent: FORCE
$(CC) -Ofast -o MacEthernetTapAgent osdep/MacEthernetTapAgent.c $(CC) -Ofast $(ARCH_FLAGS) -o MacEthernetTapAgent osdep/MacEthernetTapAgent.c
$(CODESIGN) -f --options=runtime -s $(CODESIGN_APP_CERT) MacEthernetTapAgent $(CODESIGN) -f --options=runtime -s $(CODESIGN_APP_CERT) MacEthernetTapAgent
osdep/MacDNSHelper.o: osdep/MacDNSHelper.mm osdep/MacDNSHelper.o: osdep/MacDNSHelper.mm

View file

@ -96,6 +96,35 @@ std::shared_ptr<EthernetTap> EthernetTap::newInstance(
#endif // __LINUX__ #endif // __LINUX__
#ifdef __WINDOWS__ #ifdef __WINDOWS__
HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
throw std::runtime_error("WinEthernetTap: COM initialization failed");
}
static bool _comInit = false;
static Mutex _comInit_m;
{
Mutex::Lock l(_comInit_m);
if (!_comInit) {
hres = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
if (FAILED(hres)) {
CoUninitialize();
throw std::runtime_error("WinEthernetTap: Failed to initialize security");
}
_comInit = true;
}
}
return std::shared_ptr<EthernetTap>(new WindowsEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg)); return std::shared_ptr<EthernetTap>(new WindowsEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
#endif // __WINDOWS__ #endif // __WINDOWS__

View file

@ -184,12 +184,14 @@ LinuxEthernetTap::LinuxEthernetTap(
(void)::pipe(_shutdownSignalPipe); (void)::pipe(_shutdownSignalPipe);
_tapReaderThread = std::thread([this]{ for(unsigned int t=0;t<2;++t) {
_tapReaderThread[t] = std::thread([this, t]{
fd_set readfds,nullfds; fd_set readfds,nullfds;
int n,nfds,r; int n,nfds,r;
void *buf = nullptr; void *buf = nullptr;
std::vector<void *> buffers;
{ if (t == 0) {
struct ifreq ifr; struct ifreq ifr;
memset(&ifr,0,sizeof(ifr)); memset(&ifr,0,sizeof(ifr));
strcpy(ifr.ifr_name,_dev.c_str()); strcpy(ifr.ifr_name,_dev.c_str());
@ -234,6 +236,8 @@ LinuxEthernetTap::LinuxEthernetTap(
fcntl(_fd,F_SETFL,O_NONBLOCK); fcntl(_fd,F_SETFL,O_NONBLOCK);
::close(sock); ::close(sock);
} else {
usleep(1500000);
} }
FD_ZERO(&readfds); FD_ZERO(&readfds);
@ -252,14 +256,20 @@ LinuxEthernetTap::LinuxEthernetTap(
if (FD_ISSET(_fd,&readfds)) { if (FD_ISSET(_fd,&readfds)) {
for(;;) { // read until there are no more packets, then return to outer select() loop for(;;) { // read until there are no more packets, then return to outer select() loop
if (!buf) { if (!buf) {
// To reduce use of the mutex, we keep a local buffer vector and
// swap (which is a pointer swap) with the global one when it's
// empty. This retrieves a batch of buffers to use.
if (buffers.empty()) {
std::lock_guard<std::mutex> l(_buffers_l); std::lock_guard<std::mutex> l(_buffers_l);
if (_buffers.empty()) { buffers.swap(_buffers);
}
if (buffers.empty()) {
buf = malloc(ZT_TAP_BUF_SIZE); buf = malloc(ZT_TAP_BUF_SIZE);
if (!buf) if (!buf)
break; break;
} else { } else {
buf = _buffers.back(); buf = buffers.back();
_buffers.pop_back(); buffers.pop_back();
} }
} }
@ -289,6 +299,7 @@ LinuxEthernetTap::LinuxEthernetTap(
} }
} }
}); });
}
_tapProcessorThread = std::thread([this] { _tapProcessorThread = std::thread([this] {
MAC to,from; MAC to,from;
@ -302,7 +313,9 @@ LinuxEthernetTap::LinuxEthernetTap(
_handler(_arg, nullptr, _nwid, from, to, etherType, 0, (const void *)(b + 14),(unsigned int)(qi.second - 14)); _handler(_arg, nullptr, _nwid, from, to, etherType, 0, (const void *)(b + 14),(unsigned int)(qi.second - 14));
{ {
std::lock_guard<std::mutex> l(_buffers_l); std::lock_guard<std::mutex> l(_buffers_l);
if (_buffers.size() < 128)
_buffers.push_back(qi.first); _buffers.push_back(qi.first);
else free(qi.first);
} }
} else break; } else break;
} }
@ -311,14 +324,15 @@ LinuxEthernetTap::LinuxEthernetTap(
LinuxEthernetTap::~LinuxEthernetTap() LinuxEthernetTap::~LinuxEthernetTap()
{ {
(void)::write(_shutdownSignalPipe[1],"\0",1); // causes reader thread to exit (void)::write(_shutdownSignalPipe[1],"\0",1); // causes reader thread(s) to exit
_tapq.post(std::pair<void *,int>(nullptr,0)); // causes processor thread to exit _tapq.post(std::pair<void *,int>(nullptr,0)); // causes processor thread to exit
::close(_fd); ::close(_fd);
::close(_shutdownSignalPipe[0]); ::close(_shutdownSignalPipe[0]);
::close(_shutdownSignalPipe[1]); ::close(_shutdownSignalPipe[1]);
_tapReaderThread.join(); _tapReaderThread[0].join();
_tapReaderThread[1].join();
_tapProcessorThread.join(); _tapProcessorThread.join();
for(std::vector<void *>::iterator i(_buffers.begin());i!=_buffers.end();++i) for(std::vector<void *>::iterator i(_buffers.begin());i!=_buffers.end();++i)

View file

@ -70,7 +70,7 @@ private:
int _fd; int _fd;
int _shutdownSignalPipe[2]; int _shutdownSignalPipe[2];
std::atomic_bool _enabled; std::atomic_bool _enabled;
std::thread _tapReaderThread; std::thread _tapReaderThread[2];
std::thread _tapProcessorThread; std::thread _tapProcessorThread;
std::mutex _buffers_l; std::mutex _buffers_l;
std::vector<void *> _buffers; std::vector<void *> _buffers;

View file

@ -474,29 +474,6 @@ WindowsEthernetTap::WindowsEthernetTap(
char data[1024]; char data[1024];
char tag[24]; char tag[24];
// Initialize COM
HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
throw std::runtime_error("WinEthernetTap: COM initialization failed");
}
hres = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
if (FAILED(hres)) {
CoUninitialize();
throw std::runtime_error("WinEthernetTap: Failed to initialize security");
}
// We "tag" registry entries with the network ID to identify persistent devices // We "tag" registry entries with the network ID to identify persistent devices
OSUtils::ztsnprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid); OSUtils::ztsnprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid);
@ -671,7 +648,6 @@ WindowsEthernetTap::WindowsEthernetTap(
WindowsEthernetTap::~WindowsEthernetTap() WindowsEthernetTap::~WindowsEthernetTap()
{ {
WinDNSHelper::removeDNS(_nwid); WinDNSHelper::removeDNS(_nwid);
CoUninitialize();
_run = false; _run = false;
ReleaseSemaphore(_injectSemaphore,1,NULL); ReleaseSemaphore(_injectSemaphore,1,NULL);
Thread::join(_thread); Thread::join(_thread);
@ -970,6 +946,12 @@ NET_IFINDEX WindowsEthernetTap::interfaceIndex() const
void WindowsEthernetTap::threadMain() void WindowsEthernetTap::threadMain()
throw() throw()
{ {
HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
fprintf(stderr, "WinEthernetTap: COM initialization failed");
return;
}
char tapReadBuf[ZT_MAX_MTU + 32]; char tapReadBuf[ZT_MAX_MTU + 32];
char tapPath[128]; char tapPath[128];
HANDLE wait4[3]; HANDLE wait4[3];
@ -1188,6 +1170,7 @@ void WindowsEthernetTap::threadMain()
// We will restart and re-open the tap unless _run == false // We will restart and re-open the tap unless _run == false
} }
} catch ( ... ) {} // catch unexpected exceptions -- this should not happen but would prevent program crash or other weird issues since threads should not throw } catch ( ... ) {} // catch unexpected exceptions -- this should not happen but would prevent program crash or other weird issues since threads should not throw
CoUninitialize();
} }
NET_IFINDEX WindowsEthernetTap::_getDeviceIndex() NET_IFINDEX WindowsEthernetTap::_getDeviceIndex()

View file

@ -19,7 +19,7 @@
<Run Text="ZeroTier One"/> <Run Text="ZeroTier One"/>
</Paragraph> </Paragraph>
<Paragraph TextAlignment="Center"> <Paragraph TextAlignment="Center">
<Run FontSize="14" Text="Version 1.5.0 (1.6.0-beta1)"/> <Run FontSize="14" Text="Version 1.6.0"/>
<LineBreak/> <LineBreak/>
<Run FontSize="14" Text="(c) 2011-2020 ZeroTier, Inc."/> <Run FontSize="14" Text="(c) 2011-2020 ZeroTier, Inc."/>
<LineBreak/> <LineBreak/>

View file

@ -1,5 +1,5 @@
Name: zerotier-one Name: zerotier-one
Version: 1.5.0 Version: 1.6.0
Release: 1%{?dist} Release: 1%{?dist}
Summary: ZeroTier One network virtualization service Summary: ZeroTier One network virtualization service
@ -145,6 +145,9 @@ esac
%endif %endif
%changelog %changelog
* Thu Nov 19 2020 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.0-0.1
- see https://github.com/zerotier/ZeroTierOne for release notes
* Mon Oct 05 2020 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.0-beta1 * Mon Oct 05 2020 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.0-beta1
- see https://github.com/zerotier/ZeroTierOne for release notes - see https://github.com/zerotier/ZeroTierOne for release notes