More World stuff, and mkworld.

This commit is contained in:
Adam Ierymenko 2015-10-13 08:49:36 -07:00
parent 1b1945c63e
commit cae58f43f1
13 changed files with 281 additions and 105 deletions

View file

@ -42,23 +42,6 @@ Topology::Topology(const RuntimeEnvironment *renv) :
RR(renv),
_amRoot(false)
{
try {
std::string dsWorld(RR->node->dataStoreGet("world"));
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp(dsWorld.data(),dsWorld.length());
_world.deserialize(dswtmp,0);
} catch ( ... ) {
_world = World(); // set to null if cached world is invalid
}
{
World defaultWorld;
Buffer<ZT_DEFAULT_WORLD_LENGTH> wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH);
defaultWorld.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top
if (_world.verifyUpdate(defaultWorld)) {
_world = defaultWorld;
RR->node->dataStorePut("world",ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH,false);
}
}
std::string alls(RR->node->dataStoreGet("peers.save"));
const uint8_t *all = reinterpret_cast<const uint8_t *>(alls.data());
RR->node->dataStoreDelete("peers.save");
@ -97,19 +80,24 @@ Topology::Topology(const RuntimeEnvironment *renv) :
clean(RR->node->now());
for(std::vector<World::Root>::const_iterator r(_world.roots().begin());r!=_world.roots().end();++r) {
if (r->identity == RR->identity)
_amRoot = true;
_rootAddresses.push_back(r->identity.address());
SharedPtr<Peer> *rp = _peers.get(r->identity.address());
if (rp) {
_rootPeers.push_back(*rp);
} else if (r->identity.address() != RR->identity.address()) {
SharedPtr<Peer> newrp(new Peer(RR->identity,r->identity));
_peers.set(r->identity.address(),newrp);
_rootPeers.push_back(newrp);
}
std::string dsWorld(RR->node->dataStoreGet("world"));
World cachedWorld;
try {
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp(dsWorld.data(),dsWorld.length());
cachedWorld.deserialize(dswtmp,0);
} catch ( ... ) {
cachedWorld = World(); // clear if cached world is invalid
}
World defaultWorld;
{
Buffer<ZT_DEFAULT_WORLD_LENGTH> wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH);
defaultWorld.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top
}
if (cachedWorld.shouldBeReplacedBy(defaultWorld,false)) {
_setWorld(defaultWorld);
if (dsWorld.length() > 0)
RR->node->dataStoreDelete("world");
} else _setWorld(cachedWorld);
}
Topology::~Topology()
@ -283,6 +271,16 @@ keep_searching_for_roots:
return bestRoot;
}
bool Topology::worldUpdateIfValid(const World &newWorld)
{
Mutex::Lock _l(_lock);
if (_world.shouldBeReplacedBy(newWorld,true)) {
_setWorld(newWorld);
return true;
}
return false;
}
void Topology::clean(uint64_t now)
{
Mutex::Lock _l(_lock);
@ -320,4 +318,26 @@ void Topology::_saveIdentity(const Identity &id)
}
}
void Topology::_setWorld(const World &newWorld)
{
// assumed _lock is locked (or in constructor)
_world = newWorld;
_amRoot = false;
_rootAddresses.clear();
_rootPeers.clear();
for(std::vector<World::Root>::const_iterator r(_world.roots().begin());r!=_world.roots().end();++r) {
if (r->identity == RR->identity)
_amRoot = true;
_rootAddresses.push_back(r->identity.address());
SharedPtr<Peer> *rp = _peers.get(r->identity.address());
if (rp) {
_rootPeers.push_back(*rp);
} else if (r->identity.address() != RR->identity.address()) {
SharedPtr<Peer> newrp(new Peer(RR->identity,r->identity));
_peers.set(r->identity.address(),newrp);
_rootPeers.push_back(newrp);
}
}
}
} // namespace ZeroTier