From 2e2a30b495b1ef8052259093f9422f57903b1717 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Tue, 3 May 2005 14:20:00 +0000 Subject: [PATCH] (1) Don't ignore timeouts while writing to a pipe! (As opposed to timeout of the pipe command process.) (2) Add timeout_defer option to turn timeouts into defers (default has always been to fail). (3) An upgrade to my desktop OS and to SSL has caused the output from some of the test scripts to change. --- doc/doc-txt/ChangeLog | 13 ++++++++++++- doc/doc-txt/NewStuff | 13 ++++++++++++- doc/doc-txt/OptionLists.txt | 5 +++-- src/src/exim.c | 8 +++++++- src/src/globals.c | 3 ++- src/src/globals.h | 3 ++- src/src/tls-openssl.c | 5 +---- src/src/transport.c | 5 ++++- src/src/transports/pipe.c | 20 +++++++++++++------- src/src/transports/pipe.h | 3 ++- 10 files changed, 58 insertions(+), 20 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index f462b6b76..29b0765e8 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.131 2005/05/03 10:02:27 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.132 2005/05/03 14:20:00 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -270,6 +270,17 @@ PH/44 Applied patch from the Sieve maintainer: "The vacation draft is still being worked on, but at least Exim now implements the latest version to play with." +PH/45 In a pipe transport, although a timeout while waiting for the pipe + process to complete was treated as a delivery failure, a timeout while + writing the message to the pipe was logged, but erroneously treated as a + successful delivery. Such timeouts include transport filter timeouts. For + consistency with the overall process timeout, these timeouts are now + treated as errors, giving rise to delivery failures by default. However, + there is now a new Boolean option for the pipe transport called + timeout_defer, which, if set TRUE, converts the failures into defers for + both kinds of timeout. A transport filter timeout is now identified in + the log output. + A note about Exim versions 4.44 and 4.50 ---------------------------------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 2df222c99..f0abee45a 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.38 2005/04/28 13:29:27 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.39 2005/05/03 14:20:00 ph10 Exp $ New Features in Exim -------------------- @@ -170,6 +170,17 @@ PH/10 $message_linecount is a new variable that contains the total number of PH/11 In a ${run expansion, the variable $value (which contains the standard output) is now also usable in the "else" string. +PH/12 In a pipe transport, although a timeout while waiting for the pipe + process to complete was treated as a delivery failure, a timeout while + writing the message to the pipe was logged, but erroneously treated as a + successful delivery. Such timeouts include transport filter timeouts. For + consistency with the overall process timeout, these timeouts are now + treated as errors, giving rise to delivery failures by default. However, + there is now a new Boolean option for the pipe transport called + timeout_defer, which, if set TRUE, converts the failures into defers for + both kinds of timeout. A transport filter timeout is now identified in + the log output. + Version 4.50 ------------ diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt index ba727b0bb..ac1e06a11 100644 --- a/doc/doc-txt/OptionLists.txt +++ b/doc/doc-txt/OptionLists.txt @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.7 2005/04/04 10:33:49 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.8 2005/05/03 14:20:00 ph10 Exp $ LISTS OF EXIM OPTIONS --------------------- @@ -11,7 +11,7 @@ This file contains complete lists of four kinds of Exim option: 4. Those that can appear in the build time configuration for the Exim monitor (Local/eximon.conf). -This file was last updated for Exim release 4.50. +This file was last updated for Exim release 4.51. 1. RUN TIME OPTIONS @@ -497,6 +497,7 @@ timeout time 5m lmtp 1h pipe 1h queryprogram 4.00 5s iplookup 4.00 +timeout_defer boolean false pipe 4.51 timeout_frozen_after time 0s main 3.20 timezone string + main 3.15 tls_advertise_hosts host list * main 3.20 diff --git a/src/src/exim.c b/src/src/exim.c index 35151c28c..32ddb96d2 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.18 2005/04/06 10:06:14 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.19 2005/05/03 14:20:01 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -4703,6 +4703,12 @@ while (more) close_unwanted(); /* Close unwanted file descriptors and TLS */ exim_nullstd(); /* Ensure std{in,out,err} exist */ + /* Occasionally in the test harness we don't have synchronous delivery + set (can happen with bounces). In that case, let the old process finish + before continuing, to keep the debug output the same. */ + + if (running_in_test_harness && !synchronous_delivery) millisleep(100); + /* Re-exec Exim if we need to regain privilege (note: in mua_wrapper mode, deliver_drop_privilege is forced TRUE). */ diff --git a/src/src/globals.c b/src/src/globals.c index 5a7838be3..5fed1a144 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.22 2005/04/07 10:54:54 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.23 2005/05/03 14:20:01 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1130,6 +1130,7 @@ transport_instance transport_defaults = { int transport_count; uschar **transport_filter_argv = NULL; int transport_filter_timeout; +BOOL transport_filter_timed_out = FALSE; int transport_write_timeout= 0; tree_node *tree_dns_fails = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 37faa9d50..9ba972f1f 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.h,v 1.14 2005/04/04 10:33:49 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.h,v 1.15 2005/05/03 14:20:01 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -682,6 +682,7 @@ extern BOOL timestamps_utc; /* Use UTC for all times */ extern int transport_count; /* Count of bytes transported */ extern uschar **transport_filter_argv; /* For on-the-fly filtering */ extern int transport_filter_timeout; /* Timeout for same */ +extern BOOL transport_filter_timed_out; /* True if it did */ extern transport_info transports_available[]; /* Vector of available transports */ extern transport_instance *transports; /* Chain of instantiated transports */ diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 693e6dc14..c9bdcf79c 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/tls-openssl.c,v 1.4 2005/03/29 14:53:09 ph10 Exp $ */ +/* $Cambridge: exim/src/src/tls-openssl.c,v 1.5 2005/05/03 14:20:01 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -182,9 +182,6 @@ else tls_peerdn = txt; } - -debug_printf("+++verify_callback_called=%d\n", verify_callback_called); - if (!verify_callback_called) tls_certificate_verified = TRUE; verify_callback_called = TRUE; diff --git a/src/src/transport.c b/src/src/transport.c index d4f8930fd..c38818770 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transport.c,v 1.7 2005/03/22 16:44:04 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transport.c,v 1.8 2005/05/03 14:20:01 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1099,6 +1099,8 @@ int rc, len, yield, fd_read, fd_write, save_errno; int pfd[2]; pid_t filter_pid, write_pid; +transport_filter_timed_out = FALSE; + /* If there is no filter command set up, call the internal function that does the actual work, passing it the incoming fd, and return its result. */ @@ -1211,6 +1213,7 @@ for (;;) if (sigalrm_seen) { errno = ETIMEDOUT; + transport_filter_timed_out = TRUE; goto TIDY_UP; } diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 5f7e00f60..43d0e5895 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/pipe.c,v 1.4 2005/02/17 11:58:27 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/pipe.c,v 1.5 2005/05/03 14:20:01 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -65,6 +65,8 @@ optionlist pipe_transport_options[] = { (void *)offsetof(pipe_transport_options_block, temp_errors) }, { "timeout", opt_time, (void *)offsetof(pipe_transport_options_block, timeout) }, + { "timeout_defer", opt_bool, + (void *)offsetof(pipe_transport_options_block, timeout_defer) }, { "umask", opt_octint, (void *)offsetof(pipe_transport_options_block, umask) }, { "use_bsmtp", opt_bool, @@ -101,6 +103,7 @@ pipe_transport_options_block pipe_transport_option_defaults = { FALSE, /* freeze_exec_fail */ FALSE, /* ignore_status */ FALSE, /* restrict_to_path */ + FALSE, /* timeout_defer */ FALSE, /* use_shell */ FALSE, /* use_bsmtp */ FALSE /* use_crlf */ @@ -786,17 +789,20 @@ the child process to 1 second. If the process at the far end of the pipe died without reading all of it, we expect an EPIPE error, which should be ignored. We used also to ignore WRITEINCOMPLETE but the writing function is now cleverer at handling OS where the death of a pipe doesn't give EPIPE immediately. See -comments therein. This change made 04-Sep-98. Clean up this code in a year or -so. */ +comments therein. */ if (!written_ok) { if (errno == ETIMEDOUT) + { + addr->message = string_sprintf("%stimeout while writing to pipe", + transport_filter_timed_out? "transport filter " : ""); + addr->transport_return = ob->timeout_defer? DEFER : FAIL; timeout = 1; - else if (errno == EPIPE /* || errno == ERRNO_WRITEINCOMPLETE */ ) + } + else if (errno == EPIPE) { - debug_printf("transport error %s ignored\n", - (errno == EPIPE)? "EPIPE" : "WRITEINCOMPLETE"); + debug_printf("transport error EPIPE ignored\n"); } else { @@ -834,7 +840,7 @@ if ((rc = child_close(pid, timeout)) != 0) { killpg(pid, SIGKILL); kill(outpid, SIGKILL); - addr->transport_return = FAIL; + addr->transport_return = ob->timeout_defer? DEFER : FAIL; addr->message = string_sprintf("pipe delivery process timed out"); } diff --git a/src/src/transports/pipe.h b/src/src/transports/pipe.h index 5f0bfc17f..af9141ce9 100644 --- a/src/src/transports/pipe.h +++ b/src/src/transports/pipe.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/pipe.h,v 1.2 2005/01/04 10:00:45 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/pipe.h,v 1.3 2005/05/03 14:20:01 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -26,6 +26,7 @@ typedef struct { BOOL freeze_exec_fail; BOOL ignore_status; BOOL restrict_to_path; + BOOL timeout_defer; BOOL use_shell; BOOL use_bsmtp; BOOL use_crlf; -- 2.25.1