Retry items for address errors that included the sender address (a
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 6 Feb 2007 14:19:00 +0000 (14:19 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 6 Feb 2007 14:19:00 +0000 (14:19 +0000)
feature added to Exim 4.64) were not being deleted if an address was
subsequently successfully delivered.

doc/doc-txt/ChangeLog
src/src/deliver.c
src/src/transports/smtp.c
test/confs/0554 [new file with mode: 0644]
test/log/0554 [new file with mode: 0644]
test/scripts/0000-Basic/0554 [new file with mode: 0644]
test/stderr/0554 [new file with mode: 0644]
test/stdout/0554 [new file with mode: 0644]

index 0f6eeb39251b0b9653ca9bbe5787bdaea3986115..fd3b4c4203463be580751681b73101818853f135 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.471 2007/02/06 12:19:27 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.472 2007/02/06 14:19:00 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -80,6 +80,11 @@ PH/17 Added dsn_from option to vary the From: line in DSNs.
 PH/18 Flush SMTP output before performing a callout, unless control =
       no_callout_flush is set.
 
 PH/18 Flush SMTP output before performing a callout, unless control =
       no_callout_flush is set.
 
+PH/19 Change 4.64/PH/36 introduced a bug: when address_retry_include_sender
+      was true (the default) a successful delivery failed to delete the retry
+      item, thus causing premature timeout of the address. The bug is now
+      fixed.
+
 
 Exim version 4.66
 -----------------
 
 Exim version 4.66
 -----------------
index be588dd7cb17c2018bce2dc41c623fd8271fa1de..c712e9aa2a221c0abbcc096430ff004b3490b8e7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/deliver.c,v 1.43 2007/02/06 11:11:40 ph10 Exp $ */
+/* $Cambridge: exim/src/src/deliver.c,v 1.44 2007/02/06 14:19:00 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -5478,7 +5478,7 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
 
       if (address_retry_record == NULL)
         {
 
       if (address_retry_record == NULL)
         {
-        uschar * altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
+        uschar *altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
           sender_address);
         address_retry_record = dbfn_read(dbm_file, altkey);
         if (address_retry_record != NULL &&
           sender_address);
         address_retry_record = dbfn_read(dbm_file, altkey);
         if (address_retry_record != NULL &&
@@ -5637,12 +5637,16 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
         string_sprintf("R:%s", addr->domain), 0);
 
     /* Otherwise, if there is an existing retry record in the database, add
         string_sprintf("R:%s", addr->domain), 0);
 
     /* Otherwise, if there is an existing retry record in the database, add
-    retry items to delete both forms. Since the domain might have been
-    rewritten (expanded to fully qualified) as a result of routing, ensure
-    that the rewritten form is also deleted. */
+    retry items to delete both forms. We must also allow for the possibility
+    of a routing retry that includes the sender address. Since the domain might
+    have been rewritten (expanded to fully qualified) as a result of routing,
+    ensure that the rewritten form is also deleted. */
 
     else if (testflag(addr, af_dr_retry_exists))
       {
 
     else if (testflag(addr, af_dr_retry_exists))
       {
+      uschar *altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
+        sender_address);
+      retry_add_item(addr, altkey, rf_delete);
       retry_add_item(addr, addr->address_retry_key, rf_delete);
       retry_add_item(addr, addr->domain_retry_key, rf_delete);
       if (Ustrcmp(addr->domain, old_domain) != 0)
       retry_add_item(addr, addr->address_retry_key, rf_delete);
       retry_add_item(addr, addr->domain_retry_key, rf_delete);
       if (Ustrcmp(addr->domain, old_domain) != 0)
index cf09010cbeee96368f10e9e651db5d5672f6e91d..0bc5b533ee77872c801a1fedd738e3bb91d5cbea 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/smtp.c,v 1.33 2007/01/30 15:10:59 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/smtp.c,v 1.34 2007/02/06 14:19:00 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -654,10 +654,16 @@ while (count-- > 0)
     addr->transport_return = PENDING_OK;
 
     /* If af_dr_retry_exists is set, there was a routing delay on this address;
     addr->transport_return = PENDING_OK;
 
     /* If af_dr_retry_exists is set, there was a routing delay on this address;
-    ensure that any address-specific retry record is expunged. */
+    ensure that any address-specific retry record is expunged. We do this both
+    for the basic key and for the version that also includes the sender. */
 
     if (testflag(addr, af_dr_retry_exists))
 
     if (testflag(addr, af_dr_retry_exists))
+      {
+      uschar *altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
+        sender_address);
+      retry_add_item(addr, altkey, rf_delete);
       retry_add_item(addr, addr->address_retry_key, rf_delete);
       retry_add_item(addr, addr->address_retry_key, rf_delete);
+      }
     }
 
   /* Timeout while reading the response */
     }
 
   /* Timeout while reading the response */
