pub trait Config: Send + Sync {
    type Protocol: for<'resp> Protocol<'resp>;
    type ConnectionUserMeta: Send;
    type MailUserMeta: Send;
Show 32 methods fn hostname(
        &self,
        conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> &str;
fn tls_accept<'life0, 'life1, 'async_trait, IO>(
        &'life0 self,
        io: IO,
        conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Result<Duplex<Pin<Box<dyn Send + AsyncRead>>, Pin<Box<dyn Send + AsyncWrite>>>>> + Send + 'async_trait>>
    where
        IO: 'static + Unpin + Send + AsyncRead + AsyncWrite,
        IO: 'async_trait,
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
;
fn new_mail<'life0, 'life1, 'async_trait>(
        &'life0 self,
        conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Self::MailUserMeta> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
;
fn filter_from<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        from: Option<Email>,
        meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<Option<Email>>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
;
fn filter_to<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        to: Email,
        meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<Email>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
;
fn handle_mail<'resp, 'life0, 'life1, 'async_trait, R>(
        &'resp self,
        stream: &'life0 mut EscapedDataReader<'life1, R>,
        meta: MailMetadata<Self::MailUserMeta>,
        conn_meta: &'resp mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = <Self::Protocol as Protocol<'resp>>::HandleMailReturnType> + Send + 'async_trait>>
    where
        R: Send + Unpin + AsyncRead,
        Self: 'resp,
        'resp: 'async_trait,
        R: 'async_trait,
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
; fn welcome_banner(
        &self,
        conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> &str { ... }
fn welcome_banner_reply(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn hello_banner(
        &self,
        conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> &str { ... }
fn filter_hello<'life0, 'life1, 'async_trait>(
        &'life0 self,
        is_extended: bool,
        hostname: Hostname,
        conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<HelloInfo>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
, { ... }
fn can_do_tls(
        &self,
        conn_meta: &ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> bool { ... }
fn filter_data<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        meta: &'life1 mut MailMetadata<Self::MailUserMeta>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
, { ... }
fn handle_rset<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        meta: &'life1 mut Option<MailMetadata<Self::MailUserMeta>>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
, { ... }
fn handle_starttls<'life0, 'life1, 'async_trait>(
        &'life0 self,
        conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
, { ... }
fn handle_expn<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        name: MaybeUtf8<&'life1 str>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
, { ... }
fn handle_vrfy<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        name: MaybeUtf8<&'life1 str>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
, { ... }
fn handle_help<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        subject: MaybeUtf8<&'life1 str>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
, { ... }
fn handle_noop<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        string: MaybeUtf8<&'life1 str>,
        conn_meta: &'life2 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        Self: 'async_trait
, { ... }
fn handle_quit<'life0, 'life1, 'async_trait>(
        &'life0 self,
        conn_meta: &'life1 mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Pin<Box<dyn Future<Output = Decision<()>> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
, { ... }
fn already_did_hello(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn mail_before_hello(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn already_in_mail(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn rcpt_before_mail(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn data_before_rcpt(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn data_before_mail(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn starttls_unsupported(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn command_unrecognized(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn pipeline_forbidden_after_starttls(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn line_too_long(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn handle_mail_did_not_call_complete(
        &self,
        conn_meta: &mut ConnectionMetadata<Self::ConnectionUserMeta>
    ) -> Reply { ... }
fn reply_write_timeout(&self) -> Duration { ... }
fn command_read_timeout(&self) -> Duration { ... }
}

Associated Types

Required methods

Note: this function is only ever used for the default implementations of other functions in this trait. As such, it is OK to leave it unimplemented!() if other functions are implemented.

Note: if you don’t want to implement TLS, you should override can_do_tls to return false so that STARTTLS is not advertized. This being said, returning an error here should have the same result in practice, except clients will try STARTTLS and fail

handle_mail is an async function that returns either a single decision in the case of the SMTP protocol, or an async stream of decisions in the case of the LMTP protocol.

For LMTP: there must be one such decision for each RCPT TO command that succeeded (i.e. for each accepted recipient), which allows to indicate that the message could be stored in the mailbox of some users, but not in that of other users. This can happen for instance if their mail quota is used up. The lifetimes of the borrow on the mail’s data stream is limited to the duration of the async call; this reference may not be retained by the returned stream. The async function must consume the entire data stream before returning its stream of responses. The recommended implementation of this function would start by reading the message’s content to a temporary file, and then produce a stream that writes the message to all of the mailboxes one after the other.

Note: the EscapedDataReader has an inner buffer size of RDBUF_SIZE, which means that reads should not happen with more than this buffer size.

Also, note that there is no timeout applied here, so the implementation of this function is responsible for making sure that the client does not just stop sending anything to DOS the system.

Provided methods

Note: this function is only ever used for the default implementations of other functions in this trait. As such, it is OK to leave it unimplemented!() if other functions are implemented.

Note: this function is only ever used for the default implementations of other functions in this trait. As such, it is OK to leave it unimplemented!() if other functions are implemented.

Implementors