Skip to main content

rs_smtp/
server.rs

1use crate::backend::Backend;
2use crate::conn::Conn;
3use crate::parse::parse_cmd;
4use std::sync::Arc;
5use std::time::Duration;
6
7use anyhow::Result;
8
9use tokio::net::TcpListener;
10use tokio_rustls::TlsAcceptor;
11
12
13// const ERR_TCP_AND_LMTP: &str = "smtp: cannot start LMTP server listening on a TCP socket";
14
15pub struct Server<B: Backend> {
16    pub addr: String,
17    pub tls_acceptor: Option<TlsAcceptor>,
18
19    pub domain: String,
20    pub max_recipients: usize,
21    pub max_message_bytes: usize,
22    pub max_line_length: usize,
23    pub allow_insecure_auth: bool,
24    pub strict: bool,
25
26    pub read_timeout: Duration,
27    pub write_timeout: Duration,
28
29    pub enable_smtputf8: bool,
30    pub enable_requiretls: bool,
31    pub enable_binarymime: bool,
32
33    pub backend: B,
34
35    pub caps: Vec<String>,
36
37    //pub listeners: Mutex<Vec<TcpListener>>,
38
39    //pub conns: HashMap<String, Arc<Mutex<Conn<B, S>>>>,
40}
41
42impl<B: Backend> Server<B> {
43    pub fn new(be: B) -> Self {
44        return Server{
45            addr: String::new(),
46            tls_acceptor: None,
47            domain: String::new(),
48            max_recipients: 0,
49            max_message_bytes: 0,
50            max_line_length: 2000,
51            allow_insecure_auth: true,
52            strict: false,
53            read_timeout: Duration::from_secs(0),
54            write_timeout: Duration::from_secs(0),
55            enable_smtputf8: false,
56            enable_requiretls: false,
57            enable_binarymime: false,
58            backend: be,
59            caps: vec!["PIPELINING".to_string(), "8BITMIME".to_string(), "ENHANCEDSTATUSCODES".to_string(), "CHUNKING".to_string()],
60            //listeners: Mutex::new(vec![]),
61        }
62    }
63
64    pub async fn serve(self: Arc<Self>, l: TcpListener) -> Result<()> {
65        loop {
66            match l.accept().await {
67                Ok((stream, _)) => {
68                    let server = self.clone();
69                    println!("New connection");
70                    tokio::spawn(async move {
71                        if let Err(err) = server.handle_conn(Conn::new(stream, server.max_line_length)).await {
72                            println!("Error333: {}", err);
73                        }
74                    });
75                }
76                Err(e) => {
77                    println!("Error444: {}", e);
78                }
79            }
80        }
81    }
82
83    pub async fn handle_conn(&self, mut c: Conn<B>) -> Result<()> {
84        c.greet(self.domain.clone()).await;
85
86        loop {
87            let mut line = String::new();
88            match c.read_line(&mut line, self).await {
89                Ok(0) => {
90                    println!("Connection closed");
91                    c.stream.get_mut().write_response(221, [2,4,0], &["Connection closed, bye"]).await;
92                    return Ok(());
93                }
94                Ok(_) => {
95                    match parse_cmd(line) {
96                        Ok((cmd, arg)) => {
97                            c.handle(cmd, arg, self).await;
98                        }
99                        Err(err) => {
100                            println!("Error222: {}", err);
101                            c.stream.get_mut().write_response(501, [5,5,2], &["Bad command"]).await;
102                            continue;
103                        }
104                    }
105                }
106                Err(err) => {
107                    println!("Connection error: {}", err);
108                    c.stream.get_mut().write_response(221, [2,4,0], &["Connection error, sorry"]).await;
109                    return Err(err.into());
110                }
111            }
112        }
113    }
114
115    pub async fn listen_and_serve(self) -> Result<()> {
116        let l = TcpListener::bind(&self.addr).await?;
117        Arc::new(self).serve(l).await
118    }
119
120    /*
121    pub async fn listen_and_serve_tls(&mut self) -> Result<()> {
122        let tls = self.server.tls_acceptor.as_ref().unwrap();
123        let l = TcpListener::bind(&self.server.addr).await?;
124        let l = tls.accept(l)?;
125        self.serve(l).await
126    }
127    */
128}