From 1859365f9d3f4dcb29fd36fa5e4b42859a683199 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 27 May 2021 16:43:12 -0400 Subject: [PATCH 1/2] same IPv6 temp address detection code for macOS works on FreeBSD. update ifdefs & go --- osdep/Binder.hpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osdep/Binder.hpp b/osdep/Binder.hpp index 0316edb9d..bd515eaab 100644 --- a/osdep/Binder.hpp +++ b/osdep/Binder.hpp @@ -40,7 +40,7 @@ #endif #endif -#if defined(__APPLE__) && defined(TARGET_OS_MAC) +#if defined(__unix__) && !defined(__LINUX__) #include #include #include @@ -311,8 +311,7 @@ class Binder { if (! gotViaProc) { struct ifaddrs* ifatbl = (struct ifaddrs*)0; struct ifaddrs* ifa; - -#if defined(__APPLE__) +#if defined(__unix__) && !defined(__LINUX__) // set up an IPv6 socket so we can check the state of interfaces via SIOCGIFAFLAG_IN6 int infoSock = socket(AF_INET6, SOCK_DGRAM, 0); #endif @@ -321,8 +320,8 @@ class Binder { while (ifa) { if ((ifa->ifa_name) && (ifa->ifa_addr)) { InetAddress ip = *(ifa->ifa_addr); -#if defined(__APPLE__) && defined(TARGET_OS_MAC) - // Check if the address is an IPv6 Temporary Address, macOS version +#if defined(__unix__) && !defined(__LINUX__) + // Check if the address is an IPv6 Temporary Address, macOS/BSD version if (ifa->ifa_addr->sa_family == AF_INET6) { struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ifa->ifa_addr; struct in6_ifreq ifr6; @@ -369,7 +368,7 @@ class Binder { else { interfacesEnumerated = false; } -#if defined(__APPLE__) +#if defined(__unix__) && !defined(__LINUX__) close(infoSock); #endif } From 4fed56443e47ae82b60b347d5614b8a122224320 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 27 May 2021 15:41:11 -0700 Subject: [PATCH 2/2] secondary ports are no longer based on the node ID and fully randomized instead --- service/OneService.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/service/OneService.cpp b/service/OneService.cpp index 5dfd04839..9067ffc17 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -725,15 +725,24 @@ public: OSUtils::ztsnprintf(portstr,sizeof(portstr),"%u",_ports[0]); OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S "zerotier-one.port").c_str(),std::string(portstr)); - // Attempt to bind to a secondary port chosen from our ZeroTier address. + // Attempt to bind to a secondary port. // This exists because there are buggy NATs out there that fail if more // than one device behind the same NAT tries to use the same internal // private address port number. Buggy NATs are a running theme. + // + // This used to pick the secondary port based on the node ID until we + // discovered another problem: buggy routers and malicious traffic + // "detection". A lot of routers have such things built in these days + // and mis-detect ZeroTier traffic as malicious and block it resulting + // in a node that appears to be in a coma. Secondary ports are now + // randomized on startup. if (_allowSecondaryPort) { if (_secondaryPort) { _ports[1] = _secondaryPort; } else { - _ports[1] = 20000 + ((unsigned int)_node->address() % 45500); + unsigned int randp = 0; + Utils::getSecureRandom(&randp,sizeof(randp)); + _ports[1] = 20000 + (randp % 45500); for(int i=0;;++i) { if (i > 1000) { _ports[1] = 0;