CHUNKING: fix availability on continued-transport
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 3 Apr 2022 17:10:09 +0000 (18:10 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 3 Apr 2022 17:14:13 +0000 (18:14 +0100)
doc/doc-txt/ChangeLog
src/src/transports/smtp.c
test/log/1165
test/scripts/1100-Basic-TLS/1165

index 913518dea68ea2d464c2ea2b38349ac20a088dd8..93eac06a1427f9e9deb0b756567fbf6540fc0f09 100644 (file)
@@ -112,6 +112,10 @@ JH/25 Taint-check exec arguments for transport-initiated external processes.
       the command line may be tainted, in default mode the executable name
       may not be tainted.
 
       the command line may be tainted, in default mode the executable name
       may not be tainted.
 
+JH/26 Fix CHUNKING on a continued-transport.  Previously the usabliility of
+      the the facility was not passed across execs, and only the first message
+      passed over a connection could use BDAT; any further ones using DATA.
+
 
 Exim version 4.95
 -----------------
 
 Exim version 4.95
 -----------------
index 19b06d8a928f0f13e2c3e86335aa0bac4e67864a..d897c691eb2bffc86748f232daacf2ae11303131 100644 (file)
@@ -2934,18 +2934,18 @@ if (   !continue_hostname
       smtp_peer_options & OPTION_PIPE ? "" : "not ");
 
     if (  sx->peer_offered & OPTION_CHUNKING
       smtp_peer_options & OPTION_PIPE ? "" : "not ");
 
     if (  sx->peer_offered & OPTION_CHUNKING
-       && verify_check_given_host(CUSS &ob->hosts_try_chunking, sx->conn_args.host) != OK)
-      sx->peer_offered &= ~OPTION_CHUNKING;
+       && verify_check_given_host(CUSS &ob->hosts_try_chunking, sx->conn_args.host) == OK)
+      smtp_peer_options |= OPTION_CHUNKING;
 
 
-    if (sx->peer_offered & OPTION_CHUNKING)
+    if (smtp_peer_options & OPTION_CHUNKING)
       DEBUG(D_transport) debug_printf("CHUNKING usable\n");
 
 #ifndef DISABLE_PRDR
     if (  sx->peer_offered & OPTION_PRDR
       DEBUG(D_transport) debug_printf("CHUNKING usable\n");
 
 #ifndef DISABLE_PRDR
     if (  sx->peer_offered & OPTION_PRDR
-       && verify_check_given_host(CUSS &ob->hosts_try_prdr, sx->conn_args.host) != OK)
-      sx->peer_offered &= ~OPTION_PRDR;
+       && verify_check_given_host(CUSS &ob->hosts_try_prdr, sx->conn_args.host) == OK)
+      smtp_peer_options |= OPTION_PRDR;
 
 
-    if (sx->peer_offered & OPTION_PRDR)
+    if (smtp_peer_options & OPTION_PRDR)
       DEBUG(D_transport) debug_printf("PRDR usable\n");
 #endif
 
       DEBUG(D_transport) debug_printf("PRDR usable\n");
 #endif
 
@@ -3216,7 +3216,7 @@ Or just forget about lines?  Or inflate by a fixed proportion? */
 request that */
 
 sx->prdr_active = FALSE;
 request that */
 
 sx->prdr_active = FALSE;
-if (sx->peer_offered & OPTION_PRDR)
+if (smtp_peer_options & OPTION_PRDR)
   for (address_item * addr = addrlist; addr; addr = addr->next)
     if (addr->transport_return == PENDING_DEFER)
       {
   for (address_item * addr = addrlist; addr; addr = addr->next)
     if (addr->transport_return == PENDING_DEFER)
       {
@@ -3777,7 +3777,7 @@ if (tblock->filter_command)
   if (  transport_filter_argv
      && *transport_filter_argv
      && **transport_filter_argv
   if (  transport_filter_argv
      && *transport_filter_argv
      && **transport_filter_argv
-     && sx->peer_offered & OPTION_CHUNKING
+     && smtp_peer_options & OPTION_CHUNKING
 #ifndef DISABLE_DKIM
     /* When dkim signing, chunking is handled even with a transport-filter */
      && !(ob->dkim.dkim_private_key && ob->dkim.dkim_domain && ob->dkim.dkim_selector)
 #ifndef DISABLE_DKIM
     /* When dkim signing, chunking is handled even with a transport-filter */
      && !(ob->dkim.dkim_private_key && ob->dkim.dkim_domain && ob->dkim.dkim_selector)
@@ -3785,7 +3785,7 @@ if (tblock->filter_command)
 #endif
      )
     {
 #endif
      )
     {
-    sx->peer_offered &= ~OPTION_CHUNKING;
+    smtp_peer_options &= ~OPTION_CHUNKING;
     DEBUG(D_transport) debug_printf("CHUNKING not usable due to transport filter\n");
     }
   }
     DEBUG(D_transport) debug_printf("CHUNKING not usable due to transport filter\n");
     }
   }
