mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
Fix race in multiple DB mirroring configurations.
This commit is contained in:
parent
ad2a7c2590
commit
28d0070ce2
5 changed files with 30 additions and 20 deletions
|
@ -114,6 +114,28 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
inline bool _compareRecords(const nlohmann::json &a,const nlohmann::json &b)
|
||||||
|
{
|
||||||
|
if (a.is_object() == b.is_object()) {
|
||||||
|
if (a.is_object()) {
|
||||||
|
if (a.size() != b.size())
|
||||||
|
return false;
|
||||||
|
auto amap = a.get<nlohmann::json::object_t>();
|
||||||
|
auto bmap = b.get<nlohmann::json::object_t>();
|
||||||
|
for(auto ai=amap.begin();ai!=amap.end();++ai) {
|
||||||
|
if (ai->first != "revision") { // ignore revision, compare only non-revision-counter fields
|
||||||
|
auto bi = bmap.find(ai->first);
|
||||||
|
if ((bi == bmap.end())||(bi->second != ai->second))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (a == b);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct _Network
|
struct _Network
|
||||||
{
|
{
|
||||||
_Network() : mostRecentDeauthTime(0) {}
|
_Network() : mostRecentDeauthTime(0) {}
|
||||||
|
|
|
@ -125,14 +125,14 @@ bool DBMirrorSet::save(nlohmann::json &record,bool notifyListeners)
|
||||||
}
|
}
|
||||||
if (notifyListeners) {
|
if (notifyListeners) {
|
||||||
for(auto d=dbs.begin();d!=dbs.end();++d) {
|
for(auto d=dbs.begin();d!=dbs.end();++d) {
|
||||||
if ((*d)->save(record,notifyListeners))
|
if ((*d)->save(record,true))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
for(auto d=dbs.begin();d!=dbs.end();++d) {
|
for(auto d=dbs.begin();d!=dbs.end();++d) {
|
||||||
modified |= (*d)->save(record,notifyListeners);
|
modified |= (*d)->save(record,false);
|
||||||
}
|
}
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ bool FileDB::save(nlohmann::json &record,bool notifyListeners)
|
||||||
if (nwid) {
|
if (nwid) {
|
||||||
nlohmann::json old;
|
nlohmann::json old;
|
||||||
get(nwid,old);
|
get(nwid,old);
|
||||||
if ((!old.is_object())||(old != record)) {
|
if ((!old.is_object())||(!_compareRecords(old,record))) {
|
||||||
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
||||||
OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid);
|
OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid);
|
||||||
if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
|
if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
|
||||||
|
@ -115,7 +115,7 @@ bool FileDB::save(nlohmann::json &record,bool notifyListeners)
|
||||||
if ((id)&&(nwid)) {
|
if ((id)&&(nwid)) {
|
||||||
nlohmann::json network,old;
|
nlohmann::json network,old;
|
||||||
get(nwid,network,id,old);
|
get(nwid,network,id,old);
|
||||||
if ((!old.is_object())||(old != record)) {
|
if ((!old.is_object())||(!_compareRecords(old,record))) {
|
||||||
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
||||||
OSUtils::ztsnprintf(pb,sizeof(pb),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)nwid);
|
OSUtils::ztsnprintf(pb,sizeof(pb),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)nwid);
|
||||||
OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json",pb,(unsigned long long)id);
|
OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json",pb,(unsigned long long)id);
|
||||||
|
|
|
@ -369,7 +369,7 @@ bool LFDB::save(nlohmann::json &record,bool notifyListeners)
|
||||||
if (nwid) {
|
if (nwid) {
|
||||||
nlohmann::json old;
|
nlohmann::json old;
|
||||||
get(nwid,old);
|
get(nwid,old);
|
||||||
if ((!old.is_object())||(old != record)) {
|
if ((!old.is_object())||(!_compareRecords(old,record))) {
|
||||||
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
||||||
_networkChanged(old,record,notifyListeners);
|
_networkChanged(old,record,notifyListeners);
|
||||||
{
|
{
|
||||||
|
@ -385,7 +385,7 @@ bool LFDB::save(nlohmann::json &record,bool notifyListeners)
|
||||||
if ((id)&&(nwid)) {
|
if ((id)&&(nwid)) {
|
||||||
nlohmann::json network,old;
|
nlohmann::json network,old;
|
||||||
get(nwid,network,id,old);
|
get(nwid,network,id,old);
|
||||||
if ((!old.is_object())||(old != record)) {
|
if ((!old.is_object())||(!_compareRecords(old,record))) {
|
||||||
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
||||||
_memberChanged(old,record,notifyListeners);
|
_memberChanged(old,record,notifyListeners);
|
||||||
{
|
{
|
||||||
|
|
|
@ -183,7 +183,7 @@ bool PostgreSQL::save(nlohmann::json &record,bool notifyListeners)
|
||||||
if (nwid) {
|
if (nwid) {
|
||||||
nlohmann::json old;
|
nlohmann::json old;
|
||||||
get(nwid,old);
|
get(nwid,old);
|
||||||
if ((!old.is_object())||(old != record)) {
|
if ((!old.is_object())||(!_compareRecords(old,record))) {
|
||||||
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
||||||
_commitQueue.post(std::pair<nlohmann::json,bool>(record,notifyListeners));
|
_commitQueue.post(std::pair<nlohmann::json,bool>(record,notifyListeners));
|
||||||
modified = true;
|
modified = true;
|
||||||
|
@ -195,25 +195,13 @@ bool PostgreSQL::save(nlohmann::json &record,bool notifyListeners)
|
||||||
if ((id)&&(nwid)) {
|
if ((id)&&(nwid)) {
|
||||||
nlohmann::json network,old;
|
nlohmann::json network,old;
|
||||||
get(nwid,network,id,old);
|
get(nwid,network,id,old);
|
||||||
if ((!old.is_object())||(old != record)) {
|
if ((!old.is_object())||(!_compareRecords(old,record))) {
|
||||||
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
|
||||||
_commitQueue.post(std::pair<nlohmann::json,bool>(record,notifyListeners));
|
_commitQueue.post(std::pair<nlohmann::json,bool>(record,notifyListeners));
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
waitForReady();
|
|
||||||
if (orig) {
|
|
||||||
if (*orig != record) {
|
|
||||||
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1;
|
|
||||||
_commitQueue.post(new nlohmann::json(record));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
record["revision"] = 1;
|
|
||||||
_commitQueue.post(new nlohmann::json(record));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
fprintf(stderr, "Error on PostgreSQL::save: %s\n", e.what());
|
fprintf(stderr, "Error on PostgreSQL::save: %s\n", e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue