From 2810cd7c156393f62c36ae01ba8099766e8dc777 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sun, 17 May 2015 23:56:47 +0000 Subject: Build fixes for G++, building without SQLite3 present, and warning removal. --- node/InetAddress.cpp | 3 +-- node/Node.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'node') diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index 54fc763f..940a58b2 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -137,8 +137,7 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port) reinterpret_cast(this)->sin_port = Utils::hton((uint16_t)port); } else if (ipLen == 16) { ss_family = AF_INET6; - (reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr))[0] = ((const uint64_t *)ipBytes)[0]; - (reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr))[1] = ((const uint64_t *)ipBytes)[1]; + memcpy(reinterpret_cast(this)->sin6_addr.s6_addr,ipBytes,16); reinterpret_cast(this)->sin6_port = Utils::hton((uint16_t)port); } } diff --git a/node/Node.cpp b/node/Node.cpp index 654465e8..0e3ddd14 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -251,8 +251,10 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next if ((now - _lastBeacon) >= ZT_BEACON_INTERVAL) { _lastBeacon = now; char beacon[13]; - *(reinterpret_cast(beacon)) = RR->prng->next32(); - *(reinterpret_cast(beacon + 4)) = RR->prng->next32(); + void *p = beacon; + *(reinterpret_cast(p)) = RR->prng->next32(); + p = beacon + 4; + *(reinterpret_cast(p)) = RR->prng->next32(); RR->identity.address().copyTo(beacon + 8,5); RR->antiRec->logOutgoingZT(beacon,13); putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13,0); -- cgit v1.2.3 From 12130739166895db88dca0c230f3972bd3ac3d6a Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 20 May 2015 19:38:49 -0700 Subject: Apple auto-update stuff, now for Windows. --- attic/SoftwareUpdater.cpp | 328 --------------------------------------- attic/SoftwareUpdater.hpp | 186 ---------------------- ext/installfiles/mac/postinst.sh | 6 +- ext/installfiles/mac/preinst.sh | 22 ++- make-mac.mk | 4 + node/Node.cpp | 2 +- node/Peer.hpp | 25 --- node/Utils.hpp | 27 ++++ service/OneService.cpp | 180 ++++++++++++++++++++- updater.cpp | 177 --------------------- 10 files changed, 227 insertions(+), 730 deletions(-) delete mode 100644 attic/SoftwareUpdater.cpp delete mode 100644 attic/SoftwareUpdater.hpp delete mode 100644 updater.cpp (limited to 'node') diff --git a/attic/SoftwareUpdater.cpp b/attic/SoftwareUpdater.cpp deleted file mode 100644 index e3789bcb..00000000 --- a/attic/SoftwareUpdater.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#include -#include -#include - -#include - -#include "../version.h" - -#include "Constants.hpp" -#include "SoftwareUpdater.hpp" -#include "Dictionary.hpp" -#include "C25519.hpp" -#include "Identity.hpp" -#include "Logger.hpp" -#include "RuntimeEnvironment.hpp" -#include "Thread.hpp" -#include "Node.hpp" -#include "Utils.hpp" -#include "HttpClient.hpp" - -#ifdef __UNIX_LIKE__ -#include -#include -#include -#include -#endif - -namespace ZeroTier { - -static inline std::map< Address,Identity > _mkUpdateAuth() -{ - std::map< Address,Identity > ua; - - { // 0001 - Identity id("e9bc3707b5:0:c4cef17bde99eadf9748c4fd11b9b06dc5cd8eb429227811d2c336e6b96a8d329e8abd0a4f45e47fe1bcebf878c004c822d952ff77fc2833af4c74e65985c435"); - ua[id.address()] = id; - } - { // 0002 - Identity id("56520eaf93:0:7d858b47988b34399a9a31136de07b46104d7edb4a98fa1d6da3e583d3a33e48be531532b886f0b12cd16794a66ab9220749ec5112cbe96296b18fe0cc79ca05"); - ua[id.address()] = id; - } - { // 0003 - Identity id("7c195de2e0:0:9f659071c960f9b0f0b96f9f9ecdaa27c7295feed9c79b7db6eedcc11feb705e6dd85c70fa21655204d24c897865b99eb946b753a2bbcf2be5f5e006ae618c54"); - ua[id.address()] = id; - } - { // 0004 - Identity id("415f4cfde7:0:54118e87777b0ea5d922c10b337c4f4bd1db7141845bd54004b3255551a6e356ba6b9e1e85357dbfafc45630b8faa2ebf992f31479e9005f0472685f2d8cbd6e"); - ua[id.address()] = id; - } - - return ua; -} - -static inline const char *_mkUpdateUrl() -{ -#if defined(__LINUX__) && ( defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__i386) ) - if (sizeof(void *) == 8) - return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x64-LATEST.nfo"; - else return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x86-LATEST.nfo"; -#define GOT_UPDATE_URL -#endif - -#ifdef __APPLE__ - return "http://download.zerotier.com/ZeroTierOneInstaller-mac-combined-LATEST.nfo"; -#define GOT_UPDATE_URL -#endif - -#ifdef __WINDOWS__ - return "http://download.zerotier.com/ZeroTierOneInstaller-windows-intel-LATEST.nfo"; -#define GOT_UPDATE_URL -#endif - -#ifndef GOT_UPDATE_URL - return ""; -#endif -} - -SoftwareUpdater::SoftwareUpdater(const RuntimeEnvironment *renv) : - RR(renv), - _myVersion(packVersion(ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION)), - _lastUpdateAttempt(0), - _status(UPDATE_STATUS_IDLE), - _die(false), - _lock() -{ -} - -SoftwareUpdater::~SoftwareUpdater() -{ - _die = true; - for(;;) { - _lock.lock(); - bool ip = (_status != UPDATE_STATUS_IDLE); - _lock.unlock(); - if (ip) - Thread::sleep(500); - else break; - } -} - -void SoftwareUpdater::cleanOldUpdates() -{ - std::string updatesDir(RR->homePath + ZT_PATH_SEPARATOR_S + "updates.d"); - std::map dl(Utils::listDirectory(updatesDir.c_str())); - for(std::map::iterator i(dl.begin());i!=dl.end();++i) { - if (!i->second) - Utils::rm((updatesDir + ZT_PATH_SEPARATOR_S + i->first).c_str()); - } -} - -void SoftwareUpdater::sawRemoteVersion(unsigned int vmaj,unsigned int vmin,unsigned int rev) -{ - const uint64_t tmp = packVersion(vmaj,vmin,rev); - if (tmp > _myVersion) { - Mutex::Lock _l(_lock); - if ((_status == UPDATE_STATUS_IDLE)&&(!_die)&&(ZT_DEFAULTS.updateLatestNfoURL.length())) { - const uint64_t now = Utils::now(); - if ((now - _lastUpdateAttempt) >= ZT_UPDATE_MIN_INTERVAL) { - _lastUpdateAttempt = now; - _status = UPDATE_STATUS_GETTING_NFO; - RR->http->GET(ZT_DEFAULTS.updateLatestNfoURL,HttpClient::NO_HEADERS,ZT_UPDATE_HTTP_TIMEOUT,&_cbHandleGetLatestVersionInfo,this); - } - } - } -} - -void SoftwareUpdater::checkNow() -{ - Mutex::Lock _l(_lock); - if (_status == UPDATE_STATUS_IDLE) { - _lastUpdateAttempt = Utils::now(); - _status = UPDATE_STATUS_GETTING_NFO; - RR->http->GET(ZT_DEFAULTS.updateLatestNfoURL,HttpClient::NO_HEADERS,ZT_UPDATE_HTTP_TIMEOUT,&_cbHandleGetLatestVersionInfo,this); - } -} - -const char *SoftwareUpdater::parseNfo( - const char *nfoText, - unsigned int &vMajor, - unsigned int &vMinor, - unsigned int &vRevision, - Address &signedBy, - std::string &signature, - std::string &url) -{ - try { - Dictionary nfo(nfoText); - - vMajor = Utils::strToUInt(nfo.get("vMajor").c_str()); - vMinor = Utils::strToUInt(nfo.get("vMinor").c_str()); - vRevision = Utils::strToUInt(nfo.get("vRevision").c_str()); - signedBy = nfo.get("signedBy"); - signature = Utils::unhex(nfo.get("ed25519")); - url = nfo.get("url"); - - if (signature.length() != ZT_C25519_SIGNATURE_LEN) - return "bad ed25519 signature, invalid length"; - if ((url.length() <= 7)||(url.substr(0,7) != "http://")) - return "invalid URL, must begin with http://"; - - return (const char *)0; - } catch ( ... ) { - return "invalid NFO file format or one or more required fields missing"; - } -} - -bool SoftwareUpdater::validateUpdate( - const void *data, - unsigned int len, - const Address &signedBy, - const std::string &signature) -{ - std::map< Address,Identity >::const_iterator updateAuthority = ZT_DEFAULTS.updateAuthorities.find(signedBy); - if (updateAuthority == ZT_DEFAULTS.updateAuthorities.end()) - return false; - return updateAuthority->second.verify(data,len,signature.data(),(unsigned int)signature.length()); -} - -void SoftwareUpdater::_cbHandleGetLatestVersionInfo(void *arg,int code,const std::string &url,const std::string &body) -{ - SoftwareUpdater *upd = (SoftwareUpdater *)arg; - const RuntimeEnvironment *RR = (const RuntimeEnvironment *)upd->RR; - Mutex::Lock _l(upd->_lock); - - if ((upd->_die)||(upd->_status != UPDATE_STATUS_GETTING_NFO)) { - upd->_status = UPDATE_STATUS_IDLE; - return; - } - - if (code != 200) { - LOG("software update check failed: server responded with code %d",code); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - - try { - unsigned int vMajor = 0,vMinor = 0,vRevision = 0; - Address signedBy; - std::string signature,url; - - const char *err = parseNfo(body.c_str(),vMajor,vMinor,vRevision,signedBy,signature,url); - - if (err) { - LOG("software update check aborted: .nfo file parse error: %s",err); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - - if (!ZT_DEFAULTS.updateAuthorities.count(signedBy)) { - LOG("software update check aborted: .nfo file specifies unknown signing authority"); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - -#ifndef ZT_ALWAYS_UPDATE /* for testing */ - if (packVersion(vMajor,vMinor,vRevision) <= upd->_myVersion) { - TRACE("software update check complete: version on update site is not newer than my version, no update necessary"); - upd->_status = UPDATE_STATUS_IDLE; - return; - } -#endif - - upd->_status = UPDATE_STATUS_GETTING_FILE; - upd->_signedBy = signedBy; - upd->_signature = signature; - - RR->http->GET(url,HttpClient::NO_HEADERS,ZT_UPDATE_HTTP_TIMEOUT,&_cbHandleGetLatestVersionBinary,arg); - } catch ( ... ) { - LOG("software update check failed: .nfo file invalid or missing field(s)"); - upd->_status = UPDATE_STATUS_IDLE; - } -} - -void SoftwareUpdater::_cbHandleGetLatestVersionBinary(void *arg,int code,const std::string &url,const std::string &body) -{ - SoftwareUpdater *upd = (SoftwareUpdater *)arg; - const RuntimeEnvironment *RR = (const RuntimeEnvironment *)upd->RR; - Mutex::Lock _l(upd->_lock); - - if (!validateUpdate(body.data(),(unsigned int)body.length(),upd->_signedBy,upd->_signature)) { - LOG("software update failed: update fetched from '%s' failed signature check (image size: %u)",url.c_str(),(unsigned int)body.length()); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - - size_t lastSlash = url.rfind('/'); - if (lastSlash == std::string::npos) { // sanity check, shouldn't happen - LOG("software update failed: invalid URL"); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - std::string updatesDir(RR->homePath + ZT_PATH_SEPARATOR_S + "updates.d"); - std::string updateFilename(url.substr(lastSlash + 1)); - if ((updateFilename.length() < 3)||(updateFilename.find("..") != std::string::npos)) { - LOG("software update failed: invalid URL: filename contains invalid characters"); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - for(std::string::iterator c(updateFilename.begin());c!=updateFilename.end();++c) { - // Only allow a list of whitelisted characters to make up the filename to prevent any - // path shenanigans, esp on Windows where / is not the path separator. - if (!strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.0123456789",*c)) { - LOG("software update failed: invalid URL: filename contains invalid characters"); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - } - std::string updatePath(updatesDir + ZT_PATH_SEPARATOR_S + updateFilename); -#ifdef __WINDOWS__ - CreateDirectoryA(updatesDir.c_str(),NULL); -#else - mkdir(updatesDir.c_str(),0755); -#endif - - FILE *upf = fopen(updatePath.c_str(),"wb"); - if (!upf) { - LOG("software update failed: unable to open %s for writing",updatePath.c_str()); - upd->_status = UPDATE_STATUS_IDLE; - return; - } - if (fwrite(body.data(),body.length(),1,upf) != 1) { - LOG("software update failed: unable to write to %s",updatePath.c_str()); - upd->_status = UPDATE_STATUS_IDLE; - fclose(upf); - Utils::rm(updatePath); - return; - } - fclose(upf); - -#ifdef __UNIX_LIKE__ - ::chmod(updatePath.c_str(),0755); -#endif - - // We exit with this reason code and the path as the text. It is the - // caller's responsibility (main.c) to pick this up and do the right - // thing. - upd->_status = UPDATE_STATUS_IDLE; - RR->node->terminate(Node::NODE_RESTART_FOR_UPGRADE,updatePath.c_str()); -} - -} // namespace ZeroTier diff --git a/attic/SoftwareUpdater.hpp b/attic/SoftwareUpdater.hpp deleted file mode 100644 index 9beaa8ad..00000000 --- a/attic/SoftwareUpdater.hpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#ifndef ZT_SOFTWAREUPDATER_HPP -#define ZT_SOFTWAREUPDATER_HPP - -#include - -#include - -#include "../node/Constants.hpp" -#include "../node/Mutex.hpp" -#include "../node/Address.hpp" - -#include "HttpClient.hpp" - -/** - * Delay between fetches of the root topology update URL - * - * 86400000 = check once every 24 hours (this doesn't change often) - */ -#define ZT_UPDATE_ROOT_TOPOLOGY_CHECK_INTERVAL 86400000 - -/** - * Minimum interval between attempts to do a software update - */ -#define ZT_UPDATE_MIN_INTERVAL 120000 - -/** - * Maximum interval between checks for new versions - */ -#define ZT_UPDATE_MAX_INTERVAL 7200000 - -/** - * Software update HTTP timeout in seconds - */ -#define ZT_UPDATE_HTTP_TIMEOUT 120 - -namespace ZeroTier { - -/** - * Software updater - */ -class SoftwareUpdater -{ -public: - SoftwareUpdater(); - ~SoftwareUpdater(); - - /** - * Remove old updates in updates.d - */ - void cleanOldUpdates(); - - /** - * Called on each version message from a peer - * - * If a peer has a newer version, that causes an update to be started. - * - * @param vmaj Peer's major version - * @param vmin Peer's minor version - * @param rev Peer's revision - */ - void sawRemoteVersion(unsigned int vmaj,unsigned int vmin,unsigned int rev); - - /** - * Check for updates now regardless of last check time or version - * - * This only starts a check if one is not in progress. Otherwise it does - * nothing. - */ - void checkNow(); - - /** - * Check for updates now if it's been longer than ZT_UPDATE_MAX_INTERVAL - * - * This is called periodically from the main loop. - */ - inline void checkIfMaxIntervalExceeded(uint64_t now) - { - if ((now - _lastUpdateAttempt) >= ZT_UPDATE_MAX_INTERVAL) - checkNow(); - } - - /** - * Pack three-component version into a 64-bit integer - * - * @param vmaj Major version (0..65535) - * @param vmin Minor version (0..65535) - * @param rev Revision (0..65535) - * @return Version packed into an easily comparable 64-bit integer - */ - static inline uint64_t packVersion(unsigned int vmaj,unsigned int vmin,unsigned int rev) - throw() - { - return ( ((uint64_t)(vmaj & 0xffff) << 32) | ((uint64_t)(vmin & 0xffff) << 16) | (uint64_t)(rev & 0xffff) ); - } - - /** - * Parse NFO data from .nfo file on software update site - * - * The first argument is the NFO data, and all the remaining arguments are - * result parameters to be filled with results. If an error is returned the - * results in the parameters should be considered undefined. - * - * @param nfo NFO data - * @param vMajor Result: major version - * @param vMinor Result: minor version - * @param vRevision Result: revision number - * @param signedBy Result: signing identity - * @param signature Result: Ed25519 signature data - * @param url Result: URL of update binary - * @return NULL on success or error message on failure - */ - static const char *parseNfo( - const char *nfoText, - unsigned int &vMajor, - unsigned int &vMinor, - unsigned int &vRevision, - Address &signedBy, - std::string &signature, - std::string &url); - - /** - * Validate an update once downloaded - * - * This obtains the identity corresponding to the address from the compiled-in - * list of valid signing identities. - * - * @param data Update data - * @param len Length of update data - * @param signedBy Signing authority address - * @param signature Signing authority signature - * @return True on validation success, false if rejected - */ - static bool validateUpdate( - const void *data, - unsigned int len, - const Address &signedBy, - const std::string &signature); - -private: - static void _cbHandleGetLatestVersionInfo(void *arg,int code,const std::string &url,const std::string &body); - static void _cbHandleGetLatestVersionBinary(void *arg,int code,const std::string &url,const std::string &body); - - HttpClient httpClient; - const uint64_t _myVersion; - volatile uint64_t _lastUpdateAttempt; - volatile enum { - UPDATE_STATUS_IDLE, - UPDATE_STATUS_GETTING_NFO, - UPDATE_STATUS_GETTING_FILE - } _status; - volatile bool _die; - Address _signedBy; - std::string _signature; - Mutex _lock; -}; - -} // namespace ZeroTier - -#endif diff --git a/ext/installfiles/mac/postinst.sh b/ext/installfiles/mac/postinst.sh index 094eea48..7d3d516f 100755 --- a/ext/installfiles/mac/postinst.sh +++ b/ext/installfiles/mac/postinst.sh @@ -3,15 +3,11 @@ export PATH=/bin:/usr/bin:/sbin:/usr/sbin launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1 -sleep 1 -killall zerotier-one -sleep 1 -killall -9 zerotier-one cd "/Library/Application Support/ZeroTier/One" rm -rf node.log node.log.old root-topology shutdownIfUnreadable autoupdate.log updates.d if [ ! -f authtoken.secret ]; then - head -c 1024 /dev/urandom | md5 | head -c 24 >authtoken.secret + head -c 4096 /dev/urandom | md5 | head -c 24 >authtoken.secret chown root authtoken.secret chgrp wheel authtoken.secret chmod 0600 authtoken.secret diff --git a/ext/installfiles/mac/preinst.sh b/ext/installfiles/mac/preinst.sh index 9fa50bef..c2cb494b 100755 --- a/ext/installfiles/mac/preinst.sh +++ b/ext/installfiles/mac/preinst.sh @@ -4,11 +4,23 @@ export PATH=/bin:/usr/bin:/sbin:/usr/sbin if [ -f /Library/LaunchDaemons/com.zerotier.one.plist ]; then launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1 - sleep 1 - killall zerotier-one - sleep 1 - killall -9 zerotier-one fi -cd /Applications +sleep 1 + +if [ -d "/Library/Application Support/ZeroTier/One" ]; then + cd "/Library/Application Support/ZeroTier/One" + if [ -f "zerotier-one.pid" ]; then + ztpid=`cat zerotier-one.pid` + if [ "$ztpid" -gt "0" ]; then + kill `cat zerotier-one.pid` + fi + fi +fi + +sleep 1 + +cd "/Applications" rm -rf "ZeroTier One.app" + +exit 0 diff --git a/make-mac.mk b/make-mac.mk index 4ad4c5ad..7d730ae5 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -20,6 +20,10 @@ ifeq ($(ZT_OFFICIAL_RELEASE),1) CODESIGN_CERT="Developer ID Application: ZeroTier Networks LLC (8ZD9JUCZ4V)" endif +ifeq ($(ZT_AUTO_UPDATE),1) + DEFS+=-DZT_AUTO_UPDATE +endif + # Build with ZT_ENABLE_NETWORK_CONTROLLER=1 to build with the Sqlite network controller ifeq ($(ZT_ENABLE_NETWORK_CONTROLLER),1) DEFS+=-DZT_ENABLE_NETWORK_CONTROLLER diff --git a/node/Node.cpp b/node/Node.cpp index 0e3ddd14..8eb9ae90 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -443,7 +443,7 @@ std::string Node::dataStoreGet(const char *name) void Node::postNewerVersionIfNewer(unsigned int major,unsigned int minor,unsigned int rev) { - if (Peer::compareVersion(major,minor,rev,_newestVersionSeen[0],_newestVersionSeen[1],_newestVersionSeen[2]) > 0) { + if (Utils::compareVersion(major,minor,rev,_newestVersionSeen[0],_newestVersionSeen[1],_newestVersionSeen[2]) > 0) { _newestVersionSeen[0] = major; _newestVersionSeen[1] = minor; _newestVersionSeen[2] = rev; diff --git a/node/Peer.hpp b/node/Peer.hpp index 343cfcfa..3d52761a 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -407,31 +407,6 @@ public: else return std::pair(); } - /** - * Compare Peer version tuples - */ - static inline int compareVersion(unsigned int maj1,unsigned int min1,unsigned int rev1,unsigned int maj2,unsigned int min2,unsigned int rev2) - throw() - { - if (maj1 > maj2) - return 1; - else if (maj1 < maj2) - return -1; - else { - if (min1 > min2) - return 1; - else if (min1 < min2) - return -1; - else { - if (rev1 > rev2) - return 1; - else if (rev1 < rev2) - return -1; - else return 0; - } - } - } - private: void _announceMulticastGroups(const RuntimeEnvironment *RR,uint64_t now); diff --git a/node/Utils.hpp b/node/Utils.hpp index bdd673a9..bd567cf5 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -381,6 +381,33 @@ public: } static inline int64_t ntoh(int64_t n) throw() { return (int64_t)ntoh((uint64_t)n); } + /** + * Compare Peer version tuples + * + * @return -1, 0, or 1 based on whether first tuple is less than, equal to, or greater than second + */ + static inline int compareVersion(unsigned int maj1,unsigned int min1,unsigned int rev1,unsigned int maj2,unsigned int min2,unsigned int rev2) + throw() + { + if (maj1 > maj2) + return 1; + else if (maj1 < maj2) + return -1; + else { + if (min1 > min2) + return 1; + else if (min1 < min2) + return -1; + else { + if (rev1 > rev2) + return 1; + else if (rev1 < rev2) + return -1; + else return 0; + } + } + } + /** * Hexadecimal characters 0-f */ diff --git a/service/OneService.cpp b/service/OneService.cpp index c2ea034b..b8a66f6f 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -46,9 +47,12 @@ #include "../node/Utils.hpp" #include "../node/InetAddress.hpp" #include "../node/MAC.hpp" +#include "../node/Identity.hpp" #include "../osdep/Phy.hpp" +#include "../osdep/Thread.hpp" #include "../osdep/OSUtils.hpp" +#include "../osdep/Http.hpp" #include "OneService.hpp" #include "ControlPlane.hpp" @@ -57,10 +61,14 @@ #include "../controller/SqliteNetworkController.hpp" #else class SqliteNetworkController; -#endif +#endif // ZT_ENABLE_NETWORK_CONTROLLER #ifdef __WINDOWS__ #include +#else +#include +#include +#include #endif // Include the right tap device driver for this platform -- add new platforms here @@ -98,6 +106,168 @@ namespace ZeroTier { namespace { +#ifdef ZT_AUTO_UPDATE +#define ZT_AUTO_UPDATE_MAX_HTTP_RESPONSE_SIZE (1024 * 1024 * 64) +class BackgroundSoftwareUpdateChecker +{ +public: + bool isValidSigningIdentity(const Identity &id) + { + return ( + /* 0005 */ (id == Identity("ba57ea350e:0:9d4be6d7f86c5660d5ee1951a3d759aa6e12a84fc0c0b74639500f1dbc1a8c566622e7d1c531967ebceb1e9d1761342f88324a8ba520c93c35f92f35080fa23f")) + /* 0006 */ ||(id == Identity("5067b21b83:0:8af477730f5055c48135b84bed6720a35bca4c0e34be4060a4c636288b1ec22217eb22709d610c66ed464c643130c51411bbb0294eef12fbe8ecc1a1e2c63a7a")) + /* 0007 */ ||(id == Identity("4f5e97a8f1:0:57880d056d7baeb04bbc057d6f16e6cb41388570e87f01492fce882485f65a798648595610a3ad49885604e7fb1db2dd3c2c534b75e42c3c0b110ad07b4bb138")) + /* 0008 */ ||(id == Identity("580bbb8e15:0:ad5ef31155bebc6bc413991992387e083fed26d699997ef76e7c947781edd47d1997161fa56ba337b1a2b44b129fd7c7197ce5185382f06011bc88d1363b4ddd")) + ); + } + + void doUpdateCheck() + { + std::string url(OneService::autoUpdateUrl()); + if ((url.length() <= 7)||(url.substr(0,7) != "http://")) + return; + + std::string httpHost; + std::string httpPath; + { + std::size_t slashIdx = url.substr(7).find_first_of('/'); + if (slashIdx == std::string::npos) { + httpHost = url.substr(7); + httpPath = "/"; + } else { + httpHost = url.substr(7,slashIdx); + httpPath = url.substr(slashIdx + 7); + } + } + if (httpHost.length() == 0) + return; + + std::vector ips(OSUtils::resolve(httpHost.c_str())); + for(std::vector::iterator ip(ips.begin());ip!=ips.end();++ip) { + if (!ip->port()) + ip->setPort(80); + std::string nfoPath = httpPath + "LATEST.nfo"; + std::map requestHeaders,responseHeaders; + std::string body; + requestHeaders["Host"] = httpHost; + unsigned int scode = Http::GET(ZT_AUTO_UPDATE_MAX_HTTP_RESPONSE_SIZE,60000,reinterpret_cast(&(*ip)),nfoPath.c_str(),requestHeaders,responseHeaders,body); + //fprintf(stderr,"UPDATE %s %s %u %lu\n",ip->toString().c_str(),nfoPath.c_str(),scode,body.length()); + if ((scode == 200)&&(body.length() > 0)) { + /* NFO fields: + * + * file= + * signedBy= + * ed25519= + * vMajor= + * vMinor= + * vRevision= */ + Dictionary nfo(body); + + unsigned int vMajor = Utils::strToUInt(nfo.get("vMajor","0").c_str()); + unsigned int vMinor = Utils::strToUInt(nfo.get("vMinor","0").c_str()); + unsigned int vRevision = Utils::strToUInt(nfo.get("vRevision","0").c_str()); + if (Utils::compareVersion(vMajor,vMinor,vRevision,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION) <= 0) { + //fprintf(stderr,"UPDATE %u.%u.%u is not newer than our version\n",vMajor,vMinor,vRevision); + return; + } + + Identity signedBy; + if ((!signedBy.fromString(nfo.get("signedBy","")))||(!isValidSigningIdentity(signedBy))) { + //fprintf(stderr,"UPDATE invalid signedBy or not authorized signing identity.\n"); + return; + } + + std::string filePath(nfo.get("file","")); + if ((!filePath.length())||(filePath.find("..") != std::string::npos)) + return; + filePath = httpPath + filePath; + + std::string fileData; + if (Http::GET(ZT_AUTO_UPDATE_MAX_HTTP_RESPONSE_SIZE,60000,reinterpret_cast(&(*ip)),filePath.c_str(),requestHeaders,responseHeaders,fileData) != 200) { + //fprintf(stderr,"UPDATE GET %s failed\n",filePath.c_str()); + return; + } + + std::string ed25519(nfo.get("ed25519","")); + if ((ed25519.length() == 0)||(!signedBy.verify(fileData.data(),(unsigned int)fileData.length(),ed25519.data(),(unsigned int)ed25519.length()))) { + //fprintf(stderr,"UPDATE %s failed signature check!\n",filePath.c_str()); + return; + } + + /* --------------------------------------------------------------- */ + /* We made it! Begin OS-specific installation code. */ + +#ifdef __APPLE__ + /* OSX version is in the form of a MacOSX .pkg file, so we will + * launch installer (normally in /usr/sbin) to install it. It will + * then turn around and shut down the service, update files, and + * relaunch. */ + { + char bashp[128],pkgp[128]; + Utils::snprintf(bashp,sizeof(bashp),"/tmp/ZeroTierOne-update-%u.%u.%u.sh",vMajor,vMinor,vRevision); + Utils::snprintf(pkgp,sizeof(pkgp),"/tmp/ZeroTierOne-update-%u.%u.%u.pkg",vMajor,vMinor,vRevision); + FILE *pkg = fopen(pkgp,"w"); + if ((!pkg)||(fwrite(fileData.data(),fileData.length(),1,pkg) != 1)) { + fclose(pkg); + unlink(bashp); + unlink(pkgp); + fprintf(stderr,"UPDATE error writing %s\n",pkgp); + return; + } + fclose(pkg); + FILE *bash = fopen(bashp,"w"); + if (!bash) { + fclose(pkg); + unlink(bashp); + unlink(pkgp); + fprintf(stderr,"UPDATE error writing %s\n",bashp); + return; + } + fprintf(bash, + "#!/bin/bash\n" + "export PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin\n" + "sleep 2\n" + "installer -pkg \"%s\" -target /\n" + "sleep 1\n" + "rm -f \"%s\" \"%s\"\n" + "exit 0\n", + pkgp, + pkgp, + bashp); + fclose(bash); + long pid = (long)vfork(); + if (pid == 0) { + execl("/bin/bash","/bin/bash",bashp,(char *)0); + exit(0); + } + } +#endif // __APPLE__ + +#ifdef __WINDOWS__ + /* Windows version comes in the form of .MSI package that + * takes care of everything. */ + { + } +#endif // __WINDOWS__ + + /* --------------------------------------------------------------- */ + + return; + } // else try to fetch from next IP address + } + } + + void threadMain() + throw() + { + try { + this->doUpdateCheck(); + } catch ( ... ) {} + } +}; +static BackgroundSoftwareUpdateChecker backgroundSoftwareUpdateChecker; +#endif // ZT_AUTO_UPDATE + class OneServiceImpl; static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf); @@ -197,6 +367,10 @@ public: char portstr[64]; Utils::snprintf(portstr,sizeof(portstr),"%u",port); OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S + "zerotier-one.port").c_str(),std::string(portstr)); + +#ifdef ZT_AUTO_UPDATE + Thread::start(&backgroundSoftwareUpdateChecker); +#endif } virtual ~OneServiceImpl() @@ -956,11 +1130,11 @@ std::string OneService::autoUpdateUrl() */ #if defined(__APPLE__) && ( defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__i386) ) - return "http://download.zerotier.com/update/mac_intel/LATEST.nfo"; + return "http://download.zerotier.com/update/mac_intel/"; #endif #ifdef __WINDOWS__ - return "http://download.zerotier.com/update/win_intel/LATEST.nfo"; + return "http://download.zerotier.com/update/win_intel/"; #endif #endif // ZT_AUTO_UPDATE diff --git a/updater.cpp b/updater.cpp deleted file mode 100644 index bc36394b..00000000 --- a/updater.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "version.h" -#include "include/ZeroTierOne.h" -#include "node/Constants.hpp" - -#ifdef __WINDOWS__ -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#endif - -#include "node/Utils.hpp" -#include "node/Address.hpp" -#include "node/Dictionary.hpp" -#include "node/Identity.hpp" -#include "osdep/OSUtils.hpp" -#include "osdep/Http.hpp" - -using namespace ZeroTier; - -namespace { - -static std::map< Address,Identity > updateAuthorities() -{ - std::map< Address,Identity > ua; - { // 0001 - Identity id("e9bc3707b5:0:c4cef17bde99eadf9748c4fd11b9b06dc5cd8eb429227811d2c336e6b96a8d329e8abd0a4f45e47fe1bcebf878c004c822d952ff77fc2833af4c74e65985c435"); - ua[id.address()] = id; - } - { // 0002 - Identity id("56520eaf93:0:7d858b47988b34399a9a31136de07b46104d7edb4a98fa1d6da3e583d3a33e48be531532b886f0b12cd16794a66ab9220749ec5112cbe96296b18fe0cc79ca05"); - ua[id.address()] = id; - } - { // 0003 - Identity id("7c195de2e0:0:9f659071c960f9b0f0b96f9f9ecdaa27c7295feed9c79b7db6eedcc11feb705e6dd85c70fa21655204d24c897865b99eb946b753a2bbcf2be5f5e006ae618c54"); - ua[id.address()] = id; - } - { // 0004 - Identity id("415f4cfde7:0:54118e87777b0ea5d922c10b337c4f4bd1db7141845bd54004b3255551a6e356ba6b9e1e85357dbfafc45630b8faa2ebf992f31479e9005f0472685f2d8cbd6e"); - ua[id.address()] = id; - } - return ua; -} - -static bool validateUpdate( - const void *data, - unsigned int len, - const Address &signedBy, - const std::string &signature) -{ - std::map< Address,Identity > ua(updateAuthorities()); - std::map< Address,Identity >::const_iterator updateAuthority = ua.find(signedBy); - if (updateAuthority == ua.end()) - return false; - return updateAuthority->second.verify(data,len,signature.data(),(unsigned int)signature.length()); -} - -/* -static inline const char *updateUrl() -{ -#if defined(__LINUX__) && ( defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__i386) ) - if (sizeof(void *) == 8) - return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x64-LATEST.nfo"; - else return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x86-LATEST.nfo"; -#define GOT_UPDATE_URL -#endif - -#ifdef __APPLE__ - return "http://download.zerotier.com/ZeroTierOneInstaller-mac-combined-LATEST.nfo"; -#define GOT_UPDATE_URL -#endif - -#ifdef __WINDOWS__ - return "http://download.zerotier.com/ZeroTierOneInstaller-windows-intel-LATEST.nfo"; -#define GOT_UPDATE_URL -#endif - -#ifndef GOT_UPDATE_URL - return ""; -#endif -} -*/ - -static const char *parseUpdateNfo( - const char *nfoText, - unsigned int &vMajor, - unsigned int &vMinor, - unsigned int &vRevision, - Address &signedBy, - std::string &signature, - std::string &url) -{ - try { - Dictionary nfo(nfoText); - - vMajor = Utils::strToUInt(nfo.get("vMajor").c_str()); - vMinor = Utils::strToUInt(nfo.get("vMinor").c_str()); - vRevision = Utils::strToUInt(nfo.get("vRevision").c_str()); - signedBy = nfo.get("signedBy"); - signature = Utils::unhex(nfo.get("ed25519")); - url = nfo.get("url"); - - if (signature.length() != ZT_C25519_SIGNATURE_LEN) - return "bad ed25519 signature, invalid length"; - if ((url.length() <= 7)||(url.substr(0,7) != "http://")) - return "invalid URL, must begin with http://"; - - return (const char *)0; - } catch ( ... ) { - return "invalid NFO file format or one or more required fields missing"; - } -} - -} // anonymous namespace - -#ifdef __WINDOWS__ -int _tmain(int argc, _TCHAR* argv[]) -#else -int main(int argc,char **argv) -#endif -{ -#ifdef __WINDOWS__ - WSADATA wsaData; - WSAStartup(MAKEWORD(2,2),&wsaData); -#endif - - return 0; -} -- cgit v1.2.3 From d9006712f6ffc975d97097caf2d2b4264405b32c Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 21 May 2015 15:58:26 -0700 Subject: Completely factor out "desperation" from the core. I thought of a significantly simpler way to move all of this logic entirely into the containing service, liberating the core from any concern over the nature of its pipe to the outside world. --- include/ZeroTierOne.h | 8 +++---- node/Constants.hpp | 5 ----- node/IncomingPacket.cpp | 56 ++++++++++++++++++++++++------------------------- node/IncomingPacket.hpp | 5 +---- node/Node.cpp | 15 +++++-------- node/Node.hpp | 23 +------------------- node/Path.hpp | 15 ++----------- node/Peer.cpp | 36 +++++++++++++------------------ node/Peer.hpp | 15 +++++-------- node/Switch.cpp | 48 ++++++++++++++++++------------------------ node/Switch.hpp | 20 +++++++----------- service/OneService.cpp | 10 ++++----- 12 files changed, 91 insertions(+), 165 deletions(-) (limited to 'node') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index dd7ccfa1..9b82c8d6 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -723,14 +723,14 @@ typedef int (*ZT1_DataStorePutFunction)(ZT1_Node *,void *,const char *,const voi /** * Function to send a ZeroTier packet out over the wire * - * Parameters: (1) node, (2) user ptr, (3) address, (4) link desperation, - * (5) packet data, (6) packet data length. + * Parameters: (1) node, (2) user ptr, (3) address, (4) packet data, + * (5) packet data length. * * The function must return zero on success and may return any error code * on failure. Note that success does not (of course) guarantee packet * delivery. It only means that the packet appears to have been sent. */ -typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockaddr_storage *,unsigned int,const void *,unsigned int); +typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockaddr_storage *,const void *,unsigned int); /****************************************************************************/ /* C Node API */ @@ -780,7 +780,6 @@ void ZT1_Node_delete(ZT1_Node *node); * @param node Node instance * @param now Current clock in milliseconds * @param remoteAddress Origin of packet - * @param linkDesperation Link desperation metric for link or protocol over which packet arrived * @param packetData Packet data * @param packetLength Packet length * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks() @@ -790,7 +789,6 @@ enum ZT1_ResultCode ZT1_Node_processWirePacket( ZT1_Node *node, uint64_t now, const struct sockaddr_storage *remoteAddress, - unsigned int linkDesperation, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline); diff --git a/node/Constants.hpp b/node/Constants.hpp index 3bda685d..1da10d11 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -269,11 +269,6 @@ */ #define ZT_NETWORK_AUTOCONF_DELAY 60000 -/** - * Increment core desperation after this multiple of ping checks without responses from upstream peers - */ -#define ZT_CORE_DESPERATION_INCREMENT 2 - /** * Timeout for overall peer activity (measured from last receive) */ diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 7833382a..2ddd83a8 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -69,7 +69,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR) switch(verb()) { //case Packet::VERB_NOP: default: // ignore unknown verbs, but if they pass auth check they are "received" - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),verb(),0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP); return true; case Packet::VERB_HELLO: return _doHELLO(RR); case Packet::VERB_ERROR: return _doERROR(RR,peer); @@ -140,7 +140,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); nconf->com().serialize(outp); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } } break; @@ -158,7 +158,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr default: break; } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb); } catch (std::exception &ex) { TRACE("dropped ERROR from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -219,7 +219,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) outp.append(packetId()); outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION); outp.armor(key,true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } else { RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str()); @@ -264,7 +264,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) // VALID -- continues here - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); bool trusted = false; @@ -302,7 +302,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) } outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } catch (std::exception &ex) { TRACE("dropped HELLO from %s(%s): %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -397,7 +397,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p outp.append((uint16_t)0); // no meta-data outp.append((uint64_t)nc->revision()); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } TRACE("got network configuration for network %.16llx from %s",(unsigned long long)nw->id(),source().toString().c_str()); @@ -443,7 +443,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p default: break; } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb); } catch (std::exception &ex) { TRACE("dropped OK from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -463,7 +463,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr outp.append(packetId()); queried->identity().serialize(outp,false); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } else { Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_WHOIS); @@ -471,12 +471,12 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); outp.append(payload(),ZT_ADDRESS_LENGTH); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } else { TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str()); } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP); } catch ( ... ) { TRACE("dropped WHOIS from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str()); } @@ -508,8 +508,8 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr< if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) { InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port); TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str()); - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); - RR->sw->contact(withPeer,atAddr,_linkDesperation); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); + RR->sw->contact(withPeer,atAddr); } else { TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); } @@ -549,7 +549,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr RR->node->putFrame(network->id(),MAC(peer->address(),network->id()),network->mac(),etherType,0,field(ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP); } else { TRACE("dropped FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID)); } @@ -625,7 +625,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr

