-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.286 2006/02/07 16:36:25 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.287 2006/02/08 14:28:51 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
address records were *not* found in the additional section, the port
values from the SRV records were lost.
+PH/17 If a delivery to a pipe, file, or autoreply was deferred, Exim was not
+ using the correct key (the original address) when searching the retry
+ rules in order to find which one to use for generating the retry hint.
+
Exim version 4.60
-/* $Cambridge: exim/src/src/deliver.c,v 1.26 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/deliver.c,v 1.27 2006/02/08 14:28:51 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
DEBUG(D_retry)
{
- debug_printf("retry record exists: age=%d (max=%d)\n",
- (int)(now - retry_record->time_stamp), retry_data_expire);
- debug_printf(" time to retry = %d expired = %d\n",
- (int)(now - retry_record->next_try), retry_record->expired);
+ debug_printf("retry record exists: age=%s ",
+ readconf_printtime(now - retry_record->time_stamp));
+ debug_printf("(max %s)\n", readconf_printtime(retry_data_expire));
+ debug_printf(" time to retry = %s expired = %d\n",
+ readconf_printtime(retry_record->next_try - now),
+ retry_record->expired);
}
if (queue_running && !deliver_force)
for (last_rule = retry->rules;
last_rule->next != NULL;
last_rule = last_rule->next);
+ DEBUG(D_deliver|D_retry)
+ debug_printf("now=%d received_time=%d diff=%d timeout=%d\n",
+ (int)now, received_time, (int)now - received_time,
+ last_rule->timeout);
if (now - received_time > last_rule->timeout) ok = TRUE;
}
- else ok = TRUE; /* No rule => timed out */
+ else
+ {
+ DEBUG(D_deliver|D_retry)
+ debug_printf("no retry rule found: assume timed out\n");
+ ok = TRUE; /* No rule => timed out */
+ }
DEBUG(D_deliver|D_retry)
{
-/* $Cambridge: exim/src/src/readconf.c,v 1.17 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.18 2006/02/08 14:28:51 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
int s, m, h, d, w;
uschar *p = time_buffer;
+if (t < 0)
+ {
+ *p++ = '-';
+ t = -t;
+ }
+
s = t % 60;
t /= 60;
m = t % 60;
-/* $Cambridge: exim/src/src/retry.c,v 1.5 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/retry.c,v 1.6 2006/02/08 14:28:51 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
for (last_rule = retry->rules;
last_rule->next != NULL;
last_rule = last_rule->next);
+ DEBUG(D_transport|D_retry)
+ debug_printf("now=%d received_time=%d diff=%d timeout=%d\n",
+ (int)now, received_time, (int)(now - received_time),
+ last_rule->timeout);
address_timeout = (now - received_time > last_rule->timeout);
}
+else
+ {
+ DEBUG(D_transport|D_retry)
+ debug_printf("no retry rule found: assume timed out\n");
+ }
return address_timeout;
}
retry_find_config(uschar *key, uschar *alternate, int basic_errno,
int more_errno)
{
-int replace;
+int replace = 0;
uschar *use_key, *use_alternate;
uschar *colon = Ustrchr(key, ':');
retry_config *yield;
-/* If there's a colon in the key, temporarily replace it with
-a zero to terminate the string there. */
+/* If there's a colon in the key, there are two possibilities:
+
+(1) This is a key for a host, ip address, and possibly port, in the format
+
+ hostname:ip+port
+
+ In this case, we temporarily replace the colon with a zero, to terminate
+ the string after the host name.
+
+(2) This is a key for a pipe, file, or autoreply delivery, in the format
+
+ pipe-or-file-or-auto:x@y
+
+ where x@y is the original address that provoked the delivery. The pipe or
+ file or auto will start with | or / or >, whereas a host name will start
+ with a letter or a digit. In this case we want to use the original address
+ to search for a retry rule. */
if (colon != NULL)
{
- replace = ':';
- }
-else
- {
- colon = key + Ustrlen(key);
- replace = 0;
+ if (isalnum(*key))
+ replace = ':';
+ else
+ key = Ustrrchr(key, ':') + 1; /* Take from the last colon */
}
+
+if (replace == 0) colon = key + Ustrlen(key);
*colon = 0;
/* Sort out the keys */
DEBUG(D_retry)
{
if ((rti->flags & rf_host) != 0)
- debug_printf("retry for %s (%s) = %s\n", rti->key,
- addr->domain, retry->pattern);
+ debug_printf("retry for %s (%s) = %s %d %d\n", rti->key,
+ addr->domain, retry->pattern, retry->basic_errno,
+ retry->more_errno);
else
- debug_printf("retry for %s = %s\n", rti->key, retry->pattern);
+ debug_printf("retry for %s = %s %d %d\n", rti->key, retry->pattern,
+ retry->basic_errno, retry->more_errno);
}
/* Set up the message for the database retry record. Because DBM
--- /dev/null
+# This is a little perl script that adjusts the "received" time in a -H file,
+# so that retry timeouts etc can be more easily tested. Its arguments are:
+#
+# (1) The number of the message on the queue whose time is to be adjusted; 1
+# for the first message, 2 for the second, etc.
+#
+# (2) A positive or negative number by which to adjust the received time.
+
+$fileno = $ARGV[0] - 1;
+$adjust = $ARGV[1];
+
+opendir(DIR, "spool/input");
+while (($_ = readdir(DIR))) { push(@files, $_) if /.*-H$/; }
+closedir(DIR);
+
+@files = sort @files;
+
+open(IN, "spool/input/$files[$fileno]") ||
+ die "can't open spool/input/$files[$fileno]";
+
+open(OUT, ">test-H");
+
+$_ = <IN>; print OUT;
+$_ = <IN>; print OUT;
+$_ = <IN>; print OUT;
+$_ = <IN>;
+($rtime,$rest) = $_ =~ /^(\d+)(.*)/;
+$rtime += $adjust;
+print OUT "$rtime$rest\n";
+print OUT while (<IN>);
+
+close(IN);
+close(OUT);
+
+rename("test-H", "spool/input/$files[$fileno]") || die "rename failed\n";
+
+exit(0);
+
+# End
--- /dev/null
+# Exim test configuration 0529
+
+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/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+ driver = redirect
+ data = DIR/test-mail/rmbox
+ file_transport = t1
+
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+ driver = appendfile
+ quota = 1
+ user = CALLER
+
+
+# ----- Retry -----
+
+begin retry
+
+*@test.ex quota_7d
+*@test.ex quota F,2h,15m; F,3d,1h
+* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+
+# End
--- /dev/null
+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 10HmaX-0005vi-00 == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to TESTSUITE/test-mail/rmbox)
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-52): Retry time not yet reached
+1999-03-02 09:44:33 End queue run: pid=pppp
#! /usr/bin/perl -w
-# $Cambridge: exim/test/runtest,v 1.1 2006/02/06 16:07:10 ph10 Exp $
+# $Cambridge: exim/test/runtest,v 1.2 2006/02/08 14:28:51 ph10 Exp $
###############################################################################
# This is the controlling script for the "new" test suite for Exim. It should #
# Date/time in mbx mailbox files
s/\d\d-\w\w\w-\d\d\d\d\s\d\d:\d\d:\d\d\s[-+]\d\d\d\d,/06-Sep-1999 15:52:48 +0100,/gx;
- # Date/time in debugging output for writing retry records
+ # Dates/times in debugging output for writing retry records
if (/^ first failed=(\d+) last try=(\d+) next try=(\d+) (.*)$/)
{
my($next) = $3 - $2;
$_ = " first failed=dddd last try=dddd next try=+$next $4\n";
}
+ s/^now=\d+ received_time=\d+ diff=\d+ timeout=(\d+)/now=tttt received_time=tttt diff=tttt timeout=$1/;
# Time to retry may vary
- s/time to retry = -\d+/time to retry = -ddddd/;
- s/retry record exists: age=\d/retry record exists: age=d/;
+ s/time to retry = \S+/time to retry = tttt/;
+ s/retry record exists: age=\S+/retry record exists: age=ttt/;
# Date/time in exim -bV output
s/\d\d-[A-Z][a-z]{2}-\d{4}\s\d\d:\d\d:\d\d/07-Mar-2000 12:21:52/g;
# The "client" and "client-ssl" commands run a script-driven program that plays
# the part of an email client. We also have the availability of running Perl
-# for doing one-off special things.
+# for doing one-off special things. Note that all these commands expect stdin
+# data to be supplied.
if (/^client/ || /^client-ssl/ || /^(sudo\s+)?perl\b/)
{
--- /dev/null
+# retries for quota exceeded when routed to a file
+#
+exim -d-all+retry -odi x@test.ex
+****
+# Adjust the received time for the message, then try a queue run.
+sudo perl DIR/aux-fixed/setrt 1 -86400
+****
+exim -d-all+retry -q
+****
+no_msglog_check
Deferred addresses:
userx@test.ex
locking TESTSUITE/spool/db/retry.lockfile
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
userx@test.ex
locking TESTSUITE/spool/db/retry.lockfile
deleted retry information for R:test.ex
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
userx@test.ex
locking TESTSUITE/spool/db/retry.lockfile
deleted retry information for R:test.ex
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+2 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
Deferred addresses:
usery@test.ex
locking TESTSUITE/spool/db/retry.lockfile
-retry for R:usery@test.ex = *
+retry for R:usery@test.ex = * 0 0
Writing retry data for R:usery@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<usery@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
userx@test.ex
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+1 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
usery@test.ex
locking TESTSUITE/spool/db/retry.lockfile
deleted retry information for R:test.ex
-retry for R:usery@test.ex = *
+retry for R:usery@test.ex = * 0 0
Writing retry data for R:usery@test.ex
first failed=dddd last try=dddd next try=+2 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<usery@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
userx@test.ex
deleted retry information for R:test.ex
-retry for R:userx@test.ex = *
+retry for R:userx@test.ex = * 0 0
Writing retry data for R:userx@test.ex
first failed=dddd last try=dddd next try=+2 expired=0
errno=-44 more_errno=dd,A SMTP error from remote mail server after RCPT TO:<userx@test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
address match: subject=x@y pattern=*
y in "*"? yes (matched "*")
x@y in "*"? yes (matched "*")
-retry for R:x@y = *
+retry for R:x@y = * 0 0
dbfn_read: key=R:x@y
on queue longer than maximum retry
Writing retry data for R:x@y
address match: subject=*@V4NET.0.0.0 pattern=*
V4NET.0.0.0 in "*"? yes (matched "*")
*@V4NET.0.0.0 in "*"? yes (matched "*")
-retry for T:V4NET.0.0.0:V4NET.0.0.0:1224 (y) = *
+retry for T:V4NET.0.0.0:V4NET.0.0.0:1224 (y) = * 0 0
dbfn_read: key=T:V4NET.0.0.0:V4NET.0.0.0:1224
on queue longer than maximum retry
Writing retry data for T:V4NET.0.0.0:V4NET.0.0.0:1224
checking status of 127.0.0.1
no message retry record
host retry time not reached: checking ultimate address timeout
+now=tttt received_time=tttt diff=tttt timeout=86400
127.0.0.1 [127.0.0.1]:1111 status = unusable
all IP addresses skipped or deferred at least one address
Leaving t1 transport
--- /dev/null
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+LOG: MAIN
+ <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+created log directory TESTSUITE/spool/log
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+trusted user
+admin user
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: x@test.ex
+no domain retry record
+no address retry record
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: TESTSUITE/test-mail/rmbox
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+After routing:
+ Local deliveries:
+ TESTSUITE/test-mail/rmbox
+ Remote deliveries:
+ Failed addresses:
+ Deferred addresses:
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+added retry item for T:TESTSUITE/test-mail/rmbox:x@test.ex: errno=-22 more_errno=dd flags=0
+LOG: MAIN
+ == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to TESTSUITE/test-mail/rmbox)
+Processing retry items
+Succeeded addresses:
+x@test.ex: no retry items
+Failed addresses:
+Deferred addresses:
+TESTSUITE/test-mail/rmbox
+locking TESTSUITE/spool/db/retry.lockfile
+retry for T:TESTSUITE/test-mail/rmbox:x@test.ex = *@test.ex -22 0
+Writing retry data for T:TESTSUITE/test-mail/rmbox:x@test.ex
+ first failed=dddd last try=dddd next try=+900 expired=0
+ errno=-22 more_errno=dd mailbox is full (MTA-imposed quota exceeded while writing to TESTSUITE/test-mail/rmbox)
+x@test.ex: no retry items
+end of retry processing
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+LOG: queue_run MAIN
+ Start queue run: pid=pppp
+locking TESTSUITE/spool/db/retry.lockfile
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: x@test.ex
+no domain retry record
+no address retry record
+locking TESTSUITE/spool/db/retry.lockfile
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: TESTSUITE/test-mail/rmbox
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+After routing:
+ Local deliveries:
+ TESTSUITE/test-mail/rmbox
+ Remote deliveries:
+ Failed addresses:
+ Deferred addresses:
+locking TESTSUITE/spool/db/retry.lockfile
+retry record exists: age=ttt (max 1w)
+ time to retry = tttt expired = 0
+retry time not reached for TESTSUITE/test-mail/rmbox: checking ultimate address timeout
+now=tttt received_time=tttt diff=tttt timeout=259200
+LOG: retry_defer MAIN
+ == TESTSUITE/test-mail/rmbox <x@test.ex> R=r1 T=t1 defer (-52): Retry time not yet reached
+Processing retry items
+Succeeded addresses:
+x@test.ex: no retry items
+Failed addresses:
+Deferred addresses:
+TESTSUITE/test-mail/rmbox: no retry items
+x@test.ex: no retry items
+end of retry processing
+LOG: queue_run MAIN
+ End queue run: pid=pppp
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
address match: subject=userx@test.ex pattern=*
test.ex in "*"? yes (matched "*")
userx@test.ex in "*"? yes (matched "*")
-retry for T:userx@test.ex = *
+retry for T:userx@test.ex = * 0 0
dbfn_read: key=T:userx@test.ex
Writing retry data for T:userx@test.ex
first failed=dddd last try=dddd next try=+86400 expired=0
returned from EXIM_DBOPEN
opened hints database TESTSUITE/spool/db/retry: flags=O_RDONLY
dbfn_read: key=T:userx@test.ex
-retry record exists: age=d (max=604800)
- time to retry = -ddddd expired = 0
+retry record exists: age=ttt (max 1w)
+ time to retry = tttt expired = 0
search_tidyup called
changed uid/gid: local delivery to userx <userx@test.ex> transport=t1
uid=CALLER_UID gid=CALLER_GID pid=pppp
address match: subject=userx@test.ex pattern=*
test.ex in "*"? yes (matched "*")
userx@test.ex in "*"? yes (matched "*")
-retry for T:userx@test.ex = *
+retry for T:userx@test.ex = * 0 0
dbfn_read: key=T:userx@test.ex
Writing retry data for T:userx@test.ex
first failed=dddd last try=dddd next try=+86400 expired=0