machine: Remove a deadlock when decrypting Olm messages using an existing session.

master
Damir Jelić 2020-04-23 11:37:47 +02:00
parent 1de791c207
commit cb235c47a1
2 changed files with 24 additions and 7 deletions

View File

@ -237,6 +237,7 @@ impl Client {
event: &mut EventJson<RoomEvent>, event: &mut EventJson<RoomEvent>,
) -> Option<EventJson<RoomEvent>> { ) -> Option<EventJson<RoomEvent>> {
match event.deserialize() { match event.deserialize() {
#[allow(unused_mut)]
Ok(mut e) => { Ok(mut e) => {
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
let mut decrypted_event = None; let mut decrypted_event = None;

View File

@ -59,7 +59,6 @@ use tracing::{debug, error, info, instrument, trace, warn};
pub type OneTimeKeys = BTreeMap<AlgorithmAndDeviceId, OneTimeKey>; pub type OneTimeKeys = BTreeMap<AlgorithmAndDeviceId, OneTimeKey>;
#[derive(Debug)]
pub struct OlmMachine { pub struct OlmMachine {
/// The unique user id that owns this account. /// The unique user id that owns this account.
user_id: UserId, user_id: UserId,
@ -83,6 +82,15 @@ pub struct OlmMachine {
outbound_group_session: HashMap<RoomId, OutboundGroupSession>, outbound_group_session: HashMap<RoomId, OutboundGroupSession>,
} }
impl std::fmt::Debug for OlmMachine {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OlmMachine")
.field("user_id", &self.user_id)
.field("device_id", &self.device_id)
.finish()
}
}
impl OlmMachine { impl OlmMachine {
const ALGORITHMS: &'static [&'static ruma_events::Algorithm] = &[ const ALGORITHMS: &'static [&'static ruma_events::Algorithm] = &[
&Algorithm::OlmV1Curve25519AesSha2, &Algorithm::OlmV1Curve25519AesSha2,
@ -668,6 +676,9 @@ impl OlmMachine {
return Ok(None); return Ok(None);
}; };
let mut session_to_save = None;
let mut plaintext = None;
for session in &mut *sessions.lock().await { for session in &mut *sessions.lock().await {
let mut matches = false; let mut matches = false;
@ -684,11 +695,10 @@ impl OlmMachine {
let ret = session.decrypt(message.clone()).await; let ret = session.decrypt(message.clone()).await;
if let Ok(p) = ret { if let Ok(p) = ret {
// Decryption was successful, save the new ratchet state of the plaintext = Some(p);
// session. session_to_save = Some(session.clone());
self.store.save_session(session.clone()).await?;
return Ok(Some(p)); break;
} else { } else {
// Decryption failed with a matching session, the session is // Decryption failed with a matching session, the session is
// likely wedged and needs to be rotated. // likely wedged and needs to be rotated.
@ -703,7 +713,14 @@ impl OlmMachine {
} }
} }
Ok(None) if let Some(session) = session_to_save {
// Decryption was successful, save the new ratchet state of the
// session that was used to decrypt the message.
trace!("Saved the new session state for {}", sender);
self.store.save_session(session).await?;
}
Ok(plaintext)
} }
async fn decrypt_olm_message( async fn decrypt_olm_message(
@ -836,7 +853,6 @@ impl OlmMachine {
/// # Arguments /// # Arguments
/// ///
/// * `event` - The to-device event that should be decrypted. /// * `event` - The to-device event that should be decrypted.
#[instrument]
async fn decrypt_to_device_event( async fn decrypt_to_device_event(
&mut self, &mut self,
event: &ToDeviceEncrypted, event: &ToDeviceEncrypted,