[exim-cvs] Continued-transport: check interface option. Bug…

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Continued-transport: check interface option. Bug 1141
Gitweb: https://git.exim.org/exim.git/commitdiff/237b2df13410c86663e788be831de721a782525a
Commit:     237b2df13410c86663e788be831de721a782525a
Parent:     49dc12554e8abfa11b764da14c65b93c545b6243
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Tue Jul 30 13:33:37 2024 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Tue Jul 30 13:33:37 2024 +0100


    Continued-transport: check interface option.  Bug 1141
---
 doc/doc-txt/ChangeLog        |  4 ++++
 src/src/deliver.c            |  2 +-
 src/src/transports/smtp.c    | 28 +++++++++++++++++++++++++
 test/confs/0638              | 49 ++++++++++++++++++++++++++++++++++++++++++++
 test/log/0638                | 13 ++++++++++++
 test/scripts/0000-Basic/0638 | 20 ++++++++++++++++++
 6 files changed, 115 insertions(+), 1 deletion(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 7a4f1757e..a02911cae 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -27,6 +27,10 @@ JH/05 Fix hintsdb support for dbmjz when compiled using sqlite3. Previously
       uses keys with embedded NUL bytes.  The builtin hintsdb use is unaffected,
       but installations using dbmjz will need to rebuild those DBs.


+JH/06 Bug 1141: When operating a continued-connection transport, verify that
+      the interface option, if specified, evaluates to match the connection.
+      Previously, a queued message for the same host was sent without checking.
+
 Exim version 4.98
 -----------------


diff --git a/src/src/deliver.c b/src/src/deliver.c
index 9d26d07c0..67ba505d1 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -5167,7 +5167,7 @@ do_remote_deliveries par_reduce par_wait par_read_pipe
     wait-db ones, but for all continue-more ones (though any after the
     delivery proc has the info are pointless). */


-    if (continue_hostname)
+    if (continue_hostname && continue_fd >= 0)
       {
        {
     uschar * ptr = big_buffer;
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 769c5d235..03de9dcad 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -5614,6 +5614,31 @@ retry_non_continued:
     {
     if (!smtp_get_interface(s, host_af, addrlist, &interface, tid))
       return FALSE;
+
+    if (continue_sequence > 1)
+      {
+      union sockaddr_46 interface_sock;
+      EXIM_SOCKLEN_T size = sizeof(interface_sock);
+      const uschar * local_ip_addr;
+
+      /* Assume the connection is on fd 0 */
+      if (getsockname(0, (struct sockaddr *) &interface_sock, &size) < 0)
+        {
+        DEBUG(D_transport)
+          debug_printf_indent("failed getsockname: %s\n", strerror(errno));
+        return FALSE;
+        }
+      local_ip_addr = host_ntoa(-1, &interface_sock, NULL, &sending_port);
+      if (Ustrcmp(interface, local_ip_addr) != 0)
+        {
+        DEBUG(D_transport) debug_printf_indent(
+          "tpt interface option mismatch with continued-connection\n");
+        /* Close the conn and recheck retry info */
+        continue_host_tried = FALSE;
+        break;
+        }
+      }
+
     pistring = string_sprintf("%s/%s", pistring, interface);
     }
       }
@@ -6039,6 +6064,7 @@ retry_non_continued:
     int fd = cutthrough.cctx.sock >= 0 ? cutthrough.cctx.sock : 0;


     DEBUG(D_transport) debug_printf("no hosts match already-open connection\n");
+    DEBUG(D_transport) debug_printf("  SMTP>>QUIT\n");
 #ifndef DISABLE_TLS
     /* A TLS conn could be open for a cutthrough, but not for a plain continued-
     transport */
@@ -6055,6 +6081,8 @@ retry_non_continued:
 #else
       (void) write(fd, US"QUIT\r\n", 6);
 #endif
+
+    DEBUG(D_transport) debug_printf("  SMTP(close)>>\n");
     (void) close(fd);
     cutthrough.cctx.sock = -1;
     continue_hostname = NULL;
diff --git a/test/confs/0638 b/test/confs/0638
new file mode 100644
index 000000000..d9171f349
--- /dev/null
+++ b/test/confs/0638
@@ -0,0 +1,49 @@
+# Exim test configuration 0143
+
+.include DIR/aux-var/std_conf_prefix
+
+SERVER=
+primary_hostname = myhost.test.ex
+
+# ----- Main settings -----
+
+log_selector = +received_recipients
+domainlist local_domains = test.ex : *.test.ex
+
+acl_not_smtp = accept set acl_m_control = CONTROL
+acl_smtp_rcpt = accept
+
+# ----- Routers -----
+
+begin routers
+
+server_blackhole:
+  driver =    redirect
+  condition =    ${if eq {SERVER}{server}}
+  data =    :blackhole:
+
+my_main_router:
+  driver =    manualroute
+  route_list =    * 127.0.0.1
+  self =    send
+  transport =    my_smtp
+  no_more
+
+
+# ----- Transports -----
+
+begin transports
+
+my_smtp:
+  driver =    smtp
+  interface =    $acl_m_control
+  port =    PORT_D
+  hosts_try_fastopen = :
+
+
+# ----- Retry -----
+begin retry
+
+* * F,5d,10s
+
+# End
diff --git a/test/log/0638 b/test/log/0638
new file mode 100644
index 000000000..a57174d84
--- /dev/null
+++ b/test/log/0638
@@ -0,0 +1,13 @@
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= CALLER@??? U=CALLER P=local S=sss for userx@???
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 H=127.0.0.1 [127.0.0.1] Connection refused
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 == userx@??? R=my_main_router T=my_smtp defer (dd): Connection refused
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 <= CALLER@??? U=CALLER P=local S=sss for usery@???
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 => usery@??? R=my_main_router T=my_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaZ-000000005vi-0000"
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 Completed
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 == userx@??? R=my_main_router T=my_smtp defer (-54): some host address lookups failed and retry time not reached for other hosts or connection limit reached for 'test.ex'
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=p1234, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-000000005vi-0000@??? for usery@???
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 => :blackhole: <usery@???> R=server_blackhole
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 Completed
diff --git a/test/scripts/0000-Basic/0638 b/test/scripts/0000-Basic/0638
new file mode 100644
index 000000000..4b5765680
--- /dev/null
+++ b/test/scripts/0000-Basic/0638
@@ -0,0 +1,20 @@
+# transport interface option and queued message
+need_ipv4
+#
+# This one fails to connect; creates a retry record and is queued
+exim -odf -DCONTROL=127.0.0.1 userx@???
+****
+#
+# Now put a server up
+exim -bd -DSERVER=server -oX PORT_D
+****
+#
+# Send another, using a different local IP
+# That should be received by the server, but the same conn should
+# NOT be used for the first message
+exim -odf -DCONTROL=HOSTIPV4 usery@???
+****
+#
+killdaemon
+no_msglog_check
+no_message_check


--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/