pass advertised facility to continued-transport process
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 2 Aug 2016 11:10:41 +0000 (12:10 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 2 Aug 2016 21:33:21 +0000 (22:33 +0100)
doc/doc-docbook/spec.xfpt
src/src/exim.c
src/src/globals.c
src/src/globals.h
src/src/transport.c
src/src/transports/smtp.c
src/src/verify.c
test/log/0900
test/scripts/0000-Basic/0900
test/stdout/0900

index 5edeee44237308f56e8d933d873fe7d3edc40220..6302f5185581332356963b4e1a07dcc414fd9dbb 100644 (file)
@@ -27767,7 +27767,7 @@ associated with the DATA command.
 .cindex "RFC 3030" CHUNKING
 If CHUNKING was advertised and a BDAT command sequence is received,
 the &%acl_smtp_predata%& ACL is not run.
 .cindex "RFC 3030" CHUNKING
 If CHUNKING was advertised and a BDAT command sequence is received,
 the &%acl_smtp_predata%& ACL is not run.
-.XXX why not?  It should be possible, for the first BDAT.
+. XXX why not?  It should be possible, for the first BDAT.
 The &%acl_smtp_data%& is run after the last BDAT command and all of
 the data specified is received.
 .wen
 The &%acl_smtp_data%& is run after the last BDAT command and all of
 the data specified is received.
 .wen
index 01770df7338354f74b628d96b310e4ec0a234629..14e0b9d67d76a49f2cda24ed9c0a6975b7998ef3 100644 (file)
@@ -2717,76 +2717,63 @@ for (i = 1; i < argc; i++)
       break;
       }
 
       break;
       }
 
+    else if (*argrest == 'C' && argrest[1] && !argrest[2])
+      {
+       switch(argrest[1])
+       {
     /* -MCA: set the smtp_authenticated flag; this is useful only when it
     precedes -MC (see above). The flag indicates that the host to which
     Exim is connected has accepted an AUTH sequence. */
 
     /* -MCA: set the smtp_authenticated flag; this is useful only when it
     precedes -MC (see above). The flag indicates that the host to which
     Exim is connected has accepted an AUTH sequence. */
 
-    else if (Ustrcmp(argrest, "CA") == 0)
-      {
-      smtp_authenticated = TRUE;
-      break;
-      }
+       case 'A': smtp_authenticated = TRUE; break;
 
     /* -MCD: set the smtp_use_dsn flag; this indicates that the host
        that exim is connected to supports the esmtp extension DSN */
 
 
     /* -MCD: set the smtp_use_dsn flag; this indicates that the host
        that exim is connected to supports the esmtp extension DSN */
 
-    else if (Ustrcmp(argrest, "CD") == 0)
-      {
-      smtp_use_dsn = TRUE;
-      break;
-      }
+       case 'D': smtp_peer_options |= PEER_OFFERED_DSN; break;
 
     /* -MCG: set the queue name, to a non-default value */
 
 
     /* -MCG: set the queue name, to a non-default value */
 
-    else if (Ustrcmp(argrest, "CG") == 0)
-      {
-      if (++i < argc) queue_name = string_copy(argv[i]);
-      else badarg = TRUE;
-      break;
-      }
+       case 'G': if (++i < argc) queue_name = string_copy(argv[i]);
+                 else badarg = TRUE;
+                 break;
+
+    /* -MCK: the peer offered CHUNKING.  Must precede -MC */
+
+       case 'K': smtp_peer_options |= PEER_OFFERED_CHUNKING; break;
 
     /* -MCP: set the smtp_use_pipelining flag; this is useful only when
     it preceded -MC (see above) */
 
 
     /* -MCP: set the smtp_use_pipelining flag; this is useful only when
     it preceded -MC (see above) */
 
-    else if (Ustrcmp(argrest, "CP") == 0)
-      {
-      smtp_use_pipelining = TRUE;
-      break;
-      }
+       case 'P': smtp_peer_options |= PEER_OFFERED_PIPE; break;
 
     /* -MCQ: pass on the pid of the queue-running process that started
     this chain of deliveries and the fd of its synchronizing pipe; this
     is useful only when it precedes -MC (see above) */
 
 
     /* -MCQ: pass on the pid of the queue-running process that started
     this chain of deliveries and the fd of its synchronizing pipe; this
     is useful only when it precedes -MC (see above) */
 
-    else if (Ustrcmp(argrest, "CQ") == 0)
-      {
-      if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i]));
-        else badarg = TRUE;
-      if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i]));
-        else badarg = TRUE;
-      break;
-      }
+       case 'Q': if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i]));
+                 else badarg = TRUE;
+                 if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i]));
+                 else badarg = TRUE;
+                 break;
 
     /* -MCS: set the smtp_use_size flag; this is useful only when it
     precedes -MC (see above) */
 
 
     /* -MCS: set the smtp_use_size flag; this is useful only when it
     precedes -MC (see above) */
 
