Re: [exim] Pipelining QUIT after data

Top Page
Delete this message
Reply to this message
Author: Viktor Dukhovni
Date:  
To: exim-users
Subject: Re: [exim] Pipelining QUIT after data
> On Mar 6, 2021, at 12:03 PM, Jeremy Harris via Exim-users <exim-users@???> wrote:
>
> I do find, when implementing it, that both Outlook and Google screw up,
> as server, when Exim does it. In both cases, CHUNKING had also been used.
> I wonder if anyone else has observed this?


Good question, Postfix supports BDAT only in the SMTP server, and does not
use it in the SMTP client. So the Postfix experience with PIPELINING of
DOT+QUIT is limited to "DATA" not "BDAT".

> I see no theoretical bar to pipelining QUIT after BDAT LAST,


Well, RFC3030 does not unambiguously specify whether BDAT LAST is a
synchronisation point or not. :-(

In [PIPE] https://tools.ietf.org/html/rfc2920#section-3.1 we have:

Once the client SMTP has confirmed that support exists for the
pipelining extension, the client SMTP may then elect to transmit
groups of SMTP commands in batches without waiting for a response to
each individual command. In particular, the commands RSET, MAIL FROM,
SEND FROM, SOML FROM, SAML FROM, and RCPT TO can all appear anywhere
in a pipelined command group. The EHLO, DATA, VRFY, EXPN, TURN,
QUIT, and NOOP commands can only appear as the last command in a
group since their success or failure produces a change of state which
the client SMTP must accommodate. (NOOP is included in this group so
it can be used as a synchronization point.)

Additional commands added by other SMTP extensions may only appear as
the last command in a group unless otherwise specified by the
extensions that define the commands.

The actual transfer of message content is explicitly allowed to be
the first "command" in a group. That is, a RSET/MAIL FROM sequence
used to initiate a new message transaction can be placed in the same
group as the final transfer of the headers and body of the previous
message.

With this, on the one hand we're allowed to pipeline additional commands
(e.g. QUIT) after message transfer, but on the other hand "BDAT" is not
one of the mentioned commands, and so pipelining for BDAT should be
clearly defined in RFC3030, but it is sadly not, beyond just an example:

https://tools.ietf.org/html/rfc3030#section-4.2

R: <wait for connection on TCP port
S: <open connection to server>
R: 220 cnri.reston.va.us SMTP service ready
S: EHLO ymir.claremont.edu
R: 250-cnri.reston.va.us says hello
R: 250-PIPELINING
R: 250-BINARYMIME
R: 250 CHUNKING
S: MAIL FROM:<ned@???> BODY=BINARYMIME
S: RCPT TO:<gvaudre@???>
S: RCPT TO:<jstewart@???>
R: 250 <ned@???>... Sender and BINARYMIME ok
R: 250 <gvaudre@???>... Recipient ok
R: 250 <jstewart@???>... Recipient ok

[ Have to wait after last recipient and first BDAT, to see whether
MAIL FROM and at least one of the recipients have been accepted.
But this is not specified clearly. ]

S: BDAT 100000
S: (First 100000 octets of canonical MIME message data)
S: BDAT 324
S: (Remaining 324 octets of canonical MIME message data)
S: BDAT 0 LAST

[ Here QUIT is sent separately, with no explanation. ]

R: 250 100000 octets received
R: 250 324 octets received
R: 250 Message OK, 100324 octets received
S: QUIT
R: 221 Goodbye


> but if
> servers out there are are commonly broken I may need to restrict the
> implementation. Either non-Chunking only, or a hostlist option on
> the transport, come to mind.


This should probably be raised on the ietf-smtp list, and perhaps
an erratum filed against RFC3030. It really has to specify how
BDAT is pipelined much more clearly.

Postfix does not bother with client-side BDAT, because SIZE=...
is sent as part of MAIL, and so the main reason for sending chunks
(avoiding large transmission of content which the remote server will
not accept) is rarely applicable.

-- 
    Viktor.