Proper behavior for conversations between SMTP mail hosts is documented in
RFC821. In cases where these symptoms (listed under SYMPTOMS above) have
been observed, the target SMTP host interrupts the IMC's DATA transmission
with a 552 error (sender's message has exceeded fixed maximum message
size).
While this is a valid error message, the fact that it is returned to the
IMC in the middle of the transmission of the DATA portion of a message is a
protocol violation. In the case of an error during the DATA transmission,
it is the target's responsibility to continue accepting the message
(discarding received data if necessary), and *after completion,* return the
reply code for the DATA command to the sending side.
The following sections from RFC821 detail the specifics for this issue:
4.2, paragraph 1, "... Every command must generate exactly one reply."
4.3, "Command-reply" sequence for DATA diagrammed
4.4, State diagram for DATA - Notes: "Note that the data here is a
series of lines sent from the sender to the receiver with no response
expected until the last line sent."
Example (successful) SMTP Conversation:
I = IMC (initiator), T= Target (receiver)
T: <waiting for connection on TCP port 25>
I: <open connection to target>
T: 220 tin.pan.alley.com SMTP service ready
I: HELO cartoonville.com
T: 250 tin.pan.alley.com says hello to cartoonville.com
I: MAIL FROM: <clem@cartoonville.com>
T: 250 sender OK
I: RCPT TO: <ditty@tin.pan.alley.com>
T: 250 Recipient OK
x I: DATA
T: 354 Enter mail, end with "." on a line by itself
* I: **** IMC begins sending a message header and body, and according to
I: RFC821, 4.4, "Note that the data here is a series of lines sent from
I: the sender to the receiver with no response expected until the last
I: line sent." The last line sent is signified by "." on a line by
I: itself - which is coming up next (note: this DATA content portion is
I: not usually logged)****
* I: .
y T: 250 message sent
I: QUIT
T: 221 tin.pan.alley.com closing connection
I: <Closes connection>
T: <closes connection>
Notice that once the DATA command (x) has been positively acknowledged, the
IMC expects to send the message data uninterrupted (lines between
asterisks, inclusive) until it signifies the last line (the last asterisk).
Then the following line (y) is the appropriate point at which success or
error codes should be returned from the target.
Example network trace summary (failure):
3076 IMC >>> Target SMTP
Data - continued from frame 3074, 536 bytes
(IMC is sending DATA)
3077 Target >>> IMC TCP
.A...., len: 0, seq:1417586500-1417586500, ack: 136770891, win: 967
(Target ACKs the DATA)
3078 IMC >>> Target SMTP
Data - continued from frame 3076, 536 bytes
(sending more)
3079 Target >>> IMC TCP
.A...., len: 0, seq:1417586500-1417586500, ack: 136771427, win: 967
(ACK'd)
3080 IMC >>> Target SMTP
Data - continued from frame 3078, 536 bytes
(sending more - IMC is not finished sending DATA yet)
3081 Target >>> IMC SMTP
Rsp: Requested mail action aborted: exceeded storage allocation, 54 bytes
(frame 3081 is the first protocol violation - this frame contains the 552
error code)
3082 Target >>> IMC SMTP
Rsp: Service not available, closing transmission channel, 46 bytes
(this frame is another protocol violation - this frame contains a 421 error
code "service unavailable")
3083 Target >>> IMC TCP
.A...F, len: 0, seq:1417586599-1417586599, ack: 136771427, win: 967
(this is a TCP FIN frame. See below)
3084 IMC >>> Target TCP
.A...., len: 0, seq: 136771963-136771963, ack:1417586599, win: 8254
(this is a TCP ACK frame, which ACKs through frame 3082)
3085 IMC >>> Target TCP
.A...., len: 0, seq: 136771963-136771963, ack:1417586600, win: 8254
(this is another TCP ACK frame, ACKing frame 3083, the Target's FIN)
In frame 3080, the IMC is still sending more message DATA. In frame 3081 &
3082 the target interrupts this send, returning SMTP error codes. The
target should wait until the IMC completed sending DATA before returning
these codes.
It has also been noted that receiving a FIN from the target may not
terminate the TCP connection. The procedure for closing a TCP connection is
documented in section 3.5 of RFC793. It states:
The user who CLOSEs may continue to RECEIVE until he is told that the
other side has CLOSED also.
In the trace above, the target sends a FIN in frame 3083, which informs the
IMC that it should not expect more data from the target. This action is not
a TCP protocol violation. The IMC ACKs the FIN with frame 3085, and,
because it is in the middle of sending message DATA, resumes sending, which
is now blocked from the previous SMTP protocol violations (frames 3081 and
3082).
According to RFC793, the method to unconditionally abort a TCP connection
is by sending an RST [reset] frame. Note, however, that this defeats any
ability to provide a "reason" for the connection termination to the
applications using the connection.