-    else if (Ustrcmp(argrest, "CS") == 0)
-      {
-      smtp_use_size = TRUE;
-      break;
-      }
+       case 'S': smtp_peer_options |= PEER_OFFERED_SIZE; break;
 
 
+#ifdef SUPPORT_TLS
     /* -MCT: set the tls_offered flag; this is useful only when it
     precedes -MC (see above). The flag indicates that the host to which
     Exim is connected has offered TLS support. */
 
     /* -MCT: set the tls_offered flag; this is useful only when it
     precedes -MC (see above). The flag indicates that the host to which
     Exim is connected has offered TLS support. */
 
-    #ifdef SUPPORT_TLS
-    else if (Ustrcmp(argrest, "CT") == 0)
-      {
-      tls_offered = TRUE;
-      break;
+       case 'T': smtp_peer_options |= PEER_OFFERED_TLS; break;
+#endif
+
+       default:  badarg = TRUE; break;
+       }
+       break;
       }
       }
-    #endif
 
     /* -M[x]: various operations on the following list of message ids:
        -M    deliver the messages, ignoring next retry times and thawing
 
     /* -M[x]: various operations on the following list of message ids:
        -M    deliver the messages, ignoring next retry times and thawing
index ba1336633c0ae7e505099210bd2a03254c74a169..9e6f9d34782e69ceb6f6d38f45e51bf9f6ca9017 100644 (file)
@@ -138,7 +138,6 @@ tls_support tls_out = {
 uschar *dsn_envid              = NULL;
 int     dsn_ret                = 0;
 const pcre  *regex_DSN         = NULL;
 uschar *dsn_envid              = NULL;
 int     dsn_ret                = 0;
 const pcre  *regex_DSN         = NULL;
-BOOL    smtp_use_dsn           = FALSE;
 uschar *dsn_advertise_hosts    = NULL;
 
 #ifdef SUPPORT_TLS
 uschar *dsn_advertise_hosts    = NULL;
 
 #ifdef SUPPORT_TLS
@@ -158,7 +157,6 @@ uschar *tls_eccurve            = US"prime256v1";
 # ifndef DISABLE_OCSP
 uschar *tls_ocsp_file          = NULL;
 # endif
 # ifndef DISABLE_OCSP
 uschar *tls_ocsp_file          = NULL;
 # endif
-BOOL    tls_offered            = FALSE;
 uschar *tls_privatekey         = NULL;
 BOOL    tls_remember_esmtp     = FALSE;
 uschar *tls_require_ciphers    = NULL;
 uschar *tls_privatekey         = NULL;
 BOOL    tls_remember_esmtp     = FALSE;
 uschar *tls_require_ciphers    = NULL;
@@ -1322,8 +1320,8 @@ int     smtp_rlr_base          = 0;
 double  smtp_rlr_factor        = 0.0;
 int     smtp_rlr_limit         = 0;
 int     smtp_rlr_threshold     = INT_MAX;
 double  smtp_rlr_factor        = 0.0;
 int     smtp_rlr_limit         = 0;
 int     smtp_rlr_threshold     = INT_MAX;
-BOOL    smtp_use_pipelining    = FALSE;
-BOOL    smtp_use_size          = FALSE;
+unsigned smtp_peer_options     = 0;
+unsigned smtp_peer_options_wrap= 0;
 #ifdef SUPPORT_I18N
 uschar *smtputf8_advertise_hosts = US"*";      /* overridden under test-harness */
 #endif
 #ifdef SUPPORT_I18N
 uschar *smtputf8_advertise_hosts = US"*";      /* overridden under test-harness */
 #endif
index f9af38ef5b1fc6ec78b06a9fd624f828f980e3d4..b2bfca64cb45dbfa24d088340ff0d182729df9d9 100644 (file)
@@ -119,7 +119,6 @@ extern uschar *tls_eccurve;            /* EC curve */
 # ifndef DISABLE_OCSP
 extern uschar *tls_ocsp_file;          /* OCSP stapling proof file */
 # endif
 # ifndef DISABLE_OCSP
 extern uschar *tls_ocsp_file;          /* OCSP stapling proof file */
 # endif
-extern BOOL    tls_offered;            /* Server offered TLS */
 extern uschar *tls_privatekey;         /* Private key file */
 extern BOOL    tls_remember_esmtp;     /* For YAEB */
 extern uschar *tls_require_ciphers;    /* So some can be avoided */
 extern uschar *tls_privatekey;         /* Private key file */
 extern BOOL    tls_remember_esmtp;     /* For YAEB */
 extern uschar *tls_require_ciphers;    /* So some can be avoided */
@@ -132,7 +131,6 @@ extern uschar *tls_advertise_hosts;    /* host for which TLS is advertised */
 extern uschar  *dsn_envid;             /* DSN envid string */
 extern int      dsn_ret;               /* DSN ret type*/
 extern const pcre  *regex_DSN;         /* For recognizing DSN settings */
 extern uschar  *dsn_envid;             /* DSN envid string */
 extern int      dsn_ret;               /* DSN ret type*/
 extern const pcre  *regex_DSN;         /* For recognizing DSN settings */