@@ -3862,7 +3862,7 @@ are pipelining. The responses are all handled by sync_responses().
 If using CHUNKING, do not send a BDAT until we know how big a chunk we want
 to send is. */
 
 If using CHUNKING, do not send a BDAT until we know how big a chunk we want
 to send is. */
 
-if (  !(sx->peer_offered & OPTION_CHUNKING)
+if (  !(smtp_peer_options & OPTION_CHUNKING)
    && (sx->ok || (pipelining_active && !mua_wrapper)))
   {
   int count = smtp_write_command(sx, SCMD_FLUSH, "DATA\r\n");
    && (sx->ok || (pipelining_active && !mua_wrapper)))
   {
   int count = smtp_write_command(sx, SCMD_FLUSH, "DATA\r\n");
@@ -3899,7 +3899,7 @@ well as body. Set the appropriate timeout value to be used for each chunk.
 (Haven't been able to make it work using select() for writing yet.) */
 
 if (  !sx->ok
 (Haven't been able to make it work using select() for writing yet.) */
 
 if (  !sx->ok
-   && (!(sx->peer_offered & OPTION_CHUNKING) || !pipelining_active))
+   && (!(smtp_peer_options & OPTION_CHUNKING) || !pipelining_active))
   {
   /* Save the first address of the next batch. */
   sx->first_addr = sx->next_addr;
   {
   /* Save the first address of the next batch. */
   sx->first_addr = sx->next_addr;
@@ -3928,7 +3928,7 @@ else
   of responses.  The callback needs a whole bunch of state so set up
   a transport-context structure to be passed around. */
 
   of responses.  The callback needs a whole bunch of state so set up
   a transport-context structure to be passed around. */
 
-  if (sx->peer_offered & OPTION_CHUNKING)
+  if (smtp_peer_options & OPTION_CHUNKING)
     {
     tctx.check_string = tctx.escape_string = NULL;
     tctx.options |= topt_use_bdat;
     {
     tctx.check_string = tctx.escape_string = NULL;
     tctx.options |= topt_use_bdat;
@@ -3953,7 +3953,7 @@ else
   transport_write_timeout = ob->data_timeout;
   smtp_command = US"sending data block";   /* For error messages */
   DEBUG(D_transport|D_v)
   transport_write_timeout = ob->data_timeout;
   smtp_command = US"sending data block";   /* For error messages */
   DEBUG(D_transport|D_v)
-    if (sx->peer_offered & OPTION_CHUNKING)
+    if (smtp_peer_options & OPTION_CHUNKING)
       debug_printf("         will write message using CHUNKING\n");
     else
       debug_printf("  SMTP>> writing message and terminating \".\"\n");
       debug_printf("         will write message using CHUNKING\n");
     else
       debug_printf("  SMTP>> writing message and terminating \".\"\n");
@@ -4005,7 +4005,7 @@ else
   If we can, we want the message-write to not flush (the tail end of) its data out.  */
 
   if (  sx->pipelining_used
   If we can, we want the message-write to not flush (the tail end of) its data out.  */
 
   if (  sx->pipelining_used
-     && (sx->ok && sx->completed_addr || sx->peer_offered & OPTION_CHUNKING)
+     && (sx->ok && sx->completed_addr || smtp_peer_options & OPTION_CHUNKING)
      && sx->send_quit
      && !(sx->first_addr || f.continue_more)
      && f.deliver_firsttime
      && sx->send_quit
      && !(sx->first_addr || f.continue_more)
      && f.deliver_firsttime
@@ -4103,7 +4103,7 @@ else
       }
     }
 
       }
     }
 
-  if (sx->peer_offered & OPTION_CHUNKING && sx->cmd_count > 1)
+  if (smtp_peer_options & OPTION_CHUNKING && sx->cmd_count > 1)
     {
     /* Reap any outstanding MAIL & RCPT commands, but not a DATA-go-ahead */
     switch(sync_responses(sx, sx->cmd_count-1, 0))
     {
     /* Reap any outstanding MAIL & RCPT commands, but not a DATA-go-ahead */
     switch(sync_responses(sx, sx->cmd_count-1, 0))
@@ -4276,7 +4276,7 @@ else
 #ifndef DISABLE_PRDR
       if (sx->prdr_active) setflag(addr, af_prdr_used);
 #endif
 #ifndef DISABLE_PRDR
       if (sx->prdr_active) setflag(addr, af_prdr_used);
 #endif
-      if (sx->peer_offered & OPTION_CHUNKING) setflag(addr, af_chunking_used);
+      if (smtp_peer_options & OPTION_CHUNKING) setflag(addr, af_chunking_used);
       flag = '-';
 
 #ifndef DISABLE_PRDR
       flag = '-';
 
 #ifndef DISABLE_PRDR
index 54193cd0687ea3d24bf128257ec86309d410d768..a8e0b696dbaed6f94e30fab1a2f06e563ff50e3a 100644 (file)
@@ -1,7 +1,19 @@
 2017-07-30 18:51:05.712 10HmaX-0005vi-00 <= this-user@testhost.test.ex U=this-user P=local S=sss for other-user@test.ex
 2017-07-30 18:51:05.712 10HmaX-0005vi-00 => other-user@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes K C="250- 3nn byte chunk, total 3nn\\n250 OK id=10HmaY-0005vi-00"
 2017-07-30 18:51:05.712 10HmaX-0005vi-00 Completed
 2017-07-30 18:51:05.712 10HmaX-0005vi-00 <= this-user@testhost.test.ex U=this-user P=local S=sss for other-user@test.ex
 2017-07-30 18:51:05.712 10HmaX-0005vi-00 => other-user@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes K C="250- 3nn byte chunk, total 3nn\\n250 OK id=10HmaY-0005vi-00"
 2017-07-30 18:51:05.712 10HmaX-0005vi-00 Completed
+2017-07-30 18:51:05.712 10HmaY-0005vi-00 removed by CALLER
+2017-07-30 18:51:05.712 10HmaY-0005vi-00 Completed
+2017-07-30 18:51:05.712 10HmaZ-0005vi-00 <= this-user@testhost.test.ex U=this-user P=local S=sss for first-user@test.ex
+2017-07-30 18:51:05.712 10HmbA-0005vi-00 <= this-user@testhost.test.ex U=this-user P=local S=sss for second-user@test.ex
+2017-07-30 18:51:05.712 Start queue run: pid=pppp -qq
+2017-07-30 18:51:05.712 10HmaZ-0005vi-00 => first-user@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes K C="250- 3nn byte chunk, total 3nn\\n250 OK id=10HmbB-0005vi-00"
+2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Completed
+2017-07-30 18:51:05.712 10HmbA-0005vi-00 => second-user@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]* X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no K C="250- 3nn byte chunk, total 3nn\\n250 OK id=10HmbC-0005vi-00"
+2017-07-30 18:51:05.712 10HmbA-0005vi-00 Completed
+2017-07-30 18:51:05.712 End queue run: pid=pppp -qq
 
 ******** SERVER ********
 2017-07-30 18:51:05.712 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_S
 2017-07-30 18:51:05.712 10HmaY-0005vi-00 <= <> H=localhost (testhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no K S=sss id=E10HmaX-0005vi-00@testhost.test.ex for other-user@test.ex
 
 ******** SERVER ********
 2017-07-30 18:51:05.712 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_S
 2017-07-30 18:51:05.712 10HmaY-0005vi-00 <= <> H=localhost (testhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no K S=sss id=E10HmaX-0005vi-00@testhost.test.ex for other-user@test.ex
+2017-07-30 18:51:05.712 10HmbB-0005vi-00 <= <> H=localhost (testhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no K S=sss id=E10HmaZ-0005vi-00@testhost.test.ex for first-user@test.ex
+2017-07-30 18:51:05.712 10HmbC-0005vi-00 <= <> H=localhost (testhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no K S=sss id=E10HmbA-0005vi-00@testhost.test.ex for second-user@test.ex
index 58e5163c5a3564f970d4915895ca72b6173895f0..d339b82de05310850079db721832e61ef9651b95 100644 (file)
@@ -2,8 +2,22 @@
 gnutls
 exim -DSERVER=server -DSRV=tls -bd -oX PORT_S
 ****
 gnutls
 exim -DSERVER=server -DSRV=tls -bd -oX PORT_S
 ****
+#
+# Single message
 exim -oMt this-user -f this-user -odf other-user@test.ex
 Test message. Contains FF: ÿ
 ****
 exim -oMt this-user -f this-user -odf other-user@test.ex
 Test message. Contains FF: ÿ
 ****
+exim -Mrm $msg1
+****
+#
+# Multiple messages
+exim -oMt this-user -f this-user -odq first-user@test.ex
+****
+exim -oMt this-user -f this-user -odq second-user@test.ex
+****
+exim -DALLOW=queue_run_in_order -qq
+****
+#
 killdaemon
 no_msglog_check
 killdaemon
 no_msglog_check
+no_stdout_check