Bug#283230: Exim4 drops connection with "too many syntax or protocol errors"

Christoph Barbian Christoph Barbian <cb@math.uni-sb.de>, 283230@bugs.debian.org
Sat, 27 Nov 2004 13:03:06 +0100 (CET)


Package: <exim4-daemon-heavy>
Version: <4.34-7>

When exim receives many messages in one connection it somtetimes drops the
connection, more precisely: whenever exim receives a message with valid
recipient which is delivered and after that 4 ( = smtp_max_synprot_errors
+ 1) messages with invalid recipients (and all in the same connection) it
drops the connection and logs

(4 passages similar to this one)
14196 SMTP<< MAIL From:<> SIZE=4669
14196 SMTP>> 250 OK
14196 SMTP<< RCPT To:<Prince8Gunn@math.uni-sb.de>
14196 SMTP>> 550 unknown user
14196 SMTP<< DATA
14196   SMTP protocol error in "DATA" H=eris.rz.uni-saarland.de
[134.96.7.8]:23385 valid RCPT command must precede DATA
14196 SMTP>> 503 valid RCPT command must precede DATA
14196 SMTP<< RSET
14196 SMTP>> 250 Reset OK
14196 SMTP<< RSET
14196 SMTP>> 250 Reset OK

(and finally)
14196   SMTP call from eris.rz.uni-saarland.de [134.96.7.8]:23385 dropped:
too many syntax or protocol errors (last command was "DATA")

This means that exim considers a DATA sent by the delivering MTA after
an invalid RCPT as an error (but it should not as we are pipelining)

The reason for this lies in the function
   int smtp_setup_msg (void)
in smtp_in.c ...

There is a variable pipelining_advertised in this function which is
set to FALSE by default and is set to TRUE after a successful EHLO
response (exim always advertises pipelining). So during the first call of
smtp_setup_msg everything is fine, as the following SMTP dialogue shows

14196 SMTP<< MAIL From:<fidion@yoda.proserv-msg.com> SIZE=1182
14196 SMTP>> 250 OK
14196 SMTP<< RCPT To:<abc@math.uni-sb.de>
14196 SMTP>> 550 unknown user
14196 SMTP<< DATA
14196 SMTP>> 503 valid RCPT command must precede DATA
14196 SMTP<< RSET
14196 SMTP>> 250 Reset OK
14196 SMTP<< RSET
14196 SMTP>> 250 Reset OK

Here exim answers with a 503 to the DATA but does not encounter an error
(what is ok as pipelining is advertised).

After exim has left this first call of smtp_setup_msg (what is does for
example whenever a message is accepted for delivery) we see log messages
of the first kind and exims gets out after 4 errors.

Therefore the problem is that the variable pipelining_advertised is
declared within the function smtp_setup_msg and only set to TRUE
when an EHLO is received what is only the case in the first call of
smtp_setup_msg. In all following calls it remains FALSE and exim
counts the DATA's as errors ...

  case DATA_CMD:
    if (!discarded && recipients_count <= 0)
      {
      if (pipelining_advertised && last_was_rcpt)
        smtp_printf("503 valid RCPT command must precede DATA\r\n");
      else
        done = synprot_error(L_smtp_protocol_error, 503, NULL,
          US"valid RCPT command must precede DATA");
      break;
      }

(lines 2991 - 3000 in smtp_in.c of exim-4.34-orig)

In my opinion the variable pipelining_advertised should be declared
outside smtp_setup_msg so its value is persistent over several calls
of this smtp_setup_msg...

In newer versions of exim4 I think this is fixed (I took a look at
4.43)...

By this problem you may lose email if your delivering MTA (in my case
sendmail does) defers all remaining messages in its queue to a later queue
run whenever exim drops the connection as described here...


-- System Information:
Debian Release: 3.1
Kernel: 2.4.26-1-686-smp #1 SMP
Glibc: libc-2.3.2