mimeparser: wrap try_decrypt() into block_in_place()

try_decrypt() is a CPU-bound task.
When called from async function,
it should be wrapped in tokio::task::spawn_blocking().
Using tokio::task::spawn_blocking() is difficult here
because of &mail, &private_keyring and &public_keyring borrows,
so we should at least use tokio::task::block_in_place()
to avoid blocking the executor.
This commit is contained in:
link2xt
2023-02-21 20:51:38 +00:00
parent 1450bf5483
commit 992a6cbfc2
2 changed files with 21 additions and 19 deletions

View File

@@ -6,6 +6,7 @@
- Make smeared timestamp generation non-async. #4075 - Make smeared timestamp generation non-async. #4075
### Fixes ### Fixes
- Do not block async task executor while decrypting the messages. #4079
### API-Changes ### API-Changes

View File

@@ -256,26 +256,27 @@ impl MimeMessage {
hop_info += &decryption_info.dkim_results.to_string(); hop_info += &decryption_info.dkim_results.to_string();
let public_keyring = keyring_from_peerstate(decryption_info.peerstate.as_ref()); let public_keyring = keyring_from_peerstate(decryption_info.peerstate.as_ref());
let (mail, mut signatures, encrypted) = let (mail, mut signatures, encrypted) = match tokio::task::block_in_place(|| {
match try_decrypt(context, &mail, &private_keyring, &public_keyring) { try_decrypt(context, &mail, &private_keyring, &public_keyring)
Ok(Some((raw, signatures))) => { }) {
mail_raw = raw; Ok(Some((raw, signatures))) => {
let decrypted_mail = mailparse::parse_mail(&mail_raw)?; mail_raw = raw;
if std::env::var(crate::DCC_MIME_DEBUG).is_ok() { let decrypted_mail = mailparse::parse_mail(&mail_raw)?;
info!( if std::env::var(crate::DCC_MIME_DEBUG).is_ok() {
context, info!(
"decrypted message mime-body:\n{}", context,
String::from_utf8_lossy(&mail_raw), "decrypted message mime-body:\n{}",
); String::from_utf8_lossy(&mail_raw),
} );
(Ok(decrypted_mail), signatures, true)
} }
Ok(None) => (Ok(mail), HashSet::new(), false), (Ok(decrypted_mail), signatures, true)
Err(err) => { }
warn!(context, "decryption failed: {:#}", err); Ok(None) => (Ok(mail), HashSet::new(), false),
(Err(err), HashSet::new(), false) Err(err) => {
} warn!(context, "decryption failed: {:#}", err);
}; (Err(err), HashSet::new(), false)
}
};
let mail = mail.as_ref().map(|mail| { let mail = mail.as_ref().map(|mail| {
let (content, signatures_detached) = validate_detached_signature(mail, &public_keyring) let (content, signatures_detached) = validate_detached_signature(mail, &public_keyring)
.unwrap_or((mail, Default::default())); .unwrap_or((mail, Default::default()));