PIPE_CONNECT: promote from experimental
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 28 May 2019 19:02:50 +0000 (20:02 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 28 May 2019 21:18:49 +0000 (22:18 +0100)
29 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/experimental-spec.txt
src/src/EDITME
src/src/config.h.defaults
src/src/dbstuff.h
src/src/deliver.c
src/src/exim.c
src/src/globals.c
src/src/globals.h
src/src/macro_predef.c
src/src/readconf.c
src/src/receive.c
src/src/smtp_in.c
src/src/smtp_out.c
src/src/structs.h
src/src/tls-openssl.c
src/src/transports/smtp.c
src/src/transports/smtp.h
test/runtest
test/scripts/4050-pipe-conn/REQUIRES
test/scripts/4056-pipe-conn-auth/REQUIRES
test/scripts/4058-pipe-conn-tfo/REQUIRES
test/scripts/4060-pipe-conn-gnutls/REQUIRES
test/scripts/4062-pipe-conn-openssl/REQUIRES
test/scripts/4064-pipe-conn-gnutls-auth/REQUIRES
test/scripts/4066-pipe-conn-openssl-auth/REQUIRES
test/scripts/4068-pipe-conn-gnutls-tfo/REQUIRES
test/scripts/4069-pipe-conn-openssl-tfo/REQUIRES

index bfacdef81e69f5e311acdc2249bc12d05c3aba0d..34c4310d56b2fc647440a226af05d1ca0d0dd88c 100644 (file)
@@ -14368,6 +14368,7 @@ See also the &'Policy controls'& section above.
 .row &%ignore_fromline_hosts%&       "allow &""From ""& from these hosts"
 .row &%ignore_fromline_local%&       "allow &""From ""& from local SMTP"
 .row &%pipelining_advertise_hosts%&  "advertise pipelining to these hosts"
+.row &%pipelining_connect_advertise_hosts%& "advertise pipelining to these hosts"
 .row &%prdr_enable%&                 "advertise PRDR to all hosts"
 .row &%smtputf8_advertise_hosts%&    "advertise SMTPUTF8 to these hosts"
 .row &%tls_advertise_hosts%&         "advertise TLS to these hosts"
@@ -16373,6 +16374,19 @@ for each SMTP command and response. When PIPELINING is advertised, Exim assumes
 that clients will use it; &"out of order"& commands that are &"expected"& do
 not count as protocol errors (see &%smtp_max_synprot_errors%&).
 
+.new
+.option pipelining_connect_advertise_hosts main "host list&!!" *
+.cindex "pipelining" "early connection"
+.cindex "pipelining" PIPE_CONNECT
+If Exim is built with the SUPPORT_PIPE_CONNECT build option
+this option controls which hosts the facility is advertised to
+and from which pipeline early-connection (before MAIL) SMTP
+commands are acceptable.
+When used, the pipelining saves on roundtrip times.
+
+Currently the option name &"X_PIPE_CONNECT"& is used.
+.wen
+
 
 .option prdr_enable main boolean false
 .cindex "PRDR" "enabling on server"
@@ -24553,6 +24567,30 @@ facilities such as AUTH, PIPELINING, SIZE, and STARTTLS.
 Exim will not use the SMTP PIPELINING extension when delivering to any host
 that matches this list, even if the server host advertises PIPELINING support.
 
+.new
+.option hosts_pipe_connect smtp "host list&!!" unset
+.cindex "pipelining" "early connection"
+.cindex "pipelining" PIPE_CONNECT
+If Exim is built with the SUPPORT_PIPE_CONNECT build option
+this option controls which to hosts the facility watched for
+and recorded, and used for subsequent connections.
+
+The retry hints database is used for the record,
+and records are subject to the &%retry_data_expire%& option.
+When used, the pipelining saves on roundtrip times.
+It also turns SMTP into a client-first protocol
+so combines well with TCP Fast Open.
+
+Note:
+When the facility is used, the transport &%helo_data%& option
+will be expanded before the &$sending_ip_address$& variable
+is filled in.
+A check is made for the use of that variable, without the
+presence of a &"def:"& test on it, but suitably complex coding
+can avoid the check and produce unexpected results.
+You have been warned.
+.wen
+
 
 .option hosts_avoid_tls smtp "host list&!!" unset
 .cindex "TLS" "avoiding for certain hosts"
@@ -37380,6 +37418,15 @@ The field is a single "L".
 
 On accept lines, where PIPELINING was offered but not used by the client,
 the field has a minus appended.
+
+.new
+.cindex "pipelining" "early connection"
+If Exim is built with the SUPPORT_PIPE_CONNECT build option
+accept "L" fields have a period appended if the feature was
+offered but not used, or an asterisk appended if used.
+Delivery "L" fields have an asterisk appended if used.
+.wen
+
 .next
 .cindex "log" "queue run"
 .cindex "queue runner" "logging"
index 62801740b39bfc0e45409bd6ce9bf52c227952f2..b4e58990e4d7fb2c49fec055554641311b29ff2c 100644 (file)
@@ -121,9 +121,12 @@ JH/24 Fix duplicated logging of peer name/address, on a transport connection-
       reject under TFO.
 
 JH/25 The smtp transport option "hosts_try_fastopen" now enables all hosts by
-      default.  If the platfor supports and has the facility enabled, it will
+      default.  If the platform supports and has the facility enabled, it will
       be requested on all coneections.
 
+JH/26 The PIPE_CONNECT facility is promoted from experimental status and is now
+      controlled by the build-time option SUPPORT_PIPE_CONNECT.
+
 
 Exim version 4.92
 -----------------
index 328d0940a6e059dd403bcab5fedbf2a78570d6cc..f748f61460a27692e61ed51630e379ec5c2b156c 100644 (file)
@@ -873,87 +873,6 @@ used via the transport in question.
 
 
 
-Early pipelining support
-------------------------
-Ref: https://datatracker.ietf.org/doc/draft-harris-early-pipe/
-
-If compiled with EXPERIMENTAL_PIPE_CONNECT support is included for this feature.
-The server advertises the feature in its EHLO response, currently using the name
-"X_PIPE_CONNECT" (this will change, some time in the future).
-A client may cache this information, along with the rest of the EHLO response,
-and use it for later connections.  Those later ones can send esmtp commands before
-a banner is received.
-
-Up to 1.5 roundtrip times can be taken out of cleartext connections, 2.5 on
-STARTTLS connections.
-
-In combination with the traditional PIPELINING feature the following example
-sequences are possible (among others):
-
-(client)                (server)
-
-EHLO,MAIL,RCPT,DATA ->
-                     <- banner,EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
-message-data        ->
-------
-
-EHLO,MAIL,RCPT,BDAT              ->
-                                  <- banner,EHLO-resp,MAIL-ack,RCPT-ack
-message-data                     ->
-------
-
-EHLO,STARTTLS                     ->
-                                   <- banner,EHLO-resp,TLS-goahead
-TLS1.2-client-hello               ->
-                                   <- TLS-server-hello,cert,hello-done
-client-Kex,change-cipher,finished ->
-                                   <- change-cipher,finished
-EHLO,MAIL,RCPT,DATA               ->
-                                   <- EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
-
-------
-(tls-on-connect)
-TLS1.2-client-hello               ->
-                                   <- TLS-server-hello,cert,hello-done
-client-Kex,change-cipher,finished ->
-                                   <- change-cipher,finshed
-                                   <- banner
-EHLO,MAIL,RCPT,DATA               ->
-                                   <- EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
-
-Where the initial client packet is SMTP, it can combine with the TCP Fast Open
-feature and be sent in the TCP SYN.
-
-
-A main-section option "pipelining_connect_advertise_hosts" (default: *)
-and an smtp transport option "hosts_pipe_connect" (default: unset)
-control the feature.
-
-If the "pipelining" log_selector is enabled, the "L" field in server <=
-log lines has a period appended if the feature was advertised but not used;
-or has an asterisk appended if the feature was used.  In client => lines
-the "L" field has an asterisk appended if the feature was used.
-
-The "retry_data_expire" option controls cache invalidation.
-Entries are also rewritten (or cleared) if the adverised features
-change.
-
-
-NOTE: since the EHLO command must be constructed before the connection is
-made it cannot depend on the interface IP address that will be used.
-The string "$sending_ip_address" is checked for; if it appears in helo_data
-and "def:sending_ip_address" does not, the facility is disabled.
-
-Transport configurations should be checked for this.  An example avoidance:
-
- helo_data =   ${if def:sending_ip_address \
-                  {${lookup dnsdb{>! ptr=$sending_ip_address} \
-                       {${sg{$value} {^([^!]*).*\$} {\$1}}} fail}} \
-                  {$primary_hostname}}
-
-
-
-
 TLS Session Resumption
 ----------------------
 TLS Session Resumption for TLS 1.2 and TLS 1.3 connections can be used (defined
index fe945c3fd9b74bf71e1b40ea1e5e6fcbbeab1739..fa1fe1c9fdbef4caff5448cf4ef1d9c880806c14 100644 (file)
@@ -562,6 +562,11 @@ DISABLE_MAL_MKS=yes
 # DISABLE_EVENT=yes
 
 
+# Uncomment this line to include support for early pipelining, per
+# https://datatracker.ietf.org/doc/draft-harris-early-pipe/
+# SUPPORT_PIPE_CONNECT
+
+
 #------------------------------------------------------------------------------
 # Compiling Exim with experimental features. These are documented in
 # experimental-spec.txt. "Experimental" means that the way these features are
index 27b8fb40941694c5830a880949341d7f19af1125..17239bb85215729f19b4db1fd47a8804f720efcc 100644 (file)
@@ -149,6 +149,7 @@ Do not put spaces between # and the 'define'.
 #define SUPPORT_MAILSTORE
 #define SUPPORT_MBX
 #define SUPPORT_MOVE_FROZEN_MESSAGES
+#define SUPPORT_PIPE_CONNECT
 #define SUPPORT_PAM
 #define SUPPORT_PROXY
 #define SUPPORT_SOCKS
@@ -201,7 +202,6 @@ Do not put spaces between # and the 'define'.
 #define EXPERIMENTAL_DMARC
 #define DMARC_TLD_FILE "/etc/exim/opendmarc.tlds"
 #define EXPERIMENTAL_LMDB
-#define EXPERIMENTAL_PIPE_CONNECT
 #define EXPERIMENTAL_QUEUEFILE
 #define EXPERIMENTAL_SRS
 #define EXPERIMENTAL_TLS_RESUME
index 58154d7ef73672ee4268513bdd0b324427f6b7b2..b7889bd8ef99b20b4c5025f3561608405e37794a 100644 (file)
@@ -786,7 +786,7 @@ typedef struct {
   uschar   bloom[40];     /* Bloom filter which may be larger than this */
 } dbdata_ratelimit_unique;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 /* This structure records the EHLO responses, cleartext and crypted,
 for an IP, as bitmasks (cf. OPTION_TLS) */
 
index dc7a7d5fbe24cd34741eb7dfade2566745c179bc..b26e5dbd407a778ac0e57595e04bb70b12e0aef3 100644 (file)
@@ -1250,7 +1250,7 @@ else
     {
     if (testflag(addr, af_pipelining))
       g = string_catn(g, US" L", 2);
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (testflag(addr, af_early_pipe))
       g = string_catn(g, US"*", 1);
 #endif
@@ -3564,7 +3564,7 @@ while (!done)
     case 'L':
       switch (*subid)
        {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
        case 2: setflag(addr, af_early_pipe);   /*FALLTHROUGH*/
 #endif
        case 1: setflag(addr, af_pipelining); break;
@@ -4872,7 +4872,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
 #endif
 
       if (testflag(addr, af_pipelining))
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
        if (testflag(addr, af_early_pipe))
          rmt_dlv_checked_write(fd, 'L', '2', NULL, 0);
        else
@@ -8537,7 +8537,7 @@ if (!regex_DSN) regex_DSN  =
 if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA =
   regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", FALSE, TRUE);
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 if (!regex_EARLY_PIPE) regex_EARLY_PIPE =
   regex_must_compile(US"\\n250[\\s\\-]" EARLY_PIPE_FEATURE_NAME "(\\s|\\n|$)", FALSE, TRUE);
 #endif
index abce9fc696f1ca80f4d855c05613fa3379c91551..7571705d7092a9f8310937c26ee769d3eb705560 100644 (file)
@@ -890,6 +890,9 @@ fprintf(fp, "Support for:");
 #ifndef DISABLE_OCSP
   fprintf(fp, " OCSP");
 #endif
+#ifdef SUPPORT_PIPE_CONNECT
+  fprintf(fp, " PIPE_CONNECT");
+#endif
 #ifndef DISABLE_PRDR
   fprintf(fp, " PRDR");
 #endif
@@ -930,9 +933,6 @@ fprintf(fp, "Support for:");
 #ifdef EXPERIMENTAL_DSN_INFO
   fprintf(fp, " Experimental_DSN_info");
 #endif
-#ifdef EXPERIMENTAL_PIPE_CONNECT
-  fprintf(fp, " Experimental_PIPE_CONNECT");
-#endif
 #ifdef EXPERIMENTAL_TLS_RESUME
   fprintf(fp, " Experimental_TLS_resume");
 #endif
index 5ce04a6ed16e40df8eaf1263b2ad67d156b681be..e70e38538b6e33bdbed429c4169d57fa56646158 100644 (file)
@@ -297,7 +297,7 @@ struct global_flags f =
        .sender_name_forced     = FALSE,
        .sender_set_untrusted   = FALSE,
        .smtp_authenticated     = FALSE,
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
        .smtp_in_early_pipe_advertised = FALSE,
        .smtp_in_early_pipe_no_auth = FALSE,
        .smtp_in_early_pipe_used = FALSE,
@@ -1163,7 +1163,7 @@ uschar *override_pid_file_path = NULL;
 uschar *percent_hack_domains   = NULL;
 uschar *pid_file_path          = US PID_FILE_PATH
                            "\0<--------------Space to patch pid_file_path->";
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 uschar *pipe_connect_advertise_hosts = US"*";
 #endif
 uschar *pipelining_advertise_hosts = US"*";
@@ -1253,7 +1253,7 @@ const pcre *regex_From         = NULL;
 const pcre *regex_IGNOREQUOTA  = NULL;
 const pcre *regex_PIPELINING   = NULL;
 const pcre *regex_SIZE         = NULL;
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 const pcre *regex_EARLY_PIPE   = NULL;
 #endif
 const pcre *regex_ismsgid      = NULL;
index d29fcc4e1b59e60b317ad93e736ad61ff2654475..83d29ba9b12e22bd285a0f5029c865482c463375 100644 (file)
@@ -257,7 +257,7 @@ extern struct global_flags {
  BOOL   sender_name_forced             :1; /* Set by -F */
  BOOL   sender_set_untrusted           :1; /* Sender set by untrusted caller */
  BOOL   smtp_authenticated             :1; /* Sending client has authenticated */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
  BOOL   smtp_in_early_pipe_advertised  :1; /* server advertised PIPE_CONNECT */
  BOOL  smtp_in_early_pipe_no_auth      :1; /* too many authenticator names */
  BOOL   smtp_in_early_pipe_used                :1; /* client did send early data */
@@ -746,7 +746,7 @@ extern uschar *override_pid_file_path; /* Value of -oP argument */
 
 extern uschar *percent_hack_domains;   /* Local domains for which '% operates */
 extern uschar *pid_file_path;          /* For writing daemon pids */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 extern uschar *pipe_connect_advertise_hosts; /* for banner/EHLO pipelining */
 #endif
 extern uschar *pipelining_advertise_hosts; /* As it says */
@@ -828,7 +828,7 @@ extern const pcre  *regex_CHUNKING;    /* For recognizing CHUNKING (RFC 3030) */
 extern const pcre  *regex_IGNOREQUOTA; /* For recognizing IGNOREQUOTA (LMTP) */
 extern const pcre  *regex_PIPELINING;  /* For recognizing PIPELINING */
 extern const pcre  *regex_SIZE;        /* For recognizing SIZE settings */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 extern const pcre  *regex_EARLY_PIPE;  /* For recognizing PIPE_CONNCT */
 #endif
 extern const pcre  *regex_ismsgid;     /* Compiled r.e. for message it */
index ebb4cb98a689ae84f8be1eff72ccf5a721344baf..fce981996451d41ec3052e336abc5497f74bfa0b 100644 (file)
@@ -158,6 +158,9 @@ due to conflicts with other common macros. */
 #ifndef DISABLE_OCSP
   builtin_macro_create(US"_HAVE_OCSP");
 #endif
+#ifdef SUPPORT_PIPE_CONNECT
+  builtin_macro_create(US"_HAVE_PIPE_CONNECT");
+#endif
 #ifndef DISABLE_PRDR
   builtin_macro_create(US"_HAVE_PRDR");
 #endif
@@ -197,9 +200,6 @@ due to conflicts with other common macros. */
 #ifdef EXPERIMENTAL_DSN_INFO
   builtin_macro_create(US"_HAVE_DSN_INFO");
 #endif
-#ifdef EXPERIMENTAL_PIPE_CONNECT
-  builtin_macro_create(US"_HAVE_PIPE_CONNECT");
-#endif
 #ifdef EXPERIMENTAL_TLS_RESUME
   builtin_macro_create(US"_HAVE_TLS_RESUME");
 #endif
index cffee4a0803afd437734f9443815a070da5dae3c..b9d193554160bc62bcfef743c3c96299d26445f1 100644 (file)
@@ -241,7 +241,7 @@ static optionlist optionlist_config[] = {
 #endif
   { "pid_file_path",            opt_stringptr,   &pid_file_path },
   { "pipelining_advertise_hosts", opt_stringptr, &pipelining_advertise_hosts },
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   { "pipelining_connect_advertise_hosts", opt_stringptr,
                                                 &pipe_connect_advertise_hosts },
 #endif
@@ -4207,7 +4207,7 @@ Returns:     nothing
 static void
 auths_init(void)
 {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 int nauths = 0;
 #endif
 
@@ -4233,11 +4233,11 @@ for (auth_instance * au = auths; au; au = au->next)
           "(%s and %s) have the same public name (%s)",
           au->client ? US"client" : US"server", au->name, bu->name,
           au->public_name);
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   nauths++;
 #endif
   }
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 f.smtp_in_early_pipe_no_auth = nauths > 16;
 #endif
 }
index 9769e8893cd621cb6c03bc745a913233ffd440c1..ed2afb31748f148d537c6531895a68aba01ab755 100644 (file)
@@ -1343,7 +1343,7 @@ if (received_protocol)
 if (LOGGING(pipelining) && f.smtp_in_pipelining_advertised)
   {
   g = string_catn(g, US" L", 2);
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   if (f.smtp_in_early_pipe_used)
     g = string_catn(g, US"*", 1);
   else if (f.smtp_in_early_pipe_advertised)
index 049f5b5428a79ba96b777bc621588faf092c60cc..1e478a6ac7a99b77ea75730911997a05a7bd719a 100644 (file)
@@ -142,7 +142,7 @@ static struct {
   BOOL helo_verify                     :1;
   BOOL helo_seen                       :1;
   BOOL helo_accept_junk                        :1;
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   BOOL pipe_connect_acceptable         :1;
 #endif
   BOOL rcpt_smtp_response_same         :1;
@@ -397,7 +397,7 @@ return TRUE;
 }
 
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 static BOOL
 pipeline_connect_sends(void)
 {
@@ -2995,7 +2995,7 @@ while (*p);
 /* Before we write the banner, check that there is no input pending, unless
 this synchronisation check is disabled. */
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 fl.pipe_connect_acceptable =
   sender_host_address && verify_check_host(&pipe_connect_advertise_hosts) == OK;
 
@@ -3022,7 +3022,7 @@ if (!check_sync())
 /*XXX the ehlo-resp code does its own tls/nontls bit.  Maybe subroutine that? */
 
 smtp_printf("%s",
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   fl.pipe_connect_acceptable && pipeline_connect_sends(),
 #else
   FALSE,
@@ -3973,7 +3973,7 @@ while (done <= 0)
 #endif
 
   switch(smtp_read_command(
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
          !fl.pipe_connect_acceptable,
 #else
          TRUE,
@@ -4213,7 +4213,7 @@ while (done <= 0)
          host_build_sender_fullhost();  /* Rebuild */
          break;
          }
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
        else if (!fl.pipe_connect_acceptable && !check_sync())
 #else
        else if (!check_sync())
@@ -4344,7 +4344,7 @@ while (done <= 0)
          sync_cmd_limit = NON_SYNC_CMD_PIPELINING;
          f.smtp_in_pipelining_advertised = TRUE;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
          if (fl.pipe_connect_acceptable)
            {
            f.smtp_in_early_pipe_advertised = TRUE;
@@ -4462,7 +4462,7 @@ while (done <= 0)
 #ifndef DISABLE_TLS
       if (tls_in.active.sock >= 0)
        (void)tls_write(NULL, g->s, g->ptr,
-# ifdef EXPERIMENTAL_PIPE_CONNECT
+# ifdef SUPPORT_PIPE_CONNECT
                        fl.pipe_connect_acceptable && pipeline_connect_sends());
 # else
                        FALSE);
@@ -5240,7 +5240,7 @@ while (done <= 0)
       f.dot_ends = TRUE;
 
     DATA_BDAT:         /* Common code for DATA and BDAT */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
       fl.pipe_connect_acceptable = FALSE;
 #endif
       if (!discarded && recipients_count <= 0)
index ea052b58a3a30355dc7a3201d2bfa2175e20e5d1..c1cf901dc9f3d174de4d2139e870eb349115a645 100644 (file)
@@ -699,7 +699,7 @@ int count = 0;
 
 errno = 0;  /* Ensure errno starts out zero */
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 if (sx->pending_BANNER || sx->pending_EHLO)
   {
   int rc;
index 9fade00915a075e477b2884d80419e34e7c11e9e..0b01d5880b4d0513d53e5649a61b0d4389be3d61 100644 (file)
@@ -623,7 +623,7 @@ typedef struct address_item {
     BOOL af_tcp_fastopen:1;            /* delivery usefully used TCP Fast Open */
     BOOL af_tcp_fastopen_data:1;       /* delivery sent SMTP commands on TCP Fast Open */
     BOOL af_pipelining:1;              /* delivery used (traditional) pipelining */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     BOOL af_early_pipe:1;              /* delivery used connect-time pipelining */
 #endif
 #ifndef DISABLE_PRDR
index f3ea6b28bfb7ff8d313305b92297b236a93f4033..ea30ff7cad2ce8ac6e701a902b4194a470db9f67 100644 (file)
@@ -3395,14 +3395,14 @@ a store reset there, so use POOL_PERM. */
 
 if ((more || corked))
   {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   int save_pool = store_pool;
   store_pool = POOL_PERM;
 #endif
 
   corked = string_catn(corked, buff, len);
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   store_pool = save_pool;
 #endif
 
index 5c7b440c170e5163e763d760e91451223babe036..baf304405bbd44ed1044b2a4a2c20f988e325f7c 100644 (file)
@@ -106,7 +106,7 @@ optionlist smtp_transport_options[] = {
 #endif
   { "hosts_override",       opt_bool,
       (void *)offsetof(smtp_transport_options_block, hosts_override) },
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   { "hosts_pipe_connect",   opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_pipe_connect) },
 #endif
@@ -256,7 +256,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   .hosts_avoid_tls =           NULL,
   .hosts_verify_avoid_tls =    NULL,
   .hosts_avoid_pipelining =    NULL,
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   .hosts_pipe_connect =                NULL,
 #endif
   .hosts_avoid_esmtp =         NULL,
@@ -815,7 +815,7 @@ return TRUE;
 
 
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 static uschar *
 ehlo_cache_key(const smtp_context * sx)
 {
@@ -1081,7 +1081,7 @@ address_item * addr = sx->sync_addr;
 smtp_transport_options_block * ob = sx->conn_args.ob;
 int yield = 0;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 int rc;
 if ((rc = smtp_reap_early_pipe(sx, &count)) != OK)
   return rc == FAIL ? -4 : -5;
@@ -1397,7 +1397,7 @@ smtp_auth(smtp_context * sx)
 host_item * host = sx->conn_args.host;                 /* host to deliver to */
 smtp_transport_options_block * ob = sx->conn_args.ob;  /* transport options */
 int require_auth = verify_check_given_host(CUSS &ob->hosts_require_auth, host);
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 unsigned short authbits = tls_out.active.sock >= 0
       ? sx->ehlo_resp.crypted_auths : sx->ehlo_resp.cleartext_auths;
 #endif
@@ -1413,7 +1413,7 @@ if (!regex_AUTH)
 
 if (  sx->esmtp
    &&
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
       sx->early_pipe_active ? authbits
       :
 #endif
@@ -1423,7 +1423,7 @@ if (  sx->esmtp
   uschar * names = NULL;
   expand_nmax = -1;                          /* reset */
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   if (!sx->early_pipe_active)
 #endif
     names = string_copyn(expand_nstring[1], expand_nlength[1]);
@@ -1437,7 +1437,7 @@ if (  sx->esmtp
     DEBUG(D_transport) debug_printf("scanning authentication mechanisms\n");
     fail_reason = US"no common mechanisms were found";
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (sx->early_pipe_active)
       {
       /* Scan our authenticators (which support use by a client and were offered
@@ -1794,7 +1794,7 @@ if (  checks & OPTION_SIZE
    && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
   checks &= ~OPTION_SIZE;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 if (  checks & OPTION_EARLY_PIPE
    && pcre_exec(regex_EARLY_PIPE, NULL, CS buf, bsize, 0,
                PCRE_EOPT, NULL, 0) < 0)
@@ -1841,7 +1841,7 @@ there may be more writes (like, the chunk data) done soon. */
 
 if (chunk_size > 0)
   {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   BOOL new_conn = !!(sx->outblock.conn_args);
 #endif
   if((cmd_count = smtp_write_command(sx,
@@ -1850,7 +1850,7 @@ if (chunk_size > 0)
      ) < 0) return ERROR;
   if (flags & tc_chunk_last)
     data_command = string_copy(big_buffer);  /* Save for later error message */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   /* That command write could have been the one that made the connection.
   Copy the fd from the client conn ctx (smtp transport specific) to the
   generic transport ctx. */
@@ -1883,7 +1883,7 @@ if (flags & tc_reap_prev  &&  prev_cmd_count > 0)
 
     case -5: errno = ERRNO_TLSFAILURE;
             return DEFER;
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     case -4:                           /* non-2xx for pipelined banner or EHLO */
 #endif
     case -1:                           /* Timeout on RCPT */
@@ -1977,7 +1977,7 @@ sx->conn_args.dane = FALSE;
 sx->dane_required =
   verify_check_given_host(CUSS &ob->hosts_require_dane, sx->conn_args.host) == OK;
 #endif
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
 sx->early_pipe_active = sx->early_pipe_ok = FALSE;
 sx->ehlo_resp.cleartext_features = sx->ehlo_resp.crypted_features = 0;
 sx->pending_BANNER = sx->pending_EHLO = FALSE;
@@ -2105,7 +2105,7 @@ if (!continue_hostname)
   sx->inblock.cctx = sx->outblock.cctx = &sx->cctx;
   sx->avoid_option = sx->peer_offered = smtp_peer_options = 0;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   if (  verify_check_given_host(CUSS &ob->hosts_pipe_connect,
                                            sx->conn_args.host) == OK)
 
@@ -2180,7 +2180,7 @@ will be?  Somehow I doubt it. */
 
   if (!sx->smtps)
     {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (sx->early_pipe_active)
       {
       sx->pending_BANNER = TRUE;       /* sync_responses() must eventually handle */
@@ -2281,7 +2281,7 @@ goto SEND_QUIT;
   if (sx->esmtp)
     {
     if (smtp_write_command(sx,
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
          sx->early_pipe_active ? SCMD_BUFFER :
 #endif
            SCMD_FLUSH,
@@ -2289,7 +2289,7 @@ goto SEND_QUIT;
       goto SEND_FAILED;
     sx->esmtp_sent = TRUE;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (sx->early_pipe_active)
       {
       sx->pending_EHLO = TRUE;
@@ -2322,7 +2322,7 @@ goto SEND_QUIT;
     DEBUG(D_transport)
       debug_printf("not sending EHLO (host matches hosts_avoid_esmtp)\n");
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   if (!sx->early_pipe_active)
 #endif
     if (!sx->esmtp)
@@ -2357,13 +2357,13 @@ goto SEND_QUIT;
 
   if (sx->esmtp || sx->lmtp)
     {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (!sx->early_pipe_active)
 #endif
       {
       sx->peer_offered = ehlo_response(sx->buffer,
        OPTION_TLS      /* others checked later */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
        | (sx->early_pipe_ok
          ?   OPTION_IGNQ
            | OPTION_CHUNKING | OPTION_PRDR | OPTION_DSN | OPTION_PIPE | OPTION_SIZE
@@ -2375,7 +2375,7 @@ goto SEND_QUIT;
          )
 #endif
        );
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
       if (sx->early_pipe_ok)
        {
        sx->ehlo_resp.cleartext_features = sx->peer_offered;
@@ -2468,7 +2468,7 @@ if (  smtp_peer_options & OPTION_TLS
   if (smtp_write_command(sx, SCMD_FLUSH, "STARTTLS\r\n") < 0)
     goto SEND_FAILED;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   /* If doing early-pipelining reap the banner and EHLO-response but leave
   the response for the STARTTLS we just sent alone. */
 
@@ -2572,7 +2572,7 @@ if (tls_out.active.sock >= 0)
     goto SEND_QUIT;
     }
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   /* For SMTPS there is no cleartext early-pipe; use the crypted permission bit.
   We're unlikely to get the group sent and delivered before the server sends its
   banner, but it's still worth sending as a group.
@@ -2590,7 +2590,7 @@ if (tls_out.active.sock >= 0)
 
   /* For SMTPS we need to wait for the initial OK response. */
   if (sx->smtps)
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (sx->early_pipe_active)
       {
       sx->pending_BANNER = TRUE;
@@ -2613,14 +2613,14 @@ if (tls_out.active.sock >= 0)
     }
 
   if (smtp_write_command(sx,
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
        sx->early_pipe_active ? SCMD_BUFFER :
 #endif
          SCMD_FLUSH,
        "%s %s\r\n", greeting_cmd, sx->helo_data) < 0)
     goto SEND_FAILED;
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   if (sx->early_pipe_active)
     sx->pending_EHLO = TRUE;
   else
@@ -2685,13 +2685,13 @@ if (continue_hostname == NULL
   {
   if (sx->esmtp || sx->lmtp)
     {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   if (!sx->early_pipe_active)
 #endif
     {
     sx->peer_offered = ehlo_response(sx->buffer,
        0 /* no TLS */
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
        | (sx->lmtp && ob->lmtp_ignore_quota ? OPTION_IGNQ : 0)
        | OPTION_DSN | OPTION_PIPE | OPTION_SIZE
        | OPTION_CHUNKING | OPTION_PRDR | OPTION_UTF8
@@ -2712,7 +2712,7 @@ if (continue_hostname == NULL
        | (ob->size_addition >= 0 ? OPTION_SIZE : 0)
 #endif
       );
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (tls_out.active.sock >= 0)
       sx->ehlo_resp.crypted_features = sx->peer_offered;
 #endif
@@ -2760,7 +2760,7 @@ if (continue_hostname == NULL
     DEBUG(D_transport) debug_printf("%susing DSN\n",
                        sx->peer_offered & OPTION_DSN ? "" : "not ");
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     if (  sx->early_pipe_ok
        && !sx->early_pipe_active
        && tls_out.active.sock >= 0
@@ -3276,7 +3276,7 @@ for (addr = sx->first_addr, address_count = 0;
       case -2: return -2;                      /* non-MAIL read i/o error */
       default: return -1;                      /* any MAIL error */
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
       case -4: return -1;                      /* non-2xx for pipelined banner or EHLO */
       case -5: return -1;                      /* TLS first-read error */
 #endif
@@ -3608,7 +3608,7 @@ if (  !(sx.peer_offered & OPTION_CHUNKING)
 
     case -1: goto END_OFF;             /* Timeout on RCPT */
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
     case -5:                           /* TLS first-read error */
     case -4:  HDEBUG(D_transport)
                debug_printf("failed reaping pipelined cmd responses\n");
@@ -3754,7 +3754,7 @@ else
 
       case -1: goto END_OFF;           /* Timeout on RCPT */
 
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
       case -5:                         /* TLS first-read error */
       case -4:  HDEBUG(D_transport)
                  debug_printf("failed reaping pipelined cmd responses\n");
@@ -3906,7 +3906,7 @@ else
        if (tcp_out_fastopen >= TFO_USED_DATA) setflag(addr, af_tcp_fastopen_data);
        }
       if (sx.pipelining_used) setflag(addr, af_pipelining);
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
       if (sx.early_pipe_active) setflag(addr, af_early_pipe);
 #endif
 #ifndef DISABLE_PRDR
@@ -4108,7 +4108,7 @@ if (!sx.ok)
 
     else
       {
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
       /* If we were early-pipelinng and the actual EHLO response did not match
       the cached value we assumed, we could have detected it and passed a
       custom errno through to here.  It would be nice to RSET and retry right
index 5200fcb74db4e1f7c189ad4bc97d99fefeca91f0..79d674fa1ed556fd7664b1a1b0e2983bcbc27cd5 100644 (file)
@@ -46,7 +46,7 @@ typedef struct {
   uschar *hosts_avoid_tls;
   uschar *hosts_verify_avoid_tls;
   uschar *hosts_avoid_pipelining;
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   uschar *hosts_pipe_connect;
 #endif
   uschar *hosts_avoid_esmtp;
@@ -121,7 +121,7 @@ typedef struct {
   BOOL smtps:1;
   BOOL ok:1;
   BOOL setting_up:1;
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   BOOL early_pipe_ok:1;
   BOOL early_pipe_active:1;
 #endif
@@ -138,7 +138,7 @@ typedef struct {
 #if !defined(DISABLE_TLS) && defined(SUPPORT_DANE)
   BOOL dane_required:1;
 #endif
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   BOOL pending_BANNER:1;
   BOOL pending_EHLO:1;
 #endif
@@ -160,7 +160,7 @@ typedef struct {
   uschar *     smtp_greeting;
   uschar *     helo_response;
 #endif
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
   ehlo_resp_precis     ehlo_resp;
 #endif
 
index bd0b9859b34edeef194b010d7387d7d49cde12a1..33caf204ef4d40e69cf75954b13856271694a3ac 100755 (executable)
@@ -1164,6 +1164,9 @@ RESET_AFTER_EXTRA_LINE_READ:
     # SUPPORT_PROXY
     next if /host in hosts_proxy\?/;
 
+    # PIPE_CONNECT
+    next if / in (pipelining_connect_advertise_hosts|hosts_pipe_connect)?\? no /;
+
     # Experimental_International
     next if / in smtputf8_advertise_hosts\? no \(option unset\)/;
 
@@ -1173,9 +1176,6 @@ RESET_AFTER_EXTRA_LINE_READ:
     # TCP Fast Open
     next if /^(ppppp )?setsockopt FASTOPEN: Network Error/;
 
-    # Experimental_PIPE_CONNECT
-    next if / in (pipelining_connect_advertise_hosts|hosts_pipe_connect)?\? no /;
-
     # Environment cleaning
     next if /\w+ in keep_environment\? (yes|no)/;
 
index fd2535fa57315b6d58b07381d528a403ea67e13c..1b9b3f83c542078c1f7623c462dde0a026e62aa4 100644 (file)
@@ -1 +1 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
index 9ae94aaaf1402857e384ea12ef569be9ec9adb98..5d02ef731bc2d570d3c3a1e564b0d735964e3b9b 100644 (file)
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 authenticator plaintext
index c18c49b2ee98593ee9e9dae004ce83515f32a3a6..5136f5257c7c4aeb814f9605a1926f67da58a5ff 100644 (file)
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 support TCP_Fast_Open
index 36c96e737ea12d52f81299dd1fca60481f0716ce..9c2dba1fb57d41ded4b7204b43555aa78a0b6378 100644 (file)
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 support GnuTLS
index 3863ae742d15b6413a575b43de5ee0a42426c1bb..14cbb1305154a7da35dd19fbd54b08b4ffe30825 100644 (file)
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 support OpenSSL
index fafecf0feb2ac550f904f1b2ee0b9c213cdc66b7..a7b932236d5739b3f9cef03fdf6a96559e5495b2 100644 (file)
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 support GnuTLS
 authenticator plaintext
index e58e0f91a3110e40712190466d0f1a8d01499b3e..502171d901cd498681405571b9d130eea5c9dcdf 100644 (file)
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 support OpenSSL
 authenticator plaintext
index 0cfd46cac32d7e6b7623078a16c9d4aa3930604b..7531f8c261a8df511355aa4cbcf73950cc5844ae 100644 (file)
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 support GnuTLS
 support TCP_Fast_Open
index be856b0d60d995a92cb10ac2a8df0b5d74b25898..b8d0734b31bf9df198bf2a41f72bd7511939aff0 100644 (file)
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
 support OpenSSL
 support TCP_Fast_Open