diff --git a/postfix/HISTORY b/postfix/HISTORY index 2d7c3564d..34a838444 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -11690,6 +11690,23 @@ Apologies for any names omitted. (example: sockaddr_to_hostaddr: Unknown error: success). File: util/myaddrinfo.c. +20051228 + + Workaround: don't pipeline the DOT+QUIT commands in the + SMTP client. The 20050929 paranoia about malformed server + replies eliminated a rare occurrence of "lost mail" with + sites that mis-implement DOT+QUIT pipelining. However, we + now have a larger occurrence of repeated deliveries to sites + with different implementation errors. + + The default "smtp_pipeline_dot_quit = never" setting + eliminates the repeated deliveries at the cost of a small + performance loss with normal deliveries. Other settings + are "always" (always pipeline the DOT+QUIT commands, when + pipelining is enabled) and "newmail" (pipeline DOT+QUIT + only when mail is newer than $minimal_backoff_time). + Files: smtp/smtp_proto.c, smtp/smtp.c. + Open problems: "postsuper -r" no longer resets the message arrival time, diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 0554a7089..fd785d210 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -17,6 +17,20 @@ Incompatibility with Postfix 2.1 and earlier If you upgrade from Postfix 2.1 or earlier, read RELEASE_NOTES-2.2 before proceeding. +Incompatibility with snapshot 20051228 +====================================== + +New parameter "smtp_pipeline_dot_quit" (default: "never") to work +around broken servers and firewalls. After one documented case of +lost mail, as of 20050929 Postfix is more paranoid about malformed +SMTP server replies. Unfortuately this results in repeated delivery +attempts with other broken systems. To avoid this, the SMTP+LMTP +client no longer pipelines the DOT+QUIT commands by default. Instead +of "never" you can specify "always" (self-evident) or "newmail" +(pipeline DOT+QUIT only when mail is newer than $minimal_backoff_time, +so that the number of duplicate deliveries is limited). More details +are in the postconf(5) manual. + Major changes with snapshot 20051222 ==================================== diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index a0d06322e..cabc84d9c 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -3224,7 +3224,7 @@ case insensitive lists of LHLO keywords (pipelining, starttls, auth, etc.) that the LMTP client will ignore in the LHLO response from a remote LMTP server. See lmtp_discard_lhlo_keywords for details. The table is not indexed by hostname for consistency with -smtpd_discard_ehlo_keyword_address_map

+smtpd_discard_ehlo_keyword_address_maps.

This feature is available in Postfix 2.3 and later.

@@ -3377,6 +3377,15 @@ parameter. See there for details.

This feature is available in Postfix 2.3 and later.

+ + +
lmtp_pipeline_dot_quit +(default: never)
+ +

The LMTP-specific version of the smtp_pipeline_dot_quit +configuration parameter. See there for details.

+ +
lmtp_pix_workaround_delay_time @@ -6892,6 +6901,45 @@ complete the EHLO and TLS handshake (Postfix version 2.3 and later).

smtp_always_send_ehlo parameter.

+ + +
smtp_pipeline_dot_quit +(default: never)
+ +

When ESMTP command pipelining is enabled, whether or not the +SMTP client will send the QUIT command before it has received the +server's END-OF-DATA reply.

+ +

Specify one of the following:

+ +
+ +
always
Always pipeline the END-OF-DATA and +QUIT commands. With servers or firewalls that mis-implement +END-OF-DATA + QUIT pipelining, mail will be delivered repeatedly +until it expires in the queue.
+ +
never
Wait for the server's END-OF-DATA reply +before sending the QUIT command. This avoids repeated delivery +attempts with servers and firewalls that mis-implement END-OF-DATA ++ QUIT pipelining, at the cost of a small performance loss with +sites that correctly implement SMTP.
+ +
newmail
Pipeline the END-OF-DATA and QUIT +commands only when mail is newer than $minimal_backoff_time. This +limits the number of repeated deliveries with servers and firewalls +that mis-implement END-OF-DATA + QUIT pipelining, while avoiding +the performance loss associated with the "never" setting for normal +deliveries.
+ +
+ +

Note: when smtp_fallback_relay is used, the "always" and "newmail" +settings become identical in practice.

+ +

This feature is available in Postfix 2.3 and later.

