Browse Source

Fix "orbit" semantics. Federation works.

Adam Ierymenko 8 years ago
parent
commit
af4e79735c
3 changed files with 24 additions and 5 deletions
  1. 4 4
      node/IncomingPacket.cpp
  2. 14 1
      node/Topology.cpp
  3. 6 0
      node/Topology.hpp

+ 4 - 4
node/IncomingPacket.cpp

@@ -455,16 +455,16 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
 
 				// Handle planet or moon updates if present
 				if ((ptr + 2) <= size()) {
-					const unsigned int worldLen = at<uint16_t>(ptr); ptr += 2;
-					if (RR->topology->isUpstream(peer->identity())) {
-						const unsigned int endOfWorlds = ptr + worldLen;
+					const unsigned int worldsLen = at<uint16_t>(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;
 					}
 				}
 

+ 14 - 1
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<World::Root>::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;
 				}
 			}
 		}

+ 6 - 0
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