diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ebb83032..1d1fdfbc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - cargo: bump quick-xml from 0.23.0 to 0.26.0 #3722 - Add fuzzing tests #3853 - Add mappings for some file types to Viewtype / MIME type #3881 +- Set `TCP_NODELAY` on IMAP sockets #3883 ### API-Changes - jsonrpc: add python API for webxdc updates #3872 diff --git a/src/imap/client.rs b/src/imap/client.rs index eef6e7929..434141c7d 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -8,6 +8,7 @@ use anyhow::{Context as _, Result}; use async_imap::Client as ImapClient; use async_imap::Session as ImapSession; +use tokio::io::BufWriter; use tokio::net::{self, TcpStream}; use tokio::time::timeout; use tokio_io_timeout::TimeoutStream; @@ -94,14 +95,18 @@ impl Client { pub async fn connect_secure(hostname: &str, port: u16, strict_tls: bool) -> Result { let tcp_stream = timeout(IMAP_TIMEOUT, TcpStream::connect((hostname, port))).await??; + tcp_stream.set_nodelay(true)?; + let mut timeout_stream = TimeoutStream::new(tcp_stream); timeout_stream.set_write_timeout(Some(IMAP_TIMEOUT)); timeout_stream.set_read_timeout(Some(IMAP_TIMEOUT)); let timeout_stream = Box::pin(timeout_stream); + let buffered_stream = BufWriter::new(timeout_stream); + let tls = build_tls(strict_tls); let tls_stream: Box = - Box::new(tls.connect(hostname, timeout_stream).await?); + Box::new(tls.connect(hostname, buffered_stream).await?); let mut client = ImapClient::new(tls_stream); let _greeting = client @@ -117,11 +122,16 @@ impl Client { pub async fn connect_insecure(addr: impl net::ToSocketAddrs) -> Result { let tcp_stream = timeout(IMAP_TIMEOUT, TcpStream::connect(addr)).await??; + tcp_stream.set_nodelay(true)?; + let mut timeout_stream = TimeoutStream::new(tcp_stream); timeout_stream.set_write_timeout(Some(IMAP_TIMEOUT)); timeout_stream.set_read_timeout(Some(IMAP_TIMEOUT)); let timeout_stream = Box::pin(timeout_stream); - let stream: Box = Box::new(timeout_stream); + + let buffered_stream = BufWriter::new(timeout_stream); + + let stream: Box = Box::new(buffered_stream); let mut client = ImapClient::new(stream); let _greeting = client diff --git a/src/imap/session.rs b/src/imap/session.rs index a66dd4852..326d0b81b 100644 --- a/src/imap/session.rs +++ b/src/imap/session.rs @@ -6,6 +6,7 @@ use async_imap::types::Mailbox; use async_imap::Session as ImapSession; use async_native_tls::TlsStream; use fast_socks5::client::Socks5Stream; +use tokio::io::BufWriter; use tokio::net::TcpStream; use tokio_io_timeout::TimeoutStream; @@ -48,7 +49,22 @@ impl SessionStream for Pin>> { self.as_mut().set_read_timeout_pinned(timeout); } } -impl SessionStream for Socks5Stream>>> { +impl SessionStream for TlsStream>> { + fn set_read_timeout(&mut self, timeout: Option) { + self.get_mut().get_mut().set_read_timeout(timeout); + } +} +impl SessionStream for TlsStream>>>> { + fn set_read_timeout(&mut self, timeout: Option) { + self.get_mut().set_read_timeout(timeout); + } +} +impl SessionStream for BufWriter>>> { + fn set_read_timeout(&mut self, timeout: Option) { + self.get_mut().as_mut().set_read_timeout_pinned(timeout); + } +} +impl SessionStream for Socks5Stream>>>> { fn set_read_timeout(&mut self, timeout: Option) { self.get_socket_mut().set_read_timeout(timeout) } diff --git a/src/socks.rs b/src/socks.rs index 89a9458c6..e61168593 100644 --- a/src/socks.rs +++ b/src/socks.rs @@ -6,6 +6,7 @@ use std::time::Duration; use anyhow::{Context as _, Result}; pub use async_smtp::ServerAddress; +use tokio::io::BufWriter; use tokio::net::{self, TcpStream}; use tokio::time::timeout; use tokio_io_timeout::TimeoutStream; @@ -58,15 +59,17 @@ impl Socks5Config { &self, target_addr: impl net::ToSocketAddrs, timeout_val: Duration, - ) -> Result>>>> { + ) -> Result>>>>> { let tcp_stream = timeout(timeout_val, TcpStream::connect(target_addr)) .await .context("connection timeout")? .context("connection failure")?; + let mut timeout_stream = TimeoutStream::new(tcp_stream); timeout_stream.set_write_timeout(Some(timeout_val)); timeout_stream.set_read_timeout(Some(timeout_val)); - let timeout_stream = Box::pin(timeout_stream); + let pinned_stream = Box::pin(timeout_stream); + let buffered_stream = BufWriter::new(pinned_stream); let authentication_method = if let Some((username, password)) = self.user_password.as_ref() { @@ -78,7 +81,7 @@ impl Socks5Config { None }; let socks_stream = - Socks5Stream::use_stream(timeout_stream, authentication_method, Config::default()) + Socks5Stream::use_stream(buffered_stream, authentication_method, Config::default()) .await?; Ok(socks_stream)