Retry: always use interface, if set, for retry DB key. Bug 1678
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 19 Sep 2015 12:59:22 +0000 (13:59 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 19 Sep 2015 15:31:37 +0000 (16:31 +0100)
Even constant values must be used, as multiple transports with
different values may be in play and should be kept distinct.

doc/doc-txt/ChangeLog
src/src/functions.h
src/src/smtp_out.c
src/src/transports/smtp.c
src/src/verify.c
test/confs/0610 [new file with mode: 0644]
test/log/0610 [new file with mode: 0644]
test/rejectlog/0610 [new file with mode: 0644]
test/scripts/0000-Basic/0610 [new file with mode: 0644]
test/stderr/0143
test/stdout/0610 [new file with mode: 0644]

index 37d66617e0520e8fdbe42fa0f98ba6f576864444..14f0dc737cca707a81482d1551f37a03a53120a6 100644 (file)
@@ -49,6 +49,11 @@ HS/02 Add the Exim version string to the process info.  This way exiwhat
 JH/06 Bug 1395: time-limit cacheing of DNS lookups, to the TTL value.  This may
       matter for fast-change records such as DNSBLs.
 
 JH/06 Bug 1395: time-limit cacheing of DNS lookups, to the TTL value.  This may
       matter for fast-change records such as DNSBLs.
 
+JH/07 Bug 1678: Always record an interface option value, if set,  as part of a
+      retry record, even if constant.  There may be multiple transports with
+      different interface settings and the retry behaviour needs to be kept
+      distinct.
+
 
 Exim version 4.86
 -----------------
 
 Exim version 4.86
 -----------------
index 4af0017c1d4f844dd7d339a0c189e25d789303c4..fcfe7467571a44ca93e00bbb2657b69ede34789b 100644 (file)
@@ -377,7 +377,7 @@ extern int     smtp_sock_connect(host_item *, int, int, uschar *,
 extern int     smtp_feof(void);
 extern int     smtp_ferror(void);
 extern uschar *smtp_get_connection_info(void);
 extern int     smtp_feof(void);
 extern int     smtp_ferror(void);
 extern uschar *smtp_get_connection_info(void);
-extern BOOL    smtp_get_interface(uschar *, int, address_item *, BOOL *,
+extern BOOL    smtp_get_interface(uschar *, int, address_item *,
                  uschar **, uschar *);
 extern BOOL    smtp_get_port(uschar *, address_item *, int *, uschar *);
 extern int     smtp_getc(void);
                  uschar **, uschar *);
 extern BOOL    smtp_get_port(uschar *, address_item *, int *, uschar *);
 extern int     smtp_getc(void);
index 88dde8301fd694574388ec0ec14c36df827853fd..d32ef89b5dae2e727724a6944b64444375b0b774 100644 (file)
@@ -26,7 +26,6 @@ Arguments:
                which case the function does nothing
   host_af    AF_INET or AF_INET6 for the outgoing IP address
   addr       the mail address being handled (for setting errors)
                which case the function does nothing
   host_af    AF_INET or AF_INET6 for the outgoing IP address
   addr       the mail address being handled (for setting errors)
-  changed    if not NULL, set TRUE if expansion actually changed istring
   interface  point this to the interface
   msg        to add to any error message
 
   interface  point this to the interface
   msg        to add to any error message
 
@@ -36,7 +35,7 @@ Returns:     TRUE on success, FALSE on failure, with error message
 
 BOOL
 smtp_get_interface(uschar *istring, int host_af, address_item *addr,
 
 BOOL
 smtp_get_interface(uschar *istring, int host_af, address_item *addr,
-  BOOL *changed, uschar **interface, uschar *msg)
+  uschar **interface, uschar *msg)
 {
 const uschar * expint;
 uschar *iface;
 {
 const uschar * expint;
 uschar *iface;
@@ -54,8 +53,6 @@ if (expint == NULL)
   return FALSE;
   }
 
   return FALSE;
   }
 
-if (changed != NULL) *changed = expint != istring;
-
 while (isspace(*expint)) expint++;
 if (*expint == 0) return TRUE;
 
 while (isspace(*expint)) expint++;
 if (*expint == 0) return TRUE;
 
index ac40460f1a7c30a42a07c3c92bcef76b91df6690..f129cce9b57bea6da095ee9f425677eb0f7161c9 100644 (file)
@@ -3259,7 +3259,6 @@ for (cutoff_retry = 0; expired &&
     BOOL serialized = FALSE;
     BOOL host_is_expired = FALSE;
     BOOL message_defer = FALSE;
     BOOL serialized = FALSE;
     BOOL host_is_expired = FALSE;
     BOOL message_defer = FALSE;
-    BOOL ifchanges = FALSE;
     BOOL some_deferred = FALSE;
     address_item *first_addr = NULL;
     uschar *interface = NULL;
     BOOL some_deferred = FALSE;
     address_item *first_addr = NULL;
     uschar *interface = NULL;
@@ -3435,15 +3434,18 @@ for (cutoff_retry = 0; expired &&
     if (Ustrcmp(pistring, ":25") == 0) pistring = US"";
 
     /* Select IPv4 or IPv6, and choose an outgoing interface. If the interface
     if (Ustrcmp(pistring, ":25") == 0) pistring = US"";
 
     /* Select IPv4 or IPv6, and choose an outgoing interface. If the interface
-    string changes upon expansion, we must add it to the key that is used for
-    retries, because connections to the same host from a different interface
-    should be treated separately. */
+    string is set, even if constant (as different transports can have different
+    constant settings), we must add it to the key that is used for retries,
+    because connections to the same host from a different interface should be
+    treated separately. */
 
     host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET : AF_INET6;
 
     host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET : AF_INET6;
-    if (!smtp_get_interface(ob->interface, host_af, addrlist, &ifchanges,
-         &interface, tid))
-      return FALSE;
-    if (ifchanges) pistring = string_sprintf("%s/%s", pistring, interface);
+    if ((rs = ob->interface) && *rs)
+      {
+      if (!smtp_get_interface(rs, host_af, addrlist, &interface, tid))
+       return FALSE;
+      pistring = string_sprintf("%s/%s", pistring, interface);
+      }
 
     /* The first time round the outer loop, check the status of the host by
     inspecting the retry data. The second time round, we are interested only
 
     /* The first time round the outer loop, check the status of the host by
     inspecting the retry data. The second time round, we are interested only
index dc9c58224134a64385a0e934b8d658c29b4384f6..cb88f28a91f82137d1a02a53a09c8f4f979f5b66 100644 (file)
@@ -444,7 +444,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
 
          host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET:AF_INET6;
 
 
          host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET:AF_INET6;
 
-         if (!smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
+         if (!smtp_get_interface(tf->interface, host_af, addr, &interface,
                  US"callout") ||
              !smtp_get_port(tf->port, addr, &port, US"callout"))
            log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address,
                  US"callout") ||
              !smtp_get_port(tf->port, addr, &port, US"callout"))
            log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address,
@@ -579,7 +579,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
     deliver_domain = addr->domain;
     transport_name = addr->transport->name;
 
     deliver_domain = addr->domain;
     transport_name = addr->transport->name;
 
-    if (  !smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
+    if (  !smtp_get_interface(tf->interface, host_af, addr, &interface,
             US"callout")
        || !smtp_get_port(tf->port, addr, &port, US"callout")
        )
             US"callout")
        || !smtp_get_port(tf->port, addr, &port, US"callout")
        )
diff --git a/test/confs/0610 b/test/confs/0610
new file mode 100644 (file)
index 0000000..f805c08
--- /dev/null
@@ -0,0 +1,65 @@
+# Exim test configuration 0610
+
+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
+log_selector = +sender_on_delivery
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+acl_smtp_connect = conn_chk
+acl_smtp_rcpt = accept
+
+untrusted_set_sender = *
+queue_only
+queue_run_in_order
+
+# ----- ACL -----
+
+begin acl
+
+conn_chk:
+  defer        condition = ${if eq {SERVER}{server}}
+  accept
+
+# ----- Routers -----
+
+begin routers
+
+client:
+  driver = accept
+  transport = $sender_address_local_part
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+  driver = smtp
+  allow_localhost
+  hosts = 127.0.0.1
+  port = PORT_D
+  interface = 127.0.0.1
+
+t2:
+  driver = smtp
+  allow_localhost
+  hosts = 127.0.0.1
+  port = PORT_D
+  interface = 127.0.0.2
+
+# ----- Retry -----
+
+begin retry
+
+* * F,5d,10s
+
+# End
+
diff --git a/test/log/0610 b/test/log/0610
new file mode 100644 (file)
index 0000000..d9e584b
--- /dev/null
@@ -0,0 +1,13 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= t1@dustyshoes.tld U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= t2@dustybelt.tld U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 Start queue run: pid=pppp -qq
+1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 Temporary local problem - please try later
+1999-03-02 09:44:33 10HmaX-0005vi-00 == fred@anotherone.tld R=client T=t1 defer (0) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 Temporary local problem - please try later
+1999-03-02 09:44:33 10HmaY-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 Temporary local problem - please try later
+1999-03-02 09:44:33 10HmaY-0005vi-00 == fred@anotherone.tld R=client T=t2 defer (0) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 Temporary local problem - please try later
+1999-03-02 09:44:33 End queue run: pid=pppp -qq
+
+******** 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 H=[127.0.0.1] temporarily rejected connection in "connect" ACL
+1999-03-02 09:44:33 H=[127.0.0.2] temporarily rejected connection in "connect" ACL
diff --git a/test/rejectlog/0610 b/test/rejectlog/0610
new file mode 100644 (file)
index 0000000..c1384b3
--- /dev/null
@@ -0,0 +1,4 @@
+
+******** SERVER ********
+1999-03-02 09:44:33 H=[127.0.0.1] temporarily rejected connection in "connect" ACL
+1999-03-02 09:44:33 H=[127.0.0.2] temporarily rejected connection in "connect" ACL
diff --git a/test/scripts/0000-Basic/0610 b/test/scripts/0000-Basic/0610
new file mode 100644 (file)
index 0000000..ff690f6
--- /dev/null
@@ -0,0 +1,33 @@
+# retry: transport with fixed interface
+# Exim test configuration 0610
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+exim -bs
+MAIL FROM:<t1@dustyshoes.tld>
+RCPT TO:<fred@anotherone.tld>
+DATA
+This is a test message.
+.
+RSET
+MAIL FROM:<t2@dustybelt.tld>
+RCPT TO:<fred@anotherone.tld>
+DATA
+Subject: second
+
+This is a second test message.
+.
+QUIT
+****
+#
+#
+exim -qq
+****
+#
+# Should get two separate retry records.
+dump retry
+#
+#
+killdaemon
+no_msglog_check
index 054d65d28449f59e6556716d81c2fef053219a4b..cff499045200bded613e794c9400d245153a0412 100644 (file)
@@ -15,7 +15,7 @@ transport_name <my_smtp>
 my_smtp transport entered
   userx@domain.com
 checking status of 127.0.0.1
 my_smtp transport entered
   userx@domain.com
 checking status of 127.0.0.1
-127.0.0.1 [127.0.0.1]:1111 status = usable
+127.0.0.1 [127.0.0.1]:1111/ip4.ip4.ip4.ip4 status = usable
 delivering 10HmaX-0005vi-00 to 127.0.0.1 [127.0.0.1] (userx@domain.com)
 Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
   SMTP<< 220 ESMTP
 delivering 10HmaX-0005vi-00 to 127.0.0.1 [127.0.0.1] (userx@domain.com)
 Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
   SMTP<< 220 ESMTP
diff --git a/test/stdout/0610 b/test/stdout/0610
new file mode 100644 (file)
index 0000000..24291b5
--- /dev/null
@@ -0,0 +1,16 @@
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaX-0005vi-00\r
+250 Reset OK\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaY-0005vi-00\r
+221 the.local.host.name closing connection\r
++++++++++++++++++++++++++++
+  T:127.0.0.1:127.0.0.1:1225/127.0.0.1 0 65 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 Temporary local problem - please try later
+first failed = time last try = time2 next try = time2 + 10
+  T:127.0.0.1:127.0.0.1:1225/127.0.0.2 0 65 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 Temporary local problem - please try later
+first failed = time last try = time2 next try = time2 + 10