Skip to content

Commit

Permalink
1.12.1 (#2112)
Browse files Browse the repository at this point in the history
* Fix primary port binding issue in 1.12 (#2107)

* Add test for primary port bindings to validator - See #2105

* Add delay to binding test

* Remove TCP binding logic from Binder to fix #2105

* add second control plane socket for ipv6

* fix controller network post endpoint

* exit if we can't bind at least one of IPV4 or IPV6 for control plane port

---------

Co-authored-by: Grant Limberg <[email protected]>

* Version bump, Linux version stuff, Debian dependencies from 1.12.0 rebuild, release notes.

* macOS version bump in installer

* Windows version bump.

---------

Co-authored-by: Joseph Henry <[email protected]>
Co-authored-by: Grant Limberg <[email protected]>
  • Loading branch information
3 people authored Aug 25, 2023
1 parent 0e5651f commit 464bca5
Show file tree
Hide file tree
Showing 15 changed files with 274 additions and 101 deletions.
42 changes: 39 additions & 3 deletions .github/workflows/validate-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ mkdir $TEST_DIR_PREFIX
# How long we will wait for ZT to come online before considering it a failure
MAX_WAIT_SECS=30

ZT_PORT_NODE_1=9996
ZT_PORT_NODE_2=9997

################################################################################
# Multi-node connectivity and performance test #
################################################################################
Expand Down Expand Up @@ -99,14 +102,19 @@ test() {
--xml=yes \
--xml-file=$FILENAME_MEMORY_LOG \
--leak-check=full \
./zerotier-one node1 -p9996 -U >>node_1.log 2>&1 &
./zerotier-one node1 -p$ZT_PORT_NODE_1 -U >>node_1.log 2>&1 &

# Second instance, not run in memory profiler
# Don't set up internet access until _after_ zerotier is running
# This has been a source of stuckness in the past.
$NS2 ip addr del 192.168.1.2/24 dev veth3
$NS2 sudo ./zerotier-one node2 -U -p9997 >>node_2.log 2>&1 &
sleep 1;
$NS2 sudo ./zerotier-one node2 -U -p$ZT_PORT_NODE_2 >>node_2.log 2>&1 &

sleep 10; # New HTTP control plane is a bit sluggish, so we delay here

check_bind_to_correct_ports $ZT_PORT_NODE_1
check_bind_to_correct_ports $ZT_PORT_NODE_2

$NS2 ip addr add 192.168.1.2/24 dev veth3
$NS2 ip route add default via 192.168.1.1

Expand Down Expand Up @@ -458,4 +466,32 @@ check_exit_on_invalid_identity() {
fi
}

################################################################################
# Check that we're binding to the primary port for TCP/TCP6/UDP #
################################################################################

check_bind_to_correct_ports() {
PORT_NUMBER=$1
echo "Checking bound ports:"
sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier"
if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "tcp") ]];
then
:
else
exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to tcp/$1"
fi
if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "tcp6") ]];
then
:
else
exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to tcp6/$1"
fi
if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "udp") ]];
then
:
else
exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to udp/$1"
fi
}

test "$@"
6 changes: 6 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
ZeroTier Release Notes
======

# 2023-08-25 -- Version 1.12.1

* Minor release to fix a port binding issue in Linux.
* Update Debian dependencies.
* No changes for other platforms.

# 2023-08-23 -- Version 1.12.0

* Experimental Windows ARM64 support
Expand Down
74 changes: 56 additions & 18 deletions controller/EmbeddedNetworkController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,9 +863,17 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ

void EmbeddedNetworkController::configureHTTPControlPlane(
httplib::Server &s,
httplib::Server &sv6,
const std::function<void(const httplib::Request&, httplib::Response&, std::string)> setContent)
{
s.Get("/controller/network", [&, setContent](const httplib::Request &req, httplib::Response &res) {
// Control plane Endpoints
std::string networkListPath = "/controller/network";
std::string networkPath = "/controller/network/([0-9a-fA-F]{16})";
std::string oldAndBustedNetworkCreatePath = "/controller/network/([0-9a-fA-F]{10})______";
std::string memberListPath = "/controller/network/([0-9a-fA-F]{16})/member";
std::string memberPath = "/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})";

auto networkListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) {
std::set<uint64_t> networkIds;
_db.networks(networkIds);
char tmp[64];
Expand All @@ -877,9 +885,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
}

setContent(req, res, out.dump());
});
};
s.Get(networkListPath, networkListGet);
sv6.Get(networkListPath, networkListGet);

