|
|
|
|
@ -48,13 +48,6 @@ Topology::Topology(const RuntimeEnvironment *renv) :
|
|
|
|
|
_trustedPathCount(0), |
|
|
|
|
_amRoot(false) |
|
|
|
|
{ |
|
|
|
|
World defaultPlanet; |
|
|
|
|
{ |
|
|
|
|
Buffer<ZT_DEFAULT_WORLD_LENGTH> wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH); |
|
|
|
|
defaultPlanet.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top
|
|
|
|
|
} |
|
|
|
|
addWorld(defaultPlanet,false); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
World cachedPlanet; |
|
|
|
|
std::string buf(RR->node->dataStoreGet("planet")); |
|
|
|
|
@ -64,6 +57,13 @@ Topology::Topology(const RuntimeEnvironment *renv) :
|
|
|
|
|
} |
|
|
|
|
addWorld(cachedPlanet,false); |
|
|
|
|
} catch ( ... ) {} |
|
|
|
|
|
|
|
|
|
World defaultPlanet; |
|
|
|
|
{ |
|
|
|
|
Buffer<ZT_DEFAULT_WORLD_LENGTH> wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH); |
|
|
|
|
defaultPlanet.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top
|
|
|
|
|
} |
|
|
|
|
addWorld(defaultPlanet,false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SharedPtr<Peer> Topology::addPeer(const SharedPtr<Peer> &peer) |
|
|
|
|
@ -287,7 +287,7 @@ bool Topology::addWorld(const World &newWorld,bool updateOnly)
|
|
|
|
|
|
|
|
|
|
char savePath[64]; |
|
|
|
|
if (existing->type() == World::TYPE_MOON) |
|
|
|
|
Utils::snprintf(savePath,sizeof(savePath),"moons.d/%.16llx",existing->id()); |
|
|
|
|
Utils::snprintf(savePath,sizeof(savePath),"moons.d/%.16llx.moon",existing->id()); |
|
|
|
|
else Utils::scopy(savePath,sizeof(savePath),"planet"); |
|
|
|
|
try { |
|
|
|
|
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp; |
|
|
|
|
@ -297,22 +297,71 @@ bool Topology::addWorld(const World &newWorld,bool updateOnly)
|
|
|
|
|
RR->node->dataStoreDelete(savePath); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_upstreamAddresses.clear(); |
|
|
|
|
_amRoot = false; |
|
|
|
|
for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) { |
|
|
|
|
if (i->identity == RR->identity) |
|
|
|
|
_amRoot = true; |
|
|
|
|
else _upstreamAddresses.push_back(i->identity.address()); |
|
|
|
|
if (existing->type() == World::TYPE_MOON) { |
|
|
|
|
std::vector<Address> cm; |
|
|
|
|
for(std::vector<Address>::const_iterator m(_contacingMoons.begin());m!=_contacingMoons.end();++m) { |
|
|
|
|
if (m->toInt() != ((existing->id() >> 24) & 0xffffffffffULL)) |
|
|
|
|
cm.push_back(*m); |
|
|
|
|
} |
|
|
|
|
_contacingMoons.swap(cm); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_memoizeUpstreams(); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Topology::addMoon(const uint64_t id) |
|
|
|
|
{ |
|
|
|
|
char savePath[64]; |
|
|
|
|
Utils::snprintf(savePath,sizeof(savePath),"moons.d/%.16llx.moon",id); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
std::string moonBin(RR->node->dataStoreGet(savePath)); |
|
|
|
|
if (moonBin.length() > 1) { |
|
|
|
|
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> wtmp(moonBin.data(),(unsigned int)moonBin.length()); |
|
|
|
|
World w; |
|
|
|
|
w.deserialize(wtmp); |
|
|
|
|
if (w.type() == World::TYPE_MOON) { |
|
|
|
|
addWorld(w,false); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} catch ( ... ) {} |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
const Address a(id >> 24); |
|
|
|
|
Mutex::Lock _l(_lock); |
|
|
|
|
if (std::find(_contacingMoons.begin(),_contacingMoons.end(),a) == _contacingMoons.end()) |
|
|
|
|
_contacingMoons.push_back(a); |
|
|
|
|
} |
|
|
|
|
RR->node->dataStorePut(savePath,"\0",1,false); // persist that we want to be a member
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Topology::removeMoon(const uint64_t id) |
|
|
|
|
{ |
|
|
|
|
Mutex::Lock _l(_lock); |
|
|
|
|
|
|
|
|
|
std::vector<World> nm; |
|
|
|
|
for(std::vector<World>::const_iterator m(_moons.begin());m!=_moons.end();++m) { |
|
|
|
|
for(std::vector<World::Root>::const_iterator i(m->roots().begin());i!=m->roots().end();++i) { |
|
|
|
|
if (i->identity == RR->identity) |
|
|
|
|
_amRoot = true; |
|
|
|
|
else _upstreamAddresses.push_back(i->identity.address()); |
|
|
|
|
if (m->id() != id) { |
|
|
|
|
nm.push_back(*m); |
|
|
|
|
} else { |
|
|
|
|
char savePath[64]; |
|
|
|
|
Utils::snprintf(savePath,sizeof(savePath),"moons.d/%.16llx.moon",id); |
|
|
|
|
RR->node->dataStoreDelete(savePath); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_moons.swap(nm); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
std::vector<Address> cm; |
|
|
|
|
for(std::vector<Address>::const_iterator m(_contacingMoons.begin());m!=_contacingMoons.end();++m) { |
|
|
|
|
if (m->toInt() != ((id >> 24) & 0xffffffffffULL)) |
|
|
|
|
cm.push_back(*m); |
|
|
|
|
} |
|
|
|
|
_contacingMoons.swap(cm); |
|
|
|
|
|
|
|
|
|
_memoizeUpstreams(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Topology::clean(uint64_t now) |
|
|
|
|
@ -351,4 +400,37 @@ Identity Topology::_getIdentity(const Address &zta)
|
|
|
|
|
return Identity(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Topology::_memoizeUpstreams() |
|
|
|
|
{ |
|
|
|
|
// assumes _lock is locked
|
|
|
|
|
_upstreamAddresses.clear(); |
|
|
|
|
_amRoot = false; |
|
|
|
|
for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) { |
|
|
|
|
if (i->identity == RR->identity) { |
|
|
|
|
_amRoot = true; |
|
|
|
|
} else { |
|
|
|
|
_upstreamAddresses.push_back(i->identity.address()); |
|
|
|
|
SharedPtr<Peer> &hp = _peers[i->identity.address()]; |
|
|
|
|
if (!hp) { |
|
|
|
|
hp = new Peer(RR,RR->identity,i->identity); |
|
|
|
|
saveIdentity(i->identity); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for(std::vector<World>::const_iterator m(_moons.begin());m!=_moons.end();++m) { |
|
|
|
|
for(std::vector<World::Root>::const_iterator i(m->roots().begin());i!=m->roots().end();++i) { |
|
|
|
|
if (i->identity == RR->identity) { |
|
|
|
|
_amRoot = true; |
|
|
|
|
} else { |
|
|
|
|
_upstreamAddresses.push_back(i->identity.address()); |
|
|
|
|
SharedPtr<Peer> &hp = _peers[i->identity.address()]; |
|
|
|
|
if (!hp) { |
|
|
|
|
hp = new Peer(RR,RR->identity,i->identity); |
|
|
|
|
saveIdentity(i->identity); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace ZeroTier
|
|
|
|
|
|