diff --git a/controller/DBMirrorSet.cpp b/controller/DBMirrorSet.cpp index 0e5a90f57..fe55151d5 100644 --- a/controller/DBMirrorSet.cpp +++ b/controller/DBMirrorSet.cpp @@ -248,6 +248,7 @@ void DBMirrorSet::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,u _listener->onNetworkMemberDeauthorize(this,networkId,memberId); } +/* void DBMirrorSet::membersExpiring(std::set< std::pair > &soon, std::set< std::pair > &expired) { std::unique_lock l(_membersExpiringSoon_l); @@ -284,11 +285,14 @@ void DBMirrorSet::membersExpiring(std::set< std::pair > &soo _membersExpiringSoon.erase(next++); } } +*/ +/* void DBMirrorSet::memberWillExpire(int64_t expTime, uint64_t nwid, uint64_t memberId) { std::unique_lock l(_membersExpiringSoon_l); _membersExpiringSoon.insert(std::pair< int64_t, std::pair< uint64_t, uint64_t > >(expTime, std::pair< uint64_t, uint64_t >(nwid, memberId))); } +*/ } // namespace ZeroTier diff --git a/controller/DBMirrorSet.hpp b/controller/DBMirrorSet.hpp index 9a957ee38..3943b25ca 100644 --- a/controller/DBMirrorSet.hpp +++ b/controller/DBMirrorSet.hpp @@ -61,8 +61,8 @@ public: _dbs.push_back(db); } - void membersExpiring(std::set< std::pair > &soon, std::set< std::pair > &expired); - void memberWillExpire(int64_t expTime, uint64_t nwid, uint64_t memberId); + //void membersExpiring(std::set< std::pair > &soon, std::set< std::pair > &expired); + //void memberWillExpire(int64_t expTime, uint64_t nwid, uint64_t memberId); private: DB::ChangeListener *const _listener; @@ -70,8 +70,8 @@ private: std::thread _syncCheckerThread; std::vector< std::shared_ptr< DB > > _dbs; mutable std::mutex _dbs_l; - std::set< std::pair< int64_t, std::pair > > _membersExpiringSoon; - mutable std::mutex _membersExpiringSoon_l; + //std::set< std::pair< int64_t, std::pair > > _membersExpiringSoon; + //mutable std::mutex _membersExpiringSoon_l; }; } // namespace ZeroTier diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 054bcddc5..b67b34057 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -1335,9 +1335,10 @@ void EmbeddedNetworkController::_request( // Should we check SSO Stuff? // If network is configured with SSO, and the member is not marked exempt: yes // Otherwise no, we use standard auth logic. + AuthInfo info; + int64_t authenticationExpiryTime = -1; bool networkSSOEnabled = OSUtils::jsonBool(network["ssoEnabled"], false); bool memberSSOExempt = OSUtils::jsonBool(member["ssoExempt"], false); - AuthInfo info; if (networkSSOEnabled && !memberSSOExempt) { // TODO: Get expiry time if auth is still valid @@ -1347,7 +1348,7 @@ void EmbeddedNetworkController::_request( std::string memberId = member["id"]; //fprintf(stderr, "ssoEnabled && !ssoExempt %s-%s\n", nwids, memberId.c_str()); - uint64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0); + authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0); fprintf(stderr, "authExpiryTime: %lld\n", authenticationExpiryTime); if (authenticationExpiryTime < now) { fprintf(stderr, "Handling expired member\n"); @@ -1392,7 +1393,7 @@ void EmbeddedNetworkController::_request( } } else if (authorized) { fprintf(stderr, "Setting member will expire to: %lld\n", authenticationExpiryTime); - _db.memberWillExpire(authenticationExpiryTime, nwid, identity.address().toInt()); + //_db.memberWillExpire(authenticationExpiryTime, nwid, identity.address().toInt()); } } @@ -1409,10 +1410,12 @@ void EmbeddedNetworkController::_request( member["vRev"] = vRev; member["vProto"] = vProto; + _MemberStatusKey msk(nwid,identity.address().toInt()); + { std::lock_guard l(_memberStatus_l); - _MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,identity.address().toInt())]; - + _MemberStatus &ms = _memberStatus[msk]; + ms.authenticationExpiryTime = authenticationExpiryTime; ms.vMajor = (int)vMajor; ms.vMinor = (int)vMinor; ms.vRev = (int)vRev; @@ -1420,9 +1423,13 @@ void EmbeddedNetworkController::_request( ms.lastRequestMetaData = metaData; ms.identity = identity; } - } + + if (authenticationExpiryTime > 0) { + std::lock_guard l(_expiringSoon_l); + _expiringSoon.insert(std::pair(authenticationExpiryTime, msk)); + } + } } else { - // If they are not authorized, STOP! DB::cleanMember(member); _db.save(member,true); @@ -1876,6 +1883,30 @@ void EmbeddedNetworkController::_startThreads() } } + std::vector< std::pair > expired; + int64_t now = OSUtils::now(); + { + std::lock_guard l(_expiringSoon_l); + for(auto s=_expiringSoon.begin();s!=_expiringSoon.end();) { + int64_t when = s->first; + if (when <= now) { + // Remove expired entries and if they are still correct as per the network status, deauth them. + std::lock_guard l(_memberStatus_l); + _MemberStatus &ms = _memberStatus[s->second]; + if ((ms.authenticationExpiryTime > 0)&&(ms.authenticationExpiryTime <= now)) { + expired.push_back(std::pair(s->second.networkId, s->second.nodeId)); + } + _expiringSoon.erase(s++); + } else if ((when - now) > 1000) { + // Don't bother going further into the future than necessary. + break; + } else { + ++s; + } + } + } + + /* std::set< std::pair > soon; std::set< std::pair > expired; _db.membersExpiring(soon, expired); @@ -1895,6 +1926,7 @@ void EmbeddedNetworkController::_startThreads() request(s->first,InetAddress(),0,identity,lastMetaData); } } + */ for(auto e=expired.begin();e!=expired.end();++e) { onNetworkMemberDeauthorize(nullptr, e->first, e->second); diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp index fc18cbded..6a6c919cd 100644 --- a/controller/EmbeddedNetworkController.hpp +++ b/controller/EmbeddedNetworkController.hpp @@ -109,6 +109,7 @@ private: RQENTRY_TYPE_REQUEST = 0 } type; }; + struct _MemberStatusKey { _MemberStatusKey() : networkId(0),nodeId(0) {} @@ -119,8 +120,9 @@ private: }; struct _MemberStatus { - _MemberStatus() : lastRequestTime(0),vMajor(-1),vMinor(-1),vRev(-1),vProto(-1) {} - uint64_t lastRequestTime; + _MemberStatus() : lastRequestTime(0),authenticationExpiryTime(-1),vMajor(-1),vMinor(-1),vRev(-1),vProto(-1) {} + int64_t lastRequestTime; + int64_t authenticationExpiryTime; int vMajor,vMinor,vRev,vProto; Dictionary lastRequestMetaData; Identity identity; @@ -152,6 +154,9 @@ private: std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus; std::mutex _memberStatus_l; + std::multimap< int64_t, _MemberStatusKey > _expiringSoon; + std::mutex _expiringSoon_l; + RedisConfig *_rc; std::string _ssoRedirectURL; };