From 7ea7e1898a88ee60a346582fd6185e4f727759bf Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 6 Mar 2017 16:21:49 -0800 Subject: [PATCH] Fix a bug that could cause duplicate IP address assignment on networks if many new members join the controller at once. --- controller/EmbeddedNetworkController.cpp | 3 +++ controller/EmbeddedNetworkController.hpp | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 2f6142a94..b731db832 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -664,6 +664,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( // Member is being de-authorized, so spray Revocation objects to all online members if (!newAuth) { + _clearNetworkMemberInfoCache(nwid); Revocation rev(_node->prng(),nwid,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(address),Revocation::CREDENTIAL_TYPE_COM); rev.sign(_signingId); Mutex::Lock _l(_lastRequestTime_m); @@ -1662,6 +1663,7 @@ void EmbeddedNetworkController::_request( if (nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) nc.staticIps[nc.staticIpCount++] = ip6; haveManagedIpv6AutoAssignment = true; + _clearNetworkMemberInfoCache(nwid); // clear cache to prevent IP assignment duplication on many rapid assigns break; } } @@ -1717,6 +1719,7 @@ void EmbeddedNetworkController::_request( v4ip->sin_addr.s_addr = Utils::hton(ip); } haveManagedIpv4AutoAssignment = true; + _clearNetworkMemberInfoCache(nwid); // clear cache to prevent IP assignment duplication on many rapid assigns break; } } diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp index 7163c004f..bca0956e3 100644 --- a/controller/EmbeddedNetworkController.hpp +++ b/controller/EmbeddedNetworkController.hpp @@ -121,7 +121,6 @@ private: Mutex _threads_m; // Gathers a bunch of statistics about members of a network, IP assignments, etc. that we need in various places - // This does lock _networkMemberCache_m struct _NetworkMemberInfo { _NetworkMemberInfo() : authorizedMemberCount(0),activeMemberCount(0),totalMemberCount(0),mostRecentDeauthTime(0) {} @@ -136,6 +135,11 @@ private: std::map _nmiCache; Mutex _nmiCache_m; void _getNetworkMemberInfo(uint64_t now,uint64_t nwid,_NetworkMemberInfo &nmi); + inline void _clearNetworkMemberInfoCache(const uint64_t nwid) + { + Mutex::Lock _l(_nmiCache_m); + _nmiCache.erase(nwid); + } void _pushMemberUpdate(uint64_t now,uint64_t nwid,const nlohmann::json &member);