diff options
Diffstat (limited to 'controller')
-rw-r--r-- | controller/DB.hpp | 15 | ||||
-rw-r--r-- | controller/DBMirrorSet.cpp | 48 | ||||
-rw-r--r-- | controller/DBMirrorSet.hpp | 3 | ||||
-rw-r--r-- | controller/LFDB.cpp | 2 |
4 files changed, 64 insertions, 4 deletions
diff --git a/controller/DB.hpp b/controller/DB.hpp index aebe4e11..6c518426 100644 --- a/controller/DB.hpp +++ b/controller/DB.hpp @@ -100,6 +100,19 @@ public: void networks(std::set<uint64_t> &networks); + template<typename F> + inline void each(F f) + { + nlohmann::json nullJson; + std::lock_guard<std::mutex> lck(_networks_l); + for(auto nw=_networks.begin();nw!=_networks.end();++nw) { + f(nw->first,nw->second->config,0,nullJson); // first provide network with 0 for member ID + for(auto m=nw->second->members.begin();m!=nw->second->members.end();++m) { + f(nw->first,nw->second->config,m->first,m->second); + } + } + } + virtual bool save(nlohmann::json &record,bool notifyListeners) = 0; virtual void eraseNetwork(const uint64_t networkId) = 0; @@ -114,7 +127,7 @@ public: } protected: - inline bool _compareRecords(const nlohmann::json &a,const nlohmann::json &b) + static inline bool _compareRecords(const nlohmann::json &a,const nlohmann::json &b) { if (a.is_object() == b.is_object()) { if (a.is_object()) { diff --git a/controller/DBMirrorSet.cpp b/controller/DBMirrorSet.cpp index 5b491216..852e70f3 100644 --- a/controller/DBMirrorSet.cpp +++ b/controller/DBMirrorSet.cpp @@ -29,8 +29,52 @@ namespace ZeroTier { DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) : - _listener(listener) -{ + _listener(listener), + _running(true) +{ + _syncCheckerThread = std::thread([this]() { + for(;;) { + for(int i=0;i<120;++i) { // 1 minute delay between checks + if (!_running) + return; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + + std::vector< std::shared_ptr<DB> > dbs; + { + std::lock_guard<std::mutex> l(_dbs_l); + if (_dbs.size() <= 1) + continue; // no need to do this if there's only one DB, so skip the iteration + dbs = _dbs; + } + + for(auto db=dbs.begin();db!=dbs.end();++db) { + (*db)->each([this,&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) { + if (memberId == 0) { + for(auto db2=dbs.begin();db2!=dbs.end();++db2) { + if (db->get() != db2->get()) { + nlohmann::json nw2; + if ((!(*db2)->get(networkId,nw2))||(OSUtils::jsonInt(nw2["revision"],0) < OSUtils::jsonInt(network["revision"],0))) { + nw2 = network; + (*db2)->save(nw2,false); + } + } + } + } else { + for(auto db2=dbs.begin();db2!=dbs.end();++db2) { + if (db->get() != db2->get()) { + nlohmann::json nw2,m2; + if ((!(*db2)->get(networkId,nw2,memberId,m2))||(OSUtils::jsonInt(nw2["revision"],0) < OSUtils::jsonInt(network["revision"],0))) { + m2 = member; + (*db2)->save(m2,false); + } + } + } + } + }); + } + } + }); } DBMirrorSet::~DBMirrorSet() diff --git a/controller/DBMirrorSet.hpp b/controller/DBMirrorSet.hpp index aee598af..23cb25e7 100644 --- a/controller/DBMirrorSet.hpp +++ b/controller/DBMirrorSet.hpp @@ -33,6 +33,7 @@ #include <memory> #include <mutex> #include <set> +#include <thread> namespace ZeroTier { @@ -72,6 +73,8 @@ public: private: DB::ChangeListener *const _listener; + std::atomic_bool _running; + std::thread _syncCheckerThread; std::vector< std::shared_ptr< DB > > _dbs; mutable std::mutex _dbs_l; }; diff --git a/controller/LFDB.cpp b/controller/LFDB.cpp index d00d8631..b6dc6657 100644 --- a/controller/LFDB.cpp +++ b/controller/LFDB.cpp @@ -296,7 +296,7 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons const uint64_t prevRevision = oldMember["revision"]; if (prevRevision < revision) _memberChanged(oldMember,member,timeRangeStart > 0); - } else if (network.is_object()) { + } else if (hasNetwork(nwid)) { nlohmann::json nullJson; _memberChanged(nullJson,member,timeRangeStart > 0); } |