Load sessions lazily from db

This commit is contained in:
Nicolas Werner 2020-11-27 04:19:03 +01:00
parent 37b971adb2
commit c24f9a22a5
6 changed files with 42 additions and 33 deletions

View file

@ -318,26 +318,46 @@ Cache::saveInboundMegolmSession(const MegolmSessionIndex &index,
auto txn = lmdb::txn::begin(env_); auto txn = lmdb::txn::begin(env_);
lmdb::dbi_put(txn, inboundMegolmSessionDb_, lmdb::val(key), lmdb::val(pickled)); lmdb::dbi_put(txn, inboundMegolmSessionDb_, lmdb::val(key), lmdb::val(pickled));
txn.commit(); txn.commit();
{
std::unique_lock<std::mutex> lock(session_storage.group_inbound_mtx);
session_storage.group_inbound_sessions[key] = std::move(session);
}
} }
OlmInboundGroupSession * mtx::crypto::InboundGroupSessionPtr
Cache::getInboundMegolmSession(const MegolmSessionIndex &index) Cache::getInboundMegolmSession(const MegolmSessionIndex &index)
{ {
std::unique_lock<std::mutex> lock(session_storage.group_inbound_mtx); using namespace mtx::crypto;
return session_storage.group_inbound_sessions[json(index).dump()].get();
try {
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
std::string key = json(index).dump();
lmdb::val value;
if (lmdb::dbi_get(txn, inboundMegolmSessionDb_, lmdb::val(key), value)) {
auto session = unpickle<InboundSessionObject>(
std::string(value.data(), value.size()), SECRET);
return session;
}
} catch (std::exception &e) {
nhlog::db()->error("Failed to get inbound megolm session {}", e.what());
}
return nullptr;
} }
bool bool
Cache::inboundMegolmSessionExists(const MegolmSessionIndex &index) Cache::inboundMegolmSessionExists(const MegolmSessionIndex &index)
{ {
std::unique_lock<std::mutex> lock(session_storage.group_inbound_mtx); using namespace mtx::crypto;
return session_storage.group_inbound_sessions.find(json(index).dump()) !=
session_storage.group_inbound_sessions.end(); try {
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
std::string key = json(index).dump();
lmdb::val value;
return lmdb::dbi_get(txn, inboundMegolmSessionDb_, lmdb::val(key), value);
} catch (std::exception &e) {
nhlog::db()->error("Failed to get inbound megolm session {}", e.what());
}
return false;
} }
void void
@ -545,18 +565,6 @@ Cache::restoreSessions()
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
std::string key, value; std::string key, value;
//
// Inbound Megolm Sessions
//
{
auto cursor = lmdb::cursor::open(txn, inboundMegolmSessionDb_);
while (cursor.get(key, value, MDB_NEXT)) {
auto session = unpickle<InboundSessionObject>(value, SECRET);
session_storage.group_inbound_sessions[key] = std::move(session);
}
cursor.close();
}
// //
// Outbound Megolm Sessions // Outbound Megolm Sessions
// //
@ -4173,7 +4181,7 @@ saveInboundMegolmSession(const MegolmSessionIndex &index,
{ {
instance_->saveInboundMegolmSession(index, std::move(session)); instance_->saveInboundMegolmSession(index, std::move(session));
} }
OlmInboundGroupSession * mtx::crypto::InboundGroupSessionPtr
getInboundMegolmSession(const MegolmSessionIndex &index) getInboundMegolmSession(const MegolmSessionIndex &index)
{ {
return instance_->getInboundMegolmSession(index); return instance_->getInboundMegolmSession(index);

View file

@ -256,7 +256,7 @@ exportSessionKeys();
void void
saveInboundMegolmSession(const MegolmSessionIndex &index, saveInboundMegolmSession(const MegolmSessionIndex &index,
mtx::crypto::InboundGroupSessionPtr session); mtx::crypto::InboundGroupSessionPtr session);
OlmInboundGroupSession * mtx::crypto::InboundGroupSessionPtr
getInboundMegolmSession(const MegolmSessionIndex &index); getInboundMegolmSession(const MegolmSessionIndex &index);
bool bool
inboundMegolmSessionExists(const MegolmSessionIndex &index); inboundMegolmSessionExists(const MegolmSessionIndex &index);

View file

@ -55,13 +55,11 @@ from_json(const nlohmann::json &obj, MegolmSessionIndex &msg);
struct OlmSessionStorage struct OlmSessionStorage
{ {
// Megolm sessions // Megolm sessions
std::map<std::string, mtx::crypto::InboundGroupSessionPtr> group_inbound_sessions;
std::map<std::string, mtx::crypto::OutboundGroupSessionPtr> group_outbound_sessions; std::map<std::string, mtx::crypto::OutboundGroupSessionPtr> group_outbound_sessions;
std::map<std::string, OutboundGroupSessionData> group_outbound_session_data; std::map<std::string, OutboundGroupSessionData> group_outbound_session_data;
// Guards for accessing megolm sessions. // Guards for accessing megolm sessions.
std::mutex group_outbound_mtx; std::mutex group_outbound_mtx;
std::mutex group_inbound_mtx;
}; };
struct StoredOlmSession struct StoredOlmSession

View file

@ -246,7 +246,8 @@ public:
// //
void saveInboundMegolmSession(const MegolmSessionIndex &index, void saveInboundMegolmSession(const MegolmSessionIndex &index,
mtx::crypto::InboundGroupSessionPtr session); mtx::crypto::InboundGroupSessionPtr session);
OlmInboundGroupSession *getInboundMegolmSession(const MegolmSessionIndex &index); mtx::crypto::InboundGroupSessionPtr getInboundMegolmSession(
const MegolmSessionIndex &index);
bool inboundMegolmSessionExists(const MegolmSessionIndex &index); bool inboundMegolmSessionExists(const MegolmSessionIndex &index);
// //

View file

@ -534,7 +534,7 @@ handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyR
return; return;
} }
auto session_key = mtx::crypto::export_session(session); auto session_key = mtx::crypto::export_session(session.get());
// //
// Prepare the m.room_key event. // Prepare the m.room_key event.
// //
@ -584,7 +584,8 @@ decryptEvent(const MegolmSessionIndex &index,
std::string msg_str; std::string msg_str;
try { try {
auto session = cache::client()->getInboundMegolmSession(index); auto session = cache::client()->getInboundMegolmSession(index);
auto res = olm::client()->decrypt_group_message(session, event.content.ciphertext); auto res =
olm::client()->decrypt_group_message(session.get(), event.content.ciphertext);
msg_str = std::string((char *)res.data.data(), res.data.size()); msg_str = std::string((char *)res.data.data(), res.data.size());
} catch (const lmdb::error &e) { } catch (const lmdb::error &e) {
return {DecryptionErrorCode::DbError, e.what(), std::nullopt}; return {DecryptionErrorCode::DbError, e.what(), std::nullopt};

View file

@ -604,7 +604,8 @@ EventStore::decryptEvent(const IdIndex &idx,
std::string msg_str; std::string msg_str;
try { try {
auto session = cache::client()->getInboundMegolmSession(index); auto session = cache::client()->getInboundMegolmSession(index);
auto res = olm::client()->decrypt_group_message(session, e.content.ciphertext); auto res =
olm::client()->decrypt_group_message(session.get(), e.content.ciphertext);
msg_str = std::string((char *)res.data.data(), res.data.size()); msg_str = std::string((char *)res.data.data(), res.data.size());
} catch (const lmdb::error &e) { } catch (const lmdb::error &e) {
nhlog::db()->critical("failed to retrieve megolm session with index ({}, {}, {})", nhlog::db()->critical("failed to retrieve megolm session with index ({}, {}, {})",