s.Get("/controller/network/([0-9a-fA-F]{16})", [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkGet = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkID = req.matches[1];
uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str());
json network;
Expand All @@ -889,7 +899,9 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
}

setContent(req, res, network.dump());
});
};
s.Get(networkPath, networkGet);
sv6.Get(networkPath, networkGet);

auto createNewNetwork = [&, setContent](const httplib::Request &req, httplib::Response &res) {
fprintf(stderr, "creating new network (new style)\n");
Expand All @@ -912,8 +924,10 @@ void EmbeddedNetworkController::configureHTTPControlPlane(

setContent(req, res, networkUpdateFromPostData(nwid, req.body));
};
s.Put("/controller/network", createNewNetwork);
s.Post("/controller/network", createNewNetwork);
s.Put(networkListPath, createNewNetwork);
s.Post(networkListPath, createNewNetwork);
sv6.Put(networkListPath, createNewNetwork);
sv6.Post(networkListPath, createNewNetwork);

auto createNewNetworkOldAndBusted = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto inID = req.matches[1].str();
Expand Down Expand Up @@ -941,10 +955,24 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
}
setContent(req, res, networkUpdateFromPostData(nwid, req.body));
};
s.Put("/controller/network/([0-9a-fA-F]{10})______", createNewNetworkOldAndBusted);
s.Post("/controller/network/([0-9a-fA-F]{10})______", createNewNetworkOldAndBusted);
s.Put(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted);
s.Post(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted);
sv6.Put(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted);
sv6.Post(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted);

auto networkPost = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkID = req.matches[1].str();
uint64_t nwid = Utils::hexStrToU64(networkID.c_str());

res.status = 200;
setContent(req, res, networkUpdateFromPostData(nwid, req.body));
};
s.Put(networkPath, networkPost);
s.Post(networkPath, networkPost);
sv6.Put(networkPath, networkPost);
sv6.Post(networkPath, networkPost);

s.Delete("/controller/network/([0-9a-fA-F]{16})", [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkID = req.matches[1].str();
uint64_t nwid = Utils::hexStrToU64(networkID.c_str());

Expand All @@ -956,9 +984,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane(

_db.eraseNetwork(nwid);
setContent(req, res, network.dump());
});
};
s.Delete(networkPath, networkDelete);
sv6.Delete(networkPath, networkDelete);

s.Get("/controller/network/([0-9a-fA-F]{16})/member", [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto memberListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkID = req.matches[1];
uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str());
json network;
Expand All @@ -982,9 +1012,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
}

setContent(req, res, out.dump());
});
};
s.Get(memberListPath, memberListGet);
sv6.Get(memberListPath, memberListGet);

s.Get("/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})", [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto memberGet = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkID = req.matches[1];
auto memberID = req.matches[2];
uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str());
Expand All @@ -997,7 +1029,9 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
}

setContent(req, res, member.dump());
});
};
s.Get(memberPath, memberGet);
sv6.Get(memberPath, memberGet);

auto memberPost = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkID = req.matches[1].str();
Expand Down Expand Up @@ -1102,10 +1136,12 @@ void EmbeddedNetworkController::configureHTTPControlPlane(

setContent(req, res, member.dump());
};
s.Put("/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})", memberPost);
s.Post("/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})", memberPost);
s.Put(memberPath, memberPost);
s.Post(memberPath, memberPost);
sv6.Put(memberPath, memberPost);
sv6.Post(memberPath, memberPost);

s.Delete("/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})", [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto memberDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) {
auto networkID = req.matches[1].str();
auto memberID = req.matches[2].str();

Expand All @@ -1126,7 +1162,9 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
_db.eraseMember(nwid, address);

setContent(req, res, member.dump());
});
};
s.Delete(memberPath, memberDelete);
sv6.Delete(memberPath, memberDelete);
}

void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt)
Expand Down
1 change: 1 addition & 0 deletions controller/EmbeddedNetworkController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class EmbeddedNetworkController : public NetworkController,public DB::ChangeList

void configureHTTPControlPlane(
httplib::Server &s,
httplib::Server &sV6,
const std::function<void(const httplib::Request&, httplib::Response&, std::string)>);

