diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 8392356cb..914cad476 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -468,6 +468,8 @@ EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPa _path(dbPath), _sender((NetworkController::Sender *)0), _db(this), + _ssoExpiryRunning(true), + _ssoExpiry(std::thread(&EmbeddedNetworkController::_ssoExpiryThread, this)), _rc(rc) { } @@ -476,8 +478,11 @@ EmbeddedNetworkController::~EmbeddedNetworkController() { std::lock_guard l(_threads_l); _queue.stop(); - for(auto t=_threads.begin();t!=_threads.end();++t) + for(auto t=_threads.begin();t!=_threads.end();++t) { t->join(); + } + _ssoExpiryRunning = false; + _ssoExpiry.join(); } void EmbeddedNetworkController::setSSORedirectURL(const std::string &url) { @@ -1765,10 +1770,7 @@ void EmbeddedNetworkController::_startThreads() const long hwc = std::max((long)std::thread::hardware_concurrency(),(long)1); for(long t=0;t expired; - nlohmann::json network, member; for(;;) { - expired.clear(); _RQEntry *qe = (_RQEntry *)0; Metrics::network_config_request_queue_size = _queue.size(); auto timedWaitResult = _queue.get(qe, 1000); @@ -1787,37 +1789,44 @@ void EmbeddedNetworkController::_startThreads() qe = nullptr; } } - - int64_t now = OSUtils::now(); - { - std::lock_guard l(_expiringSoon_l); - for(auto s=_expiringSoon.begin();s!=_expiringSoon.end();) { - Metrics::sso_expiration_checks++; - const int64_t when = s->first; - if (when <= now) { - // The user may have re-authorized, so we must actually look it up and check. - network.clear(); - member.clear(); - if (_db.get(s->second.networkId, network, s->second.nodeId, member)) { - int64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0); - if (authenticationExpiryTime <= now) { - expired.push_back(s->second); - } - } - s = _expiringSoon.erase(s); - } else { - // Don't bother going further into the future than necessary. - break; - } - } - } - for(auto e=expired.begin();e!=expired.end();++e) { - Metrics::sso_member_deauth++; - onNetworkMemberDeauthorize(nullptr, e->networkId, e->nodeId); - } } }); } } +void EmbeddedNetworkController::_ssoExpiryThread() { + while(_ssoExpiryRunning) { + std::vector<_MemberStatusKey> expired; + nlohmann::json network, member; + int64_t now = OSUtils::now(); + { + std::lock_guard l(_expiringSoon_l); + for(auto s=_expiringSoon.begin();s!=_expiringSoon.end();) { + Metrics::sso_expiration_checks++; + const int64_t when = s->first; + if (when <= now) { + // The user may have re-authorized, so we must actually look it up and check. + network.clear(); + member.clear(); + if (_db.get(s->second.networkId, network, s->second.nodeId, member)) { + int64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0); + if (authenticationExpiryTime <= now) { + expired.push_back(s->second); + } + } + s = _expiringSoon.erase(s); + } else { + // Don't bother going further into the future than necessary. + break; + } + } + } + for(auto e=expired.begin();e!=expired.end();++e) { + Metrics::sso_member_deauth++; + onNetworkMemberDeauthorize(nullptr, e->networkId, e->nodeId); + } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +} + } // namespace ZeroTier diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp index 4f2e20e0a..97692fa4c 100644 --- a/controller/EmbeddedNetworkController.hpp +++ b/controller/EmbeddedNetworkController.hpp @@ -81,6 +81,7 @@ public: private: void _request(uint64_t nwid,const InetAddress &fromAddr,uint64_t requestPacketId,const Identity &identity,const Dictionary &metaData); void _startThreads(); + void _ssoExpiryThread(); std::string networkUpdateFromPostData(uint64_t networkID, const std::string &body); @@ -138,6 +139,9 @@ private: std::vector _threads; std::mutex _threads_l; + bool _ssoExpiryRunning; + std::thread _ssoExpiry; + std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus; std::mutex _memberStatus_l;