From e0090e56f4b9ed70687c16ef3629a1ec6f8d2bbb Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sat, 16 May 2015 18:59:11 -0700 Subject: Build fix on OSX -- cannot call SqliteNetworkController if not compiled in. --- service/ControlPlane.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'service') diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index 1d9f9b4a..1047067e 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -445,10 +445,14 @@ unsigned int ControlPlane::handleRequest( responseContentType = "text/plain"; scode = 200; } else { +#ifdef ZT_ENABLE_NETWORK_CONTROLLER std::map::const_iterator ss(_subsystems.find(ps[0])); if (ss != _subsystems.end()) scode = ss->second->handleControlPlaneHttpGET(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); else scode = 404; +#else + scode = 404; +#endif } } else scode = 401; // isAuth == false @@ -478,10 +482,14 @@ unsigned int ControlPlane::handleRequest( } else scode = 500; } } else { +#ifdef ZT_ENABLE_NETWORK_CONTROLLER std::map::const_iterator ss(_subsystems.find(ps[0])); if (ss != _subsystems.end()) scode = ss->second->handleControlPlaneHttpPOST(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); else scode = 404; +#else + scode = 404; +#endif } } else scode = 401; // isAuth == false @@ -510,10 +518,14 @@ unsigned int ControlPlane::handleRequest( _node->freeQueryResult((void *)nws); } else scode = 500; } else { +#ifdef ZT_ENABLE_NETWORK_CONTROLLER std::map::const_iterator ss(_subsystems.find(ps[0])); if (ss != _subsystems.end()) scode = ss->second->handleControlPlaneHttpDELETE(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); else scode = 404; +#else + scode = 404; +#endif } } else { -- cgit v1.2.3 From 0e009810599a7702a05b7ae8d3d9851bb57b57f1 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sun, 17 May 2015 14:01:25 -0700 Subject: docs --- service/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'service') diff --git a/service/README.md b/service/README.md index ecab6e75..e063f349 100644 --- a/service/README.md +++ b/service/README.md @@ -151,7 +151,13 @@ This returns an array of 16-digit hexadecimal network IDs. Unlike /network under * Methods: GET, POST, DELETE * Returns: { object } -DELETE for networks is final. Don't do this unless you really mean it! +By making queries to this path you can create, configure, and delete networks. DELETE is final, so don't do it unless you really mean it. + +It's important to understand how network IDs work. The first ten digits (most significant 40 bits) of a network ID are the ZeroTier address of the controller. This is how clients find it. The last six digits (least significant 24 bits) are arbitrary and serve to identify the network uniquely on the controller. + +Thus a network's first ten digits *must* be the controller's address. If your controller is *deadbeef01*, then the networks it controls must have IDs like *deadbeef01feed02* or *deadbeef01beef03*. This API however *does not* enforce this requirement. It will allow you to add arbitrary network IDs, but they won't work since clients will never be able to find them. + +To create a new network with a random last six digits safely and atomically, you can POST to */controller/network/##########\_\_\_\_\_\_* where ########## is the controller's address and the underscores are as shown. This will pick a random unallocated network ID, which will be returned in the 'nwid' field of the returned JSON object. -- cgit v1.2.3 From 7649d6746b49512a6ab6bb83306aa19c6e74b2a6 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sun, 17 May 2015 15:38:01 -0700 Subject: docs --- service/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'service') diff --git a/service/README.md b/service/README.md index e063f349..1900a612 100644 --- a/service/README.md +++ b/service/README.md @@ -59,7 +59,7 @@ Getting /network returns an array of all networks that this node has joined. See * Methods: GET, POST, DELETE * Returns: { object } -To join a network, POST to it. POST data is optional and may be omitted. Example: POST to /network/8056c2e21c000001 to join the public "Earth" network. To leave a network, DELETE it e.g. DELETE /network/8056c2e21c000001. +To join a network, POST to it. Since networks have no mandatory writable parameters, POST data is optional and may be omitted. Example: POST to /network/8056c2e21c000001 to join the public "Earth" network. To leave a network, DELETE it e.g. DELETE /network/8056c2e21c000001. Most network settings are not writable, as they are defined by the network controller. -- cgit v1.2.3 From 086f21ed70c56b1f52791816acd812fa6d5b3ed3 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sun, 17 May 2015 15:51:07 -0700 Subject: Refactor and simplify controller integration with JSON API and OneService. --- one.cpp | 21 +-------------------- service/ControlPlane.cpp | 18 +++++++++--------- service/ControlPlane.hpp | 28 +++++++++++++--------------- service/OneService.cpp | 32 ++++++++++++++++++++++++-------- service/OneService.hpp | 4 ---- 5 files changed, 47 insertions(+), 56 deletions(-) (limited to 'service') diff --git a/one.cpp b/one.cpp index d6da3a26..27cb3ff4 100644 --- a/one.cpp +++ b/one.cpp @@ -72,12 +72,7 @@ #include "service/OneService.hpp" -#ifdef ZT_ENABLE_NETWORK_CONTROLLER -#include "controller/SqliteNetworkController.hpp" -#endif - #define ZT1_PID_PATH "zerotier-one.pid" -#define ZT1_CONTROLLER_DB_PATH "controller.db" using namespace ZeroTier; @@ -1129,19 +1124,6 @@ int main(int argc,char **argv) } #endif // __WINDOWS__ - NetworkController *controller = (NetworkController *)0; -#ifdef ZT_ENABLE_NETWORK_CONTROLLER - try { - controller = new SqliteNetworkController((homeDir + ZT_PATH_SEPARATOR_S + ZT1_CONTROLLER_DB_PATH).c_str()); - } catch (std::exception &exc) { - fprintf(stderr,"%s: failure initializing SqliteNetworkController: %s"ZT_EOL_S,argv[0],exc.what()); - return 1; - } catch ( ... ) { - fprintf(stderr,"%s: failure initializing SqliteNetworkController: unknown exception"ZT_EOL_S,argv[0]); - return 1; - } -#endif // ZT_ENABLE_NETWORK_CONTROLLER - #ifdef __UNIX_LIKE__ std::string pidPath(homeDir + ZT_PATH_SEPARATOR_S + ZT1_PID_PATH); { @@ -1158,7 +1140,7 @@ int main(int argc,char **argv) try { for(;;) { - zt1Service = OneService::newInstance(homeDir.c_str(),port,controller,(overrideRootTopology.length() > 0) ? overrideRootTopology.c_str() : (const char *)0); + zt1Service = OneService::newInstance(homeDir.c_str(),port,(overrideRootTopology.length() > 0) ? overrideRootTopology.c_str() : (const char *)0); switch(zt1Service->run()) { case OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done case OneService::ONE_NORMAL_TERMINATION: @@ -1191,7 +1173,6 @@ int main(int argc,char **argv) delete zt1Service; zt1Service = (OneService *)0; - delete controller; #ifdef __UNIX_LIKE__ OSUtils::rm(pidPath.c_str()); diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index 1047067e..81fb61ca 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -245,6 +245,9 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT1_Peer *peer ControlPlane::ControlPlane(OneService *svc,Node *n,const char *uiStaticPath) : _svc(svc), _node(n), +#ifdef ZT_ENABLE_NETWORK_CONTROLLER + _controller((SqliteNetworkController *)0), +#endif _uiStaticPath((uiStaticPath) ? uiStaticPath : "") { } @@ -446,9 +449,8 @@ unsigned int ControlPlane::handleRequest( scode = 200; } else { #ifdef ZT_ENABLE_NETWORK_CONTROLLER - std::map::const_iterator ss(_subsystems.find(ps[0])); - if (ss != _subsystems.end()) - scode = ss->second->handleControlPlaneHttpGET(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); + if (_controller) + _controller->handleControlPlaneHttpGET(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); else scode = 404; #else scode = 404; @@ -483,9 +485,8 @@ unsigned int ControlPlane::handleRequest( } } else { #ifdef ZT_ENABLE_NETWORK_CONTROLLER - std::map::const_iterator ss(_subsystems.find(ps[0])); - if (ss != _subsystems.end()) - scode = ss->second->handleControlPlaneHttpPOST(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); + if (_controller) + _controller->handleControlPlaneHttpPOST(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); else scode = 404; #else scode = 404; @@ -519,9 +520,8 @@ unsigned int ControlPlane::handleRequest( } else scode = 500; } else { #ifdef ZT_ENABLE_NETWORK_CONTROLLER - std::map::const_iterator ss(_subsystems.find(ps[0])); - if (ss != _subsystems.end()) - scode = ss->second->handleControlPlaneHttpDELETE(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); + if (_controller) + _controller->handleControlPlaneHttpDELETE(std::vector(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType); else scode = 404; #else scode = 404; diff --git a/service/ControlPlane.hpp b/service/ControlPlane.hpp index fc8a0182..75cd8cac 100644 --- a/service/ControlPlane.hpp +++ b/service/ControlPlane.hpp @@ -52,30 +52,26 @@ public: ControlPlane(OneService *svc,Node *n,const char *uiStaticPath); ~ControlPlane(); +#ifdef ZT_ENABLE_NETWORK_CONTROLLER /** - * Add an authentication token for API access + * Set controller, which will be available under /controller + * + * @param c Network controller instance */ - inline void addAuthToken(const char *tok) + inline void setController(SqliteNetworkController *c) { Mutex::Lock _l(_lock); - _authTokens.insert(std::string(tok)); + _controller = c; } +#endif /** - * Mount a subsystem under a prefix - * - * Note that the prefix must not contain a dot -- this is reserved for - * static pages -- and must not be a reserved prefix such as /peer - * or /network. Do not include path / characters in the prefix. Example - * would be 'controller' for SqliteNetworkController. - * - * @param prefix First element in URI path - * @param subsys Object to call for results of GET and POST/PUT operations + * Add an authentication token for API access */ - inline void mount(const char *prefix,SqliteNetworkController *subsys) + inline void addAuthToken(const char *tok) { Mutex::Lock _l(_lock); - _subsystems[std::string(prefix)] = subsys; + _authTokens.insert(std::string(tok)); } /** @@ -102,9 +98,11 @@ public: private: OneService *const _svc; Node *const _node; +#ifdef ZT_ENABLE_NETWORK_CONTROLLER + SqliteNetworkController *_controller; +#endif std::string _uiStaticPath; std::set _authTokens; - std::map _subsystems; Mutex _lock; }; diff --git a/service/OneService.cpp b/service/OneService.cpp index 13108aa1..42b4fc00 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -53,6 +53,12 @@ #include "OneService.hpp" #include "ControlPlane.hpp" +#ifdef ZT_ENABLE_NETWORK_CONTROLLER +#include "../controller/SqliteNetworkController.hpp" +#else +class SqliteNetworkController; +#endif + #ifdef __WINDOWS__ #include #endif @@ -85,6 +91,9 @@ namespace ZeroTier { typedef BSDEthernetTap EthernetTap; } // How often to check for new multicast subscriptions on a tap device #define ZT_TAP_CHECK_MULTICAST_INTERVAL 30000 +// Path under ZT1 home for controller database if controller is enabled +#define ZT1_CONTROLLER_DB_PATH "controller.db" + namespace ZeroTier { class OneServiceImpl; @@ -147,10 +156,12 @@ struct TcpConnection class OneServiceImpl : public OneService { public: - OneServiceImpl(const char *hp,unsigned int port,NetworkController *master,const char *overrideRootTopology) : + OneServiceImpl(const char *hp,unsigned int port,const char *overrideRootTopology) : _homePath((hp) ? hp : "."), +#ifdef ZT_ENABLE_NETWORK_CONTROLLER + _controller((_homePath + ZT_PATH_SEPARATOR_S + ZT1_CONTROLLER_DB_PATH).c_str()), +#endif _phy(this,true), - _master(master), _overrideRootTopology((overrideRootTopology) ? overrideRootTopology : ""), _node((Node *)0), _controlPlane((ControlPlane *)0), @@ -227,13 +238,16 @@ public: SnodeEventCallback, ((_overrideRootTopology.length() > 0) ? _overrideRootTopology.c_str() : (const char *)0)); - if (_master) - _node->setNetconfMaster((void *)_master); +#ifdef ZT_ENABLE_NETWORK_CONTROLLER + _node->setNetconfMaster((void *)&_controller); +#endif _controlPlane = new ControlPlane(this,_node,(_homePath + ZT_PATH_SEPARATOR_S + "ui").c_str()); _controlPlane->addAuthToken(authToken.c_str()); - if (_master) - _controlPlane->mount("controller",reinterpret_cast(_master)); + +#ifdef ZT_ENABLE_NETWORK_CONTROLLER + _controlPlane->setController(&_controller); +#endif { // Remember networks from previous session std::vector networksDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S + "networks.d").c_str())); @@ -763,8 +777,10 @@ private: } const std::string _homePath; +#ifdef ZT_ENABLE_NETWORK_CONTROLLER + SqliteNetworkController _controller; +#endif Phy _phy; - NetworkController *_master; std::string _overrideRootTopology; Node *_node; PhySocket *_v4UdpSocket; @@ -923,7 +939,7 @@ std::string OneService::platformDefaultHomePath() #endif // __UNIX_LIKE__ or not... } -OneService *OneService::newInstance(const char *hp,unsigned int port,NetworkController *master,const char *overrideRootTopology) { return new OneServiceImpl(hp,port,master,overrideRootTopology); } +OneService *OneService::newInstance(const char *hp,unsigned int port,const char *overrideRootTopology) { return new OneServiceImpl(hp,port,overrideRootTopology); } OneService::~OneService() {} } // namespace ZeroTier diff --git a/service/OneService.hpp b/service/OneService.hpp index 9df65179..33c40547 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -32,8 +32,6 @@ namespace ZeroTier { -class NetworkController; - /** * Local service for ZeroTier One as system VPN/NFV provider */ @@ -79,13 +77,11 @@ public: * * @param hp Home path * @param port TCP and UDP port for packets and HTTP control - * @param master Instance of network config master if this instance is to act as one (default: NULL) * @param overrideRootTopology String-serialized root topology (for testing, default: NULL) */ static OneService *newInstance( const char *hp, unsigned int port, - NetworkController *master = (NetworkController *)0, const char *overrideRootTopology = (const char *)0); virtual ~OneService(); -- cgit v1.2.3 From 0af18b164c0290b4cf65ffcf388563c330d18239 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sun, 17 May 2015 16:06:29 -0700 Subject: /var/db is for all of xBSD --- service/OneService.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'service') diff --git a/service/OneService.cpp b/service/OneService.cpp index 42b4fc00..fc2fba41 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -912,8 +912,8 @@ std::string OneService::platformDefaultHomePath() return std::string("/Library/Application Support/ZeroTier/One"); #else -#ifdef __FreeBSD__ - // FreeBSD likes /var/db instead of /var/lib +#ifdef __BSD__ + // BSD likes /var/db instead of /var/lib return std::string("/var/db/zerotier-one"); #else // Use /var/lib for Linux and other *nix -- cgit v1.2.3 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 ++++-- selftest.cpp | 6 ++---- service/ControlPlane.cpp | 2 ++ 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'service') 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); diff --git a/selftest.cpp b/selftest.cpp index 5d5067fd..3c7b0257 100644 --- a/selftest.cpp +++ b/selftest.cpp @@ -510,16 +510,14 @@ static int testCertificate() static int testPacket() { - unsigned char salsaKey[32],hmacKey[32]; + unsigned char salsaKey[32]; Packet a,b; a.burn(); b.burn(); - for(unsigned int i=0;i<32;++i) { + for(unsigned int i=0;i<32;++i) salsaKey[i] = (unsigned char)rand(); - hmacKey[i] = (unsigned char)rand(); - } std::cout << "[packet] Testing Packet encoder/decoder... "; diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index 81fb61ca..2e8290ed 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -33,7 +33,9 @@ #include "../ext/http-parser/http_parser.h" +#ifdef ZT_ENABLE_NETWORK_CONTROLLER #include "../controller/SqliteNetworkController.hpp" +#endif #include "../node/InetAddress.hpp" #include "../node/Node.hpp" -- cgit v1.2.3 From c7eb5f0c81d32f26d0cca47f80d9d9d5e1307aca Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 19 May 2015 18:13:20 -0700 Subject: Windows build warning removal, be more defensive in Windows tap driver code, and clean up service start/stop in installer. --- ext/installfiles/windows/ZeroTier One.aip | 18 +++++++----------- osdep/WindowsEthernetTap.cpp | 6 +++++- service/OneService.cpp | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'service') diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip index d45f306e..4be09951 100644 --- a/ext/installfiles/windows/ZeroTier One.aip +++ b/ext/installfiles/windows/ZeroTier One.aip @@ -1,5 +1,5 @@ - + @@ -23,7 +23,7 @@ - + @@ -123,8 +123,8 @@ - - + + @@ -205,7 +205,6 @@ - @@ -235,7 +234,6 @@ - @@ -253,7 +251,7 @@ - + @@ -262,8 +260,6 @@ - - @@ -314,8 +310,8 @@ - - + + diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp index 4a5d32a4..1cea0d96 100644 --- a/osdep/WindowsEthernetTap.cpp +++ b/osdep/WindowsEthernetTap.cpp @@ -594,7 +594,10 @@ void WindowsEthernetTap::threadMain() Utils::snprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_netCfgInstanceId.c_str()); int prevTapResetStatus = _systemTapResetStatus; + bool throwOneAway = true; // "Power cycle" the network port once on startup, because Windows... while (_run) { + Sleep(500); + _tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL); if (_tap == INVALID_HANDLE_VALUE) { fprintf(stderr,"Error opening %s -- retrying.\r\n",tapPath); @@ -698,7 +701,8 @@ void WindowsEthernetTap::threadMain() ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead); bool writeInProgress = false; while (_run) { - if (prevTapResetStatus != _systemTapResetStatus) { + if ((prevTapResetStatus != _systemTapResetStatus)||(throwOneAway)) { + throwOneAway = false; prevTapResetStatus = _systemTapResetStatus; break; // this will cause us to close and reopen the tap } diff --git a/service/OneService.cpp b/service/OneService.cpp index fc2fba41..a566449f 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -523,7 +523,7 @@ public: { TcpConnection *tc = reinterpret_cast(*uptr); if (tc->writeBuf.length()) { - long sent = _phy.tcpSend(sock,tc->writeBuf.data(),tc->writeBuf.length(),true); + long sent = (long)_phy.tcpSend(sock,tc->writeBuf.data(),(unsigned long)tc->writeBuf.length(),true); if (sent > 0) { tc->lastActivity = OSUtils::now(); if ((unsigned long)sent == (unsigned long)tc->writeBuf.length()) { -- cgit v1.2.3 From b6698d8415728a249426ee784fcbebfdfb8e4632 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 20 May 2015 16:35:33 -0700 Subject: Ground work for reincorporating software updater for select platforms. --- ext/installfiles/mac/get-proxy-settings.sh | 6 +++--- make-mac.mk | 20 ++++++++++++-------- one.cpp | 3 +++ service/OneService.cpp | 28 ++++++++++++++++++++++++++++ service/OneService.hpp | 14 ++++++++++++++ 5 files changed, 60 insertions(+), 11 deletions(-) (limited to 'service') diff --git a/ext/installfiles/mac/get-proxy-settings.sh b/ext/installfiles/mac/get-proxy-settings.sh index 873a8558..16ba0b47 100755 --- a/ext/installfiles/mac/get-proxy-settings.sh +++ b/ext/installfiles/mac/get-proxy-settings.sh @@ -5,9 +5,9 @@ export PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin -enabled=`system_profiler SPNetworkDataType|grep "HTTP Proxy Enabled"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'}` -port=`system_profiler SPNetworkDataType|grep "HTTP Proxy Port"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'}` -serv=`system_profiler SPNetworkDataType|grep "HTTP Proxy Server"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'}` +enabled=`system_profiler SPNetworkDataType|grep "HTTP Proxy Enabled"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null` +port=`system_profiler SPNetworkDataType|grep "HTTP Proxy Port"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null` +serv=`system_profiler SPNetworkDataType|grep "HTTP Proxy Server"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null` if [ "$enabled" = "Yes" ]; then if [ "$serv" ]; then diff --git a/make-mac.mk b/make-mac.mk index 717cbccb..4ad4c5ad 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -13,18 +13,13 @@ OBJS+=osdep/OSXEthernetTap.o CODESIGN=echo CODESIGN_CERT= +# For internal use only -- signs everything with ZeroTier's developer cert ifeq ($(ZT_OFFICIAL_RELEASE),1) - # For use by ZeroTier Networks -- sign with developer cert - ZT_AUTO_UPDATE=1 - DEFS+=-DZT_OFFICIAL_RELEASE + DEFS+=-DZT_OFFICIAL_RELEASE -DZT_AUTO_UPDATE CODESIGN=codesign 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 @@ -35,6 +30,7 @@ endif # Enable SSE-optimized Salsa20 -- all Intel macs support SSE2 DEFS+=-DZT_SALSA20_SSE +# Debug mode -- dump trace output, build binary with -g ifeq ($(ZT_DEBUG),1) DEFS+=-DZT_TRACE CFLAGS=-Wall -g -pthread $(INCLUDES) $(DEFS) @@ -63,10 +59,18 @@ selftest: $(OBJS) selftest.o $(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS) $(STRIP) zerotier-selftest -sign-pkg: FORCE +# Requires Packages: http://s.sudre.free.fr/Software/Packages/about.html +mac-dist-pkg: FORCE + cd ext/installfiles/mac ; packagesbuild "ZeroTier One.pkgproj" $(CODESIGN) -f -s $(CODESIGN_CERT) "ZeroTier One.pkg" $(CODESIGN) -vvv "ZeroTier One.pkg" +# For internal use only +official: FORCE + make clean + make -j 4 ZT_OFFICIAL_RELEASE=1 + make ZT_OFFICIAL_RELEASE=1 mac-dist-pkg + clean: rm -rf *.dSYM build-* *.pkg *.dmg *.o node/*.o controller/*.o service/*.o osdep/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o zerotier-one zerotier-idtool zerotier-selftest zerotier-cli ZeroTierOneInstaller-* diff --git a/one.cpp b/one.cpp index 4a0a57e8..f2d7970b 100644 --- a/one.cpp +++ b/one.cpp @@ -888,6 +888,9 @@ static void printHelp(const char *cn,FILE *out) { fprintf(out,"ZeroTier One version %d.%d.%d"ZT_EOL_S"(c)2011-2015 ZeroTier, Inc."ZT_EOL_S,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION); fprintf(out,"Licensed under the GNU General Public License v3"ZT_EOL_S""ZT_EOL_S); + std::string updateUrl(OneService::autoUpdateUrl()); + if (updateUrl.length()) + fprintf(out,"Automatic update enabled:"ZT_EOL_S" %s"ZT_EOL_S""ZT_EOL_S,updateUrl.c_str()); fprintf(out,"Usage: %s [-switches] [home directory]"ZT_EOL_S""ZT_EOL_S,cn); fprintf(out,"Available switches:"ZT_EOL_S); fprintf(out," -h - Display this help"ZT_EOL_S); diff --git a/service/OneService.cpp b/service/OneService.cpp index a566449f..c2ea034b 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -96,6 +96,8 @@ namespace ZeroTier { typedef BSDEthernetTap EthernetTap; } namespace ZeroTier { +namespace { + class OneServiceImpl; static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf); @@ -903,6 +905,8 @@ static int ShttpOnMessageComplete(http_parser *parser) return 0; } +} // anonymous namespace + std::string OneService::platformDefaultHomePath() { #ifdef __UNIX_LIKE__ @@ -939,6 +943,30 @@ std::string OneService::platformDefaultHomePath() #endif // __UNIX_LIKE__ or not... } +std::string OneService::autoUpdateUrl() +{ +#ifdef ZT_AUTO_UPDATE + +/* +#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"; +#endif +*/ + +#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"; +#endif + +#ifdef __WINDOWS__ + return "http://download.zerotier.com/update/win_intel/LATEST.nfo"; +#endif + +#endif // ZT_AUTO_UPDATE + return std::string(); +} + OneService *OneService::newInstance(const char *hp,unsigned int port,const char *overrideRootTopology) { return new OneServiceImpl(hp,port,overrideRootTopology); } OneService::~OneService() {} diff --git a/service/OneService.hpp b/service/OneService.hpp index 33c40547..aea314f5 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -34,6 +34,15 @@ namespace ZeroTier { /** * Local service for ZeroTier One as system VPN/NFV provider + * + * If built with ZT_ENABLE_NETWORK_CONTROLLER defined, this includes and + * runs controller/SqliteNetworkController with a database called + * controller.db in the specified home directory. + * + * If built with ZT_AUTO_UPDATE, an official ZeroTier update URL is + * periodically checked and updates are automatically downloaded, verified + * against a built-in list of update signing keys, and installed. This is + * only supported for certain platforms. */ class OneService { @@ -69,6 +78,11 @@ public: */ static std::string platformDefaultHomePath(); + /** + * @return Auto-update URL or empty string if auto-updates unsupported or not enabled + */ + static std::string autoUpdateUrl(); + /** * Create a new instance of the service * -- 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 'service') 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 905d2e91e598945d4ba3a42430cd288f0a1d0839 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 20 May 2015 20:17:56 -0700 Subject: Windows auto-update integration into OneService. --- ext/installfiles/windows/ZeroTier One.aip | 7 ++--- service/OneService.cpp | 49 ++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 9 deletions(-) (limited to 'service') diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip index 69c2c0b7..234873f8 100644 --- a/ext/installfiles/windows/ZeroTier One.aip +++ b/ext/installfiles/windows/ZeroTier One.aip @@ -23,7 +23,7 @@ - + @@ -52,7 +52,6 @@ - @@ -68,14 +67,13 @@ - - + @@ -196,7 +194,6 @@ - diff --git a/service/OneService.cpp b/service/OneService.cpp index b8a66f6f..790f691b 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -108,6 +108,7 @@ namespace { #ifdef ZT_AUTO_UPDATE #define ZT_AUTO_UPDATE_MAX_HTTP_RESPONSE_SIZE (1024 * 1024 * 64) +#define ZT_AUTO_UPDATE_CHECK_PERIOD 21600000 class BackgroundSoftwareUpdateChecker { public: @@ -247,6 +248,40 @@ public: /* Windows version comes in the form of .MSI package that * takes care of everything. */ { + char tempp[512],batp[512],msip[512],cmdline[512]; + if (GetTempPathA(sizeof(tempp),tempp) <= 0) + return; + CreateDirectoryA(tempp,(LPSECURITY_ATTRIBUTES)0); + Utils::snprintf(batp,sizeof(batp),"%s\\ZeroTierOne-update-%u.%u.%u.bat",tempp,vMajor,vMinor,vRevision); + Utils::snprintf(msip,sizeof(msip),"%s\\ZeroTierOne-update-%u.%u.%u.msi",tempp,vMajor,vMinor,vRevision); + FILE *msi = fopen(msip,"wb"); + if ((!msi)||(fwrite(fileData.data(),(size_t)fileData.length(),1,msi) != 1)) { + fclose(msi); + return; + } + fclose(msi); + FILE *bat = fopen(batp,"wb"); + if (!bat) + return; + fprintf(bat, + "TIMEOUT.EXE /T 1 /NOBREAK\r\n" + "NET.EXE STOP \"ZeroTierOneService\"\r\n" + "TIMEOUT.EXE /T 1 /NOBREAK\r\n" + "MSIEXEC.EXE /i \"%s\" /qn\r\n" + "TIMEOUT.EXE /T 1 /NOBREAK\r\n" + "NET.EXE START \"ZeroTierOneService\"\r\n" + "DEL \"%s\"\r\n" + "DEL \"%s\"\r\n", + msip, + msip, + batp); + fclose(bat); + STARTUPINFOA si; + PROCESS_INFORMATION pi; + memset(&si,0,sizeof(si)); + memset(&pi,0,sizeof(pi)); + Utils::snprintf(cmdline,sizeof(cmdline),"CMD.EXE /c \"%s\"",batp); + CreateProcessA(NULL,cmdline,NULL,NULL,FALSE,CREATE_NO_WINDOW|CREATE_NEW_PROCESS_GROUP,NULL,NULL,&si,&pi); } #endif // __WINDOWS__ @@ -367,10 +402,6 @@ 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() @@ -436,6 +467,9 @@ public: _nextBackgroundTaskDeadline = 0; uint64_t lastTapMulticastGroupCheck = 0; +#ifdef ZT_AUTO_UPDATE + uint64_t lastSoftwareUpdateCheck = 0; +#endif // ZT_AUTO_UPDATE for(;;) { _run_m.lock(); if (!_run) { @@ -453,6 +487,13 @@ public: dl = _nextBackgroundTaskDeadline; } +#ifdef ZT_AUTO_UPDATE + if ((now - lastSoftwareUpdateCheck) >= ZT_AUTO_UPDATE_CHECK_PERIOD) { + lastSoftwareUpdateCheck = OSUtils::now(); + Thread::start(&backgroundSoftwareUpdateChecker); + } +#endif // ZT_AUTO_UPDATE + if ((now - lastTapMulticastGroupCheck) >= ZT_TAP_CHECK_MULTICAST_INTERVAL) { lastTapMulticastGroupCheck = now; Mutex::Lock _l(_taps_m); -- cgit v1.2.3 From 0f7dcb3ef20f408df96307e19442cce2a1f5c6b5 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 21 May 2015 15:22:41 -0700 Subject: Add some proxy debugging, and auto-resolve and periodically re-resolve TCP fallback tunnel hostname. --- osdep/Phy.hpp | 1 + service/OneService.cpp | 28 +++++++++++++++++++++++----- tcp-proxy/tcp-proxy.cpp | 15 +++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) (limited to 'service') diff --git a/osdep/Phy.hpp b/osdep/Phy.hpp index 5cebe169..23fd2ee2 100644 --- a/osdep/Phy.hpp +++ b/osdep/Phy.hpp @@ -33,6 +33,7 @@ #include #include +#include #if defined(_WIN32) || defined(_WIN64) diff --git a/service/OneService.cpp b/service/OneService.cpp index 790f691b..aef3f557 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -53,6 +53,7 @@ #include "../osdep/Thread.hpp" #include "../osdep/OSUtils.hpp" #include "../osdep/Http.hpp" +#include "../osdep/BackgroundResolver.hpp" #include "OneService.hpp" #include "ControlPlane.hpp" @@ -102,6 +103,12 @@ namespace ZeroTier { typedef BSDEthernetTap EthernetTap; } // Path under ZT1 home for controller database if controller is enabled #define ZT1_CONTROLLER_DB_PATH "controller.db" +// TCP fallback relay host +#define ZT1_TCP_FALLBACK_RELAY "tcp-fallback.zerotier.com" + +// Frequency at which we re-resolve the TCP fallback relay +#define ZT1_TCP_FALLBACK_RERESOLVE_DELAY 86400000 + namespace ZeroTier { namespace { @@ -365,6 +372,7 @@ class OneServiceImpl : public OneService public: OneServiceImpl(const char *hp,unsigned int port,const char *overrideRootTopology) : _homePath((hp) ? hp : "."), + _tcpFallbackResolver(ZT1_TCP_FALLBACK_RELAY), #ifdef ZT_ENABLE_NETWORK_CONTROLLER _controller((_homePath + ZT_PATH_SEPARATOR_S + ZT1_CONTROLLER_DB_PATH).c_str()), #endif @@ -467,6 +475,7 @@ public: _nextBackgroundTaskDeadline = 0; uint64_t lastTapMulticastGroupCheck = 0; + uint64_t lastTcpFallbackResolve = 0; #ifdef ZT_AUTO_UPDATE uint64_t lastSoftwareUpdateCheck = 0; #endif // ZT_AUTO_UPDATE @@ -494,6 +503,11 @@ public: } #endif // ZT_AUTO_UPDATE + if ((now - lastTcpFallbackResolve) >= ZT1_TCP_FALLBACK_RERESOLVE_DELAY) { + lastTcpFallbackResolve = now; + _tcpFallbackResolver.resolveNow(); + } + if ((now - lastTapMulticastGroupCheck) >= ZT_TAP_CHECK_MULTICAST_INTERVAL) { lastTapMulticastGroupCheck = now; Mutex::Lock _l(_taps_m); @@ -595,7 +609,8 @@ public: if (!success) return; - // Outgoing connections are right now only tunnel connections + // Outgoing TCP connections are always TCP fallback tunnel connections. + TcpConnection *tc = &(_tcpConections[sock]); tc->type = TcpConnection::TCP_TUNNEL_OUTGOING; tc->shouldKeepAlive = true; // unused @@ -623,7 +638,8 @@ public: inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) { - // Incoming connections are TCP HTTP requests + // Incoming TCP connections are HTTP JSON API requests. + TcpConnection *tc = &(_tcpConections[sockN]); tc->type = TcpConnection::TCP_HTTP_INCOMING; tc->shouldKeepAlive = true; @@ -653,6 +669,7 @@ public: { TcpConnection *tc = reinterpret_cast(*uptr); switch(tc->type) { + case TcpConnection::TCP_HTTP_INCOMING: case TcpConnection::TCP_HTTP_OUTGOING: http_parser_execute(&(tc->parser),&HTTP_PARSER_SETTINGS,(const char *)data,len); @@ -661,6 +678,7 @@ public: return; } break; + case TcpConnection::TCP_TUNNEL_OUTGOING: tc->body.append((const char *)data,len); if (tc->body.length() > 65535) { @@ -727,12 +745,14 @@ public: return; } } + if (tc->body.length() > (mlen + 5)) tc->body = tc->body.substr(mlen + 5); else tc->body = ""; } } break; + } } @@ -829,9 +849,6 @@ public: this->terminate(); } break; - case ZT1_EVENT_SAW_MORE_RECENT_VERSION: { - } break; - case ZT1_EVENT_TRACE: { if (metaData) { ::fprintf(stderr,"%s"ZT_EOL_S,(const char *)metaData); @@ -994,6 +1011,7 @@ private: } const std::string _homePath; + BackgroundResolver _tcpFallbackResolver; #ifdef ZT_ENABLE_NETWORK_CONTROLLER SqliteNetworkController _controller; #endif diff --git a/tcp-proxy/tcp-proxy.cpp b/tcp-proxy/tcp-proxy.cpp index 9e3f5d07..e30981cc 100644 --- a/tcp-proxy/tcp-proxy.cpp +++ b/tcp-proxy/tcp-proxy.cpp @@ -45,6 +45,9 @@ #define ZT_TCP_PROXY_UDP_POOL_START_PORT 10000 #define ZT_TCP_PROXY_CONNECTION_TIMEOUT_SECONDS 300 +// Uncomment to print tracing output to stdout +#define ZT_TCP_PROXY_TRACE + using namespace ZeroTier; /* @@ -135,6 +138,10 @@ struct TcpProxyService if (rm != reverseMappings.end()) { Client &c = *(rm->second); +#ifdef ZT_TCP_PROXY_TRACE + printf("UDP [%u] %s >> %.16llx\n",len,reinterpret_cast(from)->toString().c_str(),(unsigned long long)&c); +#endif + unsigned long mlen = len; if (c.newVersion) mlen += 7; // new clients get IP info @@ -161,6 +168,10 @@ struct TcpProxyService for(unsigned long i=0;i> (unknown, discarded)\n",len,reinterpret_cast(from)->toString().c_str()); +#endif } } } @@ -180,6 +191,10 @@ struct TcpProxyService c.lastActivity = time((time_t *)0); c.newVersion = false; *uptrN = (void *)&c; + +#ifdef ZT_TCP_PROXY_TRACE + printf("TCP connect from %s -> %.16llx\n",reinterpret_cast(from)->toString().c_str(),(unsigned long long)&c); +#endif } void phyOnTcpClose(PhySocket *sock,void **uptr) -- 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 'service') 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

FieldTypeDescriptionWritable