diff options
author | samantharitter <samantha.ritter@10gen.com> | 2017-06-27 12:09:40 -0400 |
---|---|---|
committer | Jason Carey <jcarey@argv.me> | 2017-07-13 17:40:53 -0400 |
commit | e1cae24805e3e7282958ee67a01555dd6ce40039 (patch) | |
tree | ebce77d9a502a193784483b2201b65e1a5010d98 /src/mongo/db/logical_session_cache.cpp | |
parent | 9a49ee3a03e02597086e577f06a71a0723bc0582 (diff) | |
download | mongo-e1cae24805e3e7282958ee67a01555dd6ce40039.tar.gz |
SERVER-29610 Allow LogicalSessionIds to contain signed user information
Diffstat (limited to 'src/mongo/db/logical_session_cache.cpp')
-rw-r--r-- | src/mongo/db/logical_session_cache.cpp | 78 |
1 files changed, 51 insertions, 27 deletions
diff --git a/src/mongo/db/logical_session_cache.cpp b/src/mongo/db/logical_session_cache.cpp index 8aa1eaba802..7474c398159 100644 --- a/src/mongo/db/logical_session_cache.cpp +++ b/src/mongo/db/logical_session_cache.cpp @@ -32,13 +32,20 @@ #include "mongo/db/logical_session_cache.h" +#include "mongo/db/operation_context.h" #include "mongo/db/server_parameters.h" +#include "mongo/db/service_context.h" #include "mongo/util/duration.h" #include "mongo/util/log.h" #include "mongo/util/periodic_runner.h" namespace mongo { +namespace { +const auto getLogicalSessionCache = + ServiceContext::declareDecoration<std::unique_ptr<LogicalSessionCache>>(); +} // namespace + MONGO_EXPORT_STARTUP_SERVER_PARAMETER(logicalSessionRecordCacheSize, int, LogicalSessionCache::kLogicalSessionCacheDefaultCapacity); @@ -55,6 +62,20 @@ constexpr int LogicalSessionCache::kLogicalSessionCacheDefaultCapacity; constexpr Minutes LogicalSessionCache::kLogicalSessionDefaultTimeout; constexpr Minutes LogicalSessionCache::kLogicalSessionDefaultRefresh; +LogicalSessionCache* LogicalSessionCache::get(ServiceContext* service) { + return getLogicalSessionCache(service).get(); +} + +LogicalSessionCache* LogicalSessionCache::get(OperationContext* ctx) { + return get(ctx->getClient()->getServiceContext()); +} + +void LogicalSessionCache::set(ServiceContext* service, + std::unique_ptr<LogicalSessionCache> sessionCache) { + auto& cache = getLogicalSessionCache(service); + cache = std::move(sessionCache); +} + LogicalSessionCache::LogicalSessionCache(std::unique_ptr<ServiceLiason> service, std::unique_ptr<SessionsCollection> collection, Options options) @@ -78,42 +99,34 @@ LogicalSessionCache::~LogicalSessionCache() { } } -StatusWith<LogicalSessionRecord::Owner> LogicalSessionCache::getOwner(LogicalSessionId lsid) { +Status LogicalSessionCache::fetchAndPromote(SignedLogicalSessionId slsid) { // Search our local cache first - auto owner = getOwnerFromCache(lsid); - if (owner.isOK()) { - return owner; + auto promoteRes = promote(slsid); + if (promoteRes.isOK()) { + return promoteRes; } // Cache miss, must fetch from the sessions collection. - auto res = _sessionsColl->fetchRecord(lsid); + auto res = _sessionsColl->fetchRecord(slsid); // If we got a valid record, add it to our cache. if (res.isOK()) { auto& record = res.getValue(); record.setLastUse(_service->now()); + // Any duplicate records here are actually the same record with different + // lastUse times, ignore them. auto oldRecord = _addToCache(record); - - // If we had a conflicting record for this id, and they aren't the same record, - // it could mean that an interloper called endSession and startSession for the - // same lsid while we were fetching its record from the sessions collection. - // This means our session has been written over, do not allow the caller to use it. - // Note: we could find expired versions of our same record here, but they'll compare equal. - if (oldRecord && *oldRecord != record) { - return {ErrorCodes::NoSuchSession, "no matching session record found"}; - } - - return record.getSessionOwner(); + return Status::OK(); } + // If we could not get a valid record, return the error. return res.getStatus(); } -StatusWith<LogicalSessionRecord::Owner> LogicalSessionCache::getOwnerFromCache( - LogicalSessionId lsid) { +Status LogicalSessionCache::promote(SignedLogicalSessionId slsid) { stdx::unique_lock<stdx::mutex> lk(_cacheMutex); - auto it = _cache.find(lsid); + auto it = _cache.find(slsid.getLsid()); if (it == _cache.end()) { return {ErrorCodes::NoSuchSession, "no matching session record found in the cache"}; } @@ -126,13 +139,13 @@ StatusWith<LogicalSessionRecord::Owner> LogicalSessionCache::getOwnerFromCache( // Update the last use time before returning. it->second.setLastUse(now); - return it->second.getSessionOwner(); + return Status::OK(); } -Status LogicalSessionCache::startSession(LogicalSessionRecord authoritativeRecord) { +Status LogicalSessionCache::startSession(SignedLogicalSessionId slsid) { // Make sure the timestamp makes sense - auto now = _service->now(); - authoritativeRecord.setLastUse(now); + auto authoritativeRecord = + LogicalSessionRecord::makeAuthoritativeRecord(slsid, _service->now()); // Attempt to insert into the sessions collection first. This collection enforces // unique session ids, so it will act as concurrency control for us. @@ -148,7 +161,7 @@ Status LogicalSessionCache::startSession(LogicalSessionRecord authoritativeRecor auto oldRecord = _addToCache(authoritativeRecord); if (oldRecord) { if (*oldRecord != authoritativeRecord) { - if (!_isDead(*oldRecord, now)) { + if (!_isDead(*oldRecord, _service->now())) { return {ErrorCodes::DuplicateSession, "session with this id already exists"}; } } @@ -157,6 +170,17 @@ Status LogicalSessionCache::startSession(LogicalSessionRecord authoritativeRecor return Status::OK(); } +StatusWith<SignedLogicalSessionId> LogicalSessionCache::signLsid(OperationContext* opCtx, + LogicalSessionId* id, + boost::optional<OID> userId) { + return _service->signLsid(opCtx, id, std::move(userId)); +} + +Status LogicalSessionCache::validateLsid(OperationContext* opCtx, + const SignedLogicalSessionId& slsid) { + return _service->validateLsid(opCtx, slsid); +} + void LogicalSessionCache::_refresh() { LogicalSessionIdSet activeSessions; LogicalSessionIdSet deadSessions; @@ -177,9 +201,9 @@ void LogicalSessionCache::_refresh() { for (auto& it : cacheCopy) { auto record = it.second; if (!_isDead(record, now)) { - activeSessions.insert(record.getLsid()); + activeSessions.insert(record.getSignedLsid().getLsid()); } else { - deadSessions.insert(record.getLsid()); + deadSessions.insert(record.getSignedLsid().getLsid()); } } @@ -236,7 +260,7 @@ bool LogicalSessionCache::_isDead(const LogicalSessionRecord& record, Date_t now boost::optional<LogicalSessionRecord> LogicalSessionCache::_addToCache( LogicalSessionRecord record) { stdx::unique_lock<stdx::mutex> lk(_cacheMutex); - return _cache.add(record.getLsid(), std::move(record)); + return _cache.add(record.getSignedLsid().getLsid(), std::move(record)); } } // namespace mongo |