1 use crate::{handle_unsecured_session::handle_unsecured_session, storage::MessageStorage};
2 use std::net::SocketAddr;
3 use tokio::io::AsyncWriteExt;
4 use tokio::net::{TcpListener, TcpStream};
5
6 pub async fn listen(storage: MessageStorage) -> anyhow::Result<()> {
7 let addr = SocketAddr::from(([127, 0, 0, 1], 2525));
8 let listener = TcpListener::bind(addr).await?;
9
10 tracing::info!("SMTP server listening on {}", addr);
11
12 loop {
13 match listener.accept().await {
14 Ok((mut stream, _)) => {
15 let storage_clone = storage.clone();
16 tokio::spawn(async move {
17 if let Err(err) = handle_connection(&mut stream, storage_clone).await {
18 tracing::error!("Error handling SMTP connection: {:?}", err);
19 };
20 });
21 }
22 Err(err) => {
23 tracing::error!("Error establishing SMTP connection: {:?}", err);
24 }
25 }
26 }
27 }
28
29 async fn handle_connection(stream: &mut TcpStream, storage: MessageStorage) -> anyhow::Result<()> {
30 // Send greeting
31 stream.write_all(b"220 My SMTP server\r\n").await?;
32
33 // Handle unsecured session which will handle STARTTLS
34 handle_unsecured_session(stream, Some(storage)).await
35 }