diff --git a/test/confs/0554 b/test/confs/0554
new file mode 100644 (file)
index 0000000..edeb977
--- /dev/null
@@ -0,0 +1,40 @@
+# Exim test configuration 0554
+
+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 = manualroute
+  route_list = * 127.0.0.1
+  transport = smtp
+  self = send
+
+
+# ----- Transports -----
+
+begin transports
+
+smtp:
+  driver = smtp
+  port = PORT_S
+
+# ----- Retry -----
+
+begin retry
+
+* * F,10s,1s
+
+# End
diff --git a/test/log/0554 b/test/log/0554
new file mode 100644 (file)
index 0000000..d601ff2
--- /dev/null
@@ -0,0 +1,4 @@
+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 == x@y R=r1 T=smtp defer (-44): SMTP error from remote mail server after RCPT TO:<x@y>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
+1999-03-02 09:44:33 10HmaX-0005vi-00 => x@y R=r1 T=smtp H=127.0.0.1 [127.0.0.1]
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
diff --git a/test/scripts/0000-Basic/0554 b/test/scripts/0000-Basic/0554
new file mode 100644 (file)
index 0000000..0cf76b9
--- /dev/null
@@ -0,0 +1,41 @@
+# Retries for address errors
+need_ipv4
+#
+exim -odq x@y
+****
+# First attempt is temporarily rejected
+server PORT_S
+220 Server ready
+EHLO
+250 OK
+MAIL FROM
+250 OK
+RCPT TO
+451 Temporary error
+QUIT
+250 OK
+****
+exim -odi -d-all+retry -M $msg1
+****
+dump retry
+#
+# Next attempt succeeds
+server PORT_S
+220 Server ready
+EHLO
+250 OK
+MAIL FROM
+250 OK
+RCPT TO
+250 OK
+DATA
+354 Go Ahead
+.
+250 OK
+QUIT
+250 OK
+****
+exim -odi -d-all+retry -M $msg1
+****
+dump retry
+no_msglog_check
diff --git a/test/stderr/0554 b/test/stderr/0554
new file mode 100644 (file)
index 0000000..edd4036
--- /dev/null
@@ -0,0 +1,91 @@
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: x@y
+no domain retry record
+no address retry record
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+After routing:
+  Local deliveries:
+  Remote deliveries:
+    x@y
+  Failed addresses:
+  Deferred addresses:
+checking status of 127.0.0.1
+locking TESTSUITE/spool/db/retry.lockfile
+no retry data available
+added retry item for R:x@y:<CALLER@myhost.test.ex>: errno=-44 more_errno=dd,A flags=0
+reading retry information for R:x@y:<CALLER@myhost.test.ex> from subprocess
+  added retry item
+LOG: MAIN
+  == x@y R=r1 T=smtp defer (-44): SMTP error from remote mail server after RCPT TO:<x@y>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
+Processing retry items
+Succeeded addresses:
+Failed addresses:
+Deferred addresses:
+x@y
+locking TESTSUITE/spool/db/retry.lockfile
+retry for R:x@y:<CALLER@myhost.test.ex> = * 0 0
+failing_interval=ttt message_age=ttt
+Writing retry data for R:x@y:<CALLER@myhost.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:<x@y>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
+end of retry processing
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+locking TESTSUITE/spool/db/retry.lockfile
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: x@y
+no domain retry record
+added retry item for R:x@y:<CALLER@myhost.test.ex>: errno=-1 more_errno=dd flags=1
+added retry item for R:x@y: errno=-1 more_errno=dd flags=1
+added retry item for R:y: errno=-1 more_errno=dd flags=1
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+After routing:
+  Local deliveries:
+  Remote deliveries:
+    x@y
+  Failed addresses:
+  Deferred addresses:
+checking status of 127.0.0.1
+locking TESTSUITE/spool/db/retry.lockfile
+no host retry record
+no message retry record
+added retry item for R:x@y:<CALLER@myhost.test.ex>: errno=dd more_errno=dd,A flags=1
+added retry item for R:x@y: errno=dd more_errno=dd,A flags=1
+locking TESTSUITE/spool/db/wait-smtp.lockfile
+reading retry information for R:x@y from subprocess
+  existing delete item dropped
+  added delete item
+reading retry information for R:x@y:<CALLER@myhost.test.ex> from subprocess
+  existing delete item dropped
+  added delete item
+reading retry information for R:y from subprocess
+  existing delete item dropped
+  added delete item
+reading retry information for R:x@y from subprocess
+  existing delete item dropped
+  added delete item
+reading retry information for R:x@y:<CALLER@myhost.test.ex> from subprocess
+  existing delete item dropped
+  added delete item
+LOG: MAIN
+  => x@y R=r1 T=smtp H=127.0.0.1 [127.0.0.1]
+Processing retry items
+Succeeded addresses:
+x@y
+locking TESTSUITE/spool/db/retry.lockfile
+deleted retry information for R:x@y:<CALLER@myhost.test.ex>
+deleted retry information for R:x@y
+deleted retry information for R:y
+Failed addresses:
+Deferred addresses:
+end of retry processing
+LOG: MAIN
+  Completed
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
diff --git a/test/stdout/0554 b/test/stdout/0554
new file mode 100644 (file)
index 0000000..8c0cfea
--- /dev/null
@@ -0,0 +1,42 @@
++++++++++++++++++++++++++++
+  R:x@y:<CALLER@myhost.test.ex> -44 13121 SMTP error from remote mail server after RCPT TO:<x@y>: host 127.0.0.1 [127.0.0.1]: 451 Temporary error
+first failed = time last try = time2 next try = time2 + 1
++++++++++++++++++++++++++++
+
+******** SERVER ********
+Listening on port 1224 ... 
+Connection request from [127.0.0.1]
+220 Server ready
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 OK
+RCPT TO:<x@y>
+451 Temporary error
+QUIT
+250 OK
+End of script
+Listening on port 1224 ... 
+Connection request from [127.0.0.1]
+220 Server ready
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 OK
+RCPT TO:<x@y>
+250 OK
+DATA
+354 Go Ahead
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <CALLER@myhost.test.ex>)
+       id 10HmaX-0005vi-00
+       for x@y; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+.
+250 OK
+QUIT
+250 OK
+End of script