From 7bae95836c8824a76e0299df776a708eb3e58576 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 19 Jun 2015 10:23:25 -0700 Subject: [PATCH] Root server terminology cleanup, and tighten up a security check by checking full identity of peers instead of just address. --- include/ZeroTierOne.h | 4 +- node/Constants.hpp | 6 +-- node/IncomingPacket.cpp | 16 +++--- node/Multicaster.cpp | 47 +---------------- node/Network.cpp | 6 +-- node/Node.cpp | 14 +++-- node/Packet.hpp | 2 +- node/Peer.cpp | 6 +-- node/SelfAwareness.cpp | 2 +- node/Switch.cpp | 26 +++++----- node/Topology.cpp | 109 +++++++++++++++++++++------------------ node/Topology.hpp | 73 +++++++++++--------------- service/ControlPlane.cpp | 6 +-- 13 files changed, 131 insertions(+), 186 deletions(-) diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index b67d97edf..b6ff69abe 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -559,8 +559,8 @@ typedef struct */ enum ZT1_PeerRole { ZT1_PEER_ROLE_LEAF = 0, // ordinary node - ZT1_PEER_ROLE_HUB = 1, // locally federated hub - ZT1_PEER_ROLE_ROOTSERVER = 2 // planetary rootserver + ZT1_PEER_ROLE_RELAY = 1, // relay node + ZT1_PEER_ROLE_ROOT = 2 // root server }; /** diff --git a/node/Constants.hpp b/node/Constants.hpp index aced6fe72..ac9dbc99c 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -254,7 +254,7 @@ /** * Delay between scans of the topology active peer DB for peers that need ping * - * This is also how often pings will be retried to upstream peers (rootservers) + * This is also how often pings will be retried to upstream peers (relays, roots) * constantly until something is heard. */ #define ZT_PING_CHECK_INVERVAL 6250 @@ -279,9 +279,9 @@ * * When we send something (including frames), we generally expect a response. * Switching relays if no response in a short period of time causes more - * rapid failover if a rootserver goes down or becomes unreachable. In the + * rapid failover if a root server goes down or becomes unreachable. In the * mistaken case, little harm is done as it'll pick the next-fastest - * rootserver and will switch back eventually. + * root server and will switch back eventually. */ #define ZT_PEER_RELAY_CONVERSATION_LATENCY_THRESHOLD 10000 diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 8f95b9bad..7e2bcdaa8 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -110,7 +110,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr case Packet::ERROR_OBJ_NOT_FOUND: if (inReVerb == Packet::VERB_WHOIS) { - if (RR->topology->isRootserver(peer->address())) + if (RR->topology->isRoot(peer->identity())) RR->sw->cancelWhoisRequest(Address(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH)); } else if (inReVerb == Packet::VERB_NETWORK_CONFIG_REQUEST) { SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); @@ -128,7 +128,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr break; case Packet::ERROR_IDENTITY_COLLISION: - if (RR->topology->isRootserver(peer->address())) + if (RR->topology->isRoot(peer->identity())) RR->node->postEvent(ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION); break; @@ -268,7 +268,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); bool trusted = false; - if (RR->topology->isRootserver(id.address())) { + if (RR->topology->isRoot(id)) { RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision); trusted = true; } @@ -353,7 +353,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p peer->setRemoteVersion(vProto,vMajor,vMinor,vRevision); bool trusted = false; - if (RR->topology->isRootserver(peer->address())) { + if (RR->topology->isRoot(peer->identity())) { RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision); trusted = true; } @@ -362,10 +362,10 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p } break; case Packet::VERB_WHOIS: { - // Right now only rootservers are allowed to send OK(WHOIS) to prevent - // poisoning attacks. Further decentralization will require some other - // kind of trust mechanism. - if (RR->topology->isRootserver(peer->address())) { + /* Right now only root servers are allowed to send OK(WHOIS) to prevent + * poisoning attacks. Further decentralization will require some other + * kind of trust mechanism. */ + if (RR->topology->isRoot(peer->identity())) { const Identity id(*this,ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY); if (id.locallyValidate()) RR->sw->doAnythingWaitingForPeer(RR->topology->addPeer(SharedPtr(new Peer(RR->identity,id)))); diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 360233fe9..29e89189b 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -216,7 +216,7 @@ void Multicaster::send( if ((now - gs.lastExplicitGather) >= ZT_MULTICAST_EXPLICIT_GATHER_DELAY) { gs.lastExplicitGather = now; - SharedPtr sn(RR->topology->getBestRootserver()); + SharedPtr sn(RR->topology->getBestRoot()); if (sn) { TRACE(">>MC upstream GATHER up to %u for group %.16llx/%s",gatherLimit,nwid,mg.toString().c_str()); @@ -269,51 +269,6 @@ void Multicaster::send( // Free allocated memory buffer if any if (indexes != idxbuf) delete [] indexes; - -#ifdef ZT_SUPPORT_LEGACY_MULTICAST - // This sends a P5 multicast up to our rootserver, who then - // redistributes it manually down to all <1.0.0 peers for - // legacy support. These peers don't support the new multicast - // frame type, so even if they receive it they will ignore it. - { - SharedPtr sn(RR->topology->getBestRootserver()); - if (sn) { - uint32_t rn = RR->prng->next32(); - Packet outp(sn->address(),RR->identity.address(),Packet::VERB_P5_MULTICAST_FRAME); - - outp.append((uint16_t)0xffff); // do not forward - outp.append((unsigned char)0,320 + 1024); // empty queue and bloom filter - - outp.append((unsigned char)((com) ? ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE : 0)); - outp.append((uint64_t)nwid); - outp.append((uint16_t)0); - outp.append((unsigned char)0); - outp.append((unsigned char)0); - RR->identity.address().appendTo(outp); - outp.append((const void *)&rn,3); // random multicast ID - if (src) - src.appendTo(outp); - else MAC(RR->identity.address(),nwid).appendTo(outp); - mg.mac().appendTo(outp); - outp.append((uint32_t)mg.adi()); - outp.append((uint16_t)etherType); - outp.append((uint16_t)len); - outp.append(data,len); - unsigned int signedPortionLen = outp.size() - ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX__START_OF_SIGNED_PORTION; - - C25519::Signature sig(RR->identity.sign(outp.field(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX__START_OF_SIGNED_PORTION,signedPortionLen),signedPortionLen)); - - outp.append((uint16_t)sig.size()); - outp.append(sig.data,(unsigned int)sig.size()); - - if (com) com->serialize(outp); - - outp.compress(); - outp.armor(sn->key(),true); - sn->send(RR,outp.data(),outp.size(),now); - } - } -#endif // ZT_SUPPORT_LEGACY_MULTICAST } void Multicaster::clean(uint64_t now) diff --git a/node/Network.cpp b/node/Network.cpp index 60262cd59..a217595af 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -518,13 +518,13 @@ public: RR(renv), _now(renv->node->now()), _network(nw), - _rootserverAddresses(renv->topology->rootserverAddresses()), + _rootAddresses(renv->topology->rootAddresses()), _allMulticastGroups(nw->_allMulticastGroups()) {} inline void operator()(Topology &t,const SharedPtr &p) { - if ( ( (p->hasActiveDirectPath(_now)) && (_network->_isAllowed(p->address())) ) || (std::find(_rootserverAddresses.begin(),_rootserverAddresses.end(),p->address()) != _rootserverAddresses.end()) ) { + if ( ( (p->hasActiveDirectPath(_now)) && (_network->_isAllowed(p->address())) ) || (std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end()) ) { Packet outp(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); for(std::vector::iterator mg(_allMulticastGroups.begin());mg!=_allMulticastGroups.end();++mg) { @@ -551,7 +551,7 @@ private: const RuntimeEnvironment *RR; uint64_t _now; Network *_network; - std::vector
_rootserverAddresses; + std::vector
_rootAddresses; std::vector _allMulticastGroups; }; diff --git a/node/Node.cpp b/node/Node.cpp index 1f6d474ce..45e2463ca 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -133,9 +133,7 @@ Node::Node( if (!rt.size()) rt.fromString(ZT_DEFAULTS.defaultRootTopology); } - Dictionary rootservers(rt.get("rootservers","")); - rootservers.update(rt.get("supernodes","")); - RR->topology->setRootservers(rootservers); + RR->topology->setRootServers(Dictionary(rt.get("rootservers",""))); postEvent(ZT1_EVENT_UP); } @@ -191,7 +189,7 @@ public: RR(renv), _now(now), _relays(relays), - _rootservers(RR->topology->rootserverAddresses()) + _rootAddresses(RR->topology->rootAddresses()) { } @@ -207,7 +205,7 @@ public: } } - if ((isRelay)||(std::find(_rootservers.begin(),_rootservers.end(),p->address()) != _rootservers.end())) { + if ((isRelay)||(std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end())) { p->doPingAndKeepalive(RR,_now); if (p->lastReceive() > lastReceiveFromUpstream) lastReceiveFromUpstream = p->lastReceive(); @@ -221,7 +219,7 @@ private: const RuntimeEnvironment *RR; uint64_t _now; const std::vector< std::pair > &_relays; - std::vector
_rootservers; + std::vector
_rootAddresses; }; ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) @@ -262,7 +260,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next } } - // Ping living or rootserver/relay peers + // Ping living or root server/relay peers _PingPeersThatNeedPing pfunc(RR,now,networkRelays); RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc); @@ -386,7 +384,7 @@ ZT1_PeerList *Node::peers() const p->versionRev = -1; } p->latency = pi->second->latency(); - p->role = RR->topology->isRootserver(pi->second->address()) ? ZT1_PEER_ROLE_ROOTSERVER : ZT1_PEER_ROLE_LEAF; + p->role = RR->topology->isRoot(pi->second->identity()) ? ZT1_PEER_ROLE_ROOT : ZT1_PEER_ROLE_LEAF; std::vector paths(pi->second->paths()); Path *bestPath = pi->second->getBestPath(_now); diff --git a/node/Packet.hpp b/node/Packet.hpp index 21f8ca574..49201b712 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -626,7 +626,7 @@ public: * [... additional tuples of network/address/adi ...] * * LIKEs are sent to peers with whom you have a direct peer to peer - * connection, and always including rootservers. + * connection, and always including root servers. * * OK/ERROR are not generated. */ diff --git a/node/Peer.cpp b/node/Peer.cpp index 3093ef41d..96caa72cf 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -122,16 +122,16 @@ void Peer::received( /* Announce multicast groups of interest to direct peers if they are * considered authorized members of a given network. Also announce to - * rootservers and network controllers. */ + * root servers and network controllers. */ if ((pathIsConfirmed)&&((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000))) { _lastAnnouncedTo = now; - const bool isRootserver = RR->topology->isRootserver(_id.address()); + const bool isRoot = RR->topology->isRoot(_id); Packet outp(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); const std::vector< SharedPtr > networks(RR->node->allNetworks()); for(std::vector< SharedPtr >::const_iterator n(networks.begin());n!=networks.end();++n) { - if ( (isRootserver) || ((*n)->isAllowed(_id.address())) ) { + if ( (isRoot) || ((*n)->isAllowed(_id.address())) ) { const std::vector mgs((*n)->allMulticastGroups()); for(std::vector::const_iterator mg(mgs.begin());mg!=mgs.end();++mg) { if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) { diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index 5fc8be2a6..9f7c41d7d 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -118,7 +118,7 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi // For all peers for whom we forgot an address, send a packet indirectly if // they are still considered alive so that we will re-establish direct links. - SharedPtr sn(RR->topology->getBestRootserver()); + SharedPtr sn(RR->topology->getBestRoot()); if (sn) { Path *snp = sn->getBestPath(now); if (snp) { diff --git a/node/Switch.cpp b/node/Switch.cpp index 3ac0b9206..af80f5e81 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -320,8 +320,8 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force) * P2 in randomized order in terms of which gets sent first. This is done * since in a few cases NAT-t can be sensitive to slight timing differences * in terms of when the two peers initiate. Normally this is accounted for - * by the nearly-simultaneous RENDEZVOUS kickoff from the rootserver, but - * given that rootservers are hosted on cloud providers this can in some + * by the nearly-simultaneous RENDEZVOUS kickoff from the relay, but + * given that relay are hosted on cloud providers this can in some * cases have a few ms of latency between packet departures. By randomizing * the order we make each attempted NAT-t favor one or the other going * first, meaning if it doesn't succeed the first time it might the second @@ -565,8 +565,8 @@ void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void // It wouldn't hurt anything, just redundant and unnecessary. SharedPtr relayTo = RR->topology->getPeer(destination); if ((!relayTo)||(!relayTo->send(RR,fragment.data(),fragment.size(),RR->node->now()))) { - // Don't know peer or no direct path -- so relay via rootserver - relayTo = RR->topology->getBestRootserver(); + // Don't know peer or no direct path -- so relay via root server + relayTo = RR->topology->getBestRoot(); if (relayTo) relayTo->send(RR,fragment.data(),fragment.size(),RR->node->now()); } @@ -641,8 +641,8 @@ void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,const void *dat if ((relayTo)&&((relayTo->send(RR,packet->data(),packet->size(),RR->node->now())))) { unite(source,destination,false); } else { - // Don't know peer or no direct path -- so relay via rootserver - relayTo = RR->topology->getBestRootserver(&source,1,true); + // Don't know peer or no direct path -- so relay via root server + relayTo = RR->topology->getBestRoot(&source,1,true); if (relayTo) relayTo->send(RR,packet->data(),packet->size(),RR->node->now()); } @@ -712,13 +712,13 @@ void Switch::_handleBeacon(const InetAddress &fromAddr,const Buffer rootserver(RR->topology->getBestRootserver(peersAlreadyConsulted,numPeersAlreadyConsulted,false)); - if (rootserver) { - Packet outp(rootserver->address(),RR->identity.address(),Packet::VERB_WHOIS); + SharedPtr root(RR->topology->getBestRoot(peersAlreadyConsulted,numPeersAlreadyConsulted,false)); + if (root) { + Packet outp(root->address(),RR->identity.address(),Packet::VERB_WHOIS); addr.appendTo(outp); - outp.armor(rootserver->key(),true); - if (rootserver->send(RR,outp.data(),outp.size(),RR->node->now())) - return rootserver->address(); + outp.armor(root->key(),true); + if (root->send(RR,outp.data(),outp.size(),RR->node->now())) + return root->address(); } return Address(); } @@ -752,7 +752,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) } if (!relay) - relay = RR->topology->getBestRootserver(); + relay = RR->topology->getBestRoot(); if (!(relay)||(!(viaPath = relay->getBestPath(now)))) return false; diff --git a/node/Topology.cpp b/node/Topology.cpp index cfa6749cd..2b1cc31fe 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -36,7 +36,7 @@ namespace ZeroTier { Topology::Topology(const RuntimeEnvironment *renv) : RR(renv), - _amRootserver(false) + _amRoot(false) { } @@ -44,16 +44,16 @@ Topology::~Topology() { } -void Topology::setRootservers(const std::map< Identity,std::vector > &sn) +void Topology::setRootServers(const std::map< Identity,std::vector > &sn) { Mutex::Lock _l(_lock); - if (_rootservers == sn) + if (_roots == sn) return; // no change - _rootservers = sn; - _rootserverAddresses.clear(); - _rootserverPeers.clear(); + _roots = sn; + _rootAddresses.clear(); + _rootPeers.clear(); const uint64_t now = RR->node->now(); for(std::map< Identity,std::vector >::const_iterator i(sn.begin());i!=sn.end();++i) { @@ -64,17 +64,17 @@ void Topology::setRootservers(const std::map< Identity,std::vector for(std::vector::const_iterator j(i->second.begin());j!=i->second.end();++j) p->addPath(Path(*j,true)); p->use(now); - _rootserverPeers.push_back(p); + _rootPeers.push_back(p); } - _rootserverAddresses.push_back(i->first.address()); + _rootAddresses.push_back(i->first.address()); } - std::sort(_rootserverAddresses.begin(),_rootserverAddresses.end()); + std::sort(_rootAddresses.begin(),_rootAddresses.end()); - _amRootserver = (_rootservers.find(RR->identity) != _rootservers.end()); + _amRoot = (_roots.find(RR->identity) != _roots.end()); } -void Topology::setRootservers(const Dictionary &sn) +void Topology::setRootServers(const Dictionary &sn) { std::map< Identity,std::vector > m; for(Dictionary::const_iterator d(sn.begin());d!=sn.end();++d) { @@ -86,11 +86,11 @@ void Topology::setRootservers(const Dictionary &sn) if (udp.length() > 0) a.push_back(InetAddress(udp)); } catch ( ... ) { - TRACE("rootserver list contained invalid entry for: %s",d->first.c_str()); + TRACE("root server list contained invalid entry for: %s",d->first.c_str()); } } } - this->setRootservers(m); + this->setRootServers(m); } SharedPtr Topology::addPeer(const SharedPtr &peer) @@ -141,28 +141,28 @@ SharedPtr Topology::getPeer(const Address &zta) return SharedPtr(); } -SharedPtr Topology::getBestRootserver(const Address *avoid,unsigned int avoidCount,bool strictAvoid) +SharedPtr Topology::getBestRoot(const Address *avoid,unsigned int avoidCount,bool strictAvoid) { - SharedPtr bestRootserver; + SharedPtr bestRoot; const uint64_t now = RR->node->now(); Mutex::Lock _l(_lock); - if (_amRootserver) { - /* If I am a rootserver, the "best" rootserver is the one whose address + if (_amRoot) { + /* If I am a root server, the "best" root server is the one whose address * is numerically greater than mine (with wrap at top of list). This * causes packets searching for a route to pretty much literally * circumnavigate the globe rather than bouncing between just two. */ - if (_rootserverAddresses.size() > 1) { // gotta be one other than me for this to work - std::vector
::const_iterator sna(std::find(_rootserverAddresses.begin(),_rootserverAddresses.end(),RR->identity.address())); - if (sna != _rootserverAddresses.end()) { // sanity check -- _amRootserver should've been false in this case + if (_rootAddresses.size() > 1) { // gotta be one other than me for this to work + std::vector
::const_iterator sna(std::find(_rootAddresses.begin(),_rootAddresses.end(),RR->identity.address())); + if (sna != _rootAddresses.end()) { // sanity check -- _amRoot should've been false in this case for(;;) { - if (++sna == _rootserverAddresses.end()) - sna = _rootserverAddresses.begin(); // wrap around at end + if (++sna == _rootAddresses.end()) + sna = _rootAddresses.begin(); // wrap around at end if (*sna != RR->identity.address()) { // pick one other than us -- starting from me+1 in sorted set order std::map< Address,SharedPtr >::const_iterator p(_activePeers.find(*sna)); if ((p != _activePeers.end())&&(p->second->hasActiveDirectPath(now))) { - bestRootserver = p->second; + bestRoot = p->second; break; } } @@ -170,80 +170,87 @@ SharedPtr Topology::getBestRootserver(const Address *avoid,unsigned int av } } } else { - /* If I am not a rootserver, the best rootserver is the active one with + /* If I am not a root server, the best root server is the active one with * the lowest latency. */ - unsigned int l,bestRootserverLatency = 65536; + unsigned int l,bestLatency = 65536; uint64_t lds,ldr; - // First look for a best rootserver by comparing latencies, but exclude - // rootservers that have not responded to direct messages in order to + // First look for a best root by comparing latencies, but exclude + // root servers that have not responded to direct messages in order to // try to exclude any that are dead or unreachable. - for(std::vector< SharedPtr >::const_iterator sn(_rootserverPeers.begin());sn!=_rootserverPeers.end();) { + for(std::vector< SharedPtr >::const_iterator sn(_rootPeers.begin());sn!=_rootPeers.end();) { // Skip explicitly avoided relays for(unsigned int i=0;iaddress()) - goto keep_searching_for_rootservers; + goto keep_searching_for_roots; } // Skip possibly comatose or unreachable relays lds = (*sn)->lastDirectSend(); ldr = (*sn)->lastDirectReceive(); if ((lds)&&(lds > ldr)&&((lds - ldr) > ZT_PEER_RELAY_CONVERSATION_LATENCY_THRESHOLD)) - goto keep_searching_for_rootservers; + goto keep_searching_for_roots; if ((*sn)->hasActiveDirectPath(now)) { l = (*sn)->latency(); - if (bestRootserver) { - if ((l)&&(l < bestRootserverLatency)) { - bestRootserverLatency = l; - bestRootserver = *sn; + if (bestRoot) { + if ((l)&&(l < bestLatency)) { + bestLatency = l; + bestRoot = *sn; } } else { if (l) - bestRootserverLatency = l; - bestRootserver = *sn; + bestLatency = l; + bestRoot = *sn; } } -keep_searching_for_rootservers: +keep_searching_for_roots: ++sn; } - if (bestRootserver) { - bestRootserver->use(now); - return bestRootserver; + if (bestRoot) { + bestRoot->use(now); + return bestRoot; } else if (strictAvoid) return SharedPtr(); // If we have nothing from above, just pick one without avoidance criteria. - for(std::vector< SharedPtr >::const_iterator sn=_rootserverPeers.begin();sn!=_rootserverPeers.end();++sn) { + for(std::vector< SharedPtr >::const_iterator sn=_rootPeers.begin();sn!=_rootPeers.end();++sn) { if ((*sn)->hasActiveDirectPath(now)) { unsigned int l = (*sn)->latency(); - if (bestRootserver) { - if ((l)&&(l < bestRootserverLatency)) { - bestRootserverLatency = l; - bestRootserver = *sn; + if (bestRoot) { + if ((l)&&(l < bestLatency)) { + bestLatency = l; + bestRoot = *sn; } } else { if (l) - bestRootserverLatency = l; - bestRootserver = *sn; + bestLatency = l; + bestRoot = *sn; } } } } - if (bestRootserver) - bestRootserver->use(now); - return bestRootserver; + if (bestRoot) + bestRoot->use(now); + return bestRoot; +} + +bool Topology::isRoot(const Identity &id) const + throw() +{ + Mutex::Lock _l(_lock); + return (_roots.count(id) != 0); } void Topology::clean(uint64_t now) { Mutex::Lock _l(_lock); for(std::map< Address,SharedPtr >::iterator p(_activePeers.begin());p!=_activePeers.end();) { - if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(std::find(_rootserverAddresses.begin(),_rootserverAddresses.end(),p->first) == _rootserverAddresses.end())) { + if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(std::find(_rootAddresses.begin(),_rootAddresses.end(),p->first) == _rootAddresses.end())) { _activePeers.erase(p++); } else ++p; } diff --git a/node/Topology.hpp b/node/Topology.hpp index 8aeae784e..c878bcc6e 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -59,21 +59,19 @@ public: ~Topology(); /** - * Set up rootservers for this network - * - * @param sn Rootservers for this network + * @param sn Root server identities and addresses */ - void setRootservers(const std::map< Identity,std::vector > &sn); + void setRootServers(const std::map< Identity,std::vector > &sn); /** - * Set up rootservers for this network + * Set up root servers for this network * * This performs no signature verification of any kind. The caller must * check the signature of the root topology dictionary first. * - * @param sn Rootservers dictionary from root-topology + * @param sn 'rootservers' key from root-topology Dictionary (deserialized as Dictionary) */ - void setRootservers(const Dictionary &sn); + void setRootServers(const Dictionary &sn); /** * Add a peer to database @@ -95,65 +93,52 @@ public: SharedPtr getPeer(const Address &zta); /** - * @return Vector of peers that are rootservers + * @return Vector of peers that are root servers */ - inline std::vector< SharedPtr > rootserverPeers() const + inline std::vector< SharedPtr > rootPeers() const { Mutex::Lock _l(_lock); - return _rootserverPeers; + return _rootPeers; } /** - * @return Number of rootservers - */ - inline unsigned int numRootservers() const - { - Mutex::Lock _l(_lock); - return (unsigned int)_rootserverPeers.size(); - } - - /** - * Get the current favorite rootserver + * Get the current favorite root server * - * @return Rootserver with lowest latency or NULL if none + * @return Root server with lowest latency or NULL if none */ - inline SharedPtr getBestRootserver() + inline SharedPtr getBestRoot() { - return getBestRootserver((const Address *)0,0,false); + return getBestRoot((const Address *)0,0,false); } /** - * Get the best rootserver, avoiding rootservers listed in an array + * Get the best root server, avoiding root servers listed in an array * - * This will get the best rootserver (lowest latency, etc.) but will - * try to avoid the listed rootservers, only using them if no others + * This will get the best root server (lowest latency, etc.) but will + * try to avoid the listed root servers, only using them if no others * are available. * * @param avoid Nodes to avoid * @param avoidCount Number of nodes to avoid - * @param strictAvoid If false, consider avoided rootservers anyway if no non-avoid rootservers are available - * @return Rootserver or NULL if none + * @param strictAvoid If false, consider avoided root servers anyway if no non-avoid root servers are available + * @return Root server or NULL if none available */ - SharedPtr getBestRootserver(const Address *avoid,unsigned int avoidCount,bool strictAvoid); + SharedPtr getBestRoot(const Address *avoid,unsigned int avoidCount,bool strictAvoid); /** - * @param zta ZeroTier address - * @return True if this is a designated rootserver + * @param id Identity to check + * @return True if this is a designated root server */ - inline bool isRootserver(const Address &zta) const - throw() - { - Mutex::Lock _l(_lock); - return (std::find(_rootserverAddresses.begin(),_rootserverAddresses.end(),zta) != _rootserverAddresses.end()); - } + bool isRoot(const Identity &id) const + throw(); /** - * @return Vector of rootserver addresses + * @return Vector of root server addresses */ - inline std::vector
rootserverAddresses() const + inline std::vector
rootAddresses() const { Mutex::Lock _l(_lock); - return _rootserverAddresses; + return _rootAddresses; } /** @@ -206,13 +191,13 @@ private: const RuntimeEnvironment *RR; std::map< Address,SharedPtr > _activePeers; - std::map< Identity,std::vector > _rootservers; - std::vector< Address > _rootserverAddresses; - std::vector< SharedPtr > _rootserverPeers; + std::map< Identity,std::vector > _roots; + std::vector< Address > _rootAddresses; + std::vector< SharedPtr > _rootPeers; Mutex _lock; - bool _amRootserver; + bool _amRoot; }; } // namespace ZeroTier diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index e42c9ef85..015825867 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -211,9 +211,9 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT1_Peer *peer const char *prole = ""; switch(peer->role) { - case ZT1_PEER_ROLE_LEAF: prole = "LEAF"; break; - case ZT1_PEER_ROLE_HUB: prole = "HUB"; break; - case ZT1_PEER_ROLE_ROOTSERVER: prole = "ROOT"; break; + case ZT1_PEER_ROLE_LEAF: prole = "LEAF"; break; + case ZT1_PEER_ROLE_RELAY: prole = "RELAY"; break; + case ZT1_PEER_ROLE_ROOT: prole = "ROOT"; break; } Utils::snprintf(json,sizeof(json),