-extern BOOL     smtp_use_dsn;          /* Global for passed connections */
 extern uschar  *dsn_advertise_hosts;   /* host for which TLS is advertised */
 
 /* Input-reading functions for messages, so we can use special ones for
 extern uschar  *dsn_advertise_hosts;   /* host for which TLS is advertised */
 
 /* Input-reading functions for messages, so we can use special ones for
@@ -838,8 +836,8 @@ extern int     smtp_rlr_base;          /* Base interval for RCPT rate limit */
 extern double  smtp_rlr_factor;        /* Factor for RCPT rate limit */
 extern int     smtp_rlr_limit;         /* Max delay */
 extern int     smtp_rlr_threshold;     /* Threshold for RCPT rate limit */
 extern double  smtp_rlr_factor;        /* Factor for RCPT rate limit */
 extern int     smtp_rlr_limit;         /* Max delay */
 extern int     smtp_rlr_threshold;     /* Threshold for RCPT rate limit */
-extern BOOL    smtp_use_pipelining;    /* Global for passed connections */
-extern BOOL    smtp_use_size;          /* Global for passed connections */
+extern unsigned smtp_peer_options;     /* Global flags for passed connections */
+extern unsigned smtp_peer_options_wrap; /* stacked version hidden by TLS */
 #ifdef SUPPORT_I18N
 extern uschar *smtputf8_advertise_hosts; /* ingress control */
 #endif
 #ifdef SUPPORT_I18N
 extern uschar *smtputf8_advertise_hosts; /* ingress control */
 #endif
index 3987fad3e0b0319cf26f6f219569b504c33ff6fc..88d925e39904fd2c98a71345e397f0648ae24fde 100644 (file)
@@ -826,12 +826,12 @@ Arguments:
       end_dot               if TRUE, send a terminating "." line at the end
       no_headers            if TRUE, omit the headers
       no_body               if TRUE, omit the body
       end_dot               if TRUE, send a terminating "." line at the end
       no_headers            if TRUE, omit the headers
       no_body               if TRUE, omit the body
-    size_limit            if > 0, this is a limit to the size of message written;
+    check_string          a string to check for at the start of lines, or NULL
+    escape_string         a string to insert in front of any check string
+  size_limit              if > 0, this is a limit to the size of message written;
                             it is used when returning messages to their senders,
                             and is approximate rather than exact, owing to chunk
                             buffering
                             it is used when returning messages to their senders,
                             and is approximate rather than exact, owing to chunk
                             buffering
-    check_string          a string to check for at the start of lines, or NULL
-    escape_string         a string to insert in front of any check string
 
 Returns:                TRUE on success; FALSE (with errno) on failure.
                         In addition, the global variable transport_count
 
 Returns:                TRUE on success; FALSE (with errno) on failure.
                         In addition, the global variable transport_count
@@ -1228,7 +1228,6 @@ set up a filtering process, fork another process to call the internal function
 to write to the filter, and in this process just suck from the filter and write
 down the given fd. At the end, tidy up the pipes and the processes.
 
 to write to the filter, and in this process just suck from the filter and write
 down the given fd. At the end, tidy up the pipes and the processes.
 
-XXX
 Arguments:     as for internal_transport_write_message() above
 
 Returns:       TRUE on success; FALSE (with errno) for any failure
 Arguments:     as for internal_transport_write_message() above
 
 Returns:       TRUE on success; FALSE (with errno) for any failure
