summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--controller/EmbeddedNetworkController.cpp60
-rw-r--r--controller/EmbeddedNetworkController.hpp2
2 files changed, 48 insertions, 14 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp
index ed8ffa74..0fba8749 100644
--- a/controller/EmbeddedNetworkController.cpp
+++ b/controller/EmbeddedNetworkController.cpp
@@ -488,7 +488,6 @@ void EmbeddedNetworkController::request(
const uint64_t now = OSUtils::now();
- // Check rate limit circuit breaker to prevent flooding
{
Mutex::Lock _l(_lastRequestTime_m);
uint64_t &lrt = _lastRequestTime[std::pair<uint64_t,uint64_t>(identity.address().toInt(),nwid)];
@@ -1137,12 +1136,12 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
Mutex::Lock _l(_db_m);
member = _db.get("network",nwids,"member",Address(address).toString(),0);
}
+ json origMember(member); // for detecting changes
_initMember(member);
try {
if (b.count("activeBridge")) member["activeBridge"] = _jB(b["activeBridge"],false);
if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = _jB(b["noAutoAssignIps"],false);
- if ((b.count("identity"))&&(!member.count("identity"))) member["identity"] = _jS(b["identity"],""); // allow identity to be populated only if not already known
if (b.count("authorized")) {
const bool newAuth = _jB(b["authorized"],false);
@@ -1214,13 +1213,16 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
member["id"] = addrs;
member["address"] = addrs; // legacy
member["nwid"] = nwids;
- member["lastModified"] = now;
- json &revj = member["revision"];
- member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
- {
- Mutex::Lock _l(_db_m);
- _db.put("network",nwids,"member",Address(address).toString(),member);
+ if (member != origMember) {
+ member["lastModified"] = now;
+ json &revj = member["revision"];
+ member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
+ {
+ Mutex::Lock _l(_db_m);
+ _db.put("network",nwids,"member",Address(address).toString(),member);
+ }
+ _pushMemberUpdate(now,nwid,member);
}
// Add non-persisted fields
@@ -1309,6 +1311,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
network = _db.get("network",nwids,0);
}
+ json origNetwork(network); // for detecting changes
_initNetwork(network);
try {
@@ -1489,13 +1492,20 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
network["id"] = nwids;
network["nwid"] = nwids; // legacy
- json &rev = network["revision"];
- network["revision"] = (rev.is_number() ? ((uint64_t)rev + 1ULL) : 1ULL);
- network["lastModified"] = now;
- {
- Mutex::Lock _l(_db_m);
- _db.put("network",nwids,network);
+ if (network != origNetwork) {
+ json &revj = network["revision"];
+ network["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
+ network["lastModified"] = now;
+ {
+ Mutex::Lock _l(_db_m);
+ _db.put("network",nwids,network);
+ }
+ std::string pfx("network/"); pfx.append(nwids); pfx.append("/member/");
+ _db.filter(pfx,120000,[this,&now,&nwid](const std::string &n,const json &obj) {
+ _pushMemberUpdate(now,nwid,obj);
+ return true; // do not delete
+ });
}
_NetworkMemberInfo nmi;
@@ -1700,4 +1710,26 @@ void EmbeddedNetworkController::_getNetworkMemberInfo(uint64_t now,uint64_t nwid
}
}
+void EmbeddedNetworkController::_pushMemberUpdate(uint64_t now,uint64_t nwid,const nlohmann::json &member)
+{
+ try {
+ const std::string idstr = member["identity"];
+ const std::string mdstr = member["lastRequestMetaData"];
+ if ((idstr.length() > 0)&&(mdstr.length() > 0)) {
+ const Identity id(idstr);
+ bool online;
+ {
+ Mutex::Lock _l(_lastRequestTime_m);
+ std::map<std::pair<uint64_t,uint64_t>,uint64_t>::iterator lrt(_lastRequestTime.find(std::pair<uint64_t,uint64_t>(id.address().toInt(),nwid)));
+ online = ( (lrt != _lastRequestTime.end()) && ((now - lrt->second) < ZT_NETWORK_AUTOCONF_DELAY) );
+ }
+ Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> *metaData = new Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY>(mdstr.c_str());
+ try {
+ this->request(nwid,InetAddress(),0,id,*metaData);
+ } catch ( ... ) {}
+ delete metaData;
+ }
+ } catch ( ... ) {}
+}
+
} // namespace ZeroTier
diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp
index 79b919b9..620ef3e3 100644
--- a/controller/EmbeddedNetworkController.hpp
+++ b/controller/EmbeddedNetworkController.hpp
@@ -103,6 +103,8 @@ private:
Mutex _nmiCache_m;
void _getNetworkMemberInfo(uint64_t now,uint64_t nwid,_NetworkMemberInfo &nmi);
+ void _pushMemberUpdate(uint64_t now,uint64_t nwid,const nlohmann::json &member);
+
// These init objects with default and static/informational fields
inline void _initMember(nlohmann::json &member)
{