Gitweb:
https://git.exim.org/exim.git/commitdiff/4e48d56c083d2f763a5978e1dbf515b12dc12f96
Commit: 4e48d56c083d2f763a5978e1dbf515b12dc12f96
Parent: fd6e2d18420f43b0c956d943024cb462e1af6aa6
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Tue May 28 20:02:50 2019 +0100
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Tue May 28 22:18:49 2019 +0100
PIPE_CONNECT: promote from experimental
---
doc/doc-docbook/spec.xfpt | 47 +++++++++++++
doc/doc-txt/ChangeLog | 5 +-
doc/doc-txt/experimental-spec.txt | 81 -----------------------
src/src/EDITME | 5 ++
src/src/config.h.defaults | 2 +-
src/src/dbstuff.h | 2 +-
src/src/deliver.c | 8 +--
src/src/exim.c | 6 +-
src/src/globals.c | 6 +-
src/src/globals.h | 6 +-
src/src/macro_predef.c | 6 +-
src/src/readconf.c | 8 +--
src/src/receive.c | 2 +-
src/src/smtp_in.c | 18 ++---
src/src/smtp_out.c | 2 +-
src/src/structs.h | 2 +-
src/src/tls-openssl.c | 4 +-
src/src/transports/smtp.c | 70 ++++++++++----------
src/src/transports/smtp.h | 8 +--
test/runtest | 6 +-
test/scripts/4050-pipe-conn/REQUIRES | 2 +-
test/scripts/4056-pipe-conn-auth/REQUIRES | 2 +-
test/scripts/4058-pipe-conn-tfo/REQUIRES | 2 +-
test/scripts/4060-pipe-conn-gnutls/REQUIRES | 2 +-
test/scripts/4062-pipe-conn-openssl/REQUIRES | 2 +-
test/scripts/4064-pipe-conn-gnutls-auth/REQUIRES | 2 +-
test/scripts/4066-pipe-conn-openssl-auth/REQUIRES | 2 +-
test/scripts/4068-pipe-conn-gnutls-tfo/REQUIRES | 2 +-
test/scripts/4069-pipe-conn-openssl-tfo/REQUIRES | 2 +-
29 files changed, 143 insertions(+), 169 deletions(-)
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index bfacdef..34c4310 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -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"
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 6280174..b4e5899 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -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
-----------------
diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index 328d094..f748f61 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -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
diff --git a/src/src/EDITME b/src/src/EDITME
index fe945c3..fa1fe1c 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -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
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index 27b8fb4..17239bb 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -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
diff --git a/src/src/dbstuff.h b/src/src/dbstuff.h
index 58154d7..b7889bd 100644
--- a/src/src/dbstuff.h
+++ b/src/src/dbstuff.h
@@ -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) */
diff --git a/src/src/deliver.c b/src/src/deliver.c
index dc7a7d5..b26e5db 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -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
diff --git a/src/src/exim.c b/src/src/exim.c
index abce9fc..7571705 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -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
diff --git a/src/src/globals.c b/src/src/globals.c
index 5ce04a6..e70e385 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -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;
diff --git a/src/src/globals.h b/src/src/globals.h
index d29fcc4..83d29ba 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -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 */
diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c
index ebb4cb9..fce9819 100644
--- a/src/src/macro_predef.c
+++ b/src/src/macro_predef.c
@@ -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
diff --git a/src/src/readconf.c b/src/src/readconf.c
index cffee4a..b9d1935 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -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
}
diff --git a/src/src/receive.c b/src/src/receive.c
index 9769e88..ed2afb3 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -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)
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 049f5b5..1e478a6 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -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)
diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c
index ea052b5..c1cf901 100644
--- a/src/src/smtp_out.c
+++ b/src/src/smtp_out.c
@@ -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;
diff --git a/src/src/structs.h b/src/src/structs.h
index 9fade00..0b01d58 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -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
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index f3ea6b2..ea30ff7 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -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
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 5c7b440..baf3044 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -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
diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h
index 5200fcb..79d674f 100644
--- a/src/src/transports/smtp.h
+++ b/src/src/transports/smtp.h
@@ -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
diff --git a/test/runtest b/test/runtest
index bd0b985..33caf20 100755
--- a/test/runtest
+++ b/test/runtest
@@ -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)/;
diff --git a/test/scripts/4050-pipe-conn/REQUIRES b/test/scripts/4050-pipe-conn/REQUIRES
index fd2535f..1b9b3f8 100644
--- a/test/scripts/4050-pipe-conn/REQUIRES
+++ b/test/scripts/4050-pipe-conn/REQUIRES
@@ -1 +1 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
diff --git a/test/scripts/4056-pipe-conn-auth/REQUIRES b/test/scripts/4056-pipe-conn-auth/REQUIRES
index 9ae94aa..5d02ef7 100644
--- a/test/scripts/4056-pipe-conn-auth/REQUIRES
+++ b/test/scripts/4056-pipe-conn-auth/REQUIRES
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
authenticator plaintext
diff --git a/test/scripts/4058-pipe-conn-tfo/REQUIRES b/test/scripts/4058-pipe-conn-tfo/REQUIRES
index c18c49b..5136f52 100644
--- a/test/scripts/4058-pipe-conn-tfo/REQUIRES
+++ b/test/scripts/4058-pipe-conn-tfo/REQUIRES
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
support TCP_Fast_Open
diff --git a/test/scripts/4060-pipe-conn-gnutls/REQUIRES b/test/scripts/4060-pipe-conn-gnutls/REQUIRES
index 36c96e7..9c2dba1 100644
--- a/test/scripts/4060-pipe-conn-gnutls/REQUIRES
+++ b/test/scripts/4060-pipe-conn-gnutls/REQUIRES
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
support GnuTLS
diff --git a/test/scripts/4062-pipe-conn-openssl/REQUIRES b/test/scripts/4062-pipe-conn-openssl/REQUIRES
index 3863ae7..14cbb13 100644
--- a/test/scripts/4062-pipe-conn-openssl/REQUIRES
+++ b/test/scripts/4062-pipe-conn-openssl/REQUIRES
@@ -1,2 +1,2 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
support OpenSSL
diff --git a/test/scripts/4064-pipe-conn-gnutls-auth/REQUIRES b/test/scripts/4064-pipe-conn-gnutls-auth/REQUIRES
index fafecf0..a7b9322 100644
--- a/test/scripts/4064-pipe-conn-gnutls-auth/REQUIRES
+++ b/test/scripts/4064-pipe-conn-gnutls-auth/REQUIRES
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
support GnuTLS
authenticator plaintext
diff --git a/test/scripts/4066-pipe-conn-openssl-auth/REQUIRES b/test/scripts/4066-pipe-conn-openssl-auth/REQUIRES
index e58e0f9..502171d 100644
--- a/test/scripts/4066-pipe-conn-openssl-auth/REQUIRES
+++ b/test/scripts/4066-pipe-conn-openssl-auth/REQUIRES
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
support OpenSSL
authenticator plaintext
diff --git a/test/scripts/4068-pipe-conn-gnutls-tfo/REQUIRES b/test/scripts/4068-pipe-conn-gnutls-tfo/REQUIRES
index 0cfd46c..7531f8c 100644
--- a/test/scripts/4068-pipe-conn-gnutls-tfo/REQUIRES
+++ b/test/scripts/4068-pipe-conn-gnutls-tfo/REQUIRES
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
support GnuTLS
support TCP_Fast_Open
diff --git a/test/scripts/4069-pipe-conn-openssl-tfo/REQUIRES b/test/scripts/4069-pipe-conn-openssl-tfo/REQUIRES
index be856b0..b8d0734 100644
--- a/test/scripts/4069-pipe-conn-openssl-tfo/REQUIRES
+++ b/test/scripts/4069-pipe-conn-openssl-tfo/REQUIRES
@@ -1,3 +1,3 @@
-support Experimental_PIPE_CONNECT
+support PIPE_CONNECT
support OpenSSL
support TCP_Fast_Open