void handleRemoteTrace(const ZT_RemoteTrace &rt);
Expand Down
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
zerotier-one (1.12.1) unstable; urgency=medium

* See RELEASE-NOTES.md for release notes.

-- Adam Ierymenko <[email protected]> Fri, 25 Aug 2023 01:00:00 -0700

zerotier-one (1.12.0) unstable; urgency=medium

* See RELEASE-NOTES.md for release notes.
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Homepage: https://www.zerotier.com/

Package: zerotier-one
Architecture: any
Depends: iproute2, adduser, libstdc++6 (>= 5), openssl
Depends: adduser, libstdc++6 (>= 5), openssl
Homepage: https://www.zerotier.com/
Description: ZeroTier network virtualization service
ZeroTier One lets you join ZeroTier virtual networks and
Expand Down
2 changes: 1 addition & 1 deletion debian/control.wheezy
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Homepage: https://www.zerotier.com/

Package: zerotier-one
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, iproute, libstdc++6
Depends: ${shlibs:Depends}, ${misc:Depends}, libstdc++6
Homepage: https://www.zerotier.com/
Description: ZeroTier network virtualization service
ZeroTier One lets you join ZeroTier virtual networks and
Expand Down
Empty file modified debian/rules
100755 → 100644
Empty file.
Empty file modified debian/rules.wheezy
100755 → 100644
Empty file.
2 changes: 1 addition & 1 deletion ext/installfiles/mac/ZeroTier One.pkgproj
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@
<key>USE_HFS+_COMPRESSION</key>
<false/>
<key>VERSION</key>
<string>1.12.0</string>
<string>1.12.1</string>
</dict>
<key>TYPE</key>
<integer>0</integer>
Expand Down
8 changes: 4 additions & 4 deletions ext/installfiles/windows/ZeroTier One.aip
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
<ROW Property="AiFeatIcoZeroTierOne" Value="ZeroTierIcon.exe" Type="8"/>
<ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
<ROW Property="Manufacturer" Value="ZeroTier, Inc."/>
<ROW Property="ProductCode" Value="1033:{B07D0036-6C23-4CFD-9F2A-F2C990225591} " Type="16"/>
<ROW Property="ProductCode" Value="1033:{22301716-32F1-4247-8167-3E5441A87A58} " Type="16"/>
<ROW Property="ProductLanguage" Value="1033"/>
<ROW Property="ProductName" Value="ZeroTier One"/>
<ROW Property="ProductVersion" Value="1.12.0" Options="32"/>
<ROW Property="ProductVersion" Value="1.12.1" Options="32"/>
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND;AI_SETUPEXEPATH;SETUPEXEDIR"/>
<ROW Property="UpgradeCode" Value="{B0E2A5F3-88B6-4E77-B922-CB4739B4C4C8}"/>
Expand Down Expand Up @@ -62,7 +62,7 @@
<ROW Directory="regid.201001.com.zerotier_Dir" Directory_Parent="CommonAppDataFolder" DefaultDir="REGID2~1.ZER|regid.2010-01.com.zerotier" DirectoryOptions="12"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
<ROW Component="AI_CustomARPName" ComponentId="{0C83327B-255D-4E69-A702-EC9414459A68}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
<ROW Component="AI_CustomARPName" ComponentId="{E391FCA4-D005-4309-A481-415FAEB15274}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
<ROW Component="AI_DisableModify" ComponentId="{46FFA8C5-A0CB-4E05-9AD3-911D543DE8CA}" Directory_="APPDIR" Attributes="4" KeyPath="NoModify" Options="1"/>
<ROW Component="AI_ExePath" ComponentId="{8E02B36C-7A19-429B-A93E-77A9261AC918}" Directory_="APPDIR" Attributes="4" KeyPath="AI_ExePath"/>
<ROW Component="APPDIR" ComponentId="{4DD7907D-D7FE-4CD6-B1A0-B5C1625F5133}" Directory_="APPDIR" Attributes="0"/>
Expand Down Expand Up @@ -498,7 +498,7 @@
<ROW XmlAttribute="xsischemaLocation" XmlElement="swidsoftware_identification_tag" Name="xsi:schemaLocation" Flags="14" Order="3" Value="http://standards.iso.org/iso/19770/-2/2008/schema.xsd software_identification_tag.xsd"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.XmlElementComponent">
<ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Condition="1" Order="2" Flags="14" Text="0" UpdateIndexInParent="0"/>
<ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Condition="1" Order="2" Flags="14" Text="1" UpdateIndexInParent="0"/>
<ROW XmlElement="swidentitlement_required_indicator" ParentElement="swidsoftware_identification_tag" Name="swid:entitlement_required_indicator" Condition="1" Order="0" Flags="14" Text="false" UpdateIndexInParent="0"/>
<ROW XmlElement="swidmajor" ParentElement="swidnumeric" Name="swid:major" Condition="1" Order="0" Flags="14" Text="1" UpdateIndexInParent="0"/>
<ROW XmlElement="swidminor" ParentElement="swidnumeric" Name="swid:minor" Condition="1" Order="1" Flags="14" Text="12" UpdateIndexInParent="0"/>
Expand Down
20 changes: 5 additions & 15 deletions osdep/Binder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,10 @@ namespace ZeroTier {
class Binder {
private:
struct _Binding {
_Binding() : udpSock((PhySocket*)0), tcpListenSock((PhySocket*)0)
_Binding() : udpSock((PhySocket*)0)
{
}
PhySocket* udpSock;
PhySocket* tcpListenSock;
InetAddress address;
char ifname[256] = {};
};
Expand All @@ -111,7 +110,6 @@ class Binder {
Mutex::Lock _l(_lock);
for (unsigned int b = 0, c = _bindingCount; b < c; ++b) {
phy.close(_bindings[b].udpSock, false);
phy.close(_bindings[b].tcpListenSock, false);
}
_bindingCount = 0;
}
Expand All @@ -133,7 +131,7 @@ class Binder {
template <typename PHY_HANDLER_TYPE, typename INTERFACE_CHECKER> void refresh(Phy<PHY_HANDLER_TYPE>& phy, unsigned int* ports, unsigned int portCount, const std::vector<InetAddress> explicitBind, INTERFACE_CHECKER& ifChecker)
{
std::map<InetAddress, std::string> localIfAddrs;
PhySocket *udps, *tcps;
PhySocket *udps;
Mutex::Lock _l(_lock);
bool interfacesEnumerated = true;

Expand Down Expand Up @@ -419,11 +417,8 @@ class Binder {
}
else {
PhySocket* const udps = _bindings[b].udpSock;
PhySocket* const tcps = _bindings[b].tcpListenSock;
_bindings[b].udpSock = (PhySocket*)0;
_bindings[b].tcpListenSock = (PhySocket*)0;
phy.close(udps, false);
phy.close(tcps, false);
}
}

Expand All @@ -437,32 +432,27 @@ class Binder {
}
if (bi == _bindingCount) {
udps = phy.udpBind(reinterpret_cast<const struct sockaddr*>(&(ii->first)), (void*)0, ZT_UDP_DESIRED_BUF_SIZE);
tcps = phy.tcpListen(reinterpret_cast<const struct sockaddr*>(&(ii->first)), (void*)0);
if ((udps) && (tcps)) {
if (udps) {
#ifdef __LINUX__
// Bind Linux sockets to their device so routes that we manage do not override physical routes (wish all platforms had this!)
if (ii->second.length() > 0) {
char tmp[256];
Utils::scopy(tmp, sizeof(tmp), ii->second.c_str());
int fd = (int)Phy<PHY_HANDLER_TYPE>::getDescriptor(udps);
if (fd >= 0)
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, strlen(tmp));
fd = (int)Phy<PHY_HANDLER_TYPE>::getDescriptor(tcps);
if (fd >= 0)
if (fd >= 0) {
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, strlen(tmp));
}
}
#endif // __LINUX__
if (_bindingCount < ZT_BINDER_MAX_BINDINGS) {
_bindings[_bindingCount].udpSock = udps;
_bindings[_bindingCount].tcpListenSock = tcps;
_bindings[_bindingCount].address = ii->first;
memcpy(_bindings[_bindingCount].ifname, (char*)ii->second.c_str(), (int)ii->second.length());
++_bindingCount;
}
}
else {
phy.close(udps, false);
phy.close(tcps, false);
}
}
}
Expand Down
Loading

0 comments on commit 464bca5

Please sign in to comment.