From 06fdb9f73dedfffc8b8613017ec1bb23f970b246 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 25 Jan 2018 21:27:00 +0000 Subject: [PATCH] Cutthrough: fix multi-message initiating connections. Bug 2230 --- doc/doc-txt/ChangeLog | 6 ++ src/src/acl.c | 39 +++++---- src/src/verify.c | 1 + test/confs/5400 | 2 +- test/confs/5406 | 1 + test/log/5406 | 18 ++++ test/scripts/5400-cutthrough/5406 | 110 +++++++++++++++++++++++ test/stdout/5406 | 140 ++++++++++++++++++++++++++++++ 8 files changed, 301 insertions(+), 16 deletions(-) create mode 120000 test/confs/5406 create mode 100644 test/log/5406 create mode 100644 test/scripts/5400-cutthrough/5406 create mode 100644 test/stdout/5406 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 88f113cc4..facdece83 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -61,6 +61,12 @@ JH/10 Bug 2223: Fix mysql lookup returns for the no-data case (when the number o JH/11 The runtime Berkeley DB library version is now additionally output by "exim -d -bV". Previously only the compile-time version was shown. +JH/12 Bug 2230: Fix cutthrough routing for nonfirst messages in an initiating + SMTP connection. Previously, when one had more receipients than the + first, an abortive onward connection was made. Move to full support for + multiple onward connections in sequence, handling cutthrough connection + for all multi-message initiating connections. + Exim version 4.90 ----------------- diff --git a/src/src/acl.c b/src/src/acl.c index f01f5cf3c..9efc85844 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -3287,6 +3287,8 @@ for (; cb != NULL; cb = cb->next) p = pp; } } + else + DEBUG(D_acl) debug_printf(" cutthrough request ignored for nonfirst rcpt\n"); break; } *log_msgptr = string_sprintf("\"control=%s\" on %s item", @@ -4417,22 +4419,29 @@ switch (where) else if ( rc == OK && cutthrough.delivery && rcpt_count > cutthrough.nrcpt - && (rc = open_cutthrough_connection(addr)) == DEFER ) - if (cutthrough.defer_pass) - { - uschar * s = addr->message; - /* Horrid kludge to recover target's SMTP message */ - while (*s) s++; - do --s; while (!isdigit(*s)); - if (*--s && isdigit(*s) && *--s && isdigit(*s)) *user_msgptr = s; - acl_temp_details = TRUE; - } - else - { - HDEBUG(D_acl) debug_printf_indent("cutthrough defer; will spool\n"); - rc = OK; - } + { + if ((rc = open_cutthrough_connection(addr)) == DEFER) + if (cutthrough.defer_pass) + { + uschar * s = addr->message; + /* Horrid kludge to recover target's SMTP message */ + while (*s) s++; + do --s; while (!isdigit(*s)); + if (*--s && isdigit(*s) && *--s && isdigit(*s)) *user_msgptr = s; + acl_temp_details = TRUE; + } + else + { + HDEBUG(D_acl) debug_printf_indent("cutthrough defer; will spool\n"); + rc = OK; + } + } + else HDEBUG(D_acl) if (cutthrough.delivery) + if (rcpt_count <= cutthrough.nrcpt) + debug_printf_indent("ignore cutthrough request; nonfirst message\n"); + else if (rc != OK) + debug_printf_indent("ignore cutthrough request; ACL did not accept\n"); break; case ACL_WHERE_PREDATA: diff --git a/src/src/verify.c b/src/src/verify.c index e40a7fc27..dd5451848 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1380,6 +1380,7 @@ if(fd >= 0) _cutthrough_puts(US"QUIT\r\n", 6); /* avoid recursion */ _cutthrough_flush_send(); cutthrough.fd = -1; /* avoid recursion via read timeout */ + cutthrough.nrcpt = 0; /* permit re-cutthrough on subsequent message */ /* Wait a short time for response, and discard it */ cutthrough_response(fd, '2', NULL, 1); diff --git a/test/confs/5400 b/test/confs/5400 index 9be13fea6..5a5e60a88 100644 --- a/test/confs/5400 +++ b/test/confs/5400 @@ -1,6 +1,6 @@ # Exim test configuration 5400 -# any options on the cutthrough_delivery contol +# any options on the cutthrough_delivery control CONTROL= # optional verify-callout diff --git a/test/confs/5406 b/test/confs/5406 new file mode 120000 index 000000000..8f6811b7e --- /dev/null +++ b/test/confs/5406 @@ -0,0 +1 @@ +5400 \ No newline at end of file diff --git a/test/log/5406 b/test/log/5406 new file mode 100644 index 000000000..227e696d4 --- /dev/null +++ b/test/log/5406 @@ -0,0 +1,18 @@ +1999-03-02 09:44:33 rcpt for userx@domain.com +1999-03-02 09:44:33 10HmaX-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 rcpt for usery@domain.com +1999-03-02 09:44:33 10HmaY-0005vi-00 >> usery@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for usery@domain.com +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 rcpt for userx@domain.com +1999-03-02 09:44:33 10HmaZ-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 rcpt for usery@domain.com +1999-03-02 09:44:33 rcpt for userz@domain.com +1999-03-02 09:44:33 10HmbA-0005vi-00 >> userz@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmbA-0005vi-00 >> usery@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for usery@domain.com userz@domain.com +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed diff --git a/test/scripts/5400-cutthrough/5406 b/test/scripts/5400-cutthrough/5406 new file mode 100644 index 000000000..7a4653279 --- /dev/null +++ b/test/scripts/5400-cutthrough/5406 @@ -0,0 +1,110 @@ +# cutthrough_delivery multiple messages on initiator conn +need_ipv4 +munge loopback +# +# Two single-RCPT messages. +# Both should get cuttthrough, using separate onward connections +server PORT_S 2 +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +*eof +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +*eof +**** +exim -bs +EHLO myhost.test.ex +MAIL FROM: +RCPT TO: +DATA + +. +MAIL FROM: +RCPT TO: +DATA + +. +QUIT +**** +# +# +# +# +# +# A single-RCPT followed by a double-RCPT message +# Both should get cuttthrough, using separate onward connections +server PORT_S 2 +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +*eof +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +*eof +**** +exim -bs +EHLO myhost.test.ex +MAIL FROM: +RCPT TO: +DATA + +. +MAIL FROM: +RCPT TO: +RCPT TO: +DATA + +. +QUIT +**** +# +# +# +# +# +# End diff --git a/test/stdout/5406 b/test/stdout/5406 new file mode 100644 index 000000000..773c25dd2 --- /dev/null +++ b/test/stdout/5406 @@ -0,0 +1,140 @@ +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello CALLER at myhost.test.ex +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250 HELP +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaX-0005vi-00 +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaY-0005vi-00 +221 myhost.test.ex closing connection +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello CALLER at myhost.test.ex +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250 HELP +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaZ-0005vi-00 +250 OK +250 Accepted +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmbA-0005vi-00 +221 myhost.test.ex closing connection + +******** SERVER ******** +Listening on port 1224 ... +Connection request from [ip4.ip4.ip4.ip4] +220 ESMTP +EHLO myhost.test.ex +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +Received: from CALLER (helo=myhost.test.ex) + by myhost.test.ex with local-esmtp (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for userx@domain.com; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 +X-hdr-rtr-new: +++ + +. +250 OK +QUIT +250 OK +Expected EOF read from client +Listening on port 1224 ... +Connection request from [ip4.ip4.ip4.ip4] +220 ESMTP +EHLO myhost.test.ex +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +Received: from CALLER (helo=myhost.test.ex) + by myhost.test.ex with local-esmtp (Exim x.yz) + (envelope-from ) + id 10HmaY-0005vi-00 + for usery@domain.com; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 +X-hdr-rtr-new: +++ + +. +250 OK +QUIT +250 OK +Expected EOF read from client +End of script +Listening on port 1224 ... +Connection request from [ip4.ip4.ip4.ip4] +220 ESMTP +EHLO myhost.test.ex +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +Received: from CALLER (helo=myhost.test.ex) + by myhost.test.ex with local-esmtp (Exim x.yz) + (envelope-from ) + id 10HmaZ-0005vi-00 + for userx@domain.com; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 +X-hdr-rtr-new: +++ + +. +250 OK +QUIT +250 OK +Expected EOF read from client +Listening on port 1224 ... +Connection request from [ip4.ip4.ip4.ip4] +220 ESMTP +EHLO myhost.test.ex +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +Received: from CALLER (helo=myhost.test.ex) + by myhost.test.ex with local-esmtp (Exim x.yz) + (envelope-from ) + id 10HmbA-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 +X-hdr-rtr-new: +++ + +. +250 OK +QUIT +250 OK +Expected EOF read from client +End of script -- 2.30.2