From 047bdd8ce4bf9cc9fd22fb22a2ebaf190d492343 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Mon, 5 Feb 2007 12:35:46 +0000 Subject: [PATCH] Flush SMTP output buffer before "delay" in an ACL; add control = no_delay_flush to disable this behaviour. --- doc/doc-txt/ChangeLog | 4 ++- doc/doc-txt/NewStuff | 6 +++- src/src/acl.c | 27 +++++++++++---- src/src/globals.c | 3 +- src/src/globals.h | 3 +- test/confs/0552 | 66 ++++++++++++++++++++++++++++++++++++ test/log/0552 | 19 +++++++++++ test/scripts/0000-Basic/0552 | 20 +++++++++++ 8 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 test/confs/0552 create mode 100644 test/log/0552 create mode 100644 test/scripts/0000-Basic/0552 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 4cb842c6d..6179dec3e 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.467 2007/01/31 16:52:12 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.468 2007/02/05 12:35:46 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -71,6 +71,8 @@ PH/13 Added ${rfc2047d: to decoded RFC 2047 strings. PH/14 Added log_selector = +pid. +PH/15 Flush SMTP output before delaying, unless control=no_delay_flush is set. + Exim version 4.66 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index ccd5989cb..ae6c48991 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.134 2007/01/31 16:52:12 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.135 2007/02/05 12:35:46 ph10 Exp $ New Features in Exim -------------------- @@ -232,6 +232,10 @@ Version 4.67 id to be added to every log line, in square brackets, immediately after the time and date. +11. Exim has been modified so that it flushes SMTP output before implementing + a delay in an ACL. This behaviour can be disabled by obeying control = + no_delay_flush at some earlier point. + Version 4.66 ------------ diff --git a/src/src/acl.c b/src/src/acl.c index 3e06cdf30..517063635 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.69 2007/01/30 11:45:20 ph10 Exp $ */ +/* $Cambridge: exim/src/src/acl.c,v 1.70 2007/02/05 12:35:46 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -187,7 +187,8 @@ enum { CONTROL_FAKEDEFER, CONTROL_FAKEREJECT, CONTROL_NO_MULTILINE, - CONTROL_NO_PIPELINING + CONTROL_NO_PIPELINING, + CONTROL_NO_DELAY_FLUSH }; /* ACL control names; keep in step with the table above! This list is used for @@ -219,9 +220,10 @@ static uschar *controls[] = { US"fakereject", US"no_multiline", US"no_pipelining", + US"no_delay_flush" }; -/* Flags to indicate for which conditions /modifiers a string expansion is done +/* Flags to indicate for which conditions/modifiers a string expansion is done at the outer level. In the other cases, expansion already occurs in the checking functions. */ @@ -593,6 +595,9 @@ static unsigned int control_forbids[] = { (1<next) pipelining_enable = FALSE; break; + case CONTROL_NO_DELAY_FLUSH: + disable_delay_flush = TRUE; + break; + case CONTROL_FAKEDEFER: case CONTROL_FAKEREJECT: fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL; @@ -2720,13 +2730,18 @@ for (; cb != NULL; cb = cb->next) can't. The poll() function does not do the right thing, and in any case it is not always available. - NOTE: If ever this state of affairs changes, remember that we may be + NOTE 1: If ever this state of affairs changes, remember that we may be dealing with stdin/stdout here, in addition to TCP/IP connections. - Whatever is done must work in both cases. To detected the stdin/stdout - case, check for smtp_in or smtp_out being NULL. */ + Also, delays may be specified for non-SMTP input, where smtp_out and + smtp_in will be NULL. Whatever is done must work in all cases. + + NOTE 2: The added feature of flushing the output before a delay must + apply only to SMTP input. Hence the test for smtp_out being non-NULL. + */ else { + if (smtp_out != NULL && !disable_delay_flush) fflush(smtp_out); while (delay > 0) delay = sleep(delay); } } diff --git a/src/src/globals.c b/src/src/globals.c index b030c7f7b..b3bbd7faf 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.67 2007/01/31 16:52:12 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.68 2007/02/05 12:35:46 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -499,6 +499,7 @@ int demime_errorlevel = 0; int demime_ok = 0; uschar *demime_reason = NULL; #endif +BOOL disable_delay_flush = FALSE; #ifdef ENABLE_DISABLE_FSYNC BOOL disable_fsync = FALSE; #endif diff --git a/src/src/globals.h b/src/src/globals.h index 70227d592..570e4c87b 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.h,v 1.47 2007/01/30 15:10:59 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.h,v 1.48 2007/02/05 12:35:46 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -278,6 +278,7 @@ extern int demime_errorlevel; /* Severity of MIME error */ extern int demime_ok; /* Nonzero if message has been demimed */ extern uschar *demime_reason; /* Reason for broken MIME container */ #endif +extern BOOL disable_delay_flush; /* Don't flush before "delay" in ACL */ #ifdef ENABLE_DISABLE_FSYNC extern BOOL disable_fsync; /* Not for normal use */ #endif diff --git a/test/confs/0552 b/test/confs/0552 new file mode 100644 index 000000000..3ce775148 --- /dev/null +++ b/test/confs/0552 @@ -0,0 +1,66 @@ +# Exim test configuration 0552 + +DDF= +SERVER= + +exim_path = EXIM_PATH +host_lookup_order = bydns +primary_hostname = myhost.test.ex +rfc1413_query_timeout = 0s +spool_directory = DIR/spool +log_file_path = DIR/spool/log/SERVER%slog +gecos_pattern = "" +gecos_name = CALLER_NAME + +# ----- Main settings ----- + +acl_not_smtp = check_not +acl_smtp_connect = check_connect +acl_smtp_rcpt = check_rcpt + +queue_only + +# ----- ACL ----- + +begin ACL + +check_connect: + accept DDF + +check_rcpt: + accept delay = 1s + +check_not: + accept delay = 1s + logwrite = Accept non-SMTP + + +# ----- Routers ----- + +begin routers + +r1: + driver = accept + transport = t1 + + +# ----- Transports ----- + +begin transports + +t1: + driver = smtp + port = PORT_D + hosts = 127.0.0.1 + allow_localhost + command_timeout = 2s + + +# ----- Retry ----- + +begin retry + +* * F,1d,1s + + +# End diff --git a/test/log/0552 b/test/log/0552 new file mode 100644 index 000000000..e5a1fd831 --- /dev/null +++ b/test/log/0552 @@ -0,0 +1,19 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 Accept non-SMTP +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx1@test.ex R=r1 T=t1 defer (dd): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after MAIL FROM: SIZE=1310 +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx2@test.ex R=r1 T=t1 defer (dd): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after MAIL FROM: SIZE=1310 +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx3@test.ex R=r1 T=t1 defer (dd): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after MAIL FROM: SIZE=1310 +1999-03-02 09:44:33 End queue run: pid=pppp -qf +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaX-0005vi-00 => userx1@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] +1999-03-02 09:44:33 10HmaX-0005vi-00 -> userx2@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] +1999-03-02 09:44:33 10HmaX-0005vi-00 -> userx3@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qf + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] lost while reading message data (header) +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex diff --git a/test/scripts/0000-Basic/0552 b/test/scripts/0000-Basic/0552 new file mode 100644 index 000000000..1958dbe64 --- /dev/null +++ b/test/scripts/0000-Basic/0552 @@ -0,0 +1,20 @@ +# autoflush for delay +need_ipv4 +# +# Put a message on the queue (queue_only is set); this tests that a +# non-SMTP delay still works. +exim userx1@test.ex userx2@test.ex userx3@test.ex +**** +# This daemon is "old-style", without the flush +exim -DSERVER=server -DDDF=control=no_delay_flush -bd -oX PORT_D +**** +exim -qf +**** +killdaemon +# This daemon should flush before delaying +exim -DSERVER=server -bd -oX PORT_D +**** +exim -qf +**** +killdaemon +no_msglog_check -- 2.30.2