feat: Add configurable limits for packet sizes.
imap-codec already enforces recursion limits and our tokio codec enforces a maximum literal limit. We should make this more robust by configuring how many bytes are allowed to be maximally retained, what is the maximum line length, etc.
In the end, we want to make sure we can enforce some upper bound of required memory to serve a single client or server connection.
Questions: What is important here? Are maximum retained bytes enough? Do we really need finer controls for literals and lines? I think they are needed in order to give better error messages, e.g., when someone tries to upload too large attachements, but maybe there is a more generic solution.
First proposal:
pub struct Limits {
/// Maximum allowed line length.
///
/// This includes all bytes up to and including the first `\r\n`.
/// Note that the octet count used to start a literal, e.g., `{123}`, is already included.
max_line_length: usize,
/// Maximum allowed literal length.
///
/// This includes the mere literal as the octet count belongs to the preceeding line.
/// Note that any following bytes are treated as a new line.
max_literal_length: usize, // TODO: `usize` or `u32`?
/// Maximum allowed message length.
///
/// This includes everything a message is made of, i.e., defines the maximum
/// allowed sum of all line lengths and literal lengths.
max_message_length: usize,
}
From imap-protocol mailing list:
With the exception of the APPEND command, most literals that are likely to
appear in an IMAP command are relatively small. UW and Panda IMAP have a
limit of 10,000 octets which is far more than what anything is ever likely
to use.
APPEND (and APPEND-class exceptions such as CATENATE) is the exception.
Those literals can be as large as an email message (so potentially
hundreds of megabytes).
Many servers handle APPEND as a special case command.
The Fragmentizer implements the suggested max_message_length and allows the user to easily implement max_line_length (by providing the length and allowing to skip the message with poison_message) and max_literal_length (by providing the length and allowing to skip the message with skip_message) theirself.
@duesee Do you think we can close this?
Yes, let's close it!