node->putFrame(network->id(),from,to,etherType,0,field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP); } else { TRACE("dropped EXT_FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID)); } @@ -646,7 +646,7 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;ptrmc->add(now,at(ptr),MulticastGroup(MAC(field(ptr + 8,6),6),at(ptr + 14)),peer->address()); - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP); } catch (std::exception &ex) { TRACE("dropped MULTICAST_LIKE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -670,7 +670,7 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment } } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP); } catch (std::exception &ex) { TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -689,7 +689,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons const unsigned int h = hops(); const uint64_t pid = packetId(); - peer->received(RR,_remoteAddress,_linkDesperation,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP); if (RR->localNetworkController) { Dictionary netconf; @@ -709,7 +709,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) { TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length()); } else { - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } } break; @@ -722,7 +722,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } break; case NetworkController::NETCONF_QUERY_ACCESS_DENIED: { Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR); @@ -731,7 +731,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } break; case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR: TRACE("NETWORK_CONFIG_REQUEST failed: internal error: %s",netconf.get("error","(unknown)").c_str()); @@ -747,7 +747,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } catch (std::exception &exc) { TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); @@ -768,7 +768,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *RR,cons nw->requestConfiguration(); ptr += 8; } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -795,11 +795,11 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar outp.append((uint32_t)mg.adi()); if (RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit)) { outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped MULTICAST_GATHER from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -886,12 +886,12 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share outp.append((unsigned char)0x02); // flag 0x02 = contains gather results if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) { outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } } // else ignore -- not a member of this network - peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped MULTICAST_FRAME from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -908,7 +908,7 @@ void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); + RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); } } // namespace ZeroTier diff --git a/node/IncomingPacket.hpp b/node/IncomingPacket.hpp index 5940a78e..174fa38d 100644 --- a/node/IncomingPacket.hpp +++ b/node/IncomingPacket.hpp @@ -73,15 +73,13 @@ public: * @param data Packet data * @param len Packet length * @param remoteAddress Address from which packet came - * @param linkDesperation Link desperation for link over which packet was received * @param now Current time * @throws std::out_of_range Range error processing packet */ - IncomingPacket(const void *data,unsigned int len,const InetAddress &remoteAddress,unsigned int linkDesperation,uint64_t now) : + IncomingPacket(const void *data,unsigned int len,const InetAddress &remoteAddress,uint64_t now) : Packet(data,len), _receiveTime(now), _remoteAddress(remoteAddress), - _linkDesperation(linkDesperation), __refCount() { } @@ -129,7 +127,6 @@ private: uint64_t _receiveTime; InetAddress _remoteAddress; - unsigned int _linkDesperation; AtomicCounter __refCount; }; diff --git a/node/Node.cpp b/node/Node.cpp index 8eb9ae90..6b3f1f2c 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -80,8 +80,7 @@ Node::Node( _startTimeAfterInactivity(0), _lastPingCheck(0), _lastHousekeepingRun(0), - _lastBeacon(0), - _coreDesperation(0) + _lastBeacon(0) { _newestVersionSeen[0] = ZEROTIER_ONE_VERSION_MAJOR; _newestVersionSeen[1] = ZEROTIER_ONE_VERSION_MINOR; @@ -155,13 +154,12 @@ Node::~Node() ZT1_ResultCode Node::processWirePacket( uint64_t now, const struct sockaddr_storage *remoteAddress, - unsigned int linkDesperation, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline) { _now = now; - RR->sw->onRemotePacket(*(reinterpret_cast(remoteAddress)),linkDesperation,packetData,packetLength); + RR->sw->onRemotePacket(*(reinterpret_cast(remoteAddress)),packetData,packetLength); return ZT1_RESULT_OK; } @@ -219,8 +217,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next if ((now - _lastPingCheck) >= ZT_PING_CHECK_INVERVAL) { _lastPingCheck = now; - // This is used as a floor for the desperation and online status - // calculations if we just started up or have been asleep. + // This is used to compute whether we appear to be "online" or not if ((now - _startTimeAfterInactivity) > (ZT_PING_CHECK_INVERVAL * 3)) _startTimeAfterInactivity = now; @@ -229,7 +226,6 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc); const uint64_t lastActivityAgo = now - std::max(_startTimeAfterInactivity,pfunc.lastReceiveFromUpstream); - _coreDesperation = (unsigned int)(lastActivityAgo / (ZT_PING_CHECK_INVERVAL * ZT_CORE_DESPERATION_INCREMENT)); bool oldOnline = _online; _online = (lastActivityAgo < ZT_PEER_ACTIVITY_TIMEOUT); if (oldOnline != _online) @@ -257,7 +253,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next *(reinterpret_cast(p)) = RR->prng->next32(); RR->identity.address().copyTo(beacon + 8,5); RR->antiRec->logOutgoingZT(beacon,13); - putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13,0); + putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13); } } @@ -528,13 +524,12 @@ enum ZT1_ResultCode ZT1_Node_processWirePacket( ZT1_Node *node, uint64_t now, const struct sockaddr_storage *remoteAddress, - unsigned int linkDesperation, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline) { try { - return reinterpret_cast(node)->processWirePacket(now,remoteAddress,linkDesperation,packetData,packetLength,nextBackgroundTaskDeadline); + return reinterpret_cast(node)->processWirePacket(now,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline); } catch (std::bad_alloc &exc) { return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { diff --git a/node/Node.hpp b/node/Node.hpp index 70531bf8..f8678115 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -79,7 +79,6 @@ public: ZT1_ResultCode processWirePacket( uint64_t now, const struct sockaddr_storage *remoteAddress, - unsigned int linkDesperation, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline); @@ -119,16 +118,14 @@ public: * @param addr Destination address * @param data Packet data * @param len Packet length - * @param desperation Link desperation for reaching this address * @return True if packet appears to have been sent */ - inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len,unsigned int desperation) + inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len) { return (_wirePacketSendFunction( reinterpret_cast(this), _uPtr, reinterpret_cast(&addr), - desperation, data, len) == 0); } @@ -174,23 +171,6 @@ public: return nw; } - /** - * Get an overall current level of desperation - * - * The current level of desperation is based on how recently an upstream - * (a.k.a. supernode) peer has spoken to us. As such, it will change and - * return to 0 once something like tunneling (higher desperation link) is - * active. As a result, actual link desperation for outgoing messages - * should be the max of either this or the most recent link desperation - * for an incoming message from a given address. See Path.hpp and Peer.hpp. - * - * In other words think of this as 'the desperation we should try to - * escalate to right now.' - * - * @return Overall system level of desperation - */ - inline unsigned int coreDesperation() const throw() { return _coreDesperation; } - inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) { return (_dataStorePutFunction(reinterpret_cast(this),_uPtr,name,data,len,(int)secure) == 0); } inline bool dataStorePut(const char *name,const std::string &data,bool secure) { return dataStorePut(name,(const void *)data.data(),(unsigned int)data.length(),secure); } inline void dataStoreDelete(const char *name) { _dataStorePutFunction(reinterpret_cast(this),_uPtr,name,(const void *)0,0,0); } @@ -253,7 +233,6 @@ private: uint64_t _lastPingCheck; uint64_t _lastHousekeepingRun; uint64_t _lastBeacon; - unsigned int _coreDesperation; unsigned int _newestVersionSeen[3]; // major, minor, revision bool _online; }; diff --git a/node/Path.hpp b/node/Path.hpp index 4a8e837d..393b7225 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -57,7 +57,6 @@ public: _addr(), _lastSend(0), _lastReceived(0), - _lastReceiveDesperation(0), _fixed(false) {} Path(const Path &p) throw() { memcpy(this,&p,sizeof(Path)); } @@ -66,7 +65,6 @@ public: _addr(addr), _lastSend(0), _lastReceived(0), - _lastReceiveDesperation(0), _fixed(fixed) {} inline void init(const InetAddress &addr,bool fixed) @@ -74,7 +72,6 @@ public: _addr = addr; _lastSend = 0; _lastReceived = 0; - _lastReceiveDesperation = 0; _fixed = fixed; } @@ -107,13 +104,11 @@ public: * Called when a packet is received from this path * * @param t Time of receive - * @param d Link desperation of receive */ - inline void received(uint64_t t,unsigned int d) + inline void received(uint64_t t) throw() { _lastReceived = t; - _lastReceiveDesperation = d; } /** @@ -126,11 +121,6 @@ public: */ inline void setFixed(bool f) throw() { _fixed = f; } - /** - * @return Last desperation reported via incoming link - */ - inline unsigned int lastReceiveDesperation() const throw() { return _lastReceiveDesperation; } - /** * @param now Current time * @return True if this path is fixed or has received data in last ACTIVITY_TIMEOUT ms @@ -152,7 +142,7 @@ public: */ inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - if (RR->node->putPacket(_addr,data,len,std::max(RR->node->coreDesperation(),_lastReceiveDesperation))) { + if (RR->node->putPacket(_addr,data,len)) { sent(now); RR->antiRec->logOutgoingZT(data,len); return true; @@ -187,7 +177,6 @@ private: InetAddress _addr; uint64_t _lastSend; uint64_t _lastReceived; - unsigned int _lastReceiveDesperation; bool _fixed; }; diff --git a/node/Peer.cpp b/node/Peer.cpp index 7c0868eb..d788d006 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -60,7 +60,6 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) void Peer::received( const RuntimeEnvironment *RR, const InetAddress &remoteAddr, - int linkDesperation, unsigned int hops, uint64_t packetId, Packet::Verb verb, @@ -78,7 +77,7 @@ void Peer::received( unsigned int np = _numPaths; for(unsigned int p=0;pinit(remoteAddr,false); - slot->received(now,linkDesperation); + slot->received(now); _numPaths = np; pathIsConfirmed = true; } @@ -115,7 +114,7 @@ void Peer::received( if ((now - _lastPathConfirmationSent) >= ZT_MIN_PATH_CONFIRMATION_INTERVAL) { _lastPathConfirmationSent = now; TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); - attemptToContactAt(RR,remoteAddr,linkDesperation,now); + attemptToContactAt(RR,remoteAddr,now); } } } @@ -137,7 +136,7 @@ void Peer::received( for(std::vector::const_iterator mg(mgs.begin());mg!=mgs.end();++mg) { if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) { outp.armor(_key,true); - RR->node->putPacket(remoteAddr,outp.data(),outp.size(),linkDesperation); + RR->node->putPacket(remoteAddr,outp.data(),outp.size()); outp.reset(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); } @@ -150,7 +149,7 @@ void Peer::received( } if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) { outp.armor(_key,true); - RR->node->putPacket(remoteAddr,outp.data(),outp.size(),linkDesperation); + RR->node->putPacket(remoteAddr,outp.data(),outp.size()); } } } @@ -161,7 +160,7 @@ void Peer::received( _lastMulticastFrame = now; } -void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,unsigned int linkDesperation,uint64_t now) +void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,uint64_t now) { Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO); outp.append((unsigned char)ZT_PROTO_VERSION); @@ -189,26 +188,21 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &at } outp.armor(_key,false); // HELLO is sent in the clear - RR->node->putPacket(atAddress,outp.data(),outp.size(),linkDesperation); + RR->node->putPacket(atAddress,outp.data(),outp.size()); } void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) { Path *const bestPath = getBestPath(now); if ((bestPath)&&(bestPath->active(now))) { - const unsigned int desp = std::max(RR->node->coreDesperation(),bestPath->lastReceiveDesperation()); if ((now - bestPath->lastReceived()) >= ZT_PEER_DIRECT_PING_DELAY) { - TRACE("PING %s(%s) desperation == %u",_id.address().toString().c_str(),bestPath->address().toString().c_str(),desp); - attemptToContactAt(RR,bestPath->address(),desp,now); + TRACE("PING %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); + attemptToContactAt(RR,bestPath->address(),now); bestPath->sent(now); } else if ((now - bestPath->lastSend()) >= ZT_NAT_KEEPALIVE_DELAY) { - // We only do keepalive if desperation is zero right now, since higher - // desperation paths involve things like tunneling that do not need it. - if (desp == 0) { - TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); - RR->node->putPacket(bestPath->address(),"",0,0); - bestPath->sent(now); - } + TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); + RR->node->putPacket(bestPath->address(),"",0); + bestPath->sent(now); } } } @@ -269,7 +263,7 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc while (x < np) { if (_paths[x].address().ipScope() == scope) { if (_paths[x].fixed()) { - attemptToContactAt(RR,_paths[x].address(),_paths[x].lastReceiveDesperation(),now); + attemptToContactAt(RR,_paths[x].address(),now); _paths[y++] = _paths[x]; // keep fixed paths } } else { @@ -281,11 +275,11 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc return (y < np); } -void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6,unsigned int maxDesperation) const +void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const { uint64_t bestV4 = 0,bestV6 = 0; for(unsigned int p=0,np=_numPaths;p findCommonGround(const Peer &a,const Peer &b,uint64_t now,unsigned int maxDesperation) + static inline std::pair findCommonGround(const Peer &a,const Peer &b,uint64_t now) { std::pair v4,v6; - b.getBestActiveAddresses(now,v4.first,v6.first,maxDesperation); - a.getBestActiveAddresses(now,v4.second,v6.second,maxDesperation); + b.getBestActiveAddresses(now,v4.first,v6.first); + a.getBestActiveAddresses(now,v4.second,v6.second); if ((v6.first)&&(v6.second)) // prefer IPv6 if both have it since NAT-t is (almost) unnecessary return v6; else if ((v4.first)&&(v4.second)) diff --git a/node/Switch.cpp b/node/Switch.cpp index e2bc74c5..19a77db7 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -58,16 +58,16 @@ Switch::~Switch() { } -void Switch::onRemotePacket(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len) +void Switch::onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len) { try { if (len == ZT_PROTO_BEACON_LENGTH) { - _handleBeacon(fromAddr,linkDesperation,Buffer(data,len)); + _handleBeacon(fromAddr,Buffer(data,len)); } else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { if (((const unsigned char *)data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { - _handleRemotePacketFragment(fromAddr,linkDesperation,data,len); + _handleRemotePacketFragment(fromAddr,data,len); } else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) { - _handleRemotePacketHead(fromAddr,linkDesperation,data,len); + _handleRemotePacketHead(fromAddr,data,len); } } } catch (std::exception &ex) { @@ -291,8 +291,7 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force) const uint64_t now = RR->node->now(); - // Right now we only unite desperation == 0 links, which will be direct - std::pair cg(Peer::findCommonGround(*p1p,*p2p,now,0)); + std::pair cg(Peer::findCommonGround(*p1p,*p2p,now)); if (!(cg.first)) return false; @@ -369,18 +368,18 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force) return true; } -void Switch::contact(const SharedPtr &peer,const InetAddress &atAddr,unsigned int maxDesperation) +void Switch::contact(const SharedPtr &peer,const InetAddress &atAddr) { TRACE("sending NAT-t message to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str()); const uint64_t now = RR->node->now(); - // Attempt to contact at zero desperation first - peer->attemptToContactAt(RR,atAddr,0,now); + // Attempt to contact directly + peer->attemptToContactAt(RR,atAddr,now); // If we have not punched through after this timeout, open refreshing can of whupass { Mutex::Lock _l(_contactQueue_m); - _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,atAddr,maxDesperation)); + _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,atAddr)); } } @@ -450,7 +449,7 @@ unsigned long Switch::doTimerTasks(uint64_t now) case 0: { // First strategy: rifle method: direct packet to known port - qi->peer->attemptToContactAt(RR,qi->inaddr,qi->currentDesperation,now); + qi->peer->attemptToContactAt(RR,qi->inaddr,now); } break; case 1: { @@ -460,7 +459,7 @@ unsigned long Switch::doTimerTasks(uint64_t now) for(int i=0;i<9;++i) { if (++p > 0xffff) break; tmpaddr.setPort((unsigned int)p); - qi->peer->attemptToContactAt(RR,tmpaddr,qi->currentDesperation,now); + qi->peer->attemptToContactAt(RR,tmpaddr,now); } } break; @@ -471,19 +470,12 @@ unsigned long Switch::doTimerTasks(uint64_t now) for(int i=0;i<3;++i) { if (--p < 1024) break; tmpaddr.setPort((unsigned int)p); - qi->peer->attemptToContactAt(RR,tmpaddr,qi->currentDesperation,now); + qi->peer->attemptToContactAt(RR,tmpaddr,now); } - // Escalate link desperation after all strategies attempted - ++qi->currentDesperation; - if (qi->currentDesperation > qi->maxDesperation) { - // We've tried all strategies at all levels of desperation, give up. - _contactQueue.erase(qi++); - continue; - } else { - // Otherwise restart at new link desperation level (e.g. try a tougher transport) - qi->strategyIteration = 0; - } + // We've tried all strategies + _contactQueue.erase(qi++); + continue; } break; } @@ -572,7 +564,7 @@ const char *Switch::etherTypeName(const unsigned int etherType) return "UNKNOWN"; } -void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len) +void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len) { Packet::Fragment fragment(data,len); Address destination(fragment.destination()); @@ -644,9 +636,9 @@ void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,int linkDes } } -void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len) +void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len) { - SharedPtr packet(new IncomingPacket(data,len,fromAddr,linkDesperation,RR->node->now())); + SharedPtr packet(new IncomingPacket(data,len,fromAddr,RR->node->now())); Address source(packet->source()); Address destination(packet->destination()); @@ -714,7 +706,7 @@ void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,int linkDespera } } -void Switch::_handleBeacon(const InetAddress &fromAddr,int linkDesperation,const Buffer &data) +void Switch::_handleBeacon(const InetAddress &fromAddr,const Buffer &data) { Address beaconAddr(data.field(ZT_PROTO_BEACON_IDX_ADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); if (beaconAddr == RR->identity.address()) @@ -726,7 +718,7 @@ void Switch::_handleBeacon(const InetAddress &fromAddr,int linkDesperation,const _lastBeacon = now; Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP); outp.armor(peer->key(),false); - RR->node->putPacket(fromAddr,outp.data(),outp.size(),linkDesperation); + RR->node->putPacket(fromAddr,outp.data(),outp.size()); } } } diff --git a/node/Switch.hpp b/node/Switch.hpp index aec7f046..0b748247 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -79,11 +79,10 @@ public: * Called when a packet is received from the real network * * @param fromAddr Internet IP address of origin - * @param linkDesperation Link desperation of path over which packet was received * @param data Packet data * @param len Packet length */ - void onRemotePacket(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len); + void onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len); /** * Called when a packet comes from a local Ethernet tap @@ -136,9 +135,8 @@ public: * * @param peer Peer to contact * @param atAddr Address of peer - * @param linkDesperation Attempt up to given max desperation */ - void contact(const SharedPtr &peer,const InetAddress &atAddr,unsigned int maxDesperation); + void contact(const SharedPtr &peer,const InetAddress &atAddr); /** * Request WHOIS on a given address @@ -182,9 +180,9 @@ public: throw(); private: - void _handleRemotePacketFragment(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len); - void _handleRemotePacketHead(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len); - void _handleBeacon(const InetAddress &fromAddr,int linkDesperation,const Buffer &data); + void _handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len); + void _handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len); + void _handleBeacon(const InetAddress &fromAddr,const Buffer &data); Address _sendWhoisRequest( const Address &addr, @@ -248,19 +246,15 @@ private: struct ContactQueueEntry { ContactQueueEntry() {} - ContactQueueEntry(const SharedPtr &p,uint64_t ft,const InetAddress &a,unsigned int md) : + ContactQueueEntry(const SharedPtr &p,uint64_t ft,const InetAddress &a) : peer(p), fireAtTime(ft), inaddr(a), - maxDesperation(md), - currentDesperation(0), - strategyIteration(1) {} // start with 2nd strategy, zero desperation, since we've already tried 0/0 + strategyIteration(1) {} // start with 2nd strategy, since first was tried at inception SharedPtr peer; uint64_t fireAtTime; InetAddress inaddr; - unsigned int maxDesperation; - unsigned int currentDesperation; unsigned int strategyIteration; }; std::list _contactQueue; diff --git a/service/OneService.cpp b/service/OneService.cpp index aef3f557..3f45cd1e 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -316,7 +316,7 @@ static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData); static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize); static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure); -static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len); +static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len); static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); static void StapFrameHandler(void *uptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); @@ -590,7 +590,6 @@ public: ZT1_ResultCode rc = _node->processWirePacket( OSUtils::now(), (const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big - 0, // desperation == 0, direct UDP data, len, &_nextBackgroundTaskDeadline); @@ -730,7 +729,6 @@ public: ZT1_ResultCode rc = _node->processWirePacket( OSUtils::now(), (const struct sockaddr_storage *)&from, // Phy<> uses sockaddr_storage, so it'll always be that big - 1, // desperation == 1, TCP tunnel proxy data, plen, &_nextBackgroundTaskDeadline); @@ -915,7 +913,7 @@ public: } } - inline int nodeWirePacketSendFunction(const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len) + inline int nodeWirePacketSendFunction(const struct sockaddr_storage *addr,const void *data,unsigned int len) { switch(addr->ss_family) { case AF_INET: @@ -1047,8 +1045,8 @@ static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name { return reinterpret_cast(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); } static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure) { return reinterpret_cast(uptr)->nodeDataStorePutFunction(name,data,len,secure); } -static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len) -{ return reinterpret_cast(uptr)->nodeWirePacketSendFunction(addr,desperation,data,len); } +static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len) +{ return reinterpret_cast(uptr)->nodeWirePacketSendFunction(addr,data,len); } static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); } -- cgit v1.2.3