diff options
Diffstat (limited to 'node')
-rw-r--r-- | node/Constants.hpp | 7 | ||||
-rw-r--r-- | node/Node.cpp | 53 | ||||
-rw-r--r-- | node/Topology.cpp | 3 |
3 files changed, 61 insertions, 2 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp index 8a8c70f2..53754712 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -410,6 +410,13 @@ #define ZT_UPDATE_HTTP_TIMEOUT 120 /** + * 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 + +/** * Sanity limit on maximum bridge routes * * If the number of bridge routes exceeds this, we cull routes from the diff --git a/node/Node.cpp b/node/Node.cpp index e031dbdb..5d7de540 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -77,6 +77,7 @@ #include "IpcConnection.hpp" #include "AntiRecursion.hpp" #include "RoutingTable.hpp" +#include "HttpClient.hpp" namespace ZeroTier { @@ -220,8 +221,10 @@ struct _NodeImpl RuntimeEnvironment renv; unsigned int udpPort,tcpPort; + std::string reasonForTerminationStr; volatile Node::ReasonForTermination reasonForTermination; + volatile bool started; volatile bool running; volatile bool resynchronize; @@ -405,6 +408,47 @@ static void _CBztTraffic(const SharedPtr<Socket> &fromSock,void *arg,const InetA _r->sw->onRemotePacket(fromSock,from,data); } +static void _cbHandleGetRootTopology(void *arg,int code,const std::string &url,bool onDisk,const std::string &body) +{ + RuntimeEnvironment *_r = (RuntimeEnvironment *)arg; + if (_r->shutdownInProgress) + return; + + if ((code != 200)||(body.length() == 0)) { + TRACE("failed to retrieve %s",ZT_DEFAULTS.rootTopologyUpdateURL.c_str()); + return; + } + + try { + Dictionary rt(body); + if (!Topology::authenticateRootTopology(rt)) { + LOG("discarded invalid root topology update from %s (signature check failed)",url.c_str()); + return; + } + + { + std::string rootTopologyPath(_r->homePath + ZT_PATH_SEPARATOR_S + "root-topology"); + std::string rootTopology; + if (Utils::readFile(rootTopologyPath.c_str(),rootTopology)) { + Dictionary alreadyHave(rootTopology); + if (alreadyHave == rt) { + TRACE("retrieved root topology from %s but no change (same)",url.c_str()); + return; + } else if (alreadyHave.signatureTimestamp() > rt.signatureTimestamp()) { + TRACE("retrieved root topology from %s but no change (ours is newer)",url.c_str()); + return; + } + } + Utils::writeFile(rootTopologyPath.c_str(),body); + } + + _r->topology->setSupernodes(Dictionary(rt.get("supernodes"))); + } catch ( ... ) { + LOG("discarded invalid root topology update from %s (format invalid)",url.c_str()); + return; + } +} + Node::ReasonForTermination Node::run() throw() { @@ -508,8 +552,7 @@ Node::ReasonForTermination Node::run() Dictionary rt(rootTopology); if (!Topology::authenticateRootTopology(rt)) return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"root-topology failed signature verification check"); - Dictionary supernodes(rt.get("supernodes")); - _r->topology->setSupernodes(supernodes); + _r->topology->setSupernodes(Dictionary(rt.get("supernodes"))); } catch ( ... ) { return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"invalid root-topology format"); } @@ -555,6 +598,7 @@ Node::ReasonForTermination Node::run() uint64_t lastMulticastCheck = 0; uint64_t lastSupernodePingCheck = 0; uint64_t lastBeacon = 0; + uint64_t lastRootTopologyFetch = 0; long lastDelayDelta = 0; uint64_t networkConfigurationFingerprint = 0; @@ -711,6 +755,11 @@ Node::ReasonForTermination Node::run() _r->sm->send(ZT_DEFAULTS.v4Broadcast,false,false,bcn,ZT_PROTO_BEACON_LENGTH); } + if ((now - lastRootTopologyFetch) >= ZT_UPDATE_ROOT_TOPOLOGY_CHECK_INTERVAL) { + lastRootTopologyFetch = now; + HttpClient::GET(ZT_DEFAULTS.rootTopologyUpdateURL,HttpClient::NO_HEADERS,60,&_cbHandleGetRootTopology,_r); + } + // Sleep for loop interval or until something interesting happens. try { unsigned long delay = std::min((unsigned long)ZT_MAX_SERVICE_LOOP_INTERVAL,_r->sw->doTimerTasks()); diff --git a/node/Topology.cpp b/node/Topology.cpp index 6fcb17af..109cbca2 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -57,6 +57,9 @@ void Topology::setSupernodes(const std::map< Identity,std::vector< std::pair<Ine { Mutex::Lock _l(_supernodes_m); + if (_supernodes == sn) + return; // no change + _supernodes = sn; _supernodeAddresses.clear(); _supernodePeers.clear(); |