From 57b96af2c41ed63a12bfb41044f242fc55ab1358 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 8 Mar 2018 22:33:08 -0800 Subject: Fix for FileDB _networkChanged / _memberChanged problem. --- controller/DB.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++++-- controller/DB.hpp | 4 +- controller/FileDB.cpp | 2 +- controller/RethinkDB.cpp | 9 ++-- 4 files changed, 138 insertions(+), 10 deletions(-) diff --git a/controller/DB.cpp b/controller/DB.cpp index 70472e57..680b4120 100644 --- a/controller/DB.cpp +++ b/controller/DB.cpp @@ -222,7 +222,7 @@ void DB::networks(std::vector &networks) networks.push_back(n->first); } -void DB::_memberChanged(nlohmann::json &old,nlohmann::json &member,bool push) +void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool push) { uint64_t memberId = 0; uint64_t networkId = 0; @@ -230,6 +230,102 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &member,bool push) bool wasAuth = false; std::shared_ptr<_Network> nw; + if (old.is_object()) { + memberId = OSUtils::jsonIntHex(old["id"],0ULL); + networkId = OSUtils::jsonIntHex(old["nwid"],0ULL); + if ((memberId)&&(networkId)) { + { + std::lock_guard l(_networks_l); + auto nw2 = _networks.find(networkId); + if (nw2 != _networks.end()) + nw = nw2->second; + } + if (nw) { + std::lock_guard l(nw->lock); + if (OSUtils::jsonBool(old["activeBridge"],false)) + nw->activeBridgeMembers.erase(memberId); + wasAuth = OSUtils::jsonBool(old["authorized"],false); + if (wasAuth) + nw->authorizedMembers.erase(memberId); + json &ips = old["ipAssignments"]; + if (ips.is_array()) { + for(unsigned long i=0;iallocatedIps.erase(ipa); + } + } + } + } + } + } + + if (memberConfig.is_object()) { + if (!nw) { + memberId = OSUtils::jsonIntHex(memberConfig["id"],0ULL); + networkId = OSUtils::jsonIntHex(memberConfig["nwid"],0ULL); + if ((!memberId)||(!networkId)) + return; + std::lock_guard l(_networks_l); + std::shared_ptr<_Network> &nw2 = _networks[networkId]; + if (!nw2) + nw2.reset(new _Network); + nw = nw2; + } + + { + std::lock_guard l(nw->lock); + + nw->members[memberId] = memberConfig; + + if (OSUtils::jsonBool(memberConfig["activeBridge"],false)) + nw->activeBridgeMembers.insert(memberId); + isAuth = OSUtils::jsonBool(memberConfig["authorized"],false); + if (isAuth) + nw->authorizedMembers.insert(memberId); + json &ips = memberConfig["ipAssignments"]; + if (ips.is_array()) { + for(unsigned long i=0;iallocatedIps.insert(ipa); + } + } + } + + if (!isAuth) { + const int64_t ldt = (int64_t)OSUtils::jsonInt(memberConfig["lastDeauthorizedTime"],0ULL); + if (ldt > nw->mostRecentDeauthTime) + nw->mostRecentDeauthTime = ldt; + } + } + + if (push) + _controller->onNetworkMemberUpdate(networkId,memberId); + } else if (memberId) { + if (nw) { + std::lock_guard l(nw->lock); + nw->members.erase(memberId); + } + if (networkId) { + std::lock_guard l(_networks_l); + auto er = _networkByMember.equal_range(memberId); + for(auto i=er.first;i!=er.second;++i) { + if (i->second == networkId) { + _networkByMember.erase(i); + break; + } + } + } + } + + /* if (old.is_object()) { json &config = old["config"]; if (config.is_object()) { @@ -330,16 +426,46 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &member,bool push) } } } + */ if ((push)&&((wasAuth)&&(!isAuth)&&(networkId)&&(memberId))) _controller->onNetworkMemberDeauthorize(networkId,memberId); } -void DB::_networkChanged(nlohmann::json &old,nlohmann::json &network,bool push) +void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool push) { + if (networkConfig.is_object()) { + const std::string ids = networkConfig["id"]; + const uint64_t id = Utils::hexStrToU64(ids.c_str()); + if (id) { + std::shared_ptr<_Network> nw; + { + std::lock_guard l(_networks_l); + std::shared_ptr<_Network> &nw2 = _networks[id]; + if (!nw2) + nw2.reset(new _Network); + nw = nw2; + } + { + std::lock_guard l2(nw->lock); + nw->config = networkConfig; + } + if (push) + _controller->onNetworkUpdate(id); + } + } else if (old.is_object()) { + const std::string ids = old["id"]; + const uint64_t id = Utils::hexStrToU64(ids.c_str()); + if (id) { + std::lock_guard l(_networks_l); + _networks.erase(id); + } + } + + /* if (network.is_object()) { json &config = network["config"]; - if (config.is_object()) { + if (networkConfig.is_object()) { const std::string ids = config["id"]; const uint64_t id = Utils::hexStrToU64(ids.c_str()); if (id) { @@ -367,6 +493,7 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &network,bool push) _networks.erase(id); } } + */ } void DB::_fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info) diff --git a/controller/DB.hpp b/controller/DB.hpp index abd1483e..86626009 100644 --- a/controller/DB.hpp +++ b/controller/DB.hpp @@ -119,8 +119,8 @@ protected: std::mutex lock; }; - void _memberChanged(nlohmann::json &old,nlohmann::json &member,bool push); - void _networkChanged(nlohmann::json &old,nlohmann::json &network,bool push); + void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool push); + void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool push); void _fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info); EmbeddedNetworkController *const _controller; diff --git a/controller/FileDB.cpp b/controller/FileDB.cpp index 40b9f914..a7b59cbf 100644 --- a/controller/FileDB.cpp +++ b/controller/FileDB.cpp @@ -1,6 +1,6 @@ /* * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. + * Copyright (C) 2011-2018 ZeroTier, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/controller/RethinkDB.cpp b/controller/RethinkDB.cpp index a3bdfbc9..0948b012 100644 --- a/controller/RethinkDB.cpp +++ b/controller/RethinkDB.cpp @@ -138,10 +138,11 @@ RethinkDB::RethinkDB(EmbeddedNetworkController *const nc,const Identity &myId,co try { json &ov = tmp["old_val"]; json &nv = tmp["new_val"]; - if (ov.is_object()||nv.is_object()) { - //if (nv.is_object()) printf("NETWORK: %s" ZT_EOL_S,nv.dump().c_str()); - this->_networkChanged(ov,nv,(this->_ready <= 0)); - } + json oldConfig,newConfig; + if (ov.is_object()) oldConfig = ov["config"]; + if (nv.is_object()) newConfig = nv["config"]; + if (oldConfig.is_object()||newConfig.is_object()) + this->_networkChanged(oldConfig,newConfig,(this->_ready <= 0)); } catch ( ... ) {} // ignore bad records } } -- cgit v1.2.3