@@ -1944,7 +1943,7 @@ DEBUG(D_transport) debug_printf("transport_pass_socket entered\n");
 
 if ((pid = fork()) == 0)
   {
 
 if ((pid = fork()) == 0)
   {
-  int i = 16;
+  int i = 17;
   const uschar **argv;
 
   /* Disconnect entirely from the parent process. If we are running in the
   const uschar **argv;
 
   /* Disconnect entirely from the parent process. If we are running in the
@@ -1960,16 +1959,15 @@ if ((pid = fork()) == 0)
 
   argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0);
 
 
   argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0);
 
-  if (smtp_use_dsn) argv[i++] = US"-MCD";
-
   if (smtp_authenticated) argv[i++] = US"-MCA";
 
   if (smtp_authenticated) argv[i++] = US"-MCA";
 
-  #ifdef SUPPORT_TLS
-  if (tls_offered) argv[i++] = US"-MCT";
-  #endif
-
-  if (smtp_use_size) argv[i++] = US"-MCS";
-  if (smtp_use_pipelining) argv[i++] = US"-MCP";
+  if (smtp_peer_options & PEER_OFFERED_CHUNKING) argv[i++] = US"-MCK";
+  if (smtp_peer_options & PEER_OFFERED_DSN) argv[i++] = US"-MCD";
+  if (smtp_peer_options & PEER_OFFERED_PIPE) argv[i++] = US"-MCP";
+  if (smtp_peer_options & PEER_OFFERED_SIZE) argv[i++] = US"-MCS";
+#ifdef SUPPORT_TLS
+  if (smtp_peer_options & PEER_OFFERED_TLS) argv[i++] = US"-MCT";
+#endif
 
   if (queue_run_pid != (pid_t)0)
     {
 
   if (queue_run_pid != (pid_t)0)
     {
index 110ced24013a29eba772b29ed6573bb24dcb9861..25e493433e54c347b55eeb2cf876e4738d2500ff 100644 (file)
@@ -12,6 +12,8 @@
 #define PENDING_DEFER   (PENDING + DEFER)
 #define PENDING_OK      (PENDING + OK)
 
 #define PENDING_DEFER   (PENDING + DEFER)
 #define PENDING_OK      (PENDING + OK)
 
+#define DELIVER_BUFFER_SIZE 4096
+
 
 /* Options specific to the smtp transport. This transport also supports LMTP
 over TCP/IP. The options must be in alphabetic order (note that "_" comes
 
 /* Options specific to the smtp transport. This transport also supports LMTP
 over TCP/IP. The options must be in alphabetic order (note that "_" comes
@@ -1406,8 +1408,7 @@ if (flags & tc_reap_prev  &&  prev_cmd_count > 0)
          tctx->pending_MAIL, 0,
          tctx->inblock,
          ob->command_timeout,
          tctx->pending_MAIL, 0,
          tctx->inblock,
          ob->command_timeout,
-         buffer, 4096))
-/*XXX buffer size! */
+         buffer, DELIVER_BUFFER_SIZE))
     {
     case 1:                            /* 2xx (only) => OK */
     case 3: tctx->good_RCPT = TRUE;    /* 2xx & 5xx => OK & progress made */
     {
     case 1:                            /* 2xx (only) => OK */
     case 3: tctx->good_RCPT = TRUE;    /* 2xx & 5xx => OK & progress made */
@@ -1426,8 +1427,7 @@ if (flags & tc_reap_prev  &&  prev_cmd_count > 0)
 
 if (flags & tc_reap_one  ||  tctx->pending_BDAT)
   {
 
 if (flags & tc_reap_one  ||  tctx->pending_BDAT)
   {
-/*XXX buffer size! */
-  if (!smtp_read_response(tctx->inblock, buffer, 4096, '2',
+  if (!smtp_read_response(tctx->inblock, buffer, DELIVER_BUFFER_SIZE, '2',
        ob->command_timeout))
     {
     if (errno == 0 && buffer[0] == '4')
        ob->command_timeout))
     {
     if (errno == 0 && buffer[0] == '4')
@@ -1521,7 +1521,7 @@ BOOL completed_address = FALSE;
 BOOL esmtp = TRUE;
 BOOL pending_MAIL;
 BOOL pass_message = FALSE;
 BOOL esmtp = TRUE;
 BOOL pending_MAIL;
 BOOL pass_message = FALSE;
-uschar peer_offered = 0;       /*XXX should this be handed on cf. tls_offered, smtp_use_dsn ? */
+uschar peer_offered = 0;
 #ifndef DISABLE_PRDR
 BOOL prdr_active;
 #endif
 #ifndef DISABLE_PRDR
 BOOL prdr_active;
 #endif
@@ -1548,7 +1548,7 @@ uschar *helo_data = NULL;
 uschar *message = NULL;
 uschar new_message_id[MESSAGE_ID_LENGTH + 1];
 uschar *p;
 uschar *message = NULL;
 uschar new_message_id[MESSAGE_ID_LENGTH + 1];
 uschar *p;
-uschar buffer[4096];
+uschar buffer[DELIVER_BUFFER_SIZE];
 uschar inbuffer[4096];
 uschar outbuffer[4096];
 
 uschar inbuffer[4096];
 uschar outbuffer[4096];
 
@@ -1756,7 +1756,7 @@ goto SEND_QUIT;
 #ifdef SUPPORT_TLS
   if (smtps)
     {
 #ifdef SUPPORT_TLS
   if (smtps)
     {
-    tls_offered = TRUE;
+    smtp_peer_options |= PEER_OFFERED_TLS;
     suppress_tls = FALSE;
     ob->tls_tempfail_tryclear = FALSE;
     smtp_command = US"SSL-on-connect";
     suppress_tls = FALSE;
     ob->tls_tempfail_tryclear = FALSE;
     smtp_command = US"SSL-on-connect";
@@ -1805,7 +1805,10 @@ goto SEND_QUIT;
     if (!good_response) goto RESPONSE_FAILED;
     }
 
     if (!good_response) goto RESPONSE_FAILED;
     }
 
+  peer_offered = smtp_peer_options = 0;
+
   if (esmtp || lmtp)
   if (esmtp || lmtp)
+    {
     peer_offered = ehlo_response(buffer, Ustrlen(buffer),
       PEER_OFFERED_TLS /* others checked later */
       );
     peer_offered = ehlo_response(buffer, Ustrlen(buffer),
       PEER_OFFERED_TLS /* others checked later */
       );
@@ -1813,14 +1816,15 @@ goto SEND_QUIT;
   /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
 
 #ifdef SUPPORT_TLS
   /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
 
 #ifdef SUPPORT_TLS
-  tls_offered = !!(peer_offered & PEER_OFFERED_TLS);
+    smtp_peer_options |= peer_offered & PEER_OFFERED_TLS;
 #endif
 #endif
+    }
   }
 
 /* For continuing deliveries down the same channel, the socket is the standard
 input, and we don't need to redo EHLO here (but may need to do so for TLS - see
 below). Set up the pointer to where subsequent commands will be left, for
   }
 
 /* For continuing deliveries down the same channel, the socket is the standard
 input, and we don't need to redo EHLO here (but may need to do so for TLS - see
 below). Set up the pointer to where subsequent commands will be left, for
-error messages. Note that smtp_use_size and smtp_use_pipelining will have been
+error messages. Note that smtp_peer_options will have been
 set from the command line if they were set in the process that passed the
 connection on. */
 
 set from the command line if they were set in the process that passed the
 connection on. */
 
@@ -1845,7 +1849,7 @@ the client not be required to use TLS. If the response is bad, copy the buffer
 for error analysis. */
 
 #ifdef SUPPORT_TLS
 for error analysis. */
 
 #ifdef SUPPORT_TLS
-if (  tls_offered
+if (  smtp_peer_options & PEER_OFFERED_TLS
    && !suppress_tls
    && verify_check_given_host(&ob->hosts_avoid_tls, host) != OK)
   {
    && !suppress_tls
    && verify_check_given_host(&ob->hosts_avoid_tls, host) != OK)
   {
@@ -1907,6 +1911,7 @@ if (  tls_offered
 
     /* TLS session is set up */
 
 
     /* TLS session is set up */
 
+    smtp_peer_options_wrap = smtp_peer_options;
     for (addr = addrlist; addr; addr = addr->next)
       if (addr->transport_return == PENDING_DEFER)
         {
     for (addr = addrlist; addr; addr = addr->next)
       if (addr->transport_return == PENDING_DEFER)
         {
@@ -1976,6 +1981,7 @@ if (tls_out.active >= 0)
   helo_response = string_copy(buffer);
 #endif
   if (!good_response) goto RESPONSE_FAILED;
   helo_response = string_copy(buffer);
 #endif
   if (!good_response) goto RESPONSE_FAILED;
+  smtp_peer_options = 0;
   }
 
 /* If the host is required to use a secure channel, ensure that we
   }
 
 /* If the host is required to use a secure channel, ensure that we
@@ -1990,8 +1996,8 @@ else if (  smtps
   {
   save_errno = ERRNO_TLSREQUIRED;
   message = string_sprintf("a TLS session is required, but %s",
   {
   save_errno = ERRNO_TLSREQUIRED;
   message = string_sprintf("a TLS session is required, but %s",
-    tls_offered ? "an attempt to start TLS failed"
-               : "the server did not offer TLS support");
+    smtp_peer_options & PEER_OFFERED_TLS
+    ? "an attempt to start TLS failed" : "the server did not offer TLS support");
   goto TLS_FAILED;
   }
 #endif /*SUPPORT_TLS*/
   goto TLS_FAILED;
   }
 #endif /*SUPPORT_TLS*/
@@ -2008,6 +2014,7 @@ if (continue_hostname == NULL
     )
   {
   if (esmtp || lmtp)
     )
   {
   if (esmtp || lmtp)
+    {
     peer_offered = ehlo_response(buffer, Ustrlen(buffer),
       0 /* no TLS */
       | (lmtp && ob->lmtp_ignore_quota ? PEER_OFFERED_IGNQ : 0)
     peer_offered = ehlo_response(buffer, Ustrlen(buffer),
       0 /* no TLS */
       | (lmtp && ob->lmtp_ignore_quota ? PEER_OFFERED_IGNQ : 0)
@@ -2015,7 +2022,7 @@ if (continue_hostname == NULL
       | PEER_OFFERED_PRDR
 #ifdef SUPPORT_I18N
       | (addrlist->prop.utf8_msg ? PEER_OFFERED_UTF8 : 0)
       | PEER_OFFERED_PRDR
 #ifdef SUPPORT_I18N
       | (addrlist->prop.utf8_msg ? PEER_OFFERED_UTF8 : 0)
-       /*XXX if we hand peercaps on to continued-conn processes,
+       /*XXX if we hand peercaps on to continued-conn processes,
              must not depend on this addr */
 #endif
       | PEER_OFFERED_DSN
              must not depend on this addr */
 #endif
       | PEER_OFFERED_DSN
@@ -2023,61 +2030,64 @@ if (continue_hostname == NULL
       | (ob->size_addition >= 0 ? PEER_OFFERED_SIZE : 0)
       );
 
       | (ob->size_addition >= 0 ? PEER_OFFERED_SIZE : 0)
       );
 
-  /* Set for IGNOREQUOTA if the response to LHLO specifies support and the
-  lmtp_ignore_quota option was set. */
+    /* Set for IGNOREQUOTA if the response to LHLO specifies support and the
+    lmtp_ignore_quota option was set. */
 
 
-  igquotstr = peer_offered & PEER_OFFERED_IGNQ ? US" IGNOREQUOTA" : US"";
+    igquotstr = peer_offered & PEER_OFFERED_IGNQ ? US" IGNOREQUOTA" : US"";
 
 
-  /* If the response to EHLO specified support for the SIZE parameter, note
-  this, provided size_addition is non-negative. */
+    /* If the response to EHLO specified support for the SIZE parameter, note
+    this, provided size_addition is non-negative. */
 
 
-  smtp_use_size = !!(peer_offered & PEER_OFFERED_SIZE);
+    smtp_peer_options |= peer_offered & PEER_OFFERED_SIZE;
 
 
-  /* Note whether the server supports PIPELINING. If hosts_avoid_esmtp matched
-  the current host, esmtp will be false, so PIPELINING can never be used. If
-  the current host matches hosts_avoid_pipelining, don't do it. */
+    /* Note whether the server supports PIPELINING. If hosts_avoid_esmtp matched
+    the current host, esmtp will be false, so PIPELINING can never be used. If
+    the current host matches hosts_avoid_pipelining, don't do it. */
 
 
-  smtp_use_pipelining = peer_offered & PEER_OFFERED_PIPE
-    && verify_check_given_host(&ob->hosts_avoid_pipelining, host) != OK;
+    if (  peer_offered & PEER_OFFERED_PIPE
+       && verify_check_given_host(&ob->hosts_avoid_pipelining, host) != OK)
+      smtp_peer_options |= PEER_OFFERED_PIPE;
 
 
-  DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
-    smtp_use_pipelining ? "" : "not ");
+    DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
+      smtp_peer_options & PEER_OFFERED_PIPE ? "" : "not ");
 
 
-  if (  peer_offered & PEER_OFFERED_CHUNKING
-     && verify_check_given_host(&ob->hosts_try_chunking, host) != OK)
-    peer_offered &= ~PEER_OFFERED_CHUNKING;
+    if (  peer_offered & PEER_OFFERED_CHUNKING
+       && verify_check_given_host(&ob->hosts_try_chunking, host) != OK)
+      peer_offered &= ~PEER_OFFERED_CHUNKING;
 
 
-  if (peer_offered & PEER_OFFERED_CHUNKING)
-    {DEBUG(D_transport) debug_printf("CHUNKING usable\n");}
+    if (peer_offered & PEER_OFFERED_CHUNKING)
+      {DEBUG(D_transport) debug_printf("CHUNKING usable\n");}
 
 #ifndef DISABLE_PRDR
 
 #ifndef DISABLE_PRDR
-  if (  peer_offered & PEER_OFFERED_PRDR
-     && verify_check_given_host(&ob->hosts_try_prdr, host) != OK)
-    peer_offered &= ~PEER_OFFERED_PRDR;
+    if (  peer_offered & PEER_OFFERED_PRDR
+       && verify_check_given_host(&ob->hosts_try_prdr, host) != OK)
+      peer_offered &= ~PEER_OFFERED_PRDR;
 
 
-  if (peer_offered & PEER_OFFERED_PRDR)
-    {DEBUG(D_transport) debug_printf("PRDR usable\n");}
+    if (peer_offered & PEER_OFFERED_PRDR)
+      {DEBUG(D_transport) debug_printf("PRDR usable\n");}
 #endif
 
 #endif
 
-  /* Note if the server supports DSN */
-  smtp_use_dsn = !!(peer_offered & PEER_OFFERED_DSN);
-  DEBUG(D_transport) debug_printf("%susing DSN\n", smtp_use_dsn ? "" : "not ");
+    /* Note if the server supports DSN */
+    smtp_peer_options |= peer_offered & PEER_OFFERED_DSN;
+    DEBUG(D_transport) debug_printf("%susing DSN\n",
+                       peer_offered & PEER_OFFERED_DSN ? "" : "not ");
 
 
-  /* Note if the response to EHLO specifies support for the AUTH extension.
-  If it has, check that this host is one we want to authenticate to, and do
-  the business. The host name and address must be available when the
-  authenticator's client driver is running. */
+    /* Note if the response to EHLO specifies support for the AUTH extension.
+    If it has, check that this host is one we want to authenticate to, and do
+    the business. The host name and address must be available when the
+    authenticator's client driver is running. */
 
 
-  switch (yield = smtp_auth(buffer, sizeof(buffer), addrlist, host,
-                           ob, esmtp, &inblock, &outblock))
-    {
-    default:           goto SEND_QUIT;
-    case OK:           break;
-    case FAIL_SEND:    goto SEND_FAILED;
-    case FAIL:         goto RESPONSE_FAILED;
+    switch (yield = smtp_auth(buffer, sizeof(buffer), addrlist, host,
+                             ob, esmtp, &inblock, &outblock))
+      {
+      default:         goto SEND_QUIT;
+      case OK:         break;
+      case FAIL_SEND:  goto SEND_FAILED;
+      case FAIL:       goto RESPONSE_FAILED;
+      }
     }
   }
     }
   }
-pipelining_active = smtp_use_pipelining;
+pipelining_active = !!(smtp_peer_options & PEER_OFFERED_PIPE);
 
 /* The setting up of the SMTP call is now complete. Any subsequent errors are
 message-specific. */
 
 /* The setting up of the SMTP call is now complete. Any subsequent errors are
 message-specific. */
@@ -2162,7 +2172,7 @@ included in the count.) */
 p = buffer;
 *p = 0;
 
 p = buffer;
 *p = 0;
 
-if (smtp_use_size)
+if (peer_offered & PEER_OFFERED_SIZE)
   {
   sprintf(CS p, " SIZE=%d", message_size+message_linecount+ob->size_addition);
   while (*p) p++;
   {
   sprintf(CS p, " SIZE=%d", message_size+message_linecount+ob->size_addition);
   while (*p) p++;
@@ -2206,7 +2216,7 @@ for (dsn_all_lasthop = TRUE, addr = first_addr;
 
 /* Add any DSN flags to the mail command */
 
 
 /* Add any DSN flags to the mail command */
 
-if (smtp_use_dsn && !dsn_all_lasthop)
+if (peer_offered & PEER_OFFERED_DSN && !dsn_all_lasthop)
   {
   if (dsn_ret == dsn_ret_hdrs)
     { Ustrcpy(p, " RET=HDRS"); p += 9; }
   {
   if (dsn_ret == dsn_ret_hdrs)
     { Ustrcpy(p, " RET=HDRS"); p += 9; }
@@ -2264,7 +2274,7 @@ pending_MAIL = TRUE;     /* The block starts with MAIL */
     }
 #endif
 
     }
 #endif
 
-  rc = smtp_write_command(&outblock, smtp_use_pipelining,
+  rc = smtp_write_command(&outblock, pipelining_active,
          "MAIL FROM:<%s>%s\r\n", s, buffer);
   }
 
          "MAIL FROM:<%s>%s\r\n", s, buffer);
   }
 
@@ -2311,21 +2321,22 @@ for (addr = first_addr;
   BOOL no_flush;
   uschar * rcpt_addr;
 
   BOOL no_flush;
   uschar * rcpt_addr;
 
-  addr->dsn_aware = smtp_use_dsn ? dsn_support_yes : dsn_support_no;
+  addr->dsn_aware = peer_offered & PEER_OFFERED_DSN
+    ? dsn_support_yes : dsn_support_no;
 
   if (addr->transport_return != PENDING_DEFER) continue;
 
   address_count++;
 
   if (addr->transport_return != PENDING_DEFER) continue;
 
   address_count++;
-  no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next);
+  no_flush = pipelining_active && (!mua_wrapper || addr->next);
 
   /* Add any DSN flags to the rcpt command and add to the sent string */
 
   p = buffer;
   *p = 0;
 
 
   /* Add any DSN flags to the rcpt command and add to the sent string */
 
   p = buffer;
   *p = 0;
 
-  if (smtp_use_dsn && !(addr->dsn_flags & rf_dsnlasthop))
+  if (peer_offered & PEER_OFFERED_DSN && !(addr->dsn_flags & rf_dsnlasthop))
     {
     {
-    if ((addr->dsn_flags & rf_dsnflags) != 0)
+    if (addr->dsn_flags & rf_dsnflags)
       {
       int i;
       BOOL first = TRUE;
       {
       int i;
       BOOL first = TRUE;
@@ -2424,7 +2435,7 @@ If using CHUNKING, do not send a BDAT until we know how big a chunk we want
 to send is. */
 
 if (  !(peer_offered & PEER_OFFERED_CHUNKING)
 to send is. */
 
 if (  !(peer_offered & PEER_OFFERED_CHUNKING)
-   && (ok || (smtp_use_pipelining && !mua_wrapper)))
+   && (ok || (pipelining_active && !mua_wrapper)))
   {
   int count = smtp_write_command(&outblock, FALSE, "DATA\r\n");
 
   {
   int count = smtp_write_command(&outblock, FALSE, "DATA\r\n");
 
@@ -3031,6 +3042,7 @@ if (completed_address && ok && send_quit)
       if (tls_out.active >= 0)
         {
         tls_close(FALSE, TRUE);
       if (tls_out.active >= 0)
         {
         tls_close(FALSE, TRUE);
+       smtp_peer_options = smtp_peer_options_wrap;
         if (smtps)
           ok = FALSE;
         else
         if (smtps)
           ok = FALSE;
         else
index 4c4dfc599af24ab520d8118e7cf8ed750d300532..d890f5fc60a96d54a4c1c948aec6c06754d75f2e 100644 (file)
@@ -759,7 +759,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
       ? string_sprintf(" SIZE=%d", message_size + ob->size_addition) : US"";
 
 #ifdef SUPPORT_TLS
       ? string_sprintf(" SIZE=%d", message_size + ob->size_addition) : US"";
 
 #ifdef SUPPORT_TLS
-    tls_offered = !!(peer_offered & PEER_OFFERED_TLS);
+    smtp_peer_options |= peer_offered & PEER_OFFERED_TLS;
 #endif
 
     /* If TLS is available on this connection attempt to
 #endif
 
     /* If TLS is available on this connection attempt to
index 10e96f9a3b824ccf4d0ff8cece7adef667bf0cd6..63072b9a96a70f2c4fb3bfb5bbaa2cac998a82bd 100644 (file)
@@ -7,3 +7,4 @@
 1999-03-02 09:44:33 10HmbA-0005vi-00 SMTP data timeout (message abandoned) on connection from (tester) [127.0.0.1] F=<someone@some.domain>
 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data
 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data
 1999-03-02 09:44:33 10HmbA-0005vi-00 SMTP data timeout (message abandoned) on connection from (tester) [127.0.0.1] F=<someone@some.domain>
 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data
 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@the.local.host.name
index cb8cf63e3b970b313c5e88ee9a8bf7454bc370db..435906d608182dab1cddd8f551e1bf541d70870b 100644 (file)
@@ -2,13 +2,14 @@
 exim -DSERVER=server -bd -oX PORT_D
 ****
 #
 exim -DSERVER=server -bd -oX PORT_D
 ****
 #
+# plain, small message (no body)
 client 127.0.0.1 PORT_D
 ??? 220
 ehlo tester
 ??? 250-
 client 127.0.0.1 PORT_D
 ??? 220
 ehlo tester
 ??? 250-
-??? 250-
-??? 250-
-??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
 ??? 250-CHUNKING
 ??? 250 HELP
 mail from:someone@some.domain
 ??? 250-CHUNKING
 ??? 250 HELP
 mail from:someone@some.domain
@@ -26,6 +27,9 @@ quit
 ??? 221
 ****
 #
 ??? 221
 ****
 #
+# plain, small message (with body)
+# nonlast 1st bdat, noop, last-bdat(0)
+# immediate followon 2nd message
 client 127.0.0.1 PORT_D
 ??? 220
 ehlo tester
 client 127.0.0.1 PORT_D
 ??? 220
 ehlo tester
@@ -118,6 +122,7 @@ quit
 ??? 221
 ****
 #
 ??? 221
 ****
 #
+# followon EHLO and another message
 client 127.0.0.1 PORT_D
 ??? 220
 ehlo tester
 client 127.0.0.1 PORT_D
 ??? 220
 ehlo tester
@@ -166,5 +171,25 @@ quit
 ??? 221
 ****
 #
 ??? 221
 ****
 #
+# plain, small message (no body)
+# pipelined
+client 127.0.0.1 PORT_D
+??? 220
+EHLO tester
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-CHUNKING
+??? 250 HELP
+MAIL FROM:<someone@some.domain>\r\nRCPT TO:<CALLER@HOSTNAME>\r\nBDAT 88 LAST\r\nTo: Susan@random.com\r\nFrom: Sam@random.com\r\nSubject: This is a bodyless test message\r\n
+??? 250
+??? 250
+??? 250-
+??? 250
+quit
+??? 221
+****
+#
 killdaemon
 no_msglog_check
 killdaemon
 no_msglog_check
index 24c591617e77847f2f5d5f762d7f43d72a0146c8..28f479c229550b0ee09d6ba49d87229049d1eca3 100644 (file)
@@ -4,11 +4,11 @@ Connecting to 127.0.0.1 port 1225 ... connected
 >>> ehlo tester
 ??? 250-
 <<< 250-the.local.host.name Hello tester [127.0.0.1]
 >>> ehlo tester
 ??? 250-
 <<< 250-the.local.host.name Hello tester [127.0.0.1]
-??? 250-
+??? 250-SIZE
 <<< 250-SIZE 52428800
 <<< 250-SIZE 52428800
-??? 250-
+??? 250-8BITMIME
 <<< 250-8BITMIME
 <<< 250-8BITMIME
-??? 250-
+??? 250-PIPELINING
 <<< 250-PIPELINING
 ??? 250-CHUNKING
 <<< 250-CHUNKING
 <<< 250-PIPELINING
 ??? 250-CHUNKING
 <<< 250-CHUNKING
@@ -230,3 +230,32 @@ Connecting to 127.0.0.1 port 1225 ... connected
 ??? 221
 <<< 221 the.local.host.name closing connection
 End of script
 ??? 221
 <<< 221 the.local.host.name closing connection
 End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO tester
+??? 250-
+<<< 250-the.local.host.name Hello tester [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-CHUNKING
+<<< 250-CHUNKING
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM:<someone@some.domain>\r\nRCPT TO:<CALLER@the.local.host.name>\r\nBDAT 88 LAST\r\nTo: Susan@random.com\r\nFrom: Sam@random.com\r\nSubject: This is a bodyless test message\r\n
+??? 250
+<<< 250 OK
+??? 250
+<<< 250 Accepted
+??? 250-
+<<< 250- 88 byte chunk, total 88
+??? 250
+<<< 250 OK id=10HmbB-0005vi-00
+>>> quit
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script