Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
# | SYSTEM DISCOVERY AND CONFIGURATION |
# -----------------------------------------------------------------------------

apply_zerotierone_patches()
{
local p
shopt -s nullglob
for p in patches/zerotierone/*.patch; do
if git -C ext/ZeroTierOne apply --check "$p" >/dev/null 2>&1; then
echo "Applying $p"
git -C ext/ZeroTierOne apply "$p" || exit 1
fi
done
}

check_submodules()
{
if [ "$(ls -A ext/lwip)" ] && [ "$(ls -A ext/lwip-contrib)" ] && [ "$(ls -A ext/ZeroTierOne)" ]; then
Expand All @@ -12,6 +24,7 @@ check_submodules()
echo "Submodules seem to be missing. Please run: git submodule update --init"
exit 1
fi
apply_zerotierone_patches
}

CLANG_FORMAT=clang-format-11
Expand Down
21 changes: 21 additions & 0 deletions patches/zerotierone/0001-phy-dtor-skip-close-handlers.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
From: ZerotierB
Subject: Phy dtor must not invoke socket handlers

~Phy() runs during ~NodeService after later members (_tcpConnections_m)
are already destroyed. close(..., true) calls phyOnTcpClose which locks
that mutex → FORTIFY SIGABRT (PROXY→VPN swap). Binder already closes
UDP/listen sockets with callHandlers=false; leftover TCP must match.

diff --git a/osdep/Phy.hpp b/osdep/Phy.hpp
index 456238a89..93796448b 100644
--- a/osdep/Phy.hpp
+++ b/osdep/Phy.hpp
@@ -220,7 +220,7 @@ public:
{
for(typename std::list<PhySocketImpl>::const_iterator s(_socks.begin());s!=_socks.end();++s) {
if (s->type != ZT_PHY_SOCKET_CLOSED)
- this->close((PhySocket *)&(*s),true);
+ this->close((PhySocket *)&(*s),false);
}
ZT_PHY_CLOSE_SOCKET(_whackReceiveSocket);
ZT_PHY_CLOSE_SOCKET(_whackSendSocket);
54 changes: 45 additions & 9 deletions src/Controls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "VirtualTap.hpp"

#include <string.h>
#ifndef __WINDOWS__
#include <pthread.h>
#endif

using namespace ZeroTier;

Expand Down Expand Up @@ -54,6 +57,19 @@ Events* zts_events;
extern Mutex events_m;
Mutex service_m;

#if !defined(__WINDOWS__)
static pthread_t service_thread;
static volatile int service_thread_joinable = 0;

static void join_service_thread_if_running()
{
if (service_thread_joinable) {
pthread_join(service_thread, NULL);
service_thread_joinable = 0;
}
}
#endif

int init_subsystems()
{
/** Set up service and callback threads and tell them about one another.
Expand Down Expand Up @@ -588,8 +604,12 @@ int zts_node_start()
HANDLE serviceThread = CreateThread(NULL, 0, _runNodeService, (void*)NULL, 0, NULL);
// TODO: Check success
#else
pthread_t service_thread;
if ((res = pthread_create(&service_thread, NULL, _runNodeService, (void*)NULL)) != 0) {}
if ((res = pthread_create(&service_thread, NULL, _runNodeService, (void*)NULL)) != 0) {
service_thread_joinable = 0;
}
else {
service_thread_joinable = 1;
}
#endif
#if defined(__linux__)
// pthread_setname_np(service_thread, ZTS_SERVICE_THREAD_NAME);
Expand Down Expand Up @@ -621,9 +641,17 @@ int zts_node_get_port()

int zts_node_stop()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
{
Mutex::Lock _ls(service_m);
if (! zts_service || ! zts_service->isRunning()) {
return ZTS_ERR_SERVICE;
}
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
}
#if !defined(__WINDOWS__)
join_service_thread_if_running();
#endif
#if defined(__WINDOWS__)
WSACleanup();
#endif
Expand All @@ -632,10 +660,18 @@ int zts_node_stop()

int zts_node_free()
{
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
zts_events->setState(ZTS_STATE_FREE_CALLED);
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
{
Mutex::Lock _ls(service_m);
if (! zts_service || ! zts_service->isRunning()) {
return ZTS_ERR_SERVICE;
}
zts_events->setState(ZTS_STATE_FREE_CALLED);
zts_events->clrState(ZTS_STATE_NODE_RUNNING);
zts_service->terminate();
}
#if !defined(__WINDOWS__)
join_service_thread_if_running();
#endif
#if defined(__WINDOWS__)
WSACleanup();
#endif
Expand Down