diff options
| -rw-r--r-- | Cargo.lock | 66 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/smtp_server.rs | 44 |
3 files changed, 78 insertions, 34 deletions
@@ -80,10 +80,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] name = "cc" -version = "1.2.58" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "shlex", @@ -198,9 +204,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.93" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "797146bb2677299a1eb6b7b50a890f4c361b29ef967addf5b2fa45dae1bb6d7d" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ "once_cell", "wasm-bindgen", @@ -235,6 +241,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] +name = "mio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] name = "once_cell" version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -396,6 +413,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] name = "sqlite-wasm-rs" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -440,12 +467,17 @@ dependencies = [ [[package]] name = "tokio" -version = "1.51.0" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ + "bytes", + "libc", + "mio", "pin-project-lite", + "socket2", "tokio-macros", + "windows-sys", ] [[package]] @@ -478,10 +510,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] name = "wasm-bindgen" -version = "0.2.116" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc0882f7b5bb01ae8c5215a1230832694481c1a4be062fd410e12ea3da5b631" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", @@ -492,9 +530,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.116" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75973d3066e01d035dbedaad2864c398df42f8dd7b1ea057c35b8407c015b537" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -502,9 +540,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.116" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91af5e4be765819e0bcfee7322c14374dc821e35e72fa663a830bbc7dc199eac" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", @@ -515,9 +553,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.116" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9bf0406a78f02f336bf1e451799cca198e8acde4ffa278f0fb20487b150a633" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] @@ -9,4 +9,4 @@ env_logger = "0.11.10" libc = "0.2.184" log = "0.4.29" rusqlite = "0.39.0" -tokio = { version = "1.51.0", features = ["macros", "rt-multi-thread", "sync"] } +tokio = { version = "1.51.0", features = ["io-util", "macros", "net", "rt-multi-thread", "sync"] } diff --git a/src/smtp_server.rs b/src/smtp_server.rs index e6c0efc..2805081 100644 --- a/src/smtp_server.rs +++ b/src/smtp_server.rs @@ -1,10 +1,12 @@ -use std::{ - io::{BufRead, BufReader, Write}, - net::{IpAddr, SocketAddr, TcpListener, TcpStream}, -}; +use std::net::{IpAddr, SocketAddr}; use anyhow::Result; -use tokio::{spawn, sync::mpsc::Sender}; +use tokio::{ + io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, + net::{TcpListener, TcpStream}, + spawn, + sync::mpsc::Sender, +}; use crate::model::Mail; @@ -16,9 +18,9 @@ pub struct SmtpServer { } impl SmtpServer { - pub fn new(ip: [u8; 4], port: u16) -> Result<Self> { + pub async fn new(ip: [u8; 4], port: u16) -> Result<Self> { Ok(Self { - listener: TcpListener::bind((IpAddr::from(ip), port))?, + listener: TcpListener::bind((IpAddr::from(ip), port)).await?, running: false, }) } @@ -27,7 +29,7 @@ impl SmtpServer { pub async fn run(&mut self, tx_processor: Sender<Mail>) -> Result<()> { self.running = true; while self.running { - let (stream, addr) = match self.listener.accept() { + let (stream, addr) = match self.listener.accept().await { Ok(v) => v, Err(e) => match e.raw_os_error() { Some(libc::EMFILE | libc::ENFILE) => return Err(anyhow::Error::from(e)), @@ -68,20 +70,22 @@ struct SessionHandler { } impl SessionHandler { - async fn run(mut self, stream: TcpStream) -> Result<()> { - let mut writer = stream.try_clone()?; - let mut r = BufReader::new(&stream); + async fn run(mut self, mut stream: TcpStream) -> Result<()> { + let (r, mut writer) = stream.split(); + let mut reader = BufReader::new(r); let mut buffer = String::new(); - writer.write_all( - Reply::Ready(String::from(SERVER_NAME)) - .to_string() - .as_bytes(), - )?; + writer + .write_all( + Reply::Ready(String::from(SERVER_NAME)) + .to_string() + .as_bytes(), + ) + .await?; loop { buffer.clear(); - if r.read_line(&mut buffer)? == 0 { + if reader.read_line(&mut buffer).await? == 0 { break; } log::debug!("Received '{}' from '{}'", buffer.trim(), self.addr); @@ -100,13 +104,15 @@ impl SessionHandler { let command = match Command::try_from(buffer.as_str()) { Err(_) => { - writer.write_all(Reply::InvalidCommand.to_string().as_bytes())?; + writer + .write_all(Reply::InvalidCommand.to_string().as_bytes()) + .await?; continue; } Ok(v) => v, }; let res = self.apply(command).await?; - writer.write_all(res.to_string().as_bytes())?; + writer.write_all(res.to_string().as_bytes()).await?; } log::info!("Connection closed by {}", self.addr); |
