From af4e79735c3f97d4228472077bcd5d2ddfb2cb93 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 13 Feb 2017 16:38:21 -0800 Subject: [PATCH] Fix "orbit" semantics. Federation works. --- node/IncomingPacket.cpp | 8 ++++---- node/Topology.cpp | 15 ++++++++++++++- node/Topology.hpp | 6 ++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 41a069370..b077f7e21 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -455,16 +455,16 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p // Handle planet or moon updates if present if ((ptr + 2) <= size()) { - const unsigned int worldLen = at(ptr); ptr += 2; - if (RR->topology->isUpstream(peer->identity())) { - const unsigned int endOfWorlds = ptr + worldLen; + const unsigned int worldsLen = at(ptr); ptr += 2; + if (RR->topology->shouldAcceptWorldUpdateFrom(peer->address())) { + const unsigned int endOfWorlds = ptr + worldsLen; while (ptr < endOfWorlds) { World w; ptr += w.deserialize(*this,ptr); RR->topology->addWorld(w,false); } } else { - ptr += worldLen; + ptr += worldsLen; } } diff --git a/node/Topology.cpp b/node/Topology.cpp index 7d0b0550c..5abc4df0e 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -225,6 +225,18 @@ bool Topology::isUpstream(const Identity &id) const return (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),id.address()) != _upstreamAddresses.end()); } +bool Topology::shouldAcceptWorldUpdateFrom(const Address &addr) const +{ + Mutex::Lock _l(_upstreams_m); + if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),addr) != _upstreamAddresses.end()) + return true; + for(std::vector< std::pair< uint64_t,Address> >::const_iterator s(_moonSeeds.begin());s!=_moonSeeds.end();++s) { + if (s->second == addr) + return true; + } + return false; +} + ZT_PeerRole Topology::role(const Address &ztaddr) const { Mutex::Lock _l(_upstreams_m); @@ -312,12 +324,13 @@ bool Topology::addWorld(const World &newWorld,bool alwaysAcceptNew) for(std::vector::const_iterator r(newWorld.roots().begin());r!=newWorld.roots().end();++r) { if (r->identity.address() == m->second) { _moonSeeds.erase(m); - m = _moonSeeds.end(); // cause outer loop to terminate _moons.push_back(newWorld); existing = &(_moons.back()); break; } } + if (existing) + break; } } } diff --git a/node/Topology.hpp b/node/Topology.hpp index 39367d6e9..37615b490 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -147,6 +147,12 @@ public: */ bool isUpstream(const Identity &id) const; + /** + * @param addr Address to check + * @return True if we should accept a world update from this address + */ + bool shouldAcceptWorldUpdateFrom(const Address &addr) const; + /** * @param ztaddr ZeroTier address * @return Peer role for this device