From b2623d8d92d1be324b98281b3b80bbe3e5b34aef Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 16 May 2021 20:44:32 +0100 Subject: [PATCH] cmdlistener: Apply an idle timeout and an upload timeout Signed-off-by: Ian Jackson --- daemon/cmdlistener.rs | 15 ++++++++++++++- src/bundles.rs | 5 ++++- src/commands.rs | 2 ++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 1fcd812e..34bc09cc 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -13,6 +13,9 @@ use authproofs::*; // ---------- newtypes, type aliases, basic definitions ---------- +pub const IDLE_TIMEOUT: Duration = Duration::from_secs(60); +pub const UPLOAD_TIMEOUT: Duration = Duration::from_secs(60); + use pwd::Passwd; use std::os::unix::io::AsRawFd; use std::os::unix::net::UnixListener; @@ -262,6 +265,7 @@ fn execute_and_respond(cs: &mut CommandStreamData, cmd: MgmtCommand, } )? }; + bulk_upload.inner_mut().set_timeout(Some(UPLOAD_TIMEOUT)); let uploaded = upload.bulk(bulk_upload, size, &hash, &mut for_response)?; { @@ -1350,12 +1354,21 @@ impl CommandStream<'_> { pub fn mainloop(mut self) { loop { use MgmtChannelReadError::*; - match self.chan.read.read_withbulk::() { + match { + self.chan.read.inner_mut().set_timeout(Some(IDLE_TIMEOUT)); + let r = self.chan.read.read_withbulk::(); + r + } { Ok((cmd, mut rbulk)) => { execute_and_respond(&mut self.d, cmd, &mut rbulk, &mut self.chan.write)?; }, Err(EOF) => break, + Err(IO(e)) if e.kind() == ErrorKind::TimedOut => { + info!("{}: idle timeout reading command stream", &self.d.desc); + self.write_error(ME::IdleTimeout)?; + break; + } Err(IO(e)) => Err(e).context("read command stream")?, Err(Parse(s)) => self.write_error(ME::CommandParseFailed(s))?, } diff --git a/src/bundles.rs b/src/bundles.rs index ea61053f..f05b9f89 100644 --- a/src/bundles.rs +++ b/src/bundles.rs @@ -868,7 +868,10 @@ impl Uploading { let mut data_reporter = progress::ReadOriginator::new( for_progress, Phase::Upload, size, data); - let copied_size = io::copy(&mut data_reporter, &mut file) + let copied_size = match io::copy(&mut data_reporter, &mut file) { + Err(e) if e.kind() == ErrorKind::TimedOut => throw!(ME::UploadTimeout), + x => x, + } .with_context(|| tmp.clone()) .context("copy").map_err(IE::from)?; diff --git a/src/commands.rs b/src/commands.rs index e5095eb5..ceec49be 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -242,6 +242,8 @@ pub enum MgmtError { #[error("bad bundle: {0}")] BadBundle(String), #[error("bundle not found")] BundleNotFound, #[error("bundle(s) in use, cannot clear ({0})")] BundlesInUse(String), + #[error("idle timeout waiting for mgmt command")] IdleTimeout, + #[error("upload took too long (timed out)")] UploadTimeout, } impl From for MgmtError { -- 2.30.2