+ +
smtp_pix_workaround_delay_time diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index 41d9075d9..21c01c46f 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -170,18 +170,24 @@ SMTP(8) SMTP(8) The maximal length of message header and body lines that Postfix will send via SMTP. + smtp_pipeline_dot_quit (never) + When ESMTP command pipelining is enabled, whether + or not the SMTP client will send the QUIT command + before it has received the server's END-OF-DATA + reply. + smtp_pix_workaround_delay_time (10s) - How long the Postfix SMTP client pauses before + How long the Postfix SMTP client pauses before sending ".<CR><LF>" in order to work around the PIX firewall "<CR><LF>.<CR><LF>" bug. smtp_pix_workaround_threshold_time (500s) - How long a message must be queued before the PIX - firewall "<CR><LF>.<CR><LF>" bug workaround is + How long a message must be queued before the PIX + firewall "<CR><LF>.<CR><LF>" bug workaround is turned on. smtp_quote_rfc821_envelope (yes) - Quote addresses in SMTP MAIL FROM and RCPT TO com- + Quote addresses in SMTP MAIL FROM and RCPT TO com- mands as required by RFC 821. smtp_skip_5xx_greeting (yes) @@ -189,7 +195,7 @@ SMTP(8) SMTP(8) (go away, do not try again later). smtp_skip_quit_response (yes) - Do not wait for the response to the SMTP QUIT com- + Do not wait for the response to the SMTP QUIT com- mand. Available in Postfix version 2.0 and earlier: @@ -201,36 +207,36 @@ SMTP(8) SMTP(8) Available in Postfix version 2.2 and later: smtp_discard_ehlo_keyword_address_maps (empty) - Lookup tables, indexed by the remote SMTP server - address, with case insensitive lists of EHLO key- - words (pipelining, starttls, auth, etc.) that the + Lookup tables, indexed by the remote SMTP server + address, with case insensitive lists of EHLO key- + words (pipelining, starttls, auth, etc.) that the SMTP client will ignore in the EHLO response from a remote SMTP server. smtp_discard_ehlo_keywords (empty) - A case insensitive list of EHLO keywords (pipelin- - ing, starttls, auth, etc.) that the SMTP client + A case insensitive list of EHLO keywords (pipelin- + ing, starttls, auth, etc.) that the SMTP client will ignore in the EHLO response from a remote SMTP server. smtp_generic_maps (empty) Optional lookup tables that perform address rewrit- - ing in the SMTP client, typically to transform a + ing in the SMTP client, typically to transform a locally valid address into a globally valid address when sending mail across the Internet. Available in Postfix version 2.3 and later: lmtp_discard_lhlo_keyword_address_maps (empty) - Lookup tables, indexed by the remote LMTP server - address, with case insensitive lists of LHLO key- - words (pipelining, starttls, auth, etc.) that the + Lookup tables, indexed by the remote LMTP server + address, with case insensitive lists of LHLO key- + words (pipelining, starttls, auth, etc.) that the LMTP client will ignore in the LHLO response from a remote LMTP server. lmtp_discard_lhlo_keywords ($myhostname) - A case insensitive list of LHLO keywords (pipelin- - ing, starttls, auth, etc.) that the LMTP client + A case insensitive list of LHLO keywords (pipelin- + ing, starttls, auth, etc.) that the LMTP client will ignore in the LHLO response from a remote LMTP server. @@ -238,7 +244,7 @@ SMTP(8) SMTP(8) Available in Postfix version 2.0 and later: disable_mime_output_conversion (no) - Disable the conversion of 8BITMIME format to 7BIT + Disable the conversion of 8BITMIME format to 7BIT format. mime_boundary_length_limit (2048) @@ -253,132 +259,132 @@ SMTP(8) SMTP(8) Available in Postfix version 2.1 and later: smtp_send_xforward_command (no) - Send the non-standard XFORWARD command when the - Postfix SMTP server EHLO response announces XFOR- + Send the non-standard XFORWARD command when the + Postfix SMTP server EHLO response announces XFOR- WARD support. SASL AUTHENTICATION CONTROLS smtp_sasl_auth_enable (no) - Enable SASL authentication in the Postfix SMTP + Enable SASL authentication in the Postfix SMTP client. smtp_sasl_password_maps (empty) - Optional SMTP client lookup tables with one user- - name:password entry per remote hostname or domain, + Optional SMTP client lookup tables with one user- + name:password entry per remote hostname or domain, or sender address when sender-dependent authentica- tion is enabled. smtp_sasl_security_options (noplaintext, noanonymous) - SASL security options; as of Postfix 2.3 the list - of available features depends on the SASL client - implementation that is selected with + SASL security options; as of Postfix 2.3 the list + of available features depends on the SASL client + implementation that is selected with smtp_sasl_type. Available in Postfix version 2.2 and later: smtp_sasl_mechanism_filter (empty) - If non-empty, a Postfix SMTP client filter for the - remote SMTP server's list of offered SASL mecha- + If non-empty, a Postfix SMTP client filter for the + remote SMTP server's list of offered SASL mecha- nisms. Available in Postfix version 2.3 and later: smtp_sender_dependent_authentication (no) - Enable sender-dependent authentication in the SMTP - client; this is available only with SASL authenti- - cation, and disables SMTP connection caching to - ensure that mail from different senders will use + Enable sender-dependent authentication in the SMTP + client; this is available only with SASL authenti- + cation, and disables SMTP connection caching to + ensure that mail from different senders will use the appropriate credentials. smtp_sasl_path (empty) - Implementation-specific information that is passed - through to the SASL plug-in implementation that is + Implementation-specific information that is passed + through to the SASL plug-in implementation that is selected with smtp_sasl_type. smtp_sasl_type (cyrus) - The SASL plug-in type that the Postfix SMTP client + The SASL plug-in type that the Postfix SMTP client should use for authentication. STARTTLS SUPPORT CONTROLS - Detailed information about STARTTLS configuration may be + Detailed information about STARTTLS configuration may be found in the TLS_README document. smtp_use_tls (no) - Opportunistic mode: use TLS when a remote SMTP - server announces STARTTLS support, otherwise send + Opportunistic mode: use TLS when a remote SMTP + server announces STARTTLS support, otherwise send the mail in the clear. smtp_enforce_tls (no) - Enforcement mode: require that remote SMTP servers - use TLS encryption, and never send mail in the + Enforcement mode: require that remote SMTP servers + use TLS encryption, and never send mail in the clear. smtp_sasl_tls_security_options ($smtp_sasl_secu- rity_options) - The SASL authentication security options that the - Postfix SMTP client uses for TLS encrypted SMTP + The SASL authentication security options that the + Postfix SMTP client uses for TLS encrypted SMTP sessions. smtp_starttls_timeout (300s) - Time limit for Postfix SMTP client write and read - operations during TLS startup and shutdown hand- + Time limit for Postfix SMTP client write and read + operations during TLS startup and shutdown hand- shake procedures. smtp_tls_CAfile (empty) - The file with the certificate of the certification - authority (CA) that issued the Postfix SMTP client + The file with the certificate of the certification + authority (CA) that issued the Postfix SMTP client certificate. smtp_tls_CApath (empty) - Directory with PEM format certificate authority - certificates that the Postfix SMTP client uses to + Directory with PEM format certificate authority + certificates that the Postfix SMTP client uses to verify a remote SMTP server certificate. smtp_tls_cert_file (empty) - File with the Postfix SMTP client RSA certificate + File with the Postfix SMTP client RSA certificate in PEM format. smtp_tls_cipherlist (empty) - Controls the Postfix SMTP client TLS cipher selec- + Controls the Postfix SMTP client TLS cipher selec- tion scheme. smtp_tls_dcert_file (empty) - File with the Postfix SMTP client DSA certificate + File with the Postfix SMTP client DSA certificate in PEM format. smtp_tls_dkey_file ($smtp_tls_dcert_file) - File with the Postfix SMTP client DSA private key + File with the Postfix SMTP client DSA private key in PEM format. smtp_tls_enforce_peername (yes) - When TLS encryption is enforced, require that the + When TLS encryption is enforced, require that the remote SMTP server hostname matches the information in the remote SMTP server certificate. smtp_tls_key_file ($smtp_tls_cert_file) - File with the Postfix SMTP client RSA private key + File with the Postfix SMTP client RSA private key in PEM format. smtp_tls_loglevel (0) - Enable additional Postfix SMTP client logging of + Enable additional Postfix SMTP client logging of TLS activity. smtp_tls_note_starttls_offer (no) - Log the hostname of a remote SMTP server that - offers STARTTLS, when TLS is not already enabled + Log the hostname of a remote SMTP server that + offers STARTTLS, when TLS is not already enabled for that server. smtp_tls_per_site (empty) Optional lookup tables with the Postfix SMTP client - TLS usage policy by next-hop domain name and by + TLS usage policy by next-hop domain name and by remote SMTP server hostname. smtp_tls_scert_verifydepth (5) - The verification depth for remote SMTP server cer- + The verification depth for remote SMTP server cer- tificates. smtp_tls_session_cache_database (empty) - Name of the file containing the optional Postfix + Name of the file containing the optional Postfix SMTP client TLS session cache. smtp_tls_session_cache_timeout (3600s) @@ -386,35 +392,35 @@ SMTP(8) SMTP(8) sion cache information. tls_daemon_random_bytes (32) - The number of pseudo-random bytes that an smtp(8) - or smtpd(8) process requests from the tlsmgr(8) - server in order to seed its internal pseudo random + The number of pseudo-random bytes that an smtp(8) + or smtpd(8) process requests from the tlsmgr(8) + server in order to seed its internal pseudo random number generator (PRNG). RESOURCE AND RATE CONTROLS smtp_destination_concurrency_limit ($default_destina- tion_concurrency_limit) - The maximal number of parallel deliveries to the - same destination via the smtp message delivery + The maximal number of parallel deliveries to the + same destination via the smtp message delivery transport. smtp_destination_recipient_limit ($default_destina- tion_recipient_limit) - The maximal number of recipients per delivery via + The maximal number of recipients per delivery via the smtp message delivery transport. smtp_connect_timeout (30s) - The SMTP client time limit for completing a TCP + The SMTP client time limit for completing a TCP connection, or zero (use the operating system built-in time limit). smtp_helo_timeout (300s) - The SMTP client time limit for sending the HELO or - EHLO command, and for receiving the initial server + The SMTP client time limit for sending the HELO or + EHLO command, and for receiving the initial server response. lmtp_lhlo_timeout (300s) - The LMTP client time limit for sending the LHLO + The LMTP client time limit for sending the LHLO command, and for receiving the initial server response. @@ -423,30 +429,30 @@ SMTP(8) SMTP(8) command, and for receiving the server response. smtp_mail_timeout (300s) - The SMTP client time limit for sending the MAIL - FROM command, and for receiving the server + The SMTP client time limit for sending the MAIL + FROM command, and for receiving the server response. smtp_rcpt_timeout (300s) - The SMTP client time limit for sending the SMTP - RCPT TO command, and for receiving the server + The SMTP client time limit for sending the SMTP + RCPT TO command, and for receiving the server response. smtp_data_init_timeout (120s) - The SMTP client time limit for sending the SMTP - DATA command, and for receiving the server + The SMTP client time limit for sending the SMTP + DATA command, and for receiving the server response. smtp_data_xfer_timeout (180s) - The SMTP client time limit for sending the SMTP + The SMTP client time limit for sending the SMTP message content. smtp_data_done_timeout (600s) - The SMTP client time limit for sending the SMTP + The SMTP client time limit for sending the SMTP ".", and for receiving the server response. smtp_quit_timeout (300s) - The SMTP client time limit for sending the QUIT + The SMTP client time limit for sending the QUIT command, and for receiving the server response. Available in Postfix version 2.1 and later: @@ -457,12 +463,12 @@ SMTP(8) SMTP(8) lookups, or zero (no limit). smtp_mx_session_limit (2) - The maximal number of SMTP sessions per delivery - request before giving up or delivering to a fall- + The maximal number of SMTP sessions per delivery + request before giving up or delivering to a fall- back relay host, or zero (no limit). smtp_rset_timeout (20s) - The SMTP client time limit for sending the RSET + The SMTP client time limit for sending the RSET command, and for receiving the server response. Available in Postfix version 2.2 and earlier: @@ -474,11 +480,11 @@ SMTP(8) SMTP(8) Available in Postfix version 2.2 and later: smtp_connection_cache_destinations (empty) - Permanently enable SMTP connection caching for the + Permanently enable SMTP connection caching for the specified destinations. smtp_connection_cache_on_demand (yes) - Temporarily enable SMTP connection caching while a + Temporarily enable SMTP connection caching while a destination has a high volume of mail in the active queue. @@ -488,57 +494,57 @@ SMTP(8) SMTP(8) smtp_connection_cache_time_limit (2s) When SMTP connection caching is enabled, the amount - of time that an unused SMTP client socket is kept + of time that an unused SMTP client socket is kept open before it is closed. Available in Postfix version 2.3 and later: connection_cache_protocol_timeout (5s) - Time limit for connection cache connect, send or + Time limit for connection cache connect, send or receive operations. TROUBLE SHOOTING CONTROLS debug_peer_level (2) - The increment in verbose logging level when a - remote client or server matches a pattern in the + The increment in verbose logging level when a + remote client or server matches a pattern in the debug_peer_list parameter. debug_peer_list (empty) - Optional list of remote client or server hostname - or network address patterns that cause the verbose - logging level to increase by the amount specified + Optional list of remote client or server hostname + or network address patterns that cause the verbose + logging level to increase by the amount specified in $debug_peer_level. error_notice_recipient (postmaster) - The recipient of postmaster notifications about - mail delivery problems that are caused by policy, + The recipient of postmaster notifications about + mail delivery problems that are caused by policy, resource, software or protocol errors. notify_classes (resource, software) - The list of error classes that are reported to the + The list of error classes that are reported to the postmaster. MISCELLANEOUS CONTROLS best_mx_transport (empty) - Where the Postfix SMTP client should deliver mail + Where the Postfix SMTP client should deliver mail when it detects a "mail loops back to myself" error condition. config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and + The default location of the Postfix main.cf and master.cf configuration files. daemon_timeout (18000s) - How much time a Postfix daemon process may take to - handle a request before it is terminated by a + How much time a Postfix daemon process may take to + handle a request before it is terminated by a built-in watchdog timer. delay_logging_resolution_limit (2) - The maximal number of digits after the decimal + The maximal number of digits after the decimal point when logging sub-second delay values. disable_dns_lookups (no) - Disable DNS lookups in the Postfix SMTP and LMTP + Disable DNS lookups in the Postfix SMTP and LMTP clients. inet_interfaces (all) @@ -546,7 +552,7 @@ SMTP(8) SMTP(8) tem receives mail on. inet_protocols (ipv4) - The Internet protocols Postfix will attempt to use + The Internet protocols Postfix will attempt to use when making or accepting connections. ipc_timeout (3600s) @@ -554,74 +560,74 @@ SMTP(8) SMTP(8) over an internal communication channel. lmtp_tcp_port (24) - The default TCP port that the Postfix LMTP client + The default TCP port that the Postfix LMTP client connects to. max_idle (100s) - The maximum amount of time that an idle Postfix - daemon process waits for the next service request + The maximum amount of time that an idle Postfix + daemon process waits for the next service request before exiting. max_use (100) - The maximal number of connection requests before a + The maximal number of connection requests before a Postfix daemon process terminates. process_id (read-only) - The process ID of a Postfix command or daemon + The process ID of a Postfix command or daemon process. process_name (read-only) - The process name of a Postfix command or daemon + The process name of a Postfix command or daemon process. proxy_interfaces (empty) The network interface addresses that this mail sys- - tem receives mail on by way of a proxy or network + tem receives mail on by way of a proxy or network address translation unit. smtp_bind_address (empty) An optional numerical network address that the SMTP - client should bind to when making an IPv4 connec- + client should bind to when making an IPv4 connec- tion. smtp_bind_address6 (empty) An optional numerical network address that the SMTP - client should bind to when making an IPv6 connec- + client should bind to when making an IPv6 connec- tion. smtp_helo_name ($myhostname) - The hostname to send in the SMTP EHLO or HELO com- + The hostname to send in the SMTP EHLO or HELO com- mand. lmtp_lhlo_name ($myhostname) The hostname to send in the LMTP LHLO command. smtp_host_lookup (dns) - What mechanisms when the SMTP client uses to look + What mechanisms when the SMTP client uses to look up a host's IP address. smtp_randomize_addresses (yes) - Randomize the order of equal-preference MX host + Randomize the order of equal-preference MX host addresses. syslog_facility (mail) The syslog facility of Postfix logging. syslog_name (postfix) - The mail system name that is prepended to the - process name in syslog records, so that "smtpd" + The mail system name that is prepended to the + process name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". Available with Postfix 2.2 and earlier: fallback_relay (empty) - Optional list of relay hosts for SMTP destinations + Optional list of relay hosts for SMTP destinations that can't be found or that are unreachable. Available with Postfix 2.3 and later: smtp_fallback_relay ($fallback_relay) - Optional list of relay hosts for SMTP destinations + Optional list of relay hosts for SMTP destinations that can't be found or that are unreachable. SEE ALSO @@ -639,7 +645,7 @@ SMTP(8) SMTP(8) TLS_README, Postfix STARTTLS howto LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index a8f8f4f9e..da6589148 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -1729,7 +1729,7 @@ case insensitive lists of LHLO keywords (pipelining, starttls, auth, etc.) that the LMTP client will ignore in the LHLO response from a remote LMTP server. See lmtp_discard_lhlo_keywords for details. The table is not indexed by hostname for consistency with -smtpd_discard_ehlo_keyword_address_map +smtpd_discard_ehlo_keyword_address_maps. .PP This feature is available in Postfix 2.3 and later. .SH lmtp_discard_lhlo_keywords (default: $myhostname) @@ -1808,6 +1808,9 @@ The LMTP-specific version of the smtp_mx_session_limit configuration parameter. See there for details. .PP This feature is available in Postfix 2.3 and later. +.SH lmtp_pipeline_dot_quit (default: never) +The LMTP-specific version of the smtp_pipeline_dot_quit +configuration parameter. See there for details. .SH lmtp_pix_workaround_delay_time (default: 10s) The LMTP-specific version of the smtp_pix_workaround_delay_time configuration parameter. See there for details. @@ -3838,6 +3841,35 @@ This feature is available in Postfix 2.1 and later. .SH smtp_never_send_ehlo (default: no) Never send EHLO at the start of an SMTP session. See also the smtp_always_send_ehlo parameter. +.SH smtp_pipeline_dot_quit (default: never) +When ESMTP command pipelining is enabled, whether or not the +SMTP client will send the QUIT command before it has received the +server's END-OF-DATA reply. +.PP +Specify one of the following: +.IP "\fBalways\fR" +Always pipeline the END-OF-DATA and +QUIT commands. With servers or firewalls that mis-implement +END-OF-DATA + QUIT pipelining, mail will be delivered repeatedly +until it expires in the queue. +.IP "\fBnever\fR" +Wait for the server's END-OF-DATA reply +before sending the QUIT command. This avoids repeated delivery +attempts with servers and firewalls that mis-implement END-OF-DATA ++ QUIT pipelining, at the cost of a small performance loss with +sites that correctly implement SMTP. +.IP "\fBnewmail\fR" +Pipeline the END-OF-DATA and QUIT +commands only when mail is newer than $minimal_backoff_time. This +limits the number of repeated deliveries with servers and firewalls +that mis-implement END-OF-DATA + QUIT pipelining, while avoiding +the performance loss associated with the "never" setting for normal +deliveries. +.PP +Note: when smtp_fallback_relay is used, the "always" and "newmail" +settings become identical in practice. +.PP +This feature is available in Postfix 2.3 and later. .SH smtp_pix_workaround_delay_time (default: 10s) How long the Postfix SMTP client pauses before sending "." in order to work around the PIX firewall diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index 3f42ff7d1..f8bcaefeb 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -165,6 +165,10 @@ Defer mail delivery when no MX record resolves to an IP address. .IP "\fBsmtp_line_length_limit (990)\fR" The maximal length of message header and body lines that Postfix will send via SMTP. +.IP "\fBsmtp_pipeline_dot_quit (never)\fR" +When ESMTP command pipelining is enabled, whether or not the +SMTP client will send the QUIT command before it has received the +server's END-OF-DATA reply. .IP "\fBsmtp_pix_workaround_delay_time (10s)\fR" How long the Postfix SMTP client pauses before sending "." in order to work around the PIX firewall @@ -190,9 +194,9 @@ again later). Available in Postfix version 2.2 and later: .IP "\fBsmtp_discard_ehlo_keyword_address_maps (empty)\fR" Lookup tables, indexed by the remote SMTP server address, with -case insensitive lists of EHLO keywords (pipelining, starttls, -auth, etc.) that the SMTP client will ignore in the EHLO response -from a remote SMTP server. +case insensitive lists of EHLO keywords (pipelining, starttls, auth, +etc.) that the SMTP client will ignore in the EHLO response from a +remote SMTP server. .IP "\fBsmtp_discard_ehlo_keywords (empty)\fR" A case insensitive list of EHLO keywords (pipelining, starttls, auth, etc.) that the SMTP client will ignore in the EHLO response diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 830173962..7ec5cb6b4 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -387,6 +387,7 @@ while (<>) { s;\bsmtp_mx_session_limit\b;$&;g; s;\bsmtp_never_send_ehlo\b;$&;g; s;\bsmtp_sender_depen[-]*\n*[ ]*dent_authentication\b;$&;g; + s;\bsmtp_pipeline_dot_quit\b;$&;g; s;\bsmtp_pix_workaround_delay_time\b;$&;g; s;\bsmtp_pix_workaround_threshold_time\b;$&;g; s;\bsmtp_quit_timeout\b;$&;g; diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index c8c51be02..d6ca70d2b 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -8837,7 +8837,7 @@ case insensitive lists of LHLO keywords (pipelining, starttls, auth, etc.) that the LMTP client will ignore in the LHLO response from a remote LMTP server. See lmtp_discard_lhlo_keywords for details. The table is not indexed by hostname for consistency with -smtpd_discard_ehlo_keyword_address_map

