RFC 821
Simple Mail Transfer Protocol
RFC 821 ๐ SIMPLE MAIL TRANSFER PROTOCOL
Author: Jonathan B. Postel, ISI (Information Sciences Institute), University of Southern California, 4676 Admiralty Way, Marina del Rey, California 90291, (213) 822-1511 ๐
Date: August 1982 ๐๏ธ
Network Working Group, Request for Comments: DRAFT. So this is still a draft, not a final spec ๐ง
Replaces: RFC 788, 780, 772 ๐
Status: DRAFT โจ
Here's the table of contents, copied exactly so every section number lines up ๐
1. INTRODUCTION .................................................. 1
2. THE SMTP MODEL ................................................ 2
3. THE SMTP PROCEDURE ............................................ 4
3.1. Mail ..................................................... 4
3.2. Forwarding ............................................... 7
3.3. Verifying and Expanding .................................. 8
3.4. Sending and Mailing ..................................... 11
3.5. Opening and Closing ..................................... 13
3.6. Relaying ................................................ 14
3.7. Domains ................................................. 17
3.8. Changing Roles .......................................... 18
4. THE SMTP SPECIFICATIONS ...................................... 19
4.1. SMTP Commands ........................................... 19
4.1.1. Command Semantics ..................................... 19
4.1.2. Command Syntax ........................................ 27
4.2. SMTP Replies ............................................ 34
4.2.1. Reply Codes by Function Group ......................... 35
4.2.2. Reply Codes in Numeric Order .......................... 36
4.3. Sequencing of Commands and Replies ...................... 37
4.4. State Diagrams .......................................... 39
4.5. Details ................................................. 41
4.5.1. Minimum Implementation ................................ 41
4.5.2. Transparency .......................................... 41
4.5.3. Sizes ................................................. 42
APPENDIX A: TCP ................................................. 44
APPENDIX B: NCP ................................................. 45
APPENDIX C: NITS ................................................ 46
APPENDIX D: X.25 ................................................ 47
APPENDIX E: Theory of Reply Codes ............................... 48
APPENDIX F: Scenarios ........................................... 51
GLOSSARY ......................................................... 64
REFERENCES ....................................................... 67
1. INTRODUCTION โจ
Okay so the whole goal of SMTP (Simple Mail Transfer Protocol) is to move mail reliably and efficiently ๐๐ SMTP doesn't care what transmission system is underneath it. It just needs a reliable, ordered data stream channel ๐ Appendices A, B, C, and D show how to use SMTP with different transport services, and there's a Glossary that defines all the terms used in this doc ๐
Here's the iconic part ๐ SMTP can relay mail across transport service environments! A transport service gives processes an interprocess communication environment (IPCE). An IPCE might cover one network, several networks, or just a subset of a network. Transport systems (IPCEs) are not one-to-one with networks, so don't assume they are ๐ โโ๏ธ Any two processes can talk directly through any IPCE they both know about. Mail is just one application of interprocess communication ๐ฌ If mail needs to cross between IPCEs, it gets relayed through a process that's connected to two (or more) of them. So basically, mail can get from hosts on one transport system to hosts on another through a host that's on both ๐ฆ
2. THE SMTP MODEL ๐ง
The SMTP design is built on this model of communication: when a user asks to send mail, the sender-SMTP sets up a two-way transmission channel to a receiver-SMTP. That receiver-SMTP might be the final destination, or it might just be a middleman ๐ SMTP commands are generated by the sender-SMTP and sent to the receiver-SMTP, and SMTP replies go the other way, from the receiver-SMTP back to the sender-SMTP, as responses to those commands ๐ฌ
Once the channel is up, the SMTP-sender sends a MAIL command saying who the mail is from. If the SMTP-receiver can accept mail, it replies with an OK ๐ Next, the SMTP-sender sends a RCPT command naming one recipient. If the SMTP-receiver can accept mail for that recipient, it replies with an OK. If it can't, it rejects that recipient but not the whole mail transaction ๐ซถ The SMTP-sender and SMTP-receiver can negotiate several recipients this way. Once the recipients are sorted out, the SMTP-sender sends the mail data and ends it with a special sequence โ๏ธ If the SMTP-receiver successfully processes the mail data, it replies with an OK. The whole dialog is on purpose lock-step, one-at-a-time, no multitasking drama ๐
Here's the picture, it's giving architecture ๐๏ธ
-------------------------------------------------------------
+----------+ +----------+
+------+ | | | |
| User |<-->| | SMTP | |
+------+ | Sender- |Commands/Replies| Receiver-|
+------+ | SMTP |<-------------->| SMTP | +------+
| File |<-->| | and Mail | |<-->| File |
|System| | | | | |System|
+------+ +----------+ +----------+ +------+
Sender-SMTP Receiver-SMTP
Model for SMTP Use
Figure 1
-------------------------------------------------------------
So SMTP handles sending mail in two ways: straight from the sending user's host to the receiving user's host when both are on the same transport service, or through one or more relay SMTP-servers when the source and destination aren't on the same transport service ๐
To pull off relaying, the SMTP-server has to be given the name of the ultimate destination host, plus the destination mailbox name. No skipping this step, bestie ๐ซถ
The MAIL command takes a reverse-path, which says who the mail is from. The RCPT command takes a forward-path, which says who the mail is to ๐ The forward-path is a source route, while the reverse-path is a return route. The return route can be used to send a message back to the sender if something goes wrong with a relayed message ๐
When the same message goes to multiple recipients, SMTP encourages sending only one copy of the data for all the recipients at the same destination host ๐ฆโจ
The mail commands and replies have a rigid syntax ๐ Replies also come with a numeric code. The examples below use real commands and replies, and the complete lists are in Section 4 on specifications ๐
Commands and replies are not case sensitive. A command or reply word can be upper case, lower case, or any mix of the two ๐ค But user names in mailboxes are the exception. For some hosts the user name is case sensitive, so SMTP implementations must preserve the case of user names exactly as they appear in mailbox arguments. Host names are not case sensitive ๐ธ
Commands and replies are made of characters from the ASCII character set [1]. When the transport service gives you an 8-bit byte (octet) channel, each 7-bit character is sent right justified in an octet, with the high order bit cleared to zero ๐ค
When describing the general form of a command or reply, an argument (or special symbol) is shown as a meta-linguistic variable (or constant), like "<string>" or "<reverse-path>". The angle brackets there mean these are placeholders ๐งฉ Some arguments use angle brackets literally, though. For example, an actual reverse-path is wrapped in angle brackets, so "<John.Smith@USC-ISI.ARPA>" is an instance of <reverse-path>, and the angle brackets really do get transmitted in the command or reply ๐
3. THE SMTP PROCEDURES ๐
This section walks through the procedures SMTP uses, in several parts. First up is the basic mail procedure, which is a mail transaction. After that come forwarding mail, verifying mailbox names and expanding mailing lists, sending to terminals instead of or alongside mailboxes, and the opening and closing exchanges. Near the end, there are notes on relaying, a note on mail domains, and a chat about changing roles ๐ญ Throughout the section you'll see examples of partial command and reply sequences, and several complete scenarios are in Appendix F ๐
3.1. MAIL ๐ฌ
Okay, mail transactions have three steps ๐ช The transaction starts with a MAIL command, which gives the sender's identification. Then one or more RCPT commands follow to give the receiver info. Then a DATA command brings in the mail data. And finally, the end of mail data indicator confirms the transaction ๐
Step one is the MAIL command. The <reverse-path> holds the source mailbox:
MAIL <SP> FROM:<reverse-path> <CRLF>
This command tells the SMTP-receiver that a new mail transaction is starting, and that it should reset all of its state tables and buffers, including any recipients or mail data ๐งน It gives the reverse-path, which can be used to report errors. If it's accepted, the receiver-SMTP returns a 250 OK reply ๐
The <reverse-path> can hold more than just a mailbox. It's a reverse source routing list of hosts plus the source mailbox. The first host in the <reverse-path> should be the host that's sending this command ๐ค๏ธ
Step two is the RCPT command:
RCPT <SP> TO:<forward-path> <CRLF>
This command gives a forward-path that identifies one recipient. If it's accepted, the receiver-SMTP returns a 250 OK reply and stores the forward-path ๐ฅ If the recipient is unknown, the receiver-SMTP returns a 550 Failure reply ๐ This second step can be repeated any number of times, so go wild with the recipients ๐ฆ
The <forward-path> can also hold more than just a mailbox. It's a source routing list of hosts plus the destination mailbox. The first host in the <forward-path> should be the host that's receiving this command ๐งญ
Step three is the DATA command:
DATA <CRLF>
If it's accepted, the receiver-SMTP returns a 354 Intermediate reply and treats all the lines that follow as the message text โ๏ธ Once the end of text is received and stored, the SMTP-receiver sends a 250 OK reply. Iconic ending ๐โจ
Okay so the mail data travels over the same channel as the commands, which means the receiver needs a clear "I'm done" signal so the command-and-reply chat can pick back up ๐ฌ. SMTP does this by sending a line with only a period on it ๐ซถ. A transparency procedure keeps that period from messing with the user's actual text (see Section 4.5.2) โจ
Please note that the mail data includes the memo header items such as Date, Subject, To, Cc, From [2] ๐
That end-of-data marker also confirms the whole mail transaction and tells the receiver-SMTP to now process the stored recipients and mail data ๐ฅ. If it's accepted, the receiver-SMTP sends back a 250 OK reply ๐. The DATA command should fail only if the mail transaction was incomplete (for example, no recipients), or if resources are not available ๐.
The above procedure is an example of a mail transaction. These commands must be used only in the order discussed above. Example 1 (below) shows how these commands work together in a mail transaction ๐ฆ
Example of the SMTP Procedure ๐
This SMTP example shows mail sent by Smith at host Alpha.ARPA, to Jones, Green, and Brown at host Beta.ARPA. Here we assume that host Alpha contacts host Beta directly ๐ง
S: MAIL FROM:<Smith@Alpha.ARPA>
R: 250 OK
S: RCPT TO:<Jones@Beta.ARPA>
R: 250 OK
S: RCPT TO:<Green@Beta.ARPA>
R: 550 No such user here
S: RCPT TO:<Brown@Beta.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: <CRLF>.<CRLF>
R: 250 OK
The mail has now been accepted for Jones and Brown. Green did not have a mailbox at host Beta ๐ญ
Example 1 ๐
3.2. FORWARDING
Sometimes the destination in the <forward-path> is wrong, but the receiver-SMTP knows where the correct destination is ๐บ๏ธ. In that case, one of the following replies should be used so the sender can reach the right place โจ
251 User not local; will forward to <forward-path>
This reply means the receiver-SMTP knows the user's mailbox is on another host, and it tells the sender the correct forward-path to use from now on. Either the host, the user, or both might be different. The receiver takes responsibility for delivering the message ๐ซถ
551 User not local; please try <forward-path>
This one also means the receiver-SMTP knows the user's mailbox is on another host, and it gives the correct forward-path to use. Again, either the host, the user, or both might be different. The receiver refuses to accept mail for this user, so the sender has to either redirect the mail using the info provided or send an error response back to the originating user ๐ค
Example 2 shows these responses in action ๐
Example of Forwarding
Either
S: RCPT TO:<Postel@USC-ISI.ARPA>
R: 251 User not local; will forward to <Postel@USC-ISIF.ARPA>
Or
S: RCPT TO:<Paul@USC-ISIB.ARPA>
R: 551 User not local; please try <Mockapetris@USC-ISIF.ARPA>
Example 2 ๐
3.3. VERIFYING AND EXPANDING
SMTP also comes with extra features: commands to verify a user name or expand a mailing list ๐. These are the VRFY and EXPN commands, and they both take character string arguments. For VRFY, the string is a user name, and the response may include the full name of the user and must include the mailbox of the user. For EXPN, the string identifies a mailing list, and the multiline response may include the full names of the users and must give the mailboxes on the mailing list ๐ฌ
"User name" is a fuzzy term, and that's on purpose ๐. If a host implements VRFY or EXPN, then at least local mailboxes must be recognized as "user names". If a host chooses to recognize other strings as "user names", that is allowed โจ
On some hosts, the line between a mailing list and an alias for a single mailbox is kinda blurry, since one data structure can hold both types of entries, and it's possible to have a mailing list of one mailbox ๐ธ. If someone asks to verify a mailing list, a positive response can be given if, upon receiving a message addressed to it, the message will be delivered to everyone on the list. Otherwise an error should be reported, for example 550 That is a mailing list, not a user. If someone asks to expand a user name, a positive response can be formed by returning a list containing one name, or an error can be reported, for example 550 That is a user name, not a mailing list ๐
For a multiline reply (which is normal for EXPN), exactly one mailbox is to be specified on each line of the reply. For an ambiguous request, like VRFY Smith where there are two Smiths, the response must be 553 User ambiguous ๐ฅบ
Verifying a user name is pretty straightforward, as shown in Example 3 ๐ง
Example of Verifying a User Name
Either
S: VRFY Smith
R: 250 Fred Smith <Smith@USC-ISIF.ARPA>
Or
S: VRFY Smith
R: 251 User not local; will forward to <Smith@USC-ISIQ.ARPA>
Or
S: VRFY Jones
R: 550 String does not match anything.
Or
S: VRFY Jones
R: 551 User not local; please try <Jones@USC-ISIQ.ARPA>
Or
S: VRFY Gourzenkyinplatz
R: 553 User ambiguous.
Example 3 ๐ท
Expanding a mailing list needs a multiline reply, as Example 4 shows ๐
Example of Expanding a Mailing List
Either
S: EXPN Example-People
R: 250-Jon Postel <Postel@USC-ISIF.ARPA>
R: 250-Fred Fonebone <Fonebone@USC-ISIQ.ARPA>
R: 250-Sam Q. Smith <SQSmith@USC-ISIQ.ARPA>
R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA>
R: 250-<joe@foo-unix.ARPA>
R: 250 <xyz@bar-unix.ARPA>
Or
S: EXPN Executive-Washroom-List
R: 550 Access Denied to You.
Example 4 ๐ฆ
The character string arguments of VRFY and EXPN can't be restricted any further, because implementations handle user names and mailbox lists in lots of different ways ๐. On some systems it might make sense for the EXPN argument to be a file name for a file holding a mailing list, but there's also a whole variety of file naming conventions across the Internet ๐
The VRFY and EXPN commands are not included in the minimum implementation (Section 4.5.1), and they are not required to work across relays when they are implemented ๐ โโ๏ธ
3.4. SENDING AND MAILING
The main job of SMTP is delivering messages to users' mailboxes ๐ฅ. Some hosts also offer a similar service: delivering messages to a user's terminal, but only if the user is active on the host ๐ป. Delivery to a mailbox is called "mailing", and delivery to a terminal is called "sending". Since on many hosts sending is almost the same as mailing, these two functions are combined in SMTP ๐ค. However, the sending commands are not included in the required minimum implementation (Section 4.5.1). Users should be able to control whether messages get written to their terminals, and most hosts let users accept or refuse these messages ๐
The following three commands support the sending options. They're used in the mail transaction instead of the MAIL command, and they tell the receiver-SMTP about the special semantics of this transaction โจ
SEND <SP> FROM:<reverse-path> <CRLF>
The SEND command requires that the mail data be delivered to the user's terminal. If the user isn't active (or isn't accepting terminal messages) on the host, a 450 reply may be returned to a RCPT command. The mail transaction is successful if the message is delivered to the terminal ๐
SOML <SP> FROM:<reverse-path> <CRLF>
The Send Or MaiL command requires that the mail data be delivered to the user's terminal if the user is active (and accepting terminal messages) on the host. If the user isn't active (or isn't accepting terminal messages), the mail data is entered into the user's mailbox instead. The mail transaction is successful if the message is delivered either to the terminal or to the mailbox ๐ฎ
SAML <SP> FROM:<reverse-path> <CRLF>
The Send And MaiL command requires that the mail data be delivered to the user's terminal if the user is active (and accepting terminal messages) on the host. In any case, the mail data is entered into the user's mailbox. The mail transaction is successful if the message is delivered to the mailbox ๐
The same reply codes used for the MAIL commands are used for these commands too ๐
3.5. OPENING AND CLOSING
When the transmission channel opens, there's an exchange to make sure the hosts are talking to the hosts they think they're talking to ๐คณ
The following two commands are used for opening and closing the transmission channel:
HELO <SP> <domain> <CRLF>
QUIT <CRLF>
In the HELO command, the host sending the command identifies itself. The command can be read as saying "Hello, I am <domain>" ๐
Example of Connection Opening โ๏ธ
R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready
S: HELO USC-ISIF.ARPA
R: 250 BBN-UNIX.ARPA
Example 5 ๐ผ
Example of Connection Closing ๐
S: QUIT
R: 221 BBN-UNIX.ARPA Service closing transmission channel
Example 6 ๐งธ
3.6. RELAYING
The forward-path can be a source route in the form @ONE,@TWO:JOE@THREE, where ONE, TWO, and THREE are hosts. This form is a way to show the difference between an address and a route ๐บ๏ธ. The mailbox is the absolute address, and the route is just directions for getting there. Please don't mix those two up, bestie ๐
.
As a message gets relayed from one server-SMTP to the next, the elements of the forward-path conceptually move over to the reverse-path ๐ฆ. The reverse-path is a reverse source route, which means a source route from wherever the message is right now back to whoever originally sent it. When a server-SMTP removes its identifier from the forward-path and adds it to the reverse-path, it must use the name it's known by in the environment it's sending into, not the environment the mail came from ๐. That matters because a server-SMTP can go by different names in different environments.
If a message reaches an SMTP and the first element of the forward-path is not that SMTP's identifier, the element stays in the forward-path, and it's used to figure out where to send the message next ๐งญ. Either way, the SMTP adds its own identifier to the reverse-path โจ.
When you're using source routing, the receiver-SMTP gets mail that needs to be relayed to another server-SMTP ๐ฌ. It can accept or reject the job of relaying the mail in the same way it accepts or rejects mail for a local user. The receiver-SMTP changes the command arguments by moving its own identifier from the forward-path to the start of the reverse-path. After that, it becomes a sender-SMTP, sets up a transmission channel to the next SMTP in the forward-path, and sends the mail on ๐.
The first host in the reverse-path should be the host sending the SMTP commands, and the first host in the forward-path should be the host receiving the SMTP commands ๐.
Here's the tea: the forward-path and reverse-path show up in the SMTP commands and replies, but not necessarily in the message itself ๐ซถ. So there's no need for this syntax to appear in the "To:", "From:", "CC:", etc. fields of the message header. Main character energy is knowing when to keep the routing info backstage ๐.
If a server-SMTP has accepted the job of relaying the mail, and then later finds that the forward-path is wrong or that the mail can't be delivered for whatever reason, it must build an "undeliverable mail" notification message and send it to the originator of the undeliverable mail, as shown by the reverse-path ๐ญ.
The notification message has to come from the server-SMTP at this host ๐. Obviously, server-SMTPs should not send notification messages about problems with notification messages ๐. One way to stop loops in error reporting is to put a null reverse-path in the MAIL command of a notification message ๐ธ. When that message gets relayed, it's allowed to keep the reverse-path null. A MAIL command with a null reverse-path looks like this:
MAIL FROM:<>
Now for an undeliverable mail notification message example ๐. This notification answers a message that JOE sent from HOSTW, which went through HOSTX to HOSTY with instructions to relay it on to HOSTZ. The example shows the conversation between HOSTY and HOSTX, which is the first step in getting the notification back ๐ฆ.
-------------------------------------------------------------
Example Undeliverable Mail Notification Message
S: MAIL FROM:<>
R: 250 ok
S: RCPT TO:<@HOSTX.ARPA:JOE@HOSTW.ARPA>
R: 250 ok
S: DATA
R: 354 send the mail data, end with .
S: Date: 23 Oct 81 11:22:33
S: From: SMTP@HOSTY.ARPA
S: To: JOE@HOSTW.ARPA
S: Subject: Mail System Problem
S:
S: Sorry JOE, your message to SAM@HOSTZ.ARPA lost.
S: HOSTZ.ARPA said this:
S: "550 No Such User"
S: .
R: 250 ok
Example 7
-------------------------------------------------------------
3.7. DOMAINS ๐
Domains are a pretty new idea in the ARPA Internet mail system, and they're lowkey a glow-up ๐ . Before, the address space was a flat global space of simple character string host names. Now it's a hierarchically structured rooted tree of global addresses ๐ณ. The host name gets replaced by a domain and host designator, which is a sequence of domain element strings separated by periods. The domain elements go from the most specific to the most general ๐ฅ.
For example, "USC-ISIF.ARPA", "Fred.Cambridge.UK", and "PC7.LCS.MIT.ARPA" could all be host-and-domain identifiers ๐ง.
Whenever domain names are used in SMTP, only the official names are used. Nicknames and aliases are not allowed ๐ซ.
3.8. CHANGING ROLES ๐
The TURN command can be used to swap the roles of the two programs talking over the transmission channel ๐ซ.
If program-A is currently the sender-SMTP, and it sends the TURN command and gets an ok reply (250), then program-A becomes the receiver-SMTP ๐ธ.
If program-B is currently the receiver-SMTP, and it gets the TURN command and sends an ok reply (250), then program-B becomes the sender-SMTP ๐ฆ.
To refuse the role change, the receiver sends the 502 reply ๐ โโ๏ธ.
Heads up: this command is optional. It wouldn't normally be used when the transmission channel is TCP ๐. But when setting up the transmission channel is expensive, this command can be really useful. For example, it might help with mail exchange over the public switched telephone system as a transmission channel, especially if some hosts poll other hosts for mail ๐.
4. THE SMTP SPECIFICATIONS ๐
4.1. SMTP COMMANDS ๐
4.1.1. COMMAND SEMANTICS โจ
The SMTP commands define the mail transfer or the mail system function that the user asks for ๐. SMTP commands are character strings ended by <CRLF>. The command codes are alphabetic characters, ended by <SP> if parameters follow, and by <CRLF> otherwise ๐ค. The syntax of mailboxes has to follow the receiver site's conventions. The SMTP commands are covered below, and the SMTP replies are covered in Section 4.2 ๐.
A mail transaction involves several data objects, and each one gets passed as an argument to a different command ๐งฉ. The reverse-path is the argument of the MAIL command, the forward-path is the argument of the RCPT command, and the mail data is the argument of the DATA command. These arguments or data objects have to be sent and held until the end of mail data indication confirms the transaction ๐. The model for this is that there are separate buffers for each type of data object: a reverse-path buffer, a forward-path buffer, and a mail data buffer. Certain commands add information to a specific buffer, or clear one or more buffers ๐งน.
HELLO (HELO) ๐
This command identifies the sender-SMTP to the receiver-SMTP. The argument field holds the host name of the sender-SMTP ๐.
The receiver-SMTP identifies itself to the sender-SMTP in the connection greeting reply, and again in the response to this command ๐ซถ.
This command and an OK reply to it confirm that both the sender-SMTP and the receiver-SMTP are in the initial state. That means no transaction is in progress, and all state tables and buffers are cleared ๐งผ.
MAIL (MAIL) ๐ฎ
This command starts a mail transaction in which the mail data gets delivered to one or more mailboxes. The argument field holds a reverse-path ๐.
The reverse-path is made up of an optional list of hosts plus the sender mailbox. When the list of hosts is there, it's a "reverse" source route, and it shows that the mail was relayed through each host on the list. The first host on the list was the most recent relay ๐ฆ. This list gets used as a source route to send non-delivery notices back to the sender. Each relay host adds itself to the beginning of the list, and it must use its name as known in the IPCE it's relaying to, not the IPCE the mail came from, if those are different ๐. In some kinds of error reporting messages, like undeliverable mail notifications, the reverse-path can be null (see Example 7) ๐.
This command clears the reverse-path buffer, the forward-path buffer, and the mail data buffer. Then it puts the reverse-path information from this command into the reverse-path buffer ๐งนโจ.
RECIPIENT (RCPT) ๐ฏ
This command identifies one individual recipient of the mail data. You can name multiple recipients by using this command multiple times ๐ฏโโ๏ธ.
The forward-path is made up of an optional list of hosts plus a required destination mailbox. When the list of hosts is there, it's a source route, and it shows that the mail must be relayed to the next host on the list ๐. If the receiver-SMTP doesn't do the relay function, it may use the same reply it would use for an unknown local user, which is 550 ๐.
When mail gets relayed, the relay host has to remove itself from the beginning of the forward-path and put itself at the beginning of the reverse-path ๐. When mail reaches its final destination (meaning the forward-path only has a destination mailbox), the receiver-SMTP puts it into the destination mailbox according to its host mail conventions ๐ฅ.
For example, mail received at relay host A with these arguments:
FROM:<USERX@HOSTY.ARPA>
TO:<@HOSTA.ARPA,@HOSTB.ARPA:USERC@HOSTD.ARPA>
will be relayed on to host B with these arguments:
FROM:<@HOSTA.ARPA:USERX@HOSTY.ARPA>
TO:<@HOSTB.ARPA:USERC@HOSTD.ARPA>.
This command adds its forward-path argument to the forward-path buffer ๐.
DATA (DATA) ๐
The receiver treats the lines after this command as mail data from the sender. This command adds the mail data from this command to the mail data buffer ๐. The mail data can contain any of the 128 ASCII character codes ๐ค.
The mail data ends with a line that contains only a period. In other words, the character sequence "<CRLF>.<CRLF>" (see Section 4.5.2 on Transparency). This is the end of mail data indication ๐.
The end of mail data is a big moment, bestie ๐ The receiver has to process everything it's been storing from this transaction. That processing eats up the reverse-path buffer, the forward-path buffer, and the mail data buffer, and once the command is done, all three get cleared ๐งนโจ If processing works out, the receiver has to send an OK reply. If it fails completely, the receiver has to send a failure reply ๐ญ
Now, when the receiver-SMTP accepts a message, whether it's for relaying or final delivery, it adds a time stamp line at the very top of the mail data ๐ฐ๏ธ๐ That line says which host sent the message, which host received it (and is adding this stamp), and the date and time it arrived. So relayed messages end up with multiple time stamp lines, like a little travel log ๐ฆ
When the receiver-SMTP does the "final delivery" of a message, it adds a return path line at the top of the mail data ๐ That line keeps whatever was in the <reverse-path> from the MAIL command. And "final delivery" just means the message leaves the SMTP world ๐ Usually that means it reached the destination user, but sometimes another mail system takes over and processes it further.
It's totally possible that the mailbox in the return path is different from the real sender's mailbox! Like, if error responses are supposed to go to a special error handling mailbox instead of the person who sent the message ๐
Okay so, the last two paragraphs basically mean the final mail data starts with a return path line, then one or more time stamp lines ๐ธ After those comes the mail data header and body [2]. Check out Example 8 for the vibe โจ
Now, partial success is its own whole thing, and it's kind of dramatic ๐ญ Imagine the receiver accepts a bunch of recipients and the mail data, but it can only deliver to some of them. Maybe a mailbox is out of space or something. In that case, the reply to the DATA command still has to be an OK reply ๐ BUT the receiver-SMTP also has to put together and send an "undeliverable mail" notification to whoever sent the message ๐ฌ It can either be one notice listing every recipient that didn't get it, or separate notices for each failed recipient (see Example 7). And every undeliverable mail notification goes out using the MAIL command, even if the original request came in as SEND, SOML, or SAML ๐ง
Here's the example, bestie. Look at how the return path and time stamps stack up ๐
Example of Return Path and Received Time Stamps
Return-Path: <@GHI.ARPA,@DEF.ARPA,@ABC.ARPA:JOE@ABC.ARPA>
Received: from GHI.ARPA by JKL.ARPA ; 27 Oct 81 15:27:39 PST
Received: from DEF.ARPA by GHI.ARPA ; 27 Oct 81 15:15:13 PST
Received: from ABC.ARPA by DEF.ARPA ; 27 Oct 81 15:01:59 PST
Date: 27 Oct 81 15:01:01 PST
From: JOE@ABC.ARPA
Subject: Improved Mailing System Installed
To: SAM@JKL.ARPA
This is to inform you that ...
Example 8
SEND (SEND)
This command starts a mail transaction where the mail data gets delivered to one or more terminals ๐ The argument field holds a reverse-path, and the command only counts as successful if the message actually gets delivered to a terminal ๐
The reverse-path is an optional list of hosts plus the sender mailbox. If the host list is there, it's a "reverse" source route, and it shows the mail went through each host on the list (the first host listed was the most recent relay) ๐ค๏ธ That list gets used as a source route to send non-delivery notices back to the sender. And here's the important bit: every relay host adds itself to the front of the list, and it has to use its name as known in the IPCE it's relaying to, not the IPCE the mail came from (if those are different) ๐ซถ
This command clears the reverse-path buffer, the forward-path buffer, and the mail data buffer, then puts the reverse-path info from this command into the reverse-path buffer ๐งนโจ
SEND OR MAIL (SOML)
This one starts a mail transaction where the mail data goes to one or more terminals or mailboxes ๐ฌ For each recipient, the mail goes to their terminal if they're active on the host (and accepting terminal messages). If not, it goes to their mailbox instead ๐ฆ The argument field holds a reverse-path, and it counts as successful if the message gets delivered to a terminal or the mailbox.
The reverse-path works exactly like it does for SEND: an optional host list plus the sender mailbox, with the same "reverse" source route vibes, the same add-yourself-to-the-front rule, and the same IPCE naming rule ๐
This command also clears the reverse-path buffer, the forward-path buffer, and the mail data buffer, then drops the reverse-path info into the reverse-path buffer ๐
SEND AND MAIL (SAML)
This one is the overachiever ๐ It starts a mail transaction where the mail data goes to one or more terminals and mailboxes. For each recipient, the mail goes to their terminal if they're active on the host (and accepting terminal messages), and then goes to the recipient's mailbox for all recipients ๐ The argument field holds a reverse-path, and it's only successful if the message is delivered to the mailbox.
Same reverse-path deal as before: optional host list, sender mailbox, reverse source route, the add-yourself-to-the-front rule, and the IPCE naming rule ๐ง
This command clears the reverse-path buffer, the forward-path buffer, and the mail data buffer, then stores the reverse-path info from this command into the reverse-path buffer ๐ธ
RESET (RSET)
This command is the "abort mission" button ๐ โโ๏ธ It says the current mail transaction gets aborted. Any stored sender, recipients, and mail data must be discarded, and all buffers and state tables get cleared. The receiver must send an OK reply ๐ซถ
VERIFY (VRFY)
This command asks the receiver to confirm that the argument identifies a user ๐ If it's a user name, the receiver returns the full name of the user (if it knows it) and the fully specified mailbox ๐
This command has no effect on the reverse-path buffer, the forward-path buffer, or the mail data buffer. Totally harmless, no cap โจ
EXPAND (EXPN)
This command asks the receiver to confirm that the argument identifies a mailing list, and if it does, to send back the membership of that list ๐ The full names of the users (if known) and their fully specified mailboxes come back in a multiline reply ๐
Also no effect on the reverse-path buffer, the forward-path buffer, or the mail data buffer ๐ฆ
HELP (HELP)
This command makes the receiver send helpful info back to whoever sent the HELP command ๐ง It can take an argument (like any command name) and return more specific info as the response ๐
Same deal: no effect on the reverse-path buffer, the forward-path buffer, or the mail data buffer ๐ซถ
NOOP (NOOP)
This command is the chillest one ๐ It doesn't change any parameters or previously entered commands. The only thing it asks for is that the receiver sends an OK reply ๐ธ
No effect on the reverse-path buffer, the forward-path buffer, or the mail data buffer ๐
QUIT (QUIT)
This command says the receiver must send an OK reply, and then close the transmission channel ๐
The receiver should not close the transmission channel until it gets and replies to a QUIT command (even if there was an error) ๐ The sender should not close the transmission channel until it sends a QUIT command and gets the reply (even if there was an error response to an earlier command) ๐ญ If the connection closes early, the receiver should act as if an RSET command came in, which cancels any pending transaction but doesn't undo any transaction that was already completed. And the sender should act as if the command or transaction in progress got a temporary error (4xx) ๐
TURN (TURN)
This command is the role-swap moment ๐ It says the receiver must either (1) send an OK reply and then take on the role of the sender-SMTP, or (2) send a refusal reply and keep being the receiver-SMTP ๐
If program-A is currently the sender-SMTP and sends the TURN command and gets an OK reply (250), then program-A becomes the receiver-SMTP ๐ฆ It's then in the initial state, as if the transmission channel just opened, and it sends the 220 service ready greeting next โจ
If program-B is currently the receiver-SMTP and gets the TURN command and sends an OK reply (250), then program-B becomes the sender-SMTP ๐ It's then in the initial state, as if the transmission channel just opened, and it expects to receive the 220 service ready greeting next ๐
To refuse changing roles, the receiver sends the 502 reply ๐ โโ๏ธ
There are restrictions on the order these commands can be used in, so pay attention, bestie ๐
The very first command in a session MUST be HELO ๐. HELO MAY be used again later in the session too. If the HELO argument isn't acceptable, a 501 failure reply MUST be returned and the receiver-SMTP MUST stay in the same state ๐
NOOP, HELP, EXPN, and VRFY can be used at any time during a session ๐
MAIL, SEND, SOML, or SAML begin a mail transaction โ๏ธ Once a transaction starts, it's made of one of those transaction-beginning commands, one or more RCPT commands, and a DATA command, in that order. A mail transaction MAY be aborted by the RSET command. There MAY be zero or more transactions in a session ๐ฆ
If the transaction-beginning command's argument isn't acceptable, a 501 failure reply MUST be returned and the receiver-SMTP MUST stay in the same state. If the commands in a transaction come out of order, a 503 failure reply MUST be returned and the receiver-SMTP MUST stay in the same state ๐ญ
The last command in a session MUST be QUIT ๐ and QUIT can not be used at any other time in a session. Main character energy, but only at the end ๐
4.1.2. COMMAND SYNTAX ๐
Okay so every command is a command code followed by an argument field. Command codes are four alphabetic characters, and upper and lower case letters are treated exactly the same ๐ธ So any of these could mean the mail command:
MAIL Mail mail MaIl mAIl
This goes for symbols that stand for parameter values too, like "TO" or "to" for the forward-path. The command code and the argument fields are separated by one or more spaces. BUT within the reverse-path and forward-path arguments, case is important ๐ In some hosts, the user "smith" is totally different from the user "Smith" ๐ค
The argument field is a variable-length character string that ends with the character sequence <CRLF>. The receiver takes no action until that sequence arrives ๐ง
Square brackets mean an optional argument field. If you don't take the option, the appropriate default is implied โจ
Here are the SMTP commands:
HELO <SP> <domain> <CRLF>
MAIL <SP> FROM:<reverse-path> <CRLF>
RCPT <SP> TO:<forward-path> <CRLF>
DATA <CRLF>
RSET <CRLF>
SEND <SP> FROM:<reverse-path> <CRLF>
SOML <SP> FROM:<reverse-path> <CRLF>
SAML <SP> FROM:<reverse-path> <CRLF>
VRFY <SP> <string> <CRLF>
EXPN <SP> <string> <CRLF>
HELP [<SP> <string>] <CRLF>
NOOP <CRLF>
QUIT <CRLF>
TURN <CRLF>
The syntax for those argument fields is written in BNF below. The "..." notation means a field MAY be repeated one or more times ๐
<reverse-path> ::= <path>
<forward-path> ::= <path>
<path> ::= "<" [ <a-d-l> ":" ] <mailbox> ">"
<a-d-l> ::= <at-domain> | <at-domain> "," <a-d-l>
<at-domain> ::= "@" <domain>
<domain> ::= <element> | <element> "." <domain>
<element> ::= <name> | "#" <number> | "[" <dotnum> "]"
<mailbox> ::= <local-part> "@" <domain>
<local-part> ::= <dot-string> | <quoted-string>
<name> ::= <a> <ldh-str> <let-dig>
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig> ::= <a> | <d>
<let-dig-hyp> ::= <a> | <d> | "-"
<dot-string> ::= <string> | <string> "." <dot-string>
<string> ::= <char> | <char> <string>
<quoted-string> ::= """ <qtext> """
<qtext> ::= "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext>
<char> ::= <c> | "\" <x>
<dotnum> ::= <snum> "." <snum> "." <snum> "." <snum>
<number> ::= <d> | <d> <number>
<CRLF> ::= <CR> <LF>
<CR> ::= the carriage return character (ASCII code 13)
<LF> ::= the line feed character (ASCII code 10)
<SP> ::= the space character (ASCII code 32)
<snum> ::= one, two, or three digits representing a decimal
integer value in the range 0 through 255
<a> ::= any one of the 52 alphabetic characters A through Z
in upper case and a through z in lower case
<c> ::= any one of the 128 ASCII characters, but not any
<special> or <SP>
<d> ::= any one of the ten digits 0 through 9
<q> ::= any one of the 128 ASCII characters except <CR>,
<LF>, quote ("), or backslash (\)
<x> ::= any one of the 128 ASCII characters (no exceptions)
<special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "."
| "," | ";" | ":" | "@" """ | the control
characters (ASCII codes 0 through 31 inclusive and
127)
Heads up, the backslash \ is a quote character ๐ซถ It means the next character is used literally, not with its usual meaning. For example, "Joe\,Smith" could be a single nine-character user field where the comma is the fourth character ๐
Hosts are usually known by names that get translated into addresses on each host. The name elements of domains have to be the official names, so no nicknames or aliases allowed ๐ซ
Sometimes a host isn't known to the translation function, and communication gets blocked ๐ญ To get around that, there are two numeric forms allowed for host "names". The first is a decimal integer with a pound sign in front, #, which means the number is the host's address. The second is four small decimal integers separated by dots and wrapped in brackets, like [123.255.37.2], which means a 32-bit ARPA Internet Address split into four 8-bit fields ๐
The time stamp line and the return path line are formally defined like this:
<return-path-line> ::= "Return-Path:" <SP><reverse-path><CRLF>
<time-stamp-line> ::= "Received:" <SP> <stamp> <CRLF>
<stamp> ::= <from-domain> <by-domain> <opt-info> ";"
<daytime>
<from-domain> ::= "FROM" <SP> <domain> <SP>
<by-domain> ::= "BY" <SP> <domain> <SP>
<opt-info> ::= [<via>] [<with>] [<id>] [<for>]
<via> ::= "VIA" <SP> <link> <SP>
<with> ::= "WITH" <SP> <protocol> <SP>
<id> ::= "ID" <SP> <string> <SP>
<for> ::= "FOR" <SP> <path> <SP>
<link> ::= The standard names for links are registered with
the Network Information Center.
<protocol> ::= The standard names for protocols are
registered with the Network Information Center.
<daytime> ::= <SP> <date> <SP> <time>
<date> ::= <dd> <SP> <mon> <SP> <yy>
<time> ::= <hh> ":" <mm> ":" <ss> <SP> <zone>
<dd> ::= the one or two decimal integer day of the month in
the range 1 to 31.
<mon> ::= "JAN" | "FEB" | "MAR" | "APR" | "MAY" | "JUN" |
"JUL" | "AUG" | "SEP" | "OCT" | "NOV" | "DEC"
<yy> ::= the two decimal integer year of the century in the
range 00 to 99.
<hh> ::= the two decimal integer hour of the day in the
range 00 to 24.
<mm> ::= the two decimal integer minute of the hour in the
range 00 to 59.
<ss> ::= the two decimal integer second of the minute in the
range 00 to 59.
<zone> ::= "UT" for Universal Time (the default) or other
time zone designator (as in [2]).
Here are the examples, bestie ๐ฆ
-------------------------------------------------------------
Return Path Example
Return-Path: <@CHARLIE.ARPA,@BAKER.ARPA:JOE@ABLE.ARPA>
Example 9
-------------------------------------------------------------
-------------------------------------------------------------
Time Stamp Line Example
Received: FROM ABC.ARPA BY XYZ.ARPA ; 22 OCT 81 09:23:59 PDT
Received: from ABC.ARPA by XYZ.ARPA via TELENET with X25
id M12345 for Smith@PDQ.ARPA ; 22 OCT 81 09:23:59 PDT
Example 10
-------------------------------------------------------------
4.2. SMTP REPLIES ๐
Replies to SMTP commands are how everyone stays in sync while mail moves around ๐ซถ They also guarantee that the sender-SMTP always knows the state of the receiver-SMTP. Every command MUST generate exactly one reply ๐ฏ
The details of the command-reply sequence get spelled out in Section 5.3 on Sequencing and Section 5.4 State Diagrams ๐บ๏ธ
An SMTP reply is a three-digit number (sent as three alphanumeric characters) followed by some text. The number is for automata, so they know what state to enter next. The text is for the human user ๐งโ๐ป The three digits are meant to carry enough encoded info that the sender-SMTP doesn't need to read the text. It MAY either discard the text or pass it along to the user, as appropriate โจ The text MAY be receiver-dependent and context dependent, so you'll probably see different wording for each reply code. There's a discussion of the theory behind reply codes in Appendix E ๐ Formally, a reply is a three-digit code, <SP>, one line of text, and <CRLF>, or a multiline reply (as defined in Appendix E). Only the EXPN and HELP commands are expected to give multiline replies in normal circumstances, but multiline replies are allowed for any command ๐ธ
4.2.1. REPLY CODES BY FUNCTION GROUPS ๐
500 Syntax error, command unrecognized
[This MAY include errors such as command line too long]
501 Syntax error in parameters or arguments
502 Command not implemented
503 Bad sequence of commands
504 Command parameter not implemented
211 System status, or system help reply
214 Help message
[Information on how to use the receiver or the meaning of a
particular non-standard command; this reply is useful only
to the human user]
220 <domain> Service ready
221 <domain> Service closing transmission channel
421 <domain> Service not available,
closing transmission channel
[This MAY be a reply to any command if the service knows it
MUST shut down]
Okay so the alphabetical reply list keeps going, and the reply codes are giving main character energy ๐ ๐
250 Requested mail action okay, completed
251 User not local; will forward to <forward-path>
450 Requested mail action not taken: mailbox unavailable
[E.g., mailbox busy]
550 Requested action not taken: mailbox unavailable
[E.g., mailbox not found, no access]
451 Requested action aborted: error in processing
551 User not local; please try <forward-path>
452 Requested action not taken: insufficient system storage
552 Requested mail action aborted: exceeded storage allocation
553 Requested action not taken: mailbox name not allowed
[E.g., mailbox syntax incorrect]
354 Start mail input; end with <CRLF>.<CRLF>
554 Transaction failed
4.2.2. NUMERIC ORDER LIST OF REPLY CODES โจ
Same codes, but now lined up by number, so it's way easier to find your fave ๐ง
211 System status, or system help reply
214 Help message
[Information on how to use the receiver or the meaning of a
particular non-standard command; this reply is useful only
to the human user]
220 <domain> Service ready
221 <domain> Service closing transmission channel
250 Requested mail action okay, completed
251 User not local; will forward to <forward-path>
354 Start mail input; end with <CRLF>.<CRLF>
421 <domain> Service not available,
closing transmission channel
[This may be a reply to any command if the service knows it
must shut down]
450 Requested mail action not taken: mailbox unavailable
[E.g., mailbox busy]
451 Requested action aborted: local error in processing
452 Requested action not taken: insufficient system storage
500 Syntax error, command unrecognized
[This may include errors such as command line too long]
501 Syntax error in parameters or arguments
502 Command not implemented
503 Bad sequence of commands
504 Command parameter not implemented
550 Requested action not taken: mailbox unavailable
[E.g., mailbox not found, no access]
551 User not local; please try <forward-path>
552 Requested mail action aborted: exceeded storage allocation
553 Requested action not taken: mailbox name not allowed
[E.g., mailbox syntax incorrect]
554 Transaction failed
4.3. SEQUENCING OF COMMANDS AND REPLIES ๐ฆ
Okay so the vibe is a conversation, and the sender is the one running it ๐ The sender drops a command, the receiver replies, and repeat. The sender has to wait for that reply before sending anything else, no skipping ahead ๐
The connection greeting is the first big moment. When the connection is all set up, the receiver usually sends a 220 "Service ready" reply. The sender should wait for that greeting before sending any commands, lowkey the polite thing to do โจ
Note: all the greeting type replies have the official name of the server host as the first word following the reply code.
For example, the greeting looks like this:
220 <SP> USC-ISIF.ARPA <SP> Service ready <CRLF>
Here's the important bit ๐ The table below lists the alternative success and failure replies for each command. These must be strictly adhered to. The receiver can change the wording of the text, but the meaning and action implied by the code numbers, and by that specific command and reply sequence, cannot be changed. No cap, the numbers are the whole story ๐ฅ
COMMAND-REPLY SEQUENCES ๐
Each command is listed with its possible replies. The prefixes are "P" for preliminary (not used in SMTP), "I" for intermediate, "S" for success, "F" for failure, and "E" for error. The 421 reply (service not available, closing transmission channel) may be given to any command if the SMTP-receiver knows it must shut down. This listing is the foundation for the State Diagrams in Section 4.4, so it's kind of a big deal ๐
CONNECTION ESTABLISHMENT
S: 220
F: 421
HELO
S: 250
E: 500, 501, 504, 421
MAIL
S: 250
F: 552, 451, 452
E: 500, 501, 421
RCPT
S: 250, 251
F: 550, 551, 552, 553, 450, 451, 452
E: 500, 501, 503, 421
DATA
I: 354 -> data -> S: 250
F: 552, 554, 451, 452
F: 451, 554
E: 500, 501, 503, 421
RSET
S: 250
E: 500, 501, 504, 421
SEND
S: 250
F: 552, 451, 452
E: 500, 501, 502, 421
SOML
S: 250
F: 552, 451, 452
E: 500, 501, 502, 421
SAML
S: 250
F: 552, 451, 452
E: 500, 501, 502, 421
VRFY
S: 250, 251
F: 550, 551, 553
E: 500, 501, 502, 504, 421
EXPN
S: 250
F: 550
E: 500, 501, 502, 504, 421
HELP
S: 211, 214
E: 500, 501, 502, 504, 421
NOOP
S: 250
E: 500, 421
QUIT
S: 221
E: 500
TURN
S: 250
F: 502
E: 500, 503
4.4. STATE DIAGRAMS ๐
Here are the state diagrams for a simple-minded SMTP implementation, so it's super easy to follow. Only the first digit of the reply codes gets used ๐ง There's one diagram for each group of SMTP commands. The groupings came from building a model for each command and then bundling together the commands with structurally identical models, which is very neat organising tbh ๐
Every command has three possible outcomes: "success" (S), "failure" (F), and "error" (E). In the diagrams below, the symbol B means "begin", and the symbol W means "wait for reply" โญ
First up is the diagram for most of the SMTP commands:
1,3 +---+
----------->| E |
| +---+
|
+---+ cmd +---+ 2 +---+
| B |---------->| W |---------->| S |
+---+ +---+ +---+
|
| 4,5 +---+
----------->| F |
+---+
This diagram models the commands:
HELO, MAIL, RCPT, RSET, SEND, SOML, SAML, VRFY, EXPN, HELP,
NOOP, QUIT, TURN.
The DATA command gets a more complex diagram ๐
+---+ DATA +---+ 1,2 +---+
| B |---------->| W |-------------------->| E |
+---+ +---+ ------------>+---+
3| |4,5 |
| | |
-------------- ----- |
| | | +---+
| ---------- -------->| S |
| | | | +---+
| | ------------
| | | |
V 1,3| |2 |
+---+ data +---+ --------------->+---+
| |---------->| W | | F |
+---+ +---+-------------------->+---+
4,5
Note that the "data" here is a series of lines sent from the sender to the receiver, and no response is expected until the last line is sent. Lowkey the whole thing is one long text message, and the reply only shows up at the end ๐
4.5. DETAILS ๐ธ
4.5.1. MINIMUM IMPLEMENTATION ๐ง
To make SMTP workable, every receiver is required to support this minimum implementation:
COMMANDS -- HELO
MAIL
RCPT
DATA
RSET
NOOP
QUIT
4.5.2. TRANSPARENCY ๐ซถ
Without some way to keep data transparent, the character sequence <CRLF>.<CRLF> ends the mail text and can't be sent by the user. Users usually don't know about these "forbidden" sequences, so the following procedures are used to let all user-composed text get sent transparently ๐ฅ
- Before sending a line of mail text, the sender-SMTP checks the first character of the line. If it is a period, one additional period is inserted at the beginning of the line.
- When a line of mail text is received by the receiver-SMTP, it checks the line. If the line is made up of a single period, that's the end of mail. If the first character is a period and there are other characters on the line, the first character is deleted.
The mail data may contain any of the 128 ASCII characters. All characters are to be delivered to the recipient's mailbox, including format effectors and other control characters. If the transmission channel gives an 8-bit byte (octets) data stream, the 7-bit ASCII codes are transmitted right justified in the octets, with the high order bits cleared to zero ๐
Sometimes a system has to transform the data as it's received and stored. That might be needed for hosts that use a different character set from ASCII as their local character set, or that store data in records instead of strings. If such transforms are necessary, they must be reversible -- especially if they're applied to mail being relayed. That part is a big deal, bestie ๐ญ
4.5.3. SIZES ๐
There are several objects with required minimum maximum sizes. That means every implementation must be able to receive objects of at least these sizes, but must not send objects larger than these sizes โจ
****************************************************
* *
* TO THE MAXIMUM EXTENT POSSIBLE, IMPLEMENTATION *
* TECHNIQUES WHICH IMPOSE NO LIMITS ON THE LENGTH *
* OF THESE OBJECTS SHOULD BE USED. *
* *
****************************************************
Here are the sizes, lined up one by one ๐
- user: The maximum total length of a user name is
64characters. - domain: The maximum total length of a domain name or number is
64characters. - path: The maximum total length of a reverse-path or forward-path is
256characters (including the punctuation and element separators). - command line: The maximum total length of a command line, including the command word and the
<CRLF>, is512characters. - reply line: The maximum total length of a reply line, including the reply code and the
<CRLF>, is512characters. - text line: The maximum total length of a text line, including the
<CRLF>, is1000characters (but not counting the leading dot duplicated for transparency). - recipients buffer: The maximum total number of recipients that must be buffered is
100recipients.
****************************************************
* *
* TO THE MAXIMUM EXTENT POSSIBLE, IMPLEMENTATION *
* TECHNIQUES WHICH IMPOSE NO LIMITS ON THE LENGTH *
* OF THESE OBJECTS SHOULD BE USED. *
* *
****************************************************
Okay bestie, this box is giving main character energy ๐ . Errors from going over these limits can be reported with reply codes, like these:
500 Line too long.
501 Path too long
552 Too many recipients.
552 Too much mail data.
APPENDIX A โจ
TCP Transport service
okay so the Transmission Control Protocol [3] is what's used on the ARPA Internet, and on any network that follows the US DoD standards for internetwork protocols ๐
Connection Establishment
The SMTP transmission channel is a TCP connection between the sender process port U and the receiver process port L ๐ This one single full duplex connection is the transmission channel. The protocol gets the service port 25 (31 octal), so L=25 ๐
Data Transfer
The TCP connection carries 8-bit bytes ๐ SMTP data is 7-bit ASCII characters, so each character goes out as an 8-bit byte with the high-order bit cleared to zero. Lowkey so neat ๐ฆ
APPENDIX B ๐ธ
NCP Transport service
The ARPANET Host-to-Host Protocol [4], which the Network Control Program implements, may be used on the ARPANET ๐ฐ๏ธ
Connection Establishment
The SMTP transmission channel gets set up over NCP between the sender process socket U and the receiver process socket L. The Initial Connection Protocol [5] is followed, and that gives you a pair of simplex connections, which together make up the transmission channel ๐ง This protocol is assigned the contact socket 25 (31 octal), so L=25.
Data Transfer
The NCP data connections run in 8-bit byte mode ๐ SMTP data is still 7-bit ASCII characters, and each one is sent as an 8-bit byte with the high-order bit cleared to zero.
APPENDIX C ๐
NITS
The Network Independent Transport Service [6] may be used โจ
Connection Establishment
The SMTP transmission channel is set up over NITS between the sender process and the receiver process. The sender process runs the CONNECT primitive, and the receiver process that's waiting runs the ACCEPT primitive ๐
Data Transfer
The NITS connection supports 8-bit bytes. SMTP data is 7-bit ASCII characters, and each character goes out as an 8-bit byte with the high-order bit cleared to zero ๐
APPENDIX D ๐ฆ
X.25 Transport service
It may be possible to use the X.25 service [7] from the Public Data Networks directly ๐ค That said, it is suggested that a reliable end-to-end protocol such as TCP be used on top of X.25 connections. Trust me, bestie, TCP on top is the move ๐ซถ
APPENDIX E ๐
Theory of Reply Codes
The three digits of a reply each mean something special ๐ข The first digit tells you if the response is good, bad, or incomplete. An unsophisticated sender-SMTP can work out its next move (proceed as planned, redo, retrench, etc.) just by looking at that first digit. A sender-SMTP that wants to know roughly what kind of error happened (like a mail system error or a command syntax error) can look at the second digit, and the third digit is saved for the finest gradation of information ๐ง
There are five values for the first digit of the reply code:
1yz: Positive Preliminary reply. The command has been accepted, but the requested action is being held in abeyance, pending confirmation of the information in this reply. The sender-SMTP should send another command specifying whether to continue or abort the action.
Note: SMTP does not have any commands that allow this type of reply, and so does not have the continue or abort commands.
2yz: Positive Completion reply. The requested action has been successfully completed. A new request may be initiated. โ3yz: Positive Intermediate reply. The command has been accepted, but the requested action is being held in abeyance, pending receipt of further information. The sender-SMTP should send another command specifying this information. This reply is used in command sequence groups.4yz: Transient Negative Completion reply. The command was not accepted and the requested action did not occur. However, the error condition is temporary and the action may be requested again. The sender should return to the beginning of the command sequence (if any). It is difficult to assign a meaning to "transient" when two different sites (receiver- and sender- SMTPs) must agree on the interpretation. Each reply in this category might have a different time value, but the sender-SMTP is encouraged to try again. A rule of thumb to determine if a reply fits into the 4yz or the 5yz category (see below) is that replies are 4yz if they can be repeated without any change in command form or in properties of the sender or receiver. (E.g., the command is repeated identically and the receiver does not put up a new implementation.) โณ5yz: Permanent Negative Completion reply. The command was not accepted and the requested action did not occur. The sender-SMTP is discouraged from repeating the exact request (in the same sequence). Even some "permanent" error conditions can be corrected, so the human user may want to direct the sender-SMTP to reinitiate the command sequence by direct action at some point in the future (e.g., after the spelling has been changed, or the user has altered the account status). ๐
The second digit encodes responses in specific categories:
x0z: Syntax. These replies refer to syntax errors, syntactically correct commands that don't fit any functional category, and unimplemented or superfluous commands. ๐งพx1z: Information. These are replies to requests for information, such as status or help. ๐x2z: Connections. These are replies referring to the transmission channel. ๐x3z: Unspecified as yet.x4z: Unspecified as yet.x5z: Mail system. These replies indicate the status of the receiver mail system vis-a-vis the requested transfer or other mail system action. ๐ฌ
The third digit gives a finer gradation of meaning in each category specified by the second digit. The list of replies illustrates this. Each reply text is recommended rather than mandatory, and may even change according to the command with which it is associated. On the other hand, the reply codes must strictly follow the specifications in this section. Receiver implementations should not invent new codes for slightly different situations from the ones described here, but rather adapt codes already defined. Be consistent, bestie ๐ซก
For example, a command such as NOOP whose successful execution does not offer the sender-SMTP any new information will return a 250 reply. The response is 502 when the command requests an unimplemented non-site-specific action. A refinement of that is the 504 reply for a command that is implemented, but that requests an unimplemented parameter. ๐ฏ
The reply text may be longer than a single line. In these cases the complete text must be marked so the sender-SMTP knows when it can stop reading the reply. This requires a special format to indicate a multiple line reply. ๐
The format for multiline replies requires that every line, except the last, begin with the reply code, followed immediately by a hyphen, "-" (also known as minus), followed by text. The last line will begin with the reply code, followed immediately by <SP>, optionally some text, and <CRLF>.
For example:
123-First line
123-Second line
123-234 text beginning with numbers
123 The last line
In many cases the sender-SMTP then simply needs to search for the reply code followed by <SP> at the beginning of a line, and ignore all preceding lines. In a few cases, there is important data for the sender in the reply "text". The sender will know these cases from the current context. ๐ง
APPENDIX F ๐ฌ
Scenarios
This section presents complete scenarios of several types of SMTP sessions. Let's watch them play out ๐ฟ
A Typical SMTP Transaction Scenario
This SMTP example shows mail sent by Smith at host USC-ISIF, to Jones, Green, and Brown at host BBN-UNIX. Here we assume that host USC-ISIF contacts host BBN-UNIX directly. The mail is accepted for Jones and Brown. Green does not have a mailbox at host BBN-UNIX, so Green gets left on read ๐
R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready
S: HELO USC-ISIF.ARPA
R: 250 BBN-UNIX.ARPA
S: MAIL FROM:<Smith@USC-ISIF.ARPA>
R: 250 OK
S: RCPT TO:<Jones@BBN-UNIX.ARPA>
R: 250 OK
S: RCPT TO:<Green@BBN-UNIX.ARPA>
R: 550 No such user here
S: RCPT TO:<Brown@BBN-UNIX.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 BBN-UNIX.ARPA Service closing transmission channel
Scenario 1
Aborted SMTP Transaction Scenario
Oop, this one gets cancelled halfway through ๐
R: 220 MIT-Multics.ARPA Simple Mail Transfer Service Ready
S: HELO ISI-VAXA.ARPA
R: 250 MIT-Multics.ARPA
S: MAIL FROM:<Smith@ISI-VAXA.ARPA>
R: 250 OK
S: RCPT TO:<Jones@MIT-Multics.ARPA>
R: 250 OK
S: RCPT TO:<Green@MIT-Multics.ARPA>
R: 550 No such user here
S: RSET
R: 250 OK
S: QUIT
R: 221 MIT-Multics.ARPA Service closing transmission channel
Scenario 2
Relayed Mail Scenario
Now this one has a middleman, and it's giving relay drama ๐ง
Step 1 -- Source Host to Relay Host
R: 220 USC-ISIE.ARPA Simple Mail Transfer Service Ready
S: HELO MIT-AI.ARPA
R: 250 USC-ISIE.ARPA
S: MAIL FROM:<JQP@MIT-AI.ARPA>
R: 250 OK
R: 220 BBN-VAX.ARPA Simple Mail Transfer Service Ready
S: HELO USC-ISIE.ARPA
R: 250 BBN-VAX.ARPA
S: MAIL FROM:<@USC-ISIE.ARPA:JQP@MIT-AI.ARPA>
R: 250 OK
S: RCPT TO:<Jones@BBN-VAX.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Received: from MIT-AI.ARPA by USC-ISIE.ARPA ;
2 Nov 81 22:40:10 UT
S: Date: 2 Nov 81 22:33:44
S: From: John Q. Public <JQP@MIT-AI.ARPA>
S: Subject: The Next Meeting of the Board
S: To: Jones@BBN-Vax.ARPA
S:
S: Bill:
S: The next meeting of the board of directors will be
S: on Tuesday.
S: John.
S: .
R: 250 OK
S: QUIT
R: 221 USC-ISIE.ARPA Service closing transmission channel
Scenario 3: Verifying and Sending Scenario ๐
Here we check that the user is real before we send anything. We VRFY the name first, then SEND the message. Very organized, very iconic ๐
R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready
S: HELO MIT-MC.ARPA
R: 250 SU-SCORE.ARPA
S: VRFY Crispin
R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA>
S: SEND FROM:<EAK@MIT-MC.ARPA>
R: 250 OK
S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 SU-SCORE.ARPA Service closing transmission channel
Scenario 4: Sending and Mailing Scenarios ๐ฌ
So first the user's name gets verified ๐ง Then we try to send straight to their terminal. If that flops, the message gets mailed to their mailbox instead. Plan A, plan B, no drama ๐ซถ
R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready
S: HELO MIT-MC.ARPA
R: 250 SU-SCORE.ARPA
S: VRFY Crispin
R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA>
S: SEND FROM:<EAK@MIT-MC.ARPA>
R: 250 OK
S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA>
R: 450 User not active now
S: RSET
R: 250 OK
S: MAIL FROM:<EAK@MIT-MC.ARPA>
R: 250 OK
S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 SU-SCORE.ARPA Service closing transmission channel
Scenario 5: Doing the Preceding Scenario More Efficiently โก
Same vibe as the last one, but with fewer steps. Efficiency is giving main character energy ๐ฆ
R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready
S: HELO MIT-MC.ARPA
R: 250 SU-SCORE.ARPA
S: VRFY Crispin
R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA>
S: SOML FROM:<EAK@MIT-MC.ARPA>
R: 250 OK
S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA>
R: 250 User not active now, so will do mail.
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 SU-SCORE.ARPA Service closing transmission channel
Scenario 6: Mailing List Scenario ๐
Okay this one is a whole project ๐ First we expand each of the two mailing lists, each in its own session with a different host. Then we send the message to everyone who showed up on either list, but with no duplicates, through a relay host. Nobody gets the message twice, bestie ๐
Step 1 -- Expanding the First List
R: 220 MIT-AI.ARPA Simple Mail Transfer Service Ready
S: HELO SU-SCORE.ARPA
R: 250 MIT-AI.ARPA
S: EXPN Example-People
R: 250-<ABC@MIT-MC.ARPA>
R: 250-Fred Fonebone <Fonebone@USC-ISIQ.ARPA>
R: 250-Xenon Y. Zither <XYZ@MIT-AI.ARPA>
R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA>
R: 250-<joe@foo-unix.ARPA>
R: 250 <xyz@bar-unix.ARPA>
S: QUIT
R: 221 MIT-AI.ARPA Service closing transmission channel
Step 2 -- Expanding the Second List
R: 220 MIT-MC.ARPA Simple Mail Transfer Service Ready
S: HELO SU-SCORE.ARPA
R: 250 MIT-MC.ARPA
S: EXPN Interested-Parties
R: 250-Al Calico <ABC@MIT-MC.ARPA>
R: 250-<XYZ@MIT-AI.ARPA>
R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA>
R: 250-<fred@BBN-UNIX.ARPA>
R: 250 <xyz@bar-unix.ARPA>
S: QUIT
R: 221 MIT-MC.ARPA Service closing transmission channel
Step 3 -- Mailing to All via a Relay Host
R: 220 USC-ISIE.ARPA Simple Mail Transfer Service Ready
S: HELO SU-SCORE.ARPA
R: 250 USC-ISIE.ARPA
S: MAIL FROM:<Account.Person@SU-SCORE.ARPA>
R: 250 OK
S: RCPT TO:<@USC-ISIE.ARPA:ABC@MIT-MC.ARPA>
R: 250 OK
S: RCPT TO:<@USC-ISIE.ARPA:Fonebone@USC-ISIQA.ARPA>
R: 250 OK
S: RCPT TO:<@USC-ISIE.ARPA:XYZ@MIT-AI.ARPA>
R: 250 OK
S: RCPT
TO:<@USC-ISIE.ARPA,@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA>
R: 250 OK
S: RCPT TO:<@USC-ISIE.ARPA:joe@FOO-UNIX.ARPA>
R: 250 OK
S: RCPT TO:<@USC-ISIE.ARPA:xyz@BAR-UNIX.ARPA>
R: 250 OK
S: RCPT TO:<@USC-ISIE.ARPA:fred@BBN-UNIX.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 USC-ISIE.ARPA Service closing transmission channel
Scenario 7: Forwarding Scenarios โช๏ธ
Sometimes the mail is for someone who isn't local, so the server tells the sender where it's going next. Forwarding but make it iconic ๐ง
R: 220 USC-ISIF.ARPA Simple Mail Transfer Service Ready
S: HELO LBL-UNIX.ARPA
R: 250 USC-ISIF.ARPA
S: MAIL FROM:<mo@LBL-UNIX.ARPA>
R: 250 OK
S: RCPT TO:<fred@USC-ISIF.ARPA>
R: 251 User not local; will forward to <Jones@USC-ISI.ARPA>
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 USC-ISIF.ARPA Service closing transmission channel
Scenario 8: Forwarding Scenario, Step by Step ๐ฆข
This is the same forwarding setup, but split into two steps, so you can see it happen in order ๐
Step 1 -- Trying the Mailbox at the First Host
R: 220 USC-ISIF.ARPA Simple Mail Transfer Service Ready
S: HELO LBL-UNIX.ARPA
R: 250 USC-ISIF.ARPA
S: MAIL FROM:<mo@LBL-UNIX.ARPA>
R: 250 OK
S: RCPT TO:<fred@USC-ISIF.ARPA>
R: 251 User not local; will forward to <Jones@USC-ISI.ARPA>
S: RSET
R: 250 OK
S: QUIT
R: 221 USC-ISIF.ARPA Service closing transmission channel
Step 2 -- Delivering the Mail at the Second Host
R: 220 USC-ISI.ARPA Simple Mail Transfer Service Ready
S: HELO LBL-UNIX.ARPA
R: 250 USC-ISI.ARPA
S: MAIL FROM:<mo@LBL-UNIX.ARPA>
R: 250 OK
S: RCPT TO:<Jones@USC-ISI.ARPA>
R: OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 USC-ISI.ARPA Service closing transmission channel
Scenario 9: Too Many Recipients Scenario ๐ซ
One recipient got rejected because their storage was full, so the sender just tries again in a fresh transaction. Persistence is a whole personality ๐ช
R: 220 BERKELEY.ARPA Simple Mail Transfer Service Ready
S: HELO USC-ISIF.ARPA
R: 250 BERKELEY.ARPA
S: MAIL FROM:<Postel@USC-ISIF.ARPA>
R: 250 OK
S: RCPT TO:<fabry@BERKELEY.ARPA>
R: 250 OK
S: RCPT TO:<eric@BERKELEY.ARPA>
R: 552 Recipient storage full, try again in another transaction
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: MAIL FROM:<Postel@USC-ISIF.ARPA>
R: 250 OK
S: RCPT TO:<eric@BERKELEY.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: .
R: 250 OK
S: QUIT
R: 221 BERKELEY.ARPA Service closing transmission channel
Scenario 10 โจ
Note that a real implementation must handle many recipients as specified in Section 4.5.3. ๐ซถ
GLOSSARY โจ
Okay bestie, this is the glossary, aka the cheat sheet for all the vocab we've been throwing around ๐ Here we go!
ASCII
American Standard Code for Information Interchange [1]. The character set everything in this doc is built on ๐ค
command
A request for a mail service action that the sender-SMTP sends to the receiver-SMTP. Basically the sender asking the receiver to do something ๐จ
domain
The hierarchically structured global character string address of a host computer in the mail system. Think of it as a host's full address card ๐บ๏ธ
end of mail data indication
A special sequence of characters that tells you the mail data is over. Specifically, the five characters carriage return, line feed, period, carriage return, line feed, in that order. That little period is the big "the end" signal ๐
host
A computer in the internetwork environment where mailboxes or SMTP processes live ๐
line
A sequence of ASCII characters ending with a <CRLF>. One line, one ending, always ๐
mail data
A sequence of ASCII characters of arbitrary length, which conforms to the standard set in the Standard for the Format of ARPA Internet Text Messages (RFC 822 [2]). The actual letter content, all dressed up and following the rules ๐
mailbox
A character string (address) that identifies a user you want to send mail to. A mailbox usually has the host and user parts, and it's written as user@domain. It's also the "container" where mail gets stored ๐ฌ
receiver-SMTP process
A process that transfers mail together with a sender-SMTP process. It waits for a connection to be set up through the transport service, receives SMTP commands from the sender-SMTP, sends replies back, and does the operations it's asked to do. The receiving end, being a good listener ๐
reply
An acknowledgment, positive or negative, sent from receiver to sender over the transmission channel in response to a command. The general form is a completion code (error codes included) followed by a text string. The codes are for programs to read, and the text is usually for humans ๐ฌ
sender-SMTP process
A process that transfers mail together with a receiver-SMTP process. A local language may be used in the user interface command/reply dialogue. The sender-SMTP starts the transport service connection, sends the SMTP commands, receives replies, and runs the mail transfer ๐
session
The set of exchanges that happen while the transmission channel is open. Hot girl session, start to finish ๐
transaction
The set of exchanges needed for one message to be transmitted for one or more recipients. One message, one transaction, zero drama ๐ฆ
transmission channel
A full-duplex communication path between a sender-SMTP and a receiver-SMTP for exchanging commands, replies, and mail text. Full-duplex means both sides can talk at the same time, which is so iconic ๐ฃ๏ธ๐ฃ๏ธ
transport service
Any reliable stream-oriented data communication service. For example, NCP, TCP, NITS. The delivery people that make sure everything arrives in order ๐
user
A human being (or a process acting on behalf of a human being) who wants to get mail transfer service. Also, a recipient of computer mail. Either way, it's someone who gets their inbox ๐
word
A sequence of printing characters. Just a little group of letters, basically ๐ก
<CRLF>
The characters carriage return and line feed, in that order. The dynamic duo of line endings ๐ถ
<SP>
The space character. Tiny but mighty ๐ง
REFERENCES โจ
Here's the bibliography, the receipts for everything the doc name-drops ๐งพ
[1] ASCII
ASCII, "USA Code for Information Interchange", United States of America Standards Institute, X3.4, 1968. Also in: Feinler, E. and J. Postel, eds., "ARPANET Protocol Handbook", NIC 7104, for the Defense Communications Agency by SRI International, Menlo Park, California, Revised January 1978.
[2] RFC 822
Crocker, D., "Standard for the Format of ARPA Internet Text Messages," RFC 822, Department of Electrical Engineering, University of Delaware, August 1982.
[3] TCP
Postel, J., ed., "Transmission Control Protocol - DARPA Internet Program Protocol Specification", RFC 793, USC/Information Sciences Institute, NTIS AD Number A111091, September 1981. Also in: Feinler, E. and J. Postel, eds., "Internet Protocol Transition Workbook", SRI International, Menlo Park, California, March 1982.
[4] NCP
McKenzie,A., "Host/Host Protocol for the ARPA Network", NIC 8246, January 1972. Also in: Feinler, E. and J. Postel, eds., "ARPANET Protocol Handbook", NIC 7104, for the Defense Communications Agency by SRI International, Menlo Park, California, Revised January 1978.
[5] Initial Connection Protocol
Postel, J., "Official Initial Connection Protocol", NIC 7101, 11 June 1971. Also in: Feinler, E. and J. Postel, eds., "ARPANET Protocol Handbook", NIC 7104, for the Defense Communications Agency by SRI International, Menlo Park, California, Revised January 1978.
[6] NITS
PSS/SG3, "A Network Independent Transport Service", Study Group 3, The Post Office PSS Users Group, February 1980. Available from the DCPU, National Physical Laboratory, Teddington, UK.
[7] X.25
CCITT, "Recommendation X.25 - Interface Between Data Terminal Equipment (DTE) and Data Circuit-terminating Equipment (DCE) for Terminals Operating in the Packet Mode on Public Data Networks," CCITT Orange Book, Vol. VIII.2, International Telephone and Telegraph Consultative Committee, Geneva, 1976.
That's the whole doc, bestie! ๐๐ฆ You made it through the entire SMTP spec ๐
๐ฆ where this page comes from
- ietf: rfc821 1982-08
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms