Loading src/api.cpp +23 −11 Changes for src/api.cpp: 23 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include "authdb.h" #include "backend.h" #include "api.h" #include "index.h" #include "user.h" #include "client.h" #include "gpo.h" Loading Loading @@ -279,19 +280,24 @@ public: _SessionData = nullptr; class User user; std::vector<uuid::uuid> uids; user.list(_Backend, uids); for (const auto &uid : uids) { // O(1) indexed lookup by username instead of O(n) scan { AuthBackend::Guard guard(_Backend, AuthBackend::Shared); RecordIndex &idx = _Backend.getIndex(); if (!idx.valid() || idx.revision() != _Backend.getRevesion()) idx.build(_Backend); uuid::uuid found_uid; if (idx.findByName(DataType::UserData, "username", name, found_uid)) { std::shared_ptr<class UserData> udat = std::make_shared<class UserData>(uid); std::make_shared<class UserData>(found_uid); size_t upos = sizeof(AuthHeader); user.info(_Backend, *udat, upos); if (name == udat->getUsername()) { if (constant_time_eq(pwsalt, udat->getPwHash())) { const SessionData* sdat = AuthSession->addSession(_Backend, _Did.value, uid.value); AuthSession->addSession(_Backend, _Did.value, found_uid.value); json_object* respid = json_object_new_object(); ::uuid::uuid sessid; Loading Loading @@ -329,14 +335,19 @@ public: sha512 sha; sha.hash(pw, pwsalt); std::vector<uuid::uuid> clids; AuthClient.list(_Backend, clids); for (auto &clid : clids) { class ClientData cdat(clid); // O(1) indexed lookup by clientname instead of O(n) scan { AuthBackend::Guard guard(_Backend, AuthBackend::Shared); RecordIndex &idx = _Backend.getIndex(); if (!idx.valid() || idx.revision() != _Backend.getRevesion()) idx.build(_Backend); uuid::uuid found_clid; if (idx.findByName(DataType::ClientData, "clientname", name, found_clid)) { class ClientData cdat(found_clid); size_t upos = sizeof(AuthHeader); AuthClient.info(_Backend, cdat, upos); if (name == cdat.getName()) { if (constant_time_eq(pwsalt, cdat.getKey())) { ClientConnections* cid = AuthClient.addConnection(_Backend, cdat); json_object* respid = json_object_new_object(); Loading @@ -351,6 +362,7 @@ public: } } } } return nullptr; } Loading src/backend.cpp +5 −21 Changes for src/backend.cpp: 5 added lines, 21 removed lines. Original line number Diff line number Diff line Loading @@ -71,42 +71,26 @@ void authdb::AuthBackend::write(const unsigned char* dest, size_t destsize){ } void authdb::AuthBackend::lock(){ auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); for(;;){ int expected = 0; if(_Lock.compare_exchange_weak(expected, -1)) break; if(std::chrono::steady_clock::now() >= deadline) throw AuthBackendError("backend lock timeout"); std::this_thread::yield(); } _Lock.lock(); try { _Api->lock(); } catch (...) { _Lock.store(0); _Lock.unlock(); throw; } } void authdb::AuthBackend::unlock(){ _Api->unlock(); _Lock.store(0); _Lock.unlock(); } void authdb::AuthBackend::lock_shared(){ auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); for(;;){ int cur = _Lock.load(); if(cur >= 0 && _Lock.compare_exchange_weak(cur, cur + 1)) break; if(std::chrono::steady_clock::now() >= deadline) throw AuthBackendError("backend shared lock timeout"); std::this_thread::yield(); } _Lock.lock_shared(); } void authdb::AuthBackend::unlock_shared(){ _Lock.fetch_sub(1); _Lock.unlock_shared(); } void authdb::AuthBackend::setPos(size_t pos){ Loading src/backend.h +2 −1 Changes for src/backend.h: 2 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <stdexcept> #include <mutex> #include <shared_mutex> #include <atomic> #pragma once Loading Loading @@ -143,6 +144,6 @@ namespace authdb{ AuthBackendApi *_Api; const std::string _Options; const std::string _Domain; std::atomic<int> _Lock{0}; // 0=unlocked, -1=exclusive, >0=shared count std::shared_mutex _Lock; }; }; src/client.cpp +11 −12 Changes for src/client.cpp: 11 added lines, 12 removed lines. Original line number Diff line number Diff line Loading @@ -218,18 +218,23 @@ authdb::ClientConnections *authdb::Client::addConnection(AuthBackend &backend,co ncid.generate(); ClientConnections *conn; if(_firstConnection){ _lastConnection->_next=new ClientConnections(ncid,backend,data); _lastConnection=_lastConnection->_next; conn = _lastConnection; }else{ _firstConnection=new ClientConnections(ncid,backend,data); _lastConnection=_firstConnection; conn = _firstConnection; } return _lastConnection; _connectionIndex[ncid] = conn; return conn; } void authdb::Client::delConnection(const uuid::uuid &conid){ std::lock_guard<std::mutex> guard(_lockConnection); _connectionIndex.erase(conid); ClientConnections *prev=nullptr; for(ClientConnections *curdat=_firstConnection; curdat; ){ if(curdat->_sessionId==conid){ Loading Loading @@ -261,6 +266,7 @@ void authdb::Client::cleanupExpiredConnections(){ auto age=std::chrono::duration_cast<std::chrono::hours>(now - curdat->_created).count(); if(age >= 24){ ClientConnections *next=curdat->_next; _connectionIndex.erase(curdat->_sessionId); if(prev){ prev->_next=next; }else{ Loading @@ -281,21 +287,14 @@ void authdb::Client::cleanupExpiredConnections(){ bool authdb::Client::checkConnection(const uuid::uuid &conid) const{ std::lock_guard<std::mutex> guard(_lockConnection); for(ClientConnections *curdat=_firstConnection; curdat; curdat=curdat->_next){ if(curdat->_sessionId==conid){ return true; } } return false; return _connectionIndex.count(conid) > 0; } authdb::ClientConnections *authdb::Client::findConnection(const uuid::uuid &conid){ std::lock_guard<std::mutex> guard(_lockConnection); for(ClientConnections *curdat=_firstConnection; curdat; curdat=curdat->_next){ if(curdat->_sessionId==conid){ return curdat; } } auto it = _connectionIndex.find(conid); if (it != _connectionIndex.end()) return it->second; return nullptr; } Loading src/client.h +2 −0 Changes for src/client.h: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <chrono> #include <vector> #include <unordered_map> #include <uuidp.h> #include "authdb.h" Loading Loading @@ -108,5 +109,6 @@ namespace authdb { private: ClientConnections *_firstConnection; ClientConnections *_lastConnection; std::unordered_map<uuid::uuid, ClientConnections*> _connectionIndex; }; }; Loading
src/api.cpp +23 −11 Changes for src/api.cpp: 23 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include "authdb.h" #include "backend.h" #include "api.h" #include "index.h" #include "user.h" #include "client.h" #include "gpo.h" Loading Loading @@ -279,19 +280,24 @@ public: _SessionData = nullptr; class User user; std::vector<uuid::uuid> uids; user.list(_Backend, uids); for (const auto &uid : uids) { // O(1) indexed lookup by username instead of O(n) scan { AuthBackend::Guard guard(_Backend, AuthBackend::Shared); RecordIndex &idx = _Backend.getIndex(); if (!idx.valid() || idx.revision() != _Backend.getRevesion()) idx.build(_Backend); uuid::uuid found_uid; if (idx.findByName(DataType::UserData, "username", name, found_uid)) { std::shared_ptr<class UserData> udat = std::make_shared<class UserData>(uid); std::make_shared<class UserData>(found_uid); size_t upos = sizeof(AuthHeader); user.info(_Backend, *udat, upos); if (name == udat->getUsername()) { if (constant_time_eq(pwsalt, udat->getPwHash())) { const SessionData* sdat = AuthSession->addSession(_Backend, _Did.value, uid.value); AuthSession->addSession(_Backend, _Did.value, found_uid.value); json_object* respid = json_object_new_object(); ::uuid::uuid sessid; Loading Loading @@ -329,14 +335,19 @@ public: sha512 sha; sha.hash(pw, pwsalt); std::vector<uuid::uuid> clids; AuthClient.list(_Backend, clids); for (auto &clid : clids) { class ClientData cdat(clid); // O(1) indexed lookup by clientname instead of O(n) scan { AuthBackend::Guard guard(_Backend, AuthBackend::Shared); RecordIndex &idx = _Backend.getIndex(); if (!idx.valid() || idx.revision() != _Backend.getRevesion()) idx.build(_Backend); uuid::uuid found_clid; if (idx.findByName(DataType::ClientData, "clientname", name, found_clid)) { class ClientData cdat(found_clid); size_t upos = sizeof(AuthHeader); AuthClient.info(_Backend, cdat, upos); if (name == cdat.getName()) { if (constant_time_eq(pwsalt, cdat.getKey())) { ClientConnections* cid = AuthClient.addConnection(_Backend, cdat); json_object* respid = json_object_new_object(); Loading @@ -351,6 +362,7 @@ public: } } } } return nullptr; } Loading
src/backend.cpp +5 −21 Changes for src/backend.cpp: 5 added lines, 21 removed lines. Original line number Diff line number Diff line Loading @@ -71,42 +71,26 @@ void authdb::AuthBackend::write(const unsigned char* dest, size_t destsize){ } void authdb::AuthBackend::lock(){ auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); for(;;){ int expected = 0; if(_Lock.compare_exchange_weak(expected, -1)) break; if(std::chrono::steady_clock::now() >= deadline) throw AuthBackendError("backend lock timeout"); std::this_thread::yield(); } _Lock.lock(); try { _Api->lock(); } catch (...) { _Lock.store(0); _Lock.unlock(); throw; } } void authdb::AuthBackend::unlock(){ _Api->unlock(); _Lock.store(0); _Lock.unlock(); } void authdb::AuthBackend::lock_shared(){ auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); for(;;){ int cur = _Lock.load(); if(cur >= 0 && _Lock.compare_exchange_weak(cur, cur + 1)) break; if(std::chrono::steady_clock::now() >= deadline) throw AuthBackendError("backend shared lock timeout"); std::this_thread::yield(); } _Lock.lock_shared(); } void authdb::AuthBackend::unlock_shared(){ _Lock.fetch_sub(1); _Lock.unlock_shared(); } void authdb::AuthBackend::setPos(size_t pos){ Loading
src/backend.h +2 −1 Changes for src/backend.h: 2 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <stdexcept> #include <mutex> #include <shared_mutex> #include <atomic> #pragma once Loading Loading @@ -143,6 +144,6 @@ namespace authdb{ AuthBackendApi *_Api; const std::string _Options; const std::string _Domain; std::atomic<int> _Lock{0}; // 0=unlocked, -1=exclusive, >0=shared count std::shared_mutex _Lock; }; };
src/client.cpp +11 −12 Changes for src/client.cpp: 11 added lines, 12 removed lines. Original line number Diff line number Diff line Loading @@ -218,18 +218,23 @@ authdb::ClientConnections *authdb::Client::addConnection(AuthBackend &backend,co ncid.generate(); ClientConnections *conn; if(_firstConnection){ _lastConnection->_next=new ClientConnections(ncid,backend,data); _lastConnection=_lastConnection->_next; conn = _lastConnection; }else{ _firstConnection=new ClientConnections(ncid,backend,data); _lastConnection=_firstConnection; conn = _firstConnection; } return _lastConnection; _connectionIndex[ncid] = conn; return conn; } void authdb::Client::delConnection(const uuid::uuid &conid){ std::lock_guard<std::mutex> guard(_lockConnection); _connectionIndex.erase(conid); ClientConnections *prev=nullptr; for(ClientConnections *curdat=_firstConnection; curdat; ){ if(curdat->_sessionId==conid){ Loading Loading @@ -261,6 +266,7 @@ void authdb::Client::cleanupExpiredConnections(){ auto age=std::chrono::duration_cast<std::chrono::hours>(now - curdat->_created).count(); if(age >= 24){ ClientConnections *next=curdat->_next; _connectionIndex.erase(curdat->_sessionId); if(prev){ prev->_next=next; }else{ Loading @@ -281,21 +287,14 @@ void authdb::Client::cleanupExpiredConnections(){ bool authdb::Client::checkConnection(const uuid::uuid &conid) const{ std::lock_guard<std::mutex> guard(_lockConnection); for(ClientConnections *curdat=_firstConnection; curdat; curdat=curdat->_next){ if(curdat->_sessionId==conid){ return true; } } return false; return _connectionIndex.count(conid) > 0; } authdb::ClientConnections *authdb::Client::findConnection(const uuid::uuid &conid){ std::lock_guard<std::mutex> guard(_lockConnection); for(ClientConnections *curdat=_firstConnection; curdat; curdat=curdat->_next){ if(curdat->_sessionId==conid){ return curdat; } } auto it = _connectionIndex.find(conid); if (it != _connectionIndex.end()) return it->second; return nullptr; } Loading
src/client.h +2 −0 Changes for src/client.h: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <chrono> #include <vector> #include <unordered_map> #include <uuidp.h> #include "authdb.h" Loading Loading @@ -108,5 +109,6 @@ namespace authdb { private: ClientConnections *_firstConnection; ClientConnections *_lastConnection; std::unordered_map<uuid::uuid, ClientConnections*> _connectionIndex; }; };