+smtpd_discard_ehlo_keyword_address_maps.

This feature is available in Postfix 2.3 and later.

@@ -9125,3 +9125,43 @@ is rejected by the reject_plaintext_session restriction. rejecting the address as invalid.

This feature is available in Postfix 2.3 and later. + +%PARAM smtp_pipeline_dot_quit never + +

When ESMTP command pipelining is enabled, whether or not the +SMTP client will send the QUIT command before it has received the +server's END-OF-DATA reply.

+ +

Specify one of the following:

+ +
+ +
always
Always pipeline the END-OF-DATA and +QUIT commands. With servers or firewalls that mis-implement +END-OF-DATA + QUIT pipelining, mail will be delivered repeatedly +until it expires in the queue.
+ +
never
Wait for the server's END-OF-DATA reply +before sending the QUIT command. This avoids repeated delivery +attempts with servers and firewalls that mis-implement END-OF-DATA ++ QUIT pipelining, at the cost of a small performance loss with +sites that correctly implement SMTP.
+ +
newmail
Pipeline the END-OF-DATA and QUIT +commands only when mail is newer than $minimal_backoff_time. This +limits the number of repeated deliveries with servers and firewalls +that mis-implement END-OF-DATA + QUIT pipelining, while avoiding +the performance loss associated with the "never" setting for normal +deliveries.
+ +
+ +

