229 lines
9.1 KiB
Text
229 lines
9.1 KiB
Text
Quick Mail Transfer Protocol (QMTP)
|
|
D. J. Bernstein, djb@pobox.com
|
|
19970201
|
|
|
|
|
|
1. Introduction
|
|
|
|
The Quick Mail Transfer Protocol (QMTP) is a replacement for the
|
|
Simple Mail Transfer Protocol (SMTP). QMTP eliminates any need for
|
|
end-of-line scanning between hosts with the same end-of-line
|
|
convention. It features automatic pipelining and chunking, 8-bit
|
|
transmission, prior declaration of the message size, and efficient
|
|
batching. It is designed to be very easy to implement.
|
|
|
|
QMTP is supported by the qmail-qmtpd and maildir2qmtp programs in the
|
|
qmail package.
|
|
|
|
In this document, a string of 8-bit bytes may be written in two
|
|
different forms: as a series of hexadecimal numbers between angle
|
|
brackets, or as a sequence of ASCII characters between double quotes.
|
|
For example, <68 65 6c 6c 6f 20 77 6f 72 6c 64 21> is a string of
|
|
length 12; it is the same as the string "hello world!". Note that
|
|
these notations are part of this document, not part of the protocol.
|
|
|
|
|
|
2. Protocol
|
|
|
|
A QMTP client connects to a QMTP server, as discussed in section 7,
|
|
over a reliable stream protocol allowing transmission of 8-bit bytes.
|
|
|
|
Protocol outline: the client sends one or more packages; after each
|
|
package, the server sends back some responses.
|
|
|
|
The client begins by sending a package. A package contains a mail
|
|
message, an envelope sender address, and one or more envelope
|
|
recipient addresses. See section 4 for the format of a package.
|
|
|
|
When the server sees the end of the package, it sends back a series
|
|
of responses, one response for each envelope recipient address, in
|
|
the same order as given by the client. The server is not permitted to
|
|
change the order under any circumstances, even if two addresses are
|
|
the same. See section 5 for the format of a response.
|
|
|
|
The server is not permitted to send any portion of its responses to a
|
|
package until the client has sent the final byte of the package. The
|
|
client is permitted to close the connection before sending the final
|
|
byte of the package; in this case, the server must throw away the
|
|
package without attempting to deliver the message. However, the
|
|
server must not throw away previously accepted messages.
|
|
|
|
The client does NOT need to wait for a server response before sending
|
|
another package. The server must NOT throw away incoming data when it
|
|
sends a response. It is the client's responsibility to avoid
|
|
deadlock: if it sends a package before receiving all expected server
|
|
responses, it must continuously watch for those responses. The server
|
|
is permitted to delay its responses if further data has already shown
|
|
up from the client; while it is delaying responses, it must not pause
|
|
to wait for further data for the client.
|
|
|
|
The server is permitted to close the connection at any time, although
|
|
high-quality servers will try to avoid doing so. Any response not
|
|
received by the client indicates a temporary failure.
|
|
|
|
A QMTP session should take at most 1 hour. Both sides are expected
|
|
to close the connection after this time.
|
|
|
|
|
|
3. Messages
|
|
|
|
In this document, an ``8-bit mail message'' means a sequence of
|
|
lines. Each line is a string of zero or more 8-bit bytes.
|
|
|
|
A message is called ``safe'' if none of its bytes are <0a>.
|
|
|
|
Implementation note: Here is the intended interpretation of text
|
|
files as messages under some current operating systems. Under DOS, a
|
|
message is stored on disk as
|
|
|
|
first line, <0d 0a>, second line, <0d 0a> ... <0d 0a>, last line.
|
|
|
|
Under UNIX, a message is stored on disk as
|
|
|
|
first line, <0a>, second line, <0a> ... <0a>, last line.
|
|
|
|
Notice that both of these encodings are reversible for safe messages.
|
|
|
|
In practice, it is very common for the last line to be empty. Many
|
|
existing utilities refer to the last line as a ``partial line'' and
|
|
ignore it whether or not it is empty.
|
|
|
|
|
|
4. Packages
|
|
|
|
A package is the concatenation of three strings:
|
|
|
|
first, an encoded 8-bit mail message;
|
|
second, an encoded envelope sender address;
|
|
third, an encoded series of encoded envelope recipient addresses.
|
|
|
|
Each envelope address is a string of 8-bit bytes. The interpretation
|
|
of addresses depends on the environment in which QMTP is used and is
|
|
outside the scope of this document. Each address is encoded as a
|
|
netstring, as discussed in section 6. The series of encoded recipient
|
|
addresses is in turn encoded as a netstring.
|
|
|
|
A message is encoded as a string of 8-bit bytes in one of two ways:
|
|
|
|
Encoding #1 is <0d>, the first line, <0d 0a>, the second line,
|
|
<0d 0a>, the third line, ..., <0d 0a>, the last line.
|
|
|
|
Encoding #2 is <0a>, the first line, <0a>, the second line, <0a>,
|
|
the third line, ..., <0a>, the last line.
|
|
|
|
This string of 8-bit bytes is in turn encoded as a netstring, as
|
|
discussed in section 6.
|
|
|
|
Every server must be prepared to handle encoding #1 and encoding #2.
|
|
A server must not reject a message merely because of its encoding.
|
|
|
|
Implementation note: The intent of encoding #1 and encoding #2 is to
|
|
allow very straightforward handling of text files under DOS and UNIX
|
|
respectively. The programmer can print <0d> or <0a> and then simply
|
|
copy the file.
|
|
|
|
|
|
5. Responses
|
|
|
|
Each response is a nonempty string of 8-bit bytes, encoded as a
|
|
netstring. The first byte of the string is one of the following:
|
|
|
|
"K" The message has been accepted for delivery to this envelope
|
|
recipient. This is morally equivalent to the 250 response to
|
|
DATA in SMTP; it is subject to the reliability requirements
|
|
of RFC 1123, section 5.3.3.
|
|
|
|
"Z" Temporary failure. The client should try again later.
|
|
|
|
"D" Permanent failure.
|
|
|
|
The remaining bytes are a description of what happened. It is
|
|
expected that the description, when interpreted as UTF-2 characters,
|
|
(1) will be human-readable, (2) will not repeat the envelope
|
|
recipient address, and (3) will not include formatting characters
|
|
other than <20>. However, these expectations are not requirements,
|
|
and the client should be ready for arbitrary bytes from the server.
|
|
|
|
Descriptions beginning with <20> are reserved for future extensions.
|
|
In descriptions not beginning with <20>, the character "#" must not
|
|
appear except in HCMSSC codes.
|
|
|
|
A server must NOT accept a safe message unless it can store the
|
|
message without corruption. More precisely: if the encoded message
|
|
sent by the client matches the encoding of some safe message M, then
|
|
acceptance means that the server is accepting responsibility to
|
|
deliver M to the envelope recipient. (There is at most one
|
|
possibility for M, since encodings are reversible on safe messages.)
|
|
Deletion of nulls is NOT permissible; a server that deletes nulls
|
|
must reject any message containing nulls. Folding of long lines and
|
|
high-bit stripping are also NOT permissible.
|
|
|
|
Servers are permitted to change unsafe messages.
|
|
|
|
|
|
6. Netstrings
|
|
|
|
Any string of 8-bit bytes may be encoded as [len]":"[string]",".
|
|
Here [string] is the string and [len] is a nonempty sequence of ASCII
|
|
digits giving the length of [string] in decimal. The ASCII digits are
|
|
<30> for 0, <31> for 1, and so on up through <39> for 9. Extra zeros
|
|
at the front of [len] are prohibited: [len] begins with <30> exactly
|
|
when [string] is empty.
|
|
|
|
For example, the string "hello world!" is encoded as <31 32 3a 68
|
|
65 6c 6c 6f 20 77 6f 72 6c 64 21 2c>, i.e., "12:hello world!,". The
|
|
empty string is encoded as "0:,".
|
|
|
|
[len]":"[string]"," is called a netstring. [string] is called the
|
|
interpretation of the netstring.
|
|
|
|
|
|
7. Encapsulation
|
|
|
|
QMTP may be used on top of TCP. A QMTP-over-TCP server listens for
|
|
TCP connections on port 209.
|
|
|
|
|
|
8. Examples
|
|
|
|
A client opens a connection and sends the concatenation of the
|
|
following strings:
|
|
|
|
"246:" <0a>
|
|
"Received: (qmail-queue invoked by uid 0);"
|
|
" 29 Jul 1996 09:36:40 -0000" <0a>
|
|
"Date: 29 Jul 1996 11:35:35 -0000" <0a>
|
|
"Message-ID: <19960729113535.375.qmail@heaven.af.mil>" <0a>
|
|
"From: God@heaven.af.mil" <0a>
|
|
"To: djb@silverton.berkeley.edu (D. J. Bernstein)" <0a>
|
|
<0a>
|
|
"This is a test." <0a> ","
|
|
"24:" "God-DSN-37@heaven.af.mil" ","
|
|
"30:" "26:djb@silverton.berkeley.edu," ","
|
|
|
|
"356:" <0d>
|
|
"From: MAILER-DAEMON@heaven.af.mil" <0d 0a>
|
|
"To:" <0d 0a>
|
|
" Hate." <22> "The Quoting" <22>
|
|
"@SILVERTON.berkeley.edu," <0d 0a>
|
|
" " <22> "\\Backslashes!" <22>
|
|
"@silverton.BERKELEY.edu" <0d 0a>
|
|
<0d 0a>
|
|
"The recipient addresses here could"
|
|
" have been encoded in SMTP as" <0d 0a>
|
|
"" <0d 0a>
|
|
" RCPT TO:<Hate.The\ Quoting@silverton.berkeley.EDU>" <0d 0a>
|
|
" RCPT TO:<\\Backslashes!@silverton.berkeley.edu>" <0d 0a>
|
|
<0d 0a>
|
|
"This ends with a partial last line, right here" ","
|
|
"0:" ","
|
|
"83:" "39:Hate.The Quoting@silverton.berkeley.edu,"
|
|
"36:\Backslashes!@silverton.berkeley.EDU," ","
|
|
|
|
The server sends the following response, indicating acceptance:
|
|
|
|
"21:Kok 838640135 qp 1390,"
|
|
"21:Kok 838640135 qp 1391,"
|
|
"21:Kok 838640135 qp 1391,"
|
|
|
|
The client closes the connection.
|