Routers: make retry_use_local_part default true when any non-domain condition is...
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 1 Aug 2019 18:31:36 +0000 (19:31 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 10 Aug 2019 18:27:02 +0000 (19:27 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/deliver.c
src/src/route.c
test/confs/0264
test/log/0264
test/scripts/0000-Basic/0264
test/stderr/0264 [new file with mode: 0644]
test/stderr/0375
test/stdout/0264

index 736ac0fe43538c7d3ec33b9b476d058f19f41d32..aa39965052faf3ebbf1917dc56bc940c427884f0 100644 (file)
@@ -18884,11 +18884,24 @@ latter kind.
 
 This option controls whether the local part is used to form the key for retry
 hints for addresses that suffer temporary errors while being handled by this
 
 This option controls whether the local part is used to form the key for retry
 hints for addresses that suffer temporary errors while being handled by this
-router. The default value is true for any router that has &%check_local_user%&
+.new
+router. The default value is true for any router that has any of
+&%check_local_user%&, 
+&%local_parts%&,
+&%condition%&,
+&%local_part_prefix%&,
+&%local_part_suffix%&,
+&%senders%& or
+&%require_files%&
+.wen
 set, and false otherwise. Note that this option does not apply to hints keys
 for transport delays; they are controlled by a generic transport option of the
 same name.
 
 set, and false otherwise. Note that this option does not apply to hints keys
 for transport delays; they are controlled by a generic transport option of the
 same name.
 
+Failing to set this option when it is needed
+(because a remote router handles only some of the local-parts for a domain)
+can result in incorrect error messages being generated.
+
 The setting of &%retry_use_local_part%& applies only to the router on which it
 appears. If the router generates child addresses, they are routed
 independently; this setting does not become attached to them.
 The setting of &%retry_use_local_part%& applies only to the router on which it
 appears. If the router generates child addresses, they are routed
 independently; this setting does not become attached to them.
index 7fca99b620413ab5538c3a71e38dc10597e18c4b..6d1b2631bb81f74d3d74f1035662d860c77642e7 100644 (file)
@@ -164,6 +164,12 @@ JH/34 Fix crash after TLS shutdown.  When the TCP/SMTP channel was left open,
 JH/35 Bug 2409: filter out-of-spec chars from callout response before using
       them in our smtp response.
 
 JH/35 Bug 2409: filter out-of-spec chars from callout response before using
       them in our smtp response.
 
+JH/35 Have the general router option retry_use_local_part default to true when
+      any of the restrictive preconditions are set (to anything).  Previously it
+      was only for check_local user.  The change removes one item of manual
+      configuration which is required for proper retries when a remote router
+      handles a subset of addresses for a domain.
+
 
 Exim version 4.92
 -----------------
 
 Exim version 4.92
 -----------------
index 66e49d3712297f57489b3844ce82b73b1ab45bc8..a82a04f42a27d7cb2b011786cf575bdb363969df 100644 (file)
@@ -4794,7 +4794,6 @@ all pipes, so I do not see a reason to use non-blocking IO here
     for(; addr; addr = addr->next)
       {
       uschar *ptr;
     for(; addr; addr = addr->next)
       {
       uschar *ptr;
-      retry_item *r;
 
       /* The certificate verification status goes into the flags */
       if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
 
       /* The certificate verification status goes into the flags */
       if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
@@ -4894,7 +4893,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
 
       /* Retry information: for most success cases this will be null. */
 
 
       /* Retry information: for most success cases this will be null. */
 
-      for (r = addr->retries; r; r = r->next)
+      for (retry_item * r = addr->retries; r; r = r->next)
         {
         sprintf(CS big_buffer, "%c%.500s", r->flags, r->key);
         ptr = big_buffer + Ustrlen(big_buffer+2) + 3;
         {
         sprintf(CS big_buffer, "%c%.500s", r->flags, r->key);
         ptr = big_buffer + Ustrlen(big_buffer+2) + 3;
index 41716bc0e4ad2d9bcb5c6049501d3a52137f36b9..c6119eed0e68c1bfbd93723f2b73be1b1a3f7379 100644 (file)
@@ -281,7 +281,8 @@ for (router_instance * r = routers; r; r = r->next)
   TRUE; otherwise its default is FALSE. */
 
   if (r->retry_use_local_part == TRUE_UNSET)
   TRUE; otherwise its default is FALSE. */
 
   if (r->retry_use_local_part == TRUE_UNSET)
-    r->retry_use_local_part = r->check_local_user;
+    r->retry_use_local_part =
+      r->check_local_user || r->local_parts || r->condition || r->prefix || r->suffix || r->senders || r->require_files;
 
   /* Build a host list if fallback hosts is set. */
 
 
   /* Build a host list if fallback hosts is set. */
 
index 792b304dd852c0e616b5c3a0571f3fb21f24d865..7c0a066e92776eb6fa6b759e543315abe1e891ab 100644 (file)
@@ -63,6 +63,12 @@ r5:
   allow_defer
   data = :defer: not just now
 
   allow_defer
   data = :defer: not just now
 
+r_remain:
+  driver = redirect
+  allow_defer
+  data = :defer: not just now
+
+
 # ----- Retry -----
 
 begin retry
 # ----- Retry -----
 
 begin retry
index d26865be83c1f88f877fa517158677fe4eef9a7c..599ea47164dfdcd2df4e6fb8f7690a2951e0b1eb 100644 (file)
 1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 Start queue run: pid=pppp
 1999-03-02 09:44:33 10HmbF-0005vi-00 == r4.a@outside routing defer (-51): retry time not reached
 1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 Start queue run: pid=pppp
 1999-03-02 09:44:33 10HmbF-0005vi-00 == r4.a@outside routing defer (-51): retry time not reached
-1999-03-02 09:44:33 10HmbG-0005vi-00 == r4.b@outside routing defer (-51): retry time not reached
+1999-03-02 09:44:33 10HmbG-0005vi-00 == r4.b@outside R=r4 defer (-1): not just now
 1999-03-02 09:44:33 End queue run: pid=pppp
 1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmbH-0005vi-00 == r5.a@r5domain.ex R=r5 defer (-1): not just now
 1999-03-02 09:44:33 End queue run: pid=pppp
 1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmbH-0005vi-00 == r5.a@r5domain.ex R=r5 defer (-1): not just now
+1999-03-02 09:44:33 10HmbF-0005vi-00 removed by CALLER
+1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbG-0005vi-00 removed by CALLER
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbH-0005vi-00 removed by CALLER
+1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbI-0005vi-00 == rz.a@outside R=r_remain defer (-1): not just now
+1999-03-02 09:44:33 10HmbJ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbJ-0005vi-00 == rz.b@outside R=r_remain defer (-1): not just now
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmbI-0005vi-00 == rz.a@outside routing defer (-51): retry time not reached
+1999-03-02 09:44:33 10HmbJ-0005vi-00 == rz.b@outside routing defer (-51): retry time not reached
+1999-03-02 09:44:33 End queue run: pid=pppp
index 5d6bcfb2998c6eca5c78f946eee9018f59aa50ea..2b97ad4f69647bb11fbd0f1c6a93394a48c738b4 100644 (file)
@@ -27,13 +27,28 @@ exim -q
 ****
 exim -Mrm $msg1 $msg2
 ****
 ****
 exim -Mrm $msg1 $msg2
 ****
+# Using a router with preconditions (local_parts, here) should get an address-retry record
+sudo rm DIR/spool/db/retry
 exim -odi r4.a@outside
 ****
 exim -odi r4.a@outside
 ****
+dump retry
 exim -odq r4.b@outside
 ****
 exim -q
 ****
 exim -odi r5.a@r5domain.ex
 ****
 exim -odq r4.b@outside
 ****
 exim -q
 ****
 exim -odi r5.a@r5domain.ex
 ****
+exim -Mrm $msg1 $msg2 $msg3
+****
+# Using a router with no non-domain preconditions, first should write a domain-retry record.
+sudo rm DIR/spool/db/retry
+exim -odi rz.a@outside
+****
+dump retry
+# Second will find it - this is visible in debug output
+exim -d-all+route+deliver+retry -odi rz.b@outside
+****
+exim -q
+****
 no_msglog_check
 no_message_check
 no_msglog_check
 no_message_check
diff --git a/test/stderr/0264 b/test/stderr/0264
new file mode 100644 (file)
index 0000000..7e86817
--- /dev/null
@@ -0,0 +1,105 @@
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+Writing spool header file: TESTSUITE/spool//input//hdr.10HmbJ-0005vi-00
+DSN: Write SPOOL: -dsn_envid NULL
+DSN: Write SPOOL  :-dsn_ret 0
+DSN: Flags: 0x0
+DSN: **** SPOOL_OUT - address: <rz.b@outside> errorsto: <NULL> orcpt: <NULL> dsn_flags: 0x0
+Renaming spool header file: TESTSUITE/spool//input//10HmbJ-0005vi-00-H
+LOG: MAIN
+  <= CALLER@test.ex U=CALLER P=local S=sss
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+trusted user
+admin user
+dropping to exim gid; retaining priv uid
+delivering 10HmbJ-0005vi-00
+Trying spool file TESTSUITE/spool//input//10HmbJ-0005vi-00-D
+reading spool file 10HmbJ-0005vi-00-H
+user=CALLER uid=CALLER_UID gid=CALLER_GID sender=CALLER@test.ex
+sender_local=1 ident=CALLER
+Non-recipients:
+Empty Tree
+---- End of tree ----
+recipients_count=1
+**** SPOOL_IN - No additional fields
+body_linecount=0 message_linecount=7
+DSN: set orcpt:   flags: 0x0
+Delivery address list:
+  rz.b@outside 
+locking TESTSUITE/spool/db/retry.lockfile
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering: rz.b@outside
+unique = rz.b@outside
+have domain  retry record; next_try = now+0
+no   address retry record
+rz.b@outside: queued for routing
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+routing rz.b@outside
+--------> r1 router <--------
+local_part=rz.b domain=outside
+checking domains
+r1 router skipped: domains mismatch
+--------> r2 router <--------
+local_part=rz.b domain=outside
+checking domains
+r2 router skipped: domains mismatch
+--------> r3 router <--------
+local_part=rz.b domain=outside
+checking local_parts
+r3 router skipped: local_parts mismatch
+--------> r4 router <--------
+local_part=rz.b domain=outside
+checking local_parts
+r4 router skipped: local_parts mismatch
+--------> r5 router <--------
+local_part=rz.b domain=outside
+checking local_parts
+r5 router skipped: local_parts mismatch
+--------> r_remain router <--------
+local_part=rz.b domain=outside
+calling r_remain router
+rda_interpret (string): ':defer: not just now'
+expanded: ':defer: not just now'
+file is not a filter file
+parse_forward_list: :defer: not just now
+extract item: :defer: not just now
+r_remain router: defer for rz.b@outside
+  message: not just now
+added retry item for R:outside: errno=-1 more_errno=dd flags=0
+post-process rz.b@outside (1)
+LOG: MAIN
+  == rz.b@outside R=r_remain defer (-1): not just now
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+After routing:
+  Local deliveries:
+  Remote deliveries:
+  Failed addresses:
+  Deferred addresses:
+    rz.b@outside
+>>>>>>>>>>>>>>>> deliveries are done >>>>>>>>>>>>>>>>
+Processing retry items
+Succeeded addresses:
+Failed addresses:
+Deferred addresses:
+ rz.b@outside
+locking TESTSUITE/spool/db/retry.lockfile
+retry for R:outside = * 0 0
+failing_interval=ttt message_age=ttt
+Writing retry data for R:outside
+  first failed=dddd last try=dddd next try=+300 expired=0
+  errno=-1 more_errno=dd not just now
+end of retry processing
+time on queue = 0s  id 10HmbJ-0005vi-00  addr rz.b@outside
+warning counts: required 0 done 0
+delivery deferred: update_spool=1 header_rewritten=0
+Writing spool header file: TESTSUITE/spool//input//hdr.10HmbJ-0005vi-00
+DSN: Write SPOOL: -dsn_envid NULL
+DSN: Write SPOOL  :-dsn_ret 0
+DSN: Flags: 0x0
+DSN: **** SPOOL_OUT - address: <rz.b@outside> errorsto: <NULL> orcpt: <NULL> dsn_flags: 0x0
+Renaming spool header file: TESTSUITE/spool//input//10HmbJ-0005vi-00-H
+end delivery of 10HmbJ-0005vi-00
+>>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
index 2c8bffcc7b9e170a2d167389ff65d9f9df14bcc7..cc30e566832da80541746e79dc11b9379786555e 100644 (file)
@@ -910,7 +910,6 @@ After routing:
 locking TESTSUITE/spool/db/retry.lockfile
 LOG: MAIN
   => CALLER <CALLER@myhost.test.ex> P=<> R=real T=real
 locking TESTSUITE/spool/db/retry.lockfile
 LOG: MAIN
   => CALLER <CALLER@myhost.test.ex> P=<> R=real T=real
-locking TESTSUITE/spool/db/retry.lockfile
 LOG: MAIN
   Completed
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 LOG: MAIN
   Completed
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
@@ -1019,7 +1018,6 @@ locking TESTSUITE/spool/db/retry.lockfile
 LOG: MAIN
   => h1 <h1@myhost.test.ex> P=<CALLER@myhost.test.ex> R=ut8 T=ut1
 log writing disabled
 LOG: MAIN
   => h1 <h1@myhost.test.ex> P=<CALLER@myhost.test.ex> R=ut8 T=ut1
 log writing disabled
-locking TESTSUITE/spool/db/retry.lockfile
 LOG: MAIN
   Completed
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 LOG: MAIN
   Completed
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
index 48b789e6a5f2c490d4bc23005856df5943268b26..4fbb7da8789a5e82d33e827bad1175cbb7d1be66 100644 (file)
@@ -12,3 +12,12 @@ Message 10HmbB-0005vi-00 has been removed
 Message 10HmbC-0005vi-00 has been removed
 Message 10HmbD-0005vi-00 has been removed
 Message 10HmbE-0005vi-00 has been removed
 Message 10HmbC-0005vi-00 has been removed
 Message 10HmbD-0005vi-00 has been removed
 Message 10HmbE-0005vi-00 has been removed
++++++++++++++++++++++++++++
+  R:r4.a@outside -1 0 not just now
+first failed = time last try = time2 next try = time2 + 300
+Message 10HmbF-0005vi-00 has been removed
+Message 10HmbG-0005vi-00 has been removed
+Message 10HmbH-0005vi-00 has been removed
++++++++++++++++++++++++++++
+  R:outside -1 0 not just now
+first failed = time last try = time2 next try = time2 + 300