Note: when smtp_fallback_relay is used, the "always" and "newmail" +settings become identical in practice.

+ +

This feature is available in Postfix 2.3 and later.

+ +%PARAM lmtp_pipeline_dot_quit never + +

The LMTP-specific version of the smtp_pipeline_dot_quit +configuration parameter. See there for details.

diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 685bf2647..51c6668cf 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1006,6 +1006,16 @@ extern int var_smtp_pix_thresh; #define DEF_LMTP_PIX_DELAY "10s" extern int var_smtp_pix_delay; +#define SMTP_PIPE_DOT_QUIT_NEVER "never" +#define SMTP_PIPE_DOT_QUIT_NEWMAIL "newmail" +#define SMTP_PIPE_DOT_QUIT_ALWAYS "always" + +#define VAR_SMTP_PIPE_DOT_QUIT "smtp_pipeline_dot_quit" +#define DEF_SMTP_PIPE_DOT_QUIT SMTP_PIPE_DOT_QUIT_NEVER +#define VAR_LMTP_PIPE_DOT_QUIT "lmtp_pipeline_dot_quit" +#define DEF_LMTP_PIPE_DOT_QUIT SMTP_PIPE_DOT_QUIT_NEVER +extern char *var_smtp_pipe_dot_quit; + #define VAR_SMTP_DEFER_MXADDR "smtp_defer_if_no_mx_address_found" #define DEF_SMTP_DEFER_MXADDR 0 #define VAR_LMTP_DEFER_MXADDR "lmtp_defer_if_no_mx_address_found" diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index f0381afbe..1210c95e4 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20051227" +#define MAIL_RELEASE_DATE "20051228" #define MAIL_VERSION_NUMBER "2.3" #ifdef SNAPSHOT diff --git a/postfix/src/smtp/lmtp_params.c b/postfix/src/smtp/lmtp_params.c index efb85e3e6..a29e9e552 100644 --- a/postfix/src/smtp/lmtp_params.c +++ b/postfix/src/smtp/lmtp_params.c @@ -22,6 +22,7 @@ VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0, VAR_LMTP_GENERIC_MAPS, DEF_LMTP_GENERIC_MAPS, &var_smtp_generic_maps, 0, 0, VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0, + VAR_LMTP_PIPE_DOT_QUIT, DEF_LMTP_PIPE_DOT_QUIT, &var_smtp_pipe_dot_quit, 1, 0, 0, }; static CONFIG_TIME_TABLE lmtp_time_table[] = { @@ -43,6 +44,7 @@ VAR_LMTP_STARTTLS_TMOUT, DEF_LMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0, #endif VAR_SCACHE_PROTO_TMOUT, DEF_SCACHE_PROTO_TMOUT, &var_scache_proto_tmout, 1, 0, + VAR_MIN_BACKOFF_TIME, DEF_MIN_BACKOFF_TIME, &var_min_backoff_time, 1, 0, 0, }; static CONFIG_INT_TABLE lmtp_int_table[] = { diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index a2b862daa..2196e4db1 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -143,6 +143,10 @@ /* .IP "\fBsmtp_line_length_limit (990)\fR" /* The maximal length of message header and body lines that Postfix /* will send via SMTP. +/* .IP "\fBsmtp_pipeline_dot_quit (never)\fR" +/* When ESMTP command pipelining is enabled, whether or not the +/* SMTP client will send the QUIT command before it has received the +/* server's END-OF-DATA reply. /* .IP "\fBsmtp_pix_workaround_delay_time (10s)\fR" /* How long the Postfix SMTP client pauses before sending /* "." in order to work around the PIX firewall @@ -168,9 +172,9 @@ /* Available in Postfix version 2.2 and later: /* .IP "\fBsmtp_discard_ehlo_keyword_address_maps (empty)\fR" /* Lookup tables, indexed by the remote SMTP server address, with -/* case insensitive lists of EHLO keywords (pipelining, starttls, -/* auth, etc.) that the SMTP client will ignore in the EHLO response -/* from a remote SMTP server. +/* case insensitive lists of EHLO keywords (pipelining, starttls, auth, +/* etc.) that the SMTP client will ignore in the EHLO response from a +/* remote SMTP server. /* .IP "\fBsmtp_discard_ehlo_keywords (empty)\fR" /* A case insensitive list of EHLO keywords (pipelining, starttls, /* auth, etc.) that the SMTP client will ignore in the EHLO response @@ -526,6 +530,7 @@ #include #include #include +#include /* Global library. */ @@ -617,6 +622,8 @@ char *var_prop_extension; bool var_smtp_sender_auth; char *var_lmtp_tcp_port; int var_scache_proto_tmout; +char *var_smtp_pipe_dot_quit; +int var_min_backoff_time; /* * Global variables. smtp_errno is set by the address lookup routines and by @@ -629,6 +636,7 @@ SCACHE *smtp_scache; MAPS *smtp_ehlo_dis_maps; MAPS *smtp_generic_maps; int smtp_ext_prop_mask; +int smtp_pipe_dot_quit; #ifdef USE_TLS @@ -722,6 +730,12 @@ static void post_init(char *unused_name, char **unused_argv) SMTP_HOST_LOOKUP_NATIVE, SMTP_HOST_FLAG_NATIVE, 0, }; + static NAME_CODE pipe_dot_quit_codes[] = { + SMTP_PIPE_DOT_QUIT_NEVER, SMTP_PIPE_DOT_QUIT_CODE_NEVER, + SMTP_PIPE_DOT_QUIT_NEWMAIL, SMTP_PIPE_DOT_QUIT_CODE_NEWMAIL, + SMTP_PIPE_DOT_QUIT_ALWAYS, SMTP_PIPE_DOT_QUIT_CODE_ALWAYS, + 0, SMTP_PIPE_DOT_QUIT_CODE_ERROR, + }; /* * Select hostname lookup mechanisms. @@ -748,6 +762,16 @@ static void post_init(char *unused_name, char **unused_argv) var_ipc_idle_limit, var_ipc_ttl_limit); #endif + + /* + * Initialize dot-quit pipelining workaround. + */ + smtp_pipe_dot_quit = name_code(pipe_dot_quit_codes, + NAME_CODE_FLAG_NONE, + var_smtp_pipe_dot_quit); + if (smtp_pipe_dot_quit == SMTP_PIPE_DOT_QUIT_CODE_ERROR) + msg_fatal("unknown %s value: %s", VAR_SMTP_PIPE_DOT_QUIT, + var_smtp_pipe_dot_quit); } /* pre_init - pre-jail initialization */ diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h index 9e4e5c8ed..620c6de93 100644 --- a/postfix/src/smtp/smtp.h +++ b/postfix/src/smtp/smtp.h @@ -166,6 +166,13 @@ extern SSL_CTX *smtp_tls_ctx; /* client-side TLS engine */ #endif +#define SMTP_PIPE_DOT_QUIT_CODE_ERROR 0 +#define SMTP_PIPE_DOT_QUIT_CODE_NEVER 1 +#define SMTP_PIPE_DOT_QUIT_CODE_NEWMAIL 2 +#define SMTP_PIPE_DOT_QUIT_CODE_ALWAYS 3 + +extern int smtp_pipe_dot_quit; + /* * smtp_session.c */ diff --git a/postfix/src/smtp/smtp_chat.c b/postfix/src/smtp/smtp_chat.c index 6008b2d0b..d92e9063e 100644 --- a/postfix/src/smtp/smtp_chat.c +++ b/postfix/src/smtp/smtp_chat.c @@ -289,7 +289,7 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session) msg_warn("non-%s response from %s: %s", (session->state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP", - session->namaddr, STR(session->buffer)); + session->namaddrport, STR(session->buffer)); vstream_longjmp(session->stream, SMTP_ERR_PROTO); } } diff --git a/postfix/src/smtp/smtp_params.c b/postfix/src/smtp/smtp_params.c index f3a1494b1..95765849c 100644 --- a/postfix/src/smtp/smtp_params.c +++ b/postfix/src/smtp/smtp_params.c @@ -23,6 +23,7 @@ VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0, VAR_SMTP_GENERIC_MAPS, DEF_SMTP_GENERIC_MAPS, &var_smtp_generic_maps, 0, 0, VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0, + VAR_SMTP_PIPE_DOT_QUIT, DEF_SMTP_PIPE_DOT_QUIT, &var_smtp_pipe_dot_quit, 1, 0, 0, }; static CONFIG_TIME_TABLE smtp_time_table[] = { @@ -44,6 +45,7 @@ VAR_SMTP_STARTTLS_TMOUT, DEF_SMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0, #endif VAR_SCACHE_PROTO_TMOUT, DEF_SCACHE_PROTO_TMOUT, &var_scache_proto_tmout, 1, 0, + VAR_MIN_BACKOFF_TIME, DEF_MIN_BACKOFF_TIME, &var_min_backoff_time, 1, 0, 0, }; static CONFIG_INT_TABLE smtp_int_table[] = { diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index 5fbe78d73..f6c5583df 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -926,8 +926,16 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state, #define SENDER_IS_AHEAD \ (recv_state < send_state || recv_rcpt != send_rcpt) +#define DONT_PIPELINE_DOT_QUIT \ + (smtp_pipe_dot_quit == SMTP_PIPE_DOT_QUIT_CODE_NEVER \ + || (smtp_pipe_dot_quit == SMTP_PIPE_DOT_QUIT_CODE_NEWMAIL \ + && request->msg_stats.incoming_arrival.tv_sec \ + < vstream_ftime(session->stream) - var_min_backoff_time)) + #define SENDER_IN_WAIT_STATE \ - (send_state == SMTP_STATE_DOT || send_state == SMTP_STATE_LAST) + (send_state == SMTP_STATE_DOT || send_state == SMTP_STATE_LAST \ + || (recv_state == SMTP_STATE_DOT && send_state == SMTP_STATE_QUIT \ + && DONT_PIPELINE_DOT_QUIT)) #define SENDING_MAIL \ (recv_state <= SMTP_STATE_DOT) @@ -1144,7 +1152,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state, break; /* - * Build the "." command before we have seen the DATA response. + * Build the "." command after we have seen the DATA response + * (DATA is a protocol synchronization point). * * Changing the connection caching state here is safe because it * affects none of the not-yet processed replies to