2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-31 06:05:37 +00:00

postfix-2.3.5-RC1

This commit is contained in:
Wietse Venema
2006-12-05 00:00:00 -05:00
committed by Viktor Dukhovni
parent 8aa4821346
commit fd0940608c
22 changed files with 226 additions and 55 deletions

View File

@@ -135,7 +135,6 @@ Postfix daemons:
src/cleanup/ Canonicalize and enqueue mail src/cleanup/ Canonicalize and enqueue mail
src/discard/ Trivial discard mailer src/discard/ Trivial discard mailer
src/error/ Trivial error mailer src/error/ Trivial error mailer
src/lmtp/ LMTP client
src/local/ Local delivery src/local/ Local delivery
src/master/ Postfix resident superserver src/master/ Postfix resident superserver
src/oqmgr/ Old queue manager src/oqmgr/ Old queue manager
@@ -144,9 +143,10 @@ Postfix daemons:
src/qmgr/ Queue manager src/qmgr/ Queue manager
src/qmqpd/ QMQPD server src/qmqpd/ QMQPD server
src/showq/ List Postfix queue status src/showq/ List Postfix queue status
src/smtp/ SMTP client src/smtp/ SMTP and LMTP client
src/smtpd/ SMTP server src/smtpd/ SMTP server
src/spawn/ Run non-Postfix server src/spawn/ Run non-Postfix server
src/tlsmgr/ TLS session keys and random pool
src/trivial-rewrite/ Address rewriting and resolving src/trivial-rewrite/ Address rewriting and resolving
src/verify/ address verification service src/verify/ address verification service
src/virtual/ virtual mailbox-only delivery agent src/virtual/ virtual mailbox-only delivery agent

View File

@@ -12769,3 +12769,61 @@ Apologies for any names omitted.
Bugfix: null pointer bug when receiving a non-protocol Bugfix: null pointer bug when receiving a non-protocol
response on a cached SMTP/LMTP connection. Report by Brian response on a cached SMTP/LMTP connection. Report by Brian
Kantor. Fix by Victor Duchovni. File: smtp/smtp_reuse.c. Kantor. Fix by Victor Duchovni. File: smtp/smtp_reuse.c.
20061113
Bugfix: the Postfix install/upgrade procedure broke with
non-default config_directory. File: conf/post-install.
20061115
Bugfix: null pointer bug in end-of-header Milter action
when the last header line is too large. Reported by Mark
Martinec. The root of the problem is that the MIME state
engine may execute up to three call-back functions when it
reaches the end of the headers, before it returns to the
caller; as long as call-backs return no result, each call-back
has to check for itself if a previous call-back ran into a
problem. File: milter/milter8.c.
Workaround: reduce effective header_size_limit to 60000
when Milter inspection is enabled, to avoid breaking the
Milter protocol request length limit. File:
cleanup/cleanup_message.c.
20061123
Workaround: more agressive early refill of in-memory
recipients to prevent a worst-case scenario where the queue
manager became starved until after the last batch of slow
in-memory recipients of jumbo multi-recipient mail. Files:
qmgr/qmgr_job.c.
Safety: don't read more than 5000 recipients at a time, to
avoid spending too much time away from interrupts. File:
qmgr/qmgr_message.c.
20061201
Workaround: don't complain with "Error 0" in the trivial-rewrite,
verify, proxymap or connection cache client when the server
exits after the client sends its request. We still complain,
however, when the problem persists. Files: global/rewrite_clnt.c,
global/resolve_clnt.c, global/verify_clnt.c, global/scache_clnt.c,
global/dict_proxy.c.
Safety: the header_size_limit is now enforced more strictly,
to avoid inter-operability problems with the Milter protocol.
Long headers are truncated at a line boundary if possible,
otherwise they are cut between line boundaries. File:
cleanup/cleanup_out.c.
20061203
Bugfix (introduced with Postfix 2.2): with SMTP server
tarpit delays of smtp_rset_timeout or larger, the SMTP
client could get out of sync with the server while reusing
a connection. The symptoms were "recipient rejected .. in
reply to DATA". Fix by Victor Duchovni and Wietse. File:
smtp/smtp_proto.c.

View File

@@ -787,14 +787,14 @@ mailbox, or delivery to non-Postfix command.
Content-Description: Notification Content-Description: Notification
Content-Type: text/plain Content-Type: text/plain
This is the Postfix program at host spike.porcupine.org. This is the mail system at host spike.porcupine.org.
Enclosed is the mail delivery report that you requested. Enclosed is the mail delivery report that you requested.
The Postfix program The mail system
<postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 <postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250
Ok 2.1.5 Ok
The second part of the report is in machine-readable form, and includes the The second part of the report is in machine-readable form, and includes the
following information: following information:
@@ -814,13 +814,13 @@ version 2.3 and later.
Reporting-MTA: dns; spike.porcupine.org Reporting-MTA: dns; spike.porcupine.org
X-Postfix-Queue-ID: 84863BC0E5 X-Postfix-Queue-ID: 84863BC0E5
X-Postfix-Sender: rfc822; wietse@porcupine.org X-Postfix-Sender: rfc822; wietse@porcupine.org
Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
Final-Recipient: rfc822; postfix-users@postfix.org Final-Recipient: rfc822; postfix-users@postfix.org
Action: deliverable Action: deliverable
Status: 2.0.0 Status: 2.1.5
Remote-MTA: dns; mail.cloud9.net Remote-MTA: dns; mail.cloud9.net
Diagnostic-Code: smtp; 250 Ok Diagnostic-Code: smtp; 250 2.1.5 Ok
The third part of the report contains the message that Postfix would have The third part of the report contains the message that Postfix would have
delivered, including From: and To: message headers, so that you can see any delivered, including From: and To: message headers, so that you can see any
@@ -831,10 +831,10 @@ no body content so none is shown in the example below.
Content-Type: message/rfc822 Content-Type: message/rfc822
Received: by spike.porcupine.org (Postfix, from userid 1001) Received: by spike.porcupine.org (Postfix, from userid 1001)
id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT) id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
Subject: probe Subject: probe
To: postfix-users@postfix.org To: postfix-users@postfix.org
Message-Id: <20040413232743.84863BC0E5@spike.porcupine.org> Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org>
Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
From: wietse@porcupine.org (Wietse Venema) From: wietse@porcupine.org (Wietse Venema)

View File

@@ -589,14 +589,14 @@ EOF
# This safety net is also documented in LOCAL_RECIPIENT_README. # This safety net is also documented in LOCAL_RECIPIENT_README.
unknown_local=unknown_local_recipient_reject_code unknown_local=unknown_local_recipient_reject_code
has_lrm=`$POSTCONF -n local_recipient_maps` has_lrm=`$POSTCONF -c $config_directory -n local_recipient_maps`
has_lrjc=`$POSTCONF -n $unknown_local` has_lrjc=`$POSTCONF -c $config_directory -n $unknown_local`
if [ -z "$has_lrm" -a -z "$has_lrjc" ] if [ -z "$has_lrm" -a -z "$has_lrjc" ]
then then
echo SAFETY: editing main.cf, setting $unknown_local=450. echo SAFETY: editing main.cf, setting $unknown_local=450.
echo See the LOCAL_RECIPIENT_README file for details. echo See the LOCAL_RECIPIENT_README file for details.
$POSTCONF -e "$unknown_local = 450" || exit 1 $POSTCONF -c $config_directory -e "$unknown_local = 450" || exit 1
fi fi
# Add missing proxymap service to master.cf. # Add missing proxymap service to master.cf.
@@ -678,8 +678,8 @@ EOF
test -n "$first_install_reminder" && { test -n "$first_install_reminder" && {
ALIASES=`$POSTCONF -h alias_database | sed 's/^[^:]*://'` ALIASES=`$POSTCONF -c $config_directory -h alias_database | sed 's/^[^:]*://'`
NEWALIASES_PATH=`$POSTCONF -h newaliases_path` NEWALIASES_PATH=`$POSTCONF -c $config_directory -h newaliases_path`
cat <<EOF | ${FMT} cat <<EOF | ${FMT}
Warning: you still need to edit myorigin/mydestination/mynetworks Warning: you still need to edit myorigin/mydestination/mynetworks

View File

@@ -1174,13 +1174,13 @@ to mailbox, or delivery to non-Postfix command. </p>
Content-Description: Notification Content-Description: Notification
Content-Type: text/plain Content-Type: text/plain
This is the Postfix program at host spike.porcupine.org. This is the mail system at host spike.porcupine.org.
Enclosed is the mail delivery report that you requested. Enclosed is the mail delivery report that you requested.
The Postfix program The mail system
&lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 Ok &lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok
</pre> </pre>
</blockquote> </blockquote>
@@ -1210,13 +1210,13 @@ Content-Type: message/delivery-status
Reporting-MTA: dns; spike.porcupine.org Reporting-MTA: dns; spike.porcupine.org
X-Postfix-Queue-ID: 84863BC0E5 X-Postfix-Queue-ID: 84863BC0E5
X-Postfix-Sender: rfc822; wietse@porcupine.org X-Postfix-Sender: rfc822; wietse@porcupine.org
Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
Final-Recipient: rfc822; postfix-users@postfix.org Final-Recipient: rfc822; postfix-users@postfix.org
Action: deliverable Action: deliverable
Status: 2.0.0 Status: 2.1.5
Remote-MTA: dns; mail.cloud9.net Remote-MTA: dns; mail.cloud9.net
Diagnostic-Code: smtp; 250 Ok Diagnostic-Code: smtp; 250 2.1.5 Ok
</pre> </pre>
</blockquote> </blockquote>
@@ -1232,11 +1232,11 @@ Content-Description: Message
Content-Type: message/rfc822 Content-Type: message/rfc822
Received: by spike.porcupine.org (Postfix, from userid 1001) Received: by spike.porcupine.org (Postfix, from userid 1001)
id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT) id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
Subject: probe Subject: probe
To: postfix-users@postfix.org To: postfix-users@postfix.org
Message-Id: &lt;20040413232743.84863BC0E5@spike.porcupine.org&gt; Message-Id: &lt;20061126220101.84863BC0E5@spike.porcupine.org&gt;
Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
From: wietse@porcupine.org (Wietse Venema) From: wietse@porcupine.org (Wietse Venema)
</pre> </pre>
</blockquote> </blockquote>

View File

@@ -1174,13 +1174,13 @@ to mailbox, or delivery to non-Postfix command. </p>
Content-Description: Notification Content-Description: Notification
Content-Type: text/plain Content-Type: text/plain
This is the Postfix program at host spike.porcupine.org. This is the mail system at host spike.porcupine.org.
Enclosed is the mail delivery report that you requested. Enclosed is the mail delivery report that you requested.
The Postfix program The mail system
&lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 Ok &lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok
</pre> </pre>
</blockquote> </blockquote>
@@ -1210,13 +1210,13 @@ Content-Type: message/delivery-status
Reporting-MTA: dns; spike.porcupine.org Reporting-MTA: dns; spike.porcupine.org
X-Postfix-Queue-ID: 84863BC0E5 X-Postfix-Queue-ID: 84863BC0E5
X-Postfix-Sender: rfc822; wietse@porcupine.org X-Postfix-Sender: rfc822; wietse@porcupine.org
Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
Final-Recipient: rfc822; postfix-users@postfix.org Final-Recipient: rfc822; postfix-users@postfix.org
Action: deliverable Action: deliverable
Status: 2.0.0 Status: 2.1.5
Remote-MTA: dns; mail.cloud9.net Remote-MTA: dns; mail.cloud9.net
Diagnostic-Code: smtp; 250 Ok Diagnostic-Code: smtp; 250 2.1.5 Ok
</pre> </pre>
</blockquote> </blockquote>
@@ -1232,11 +1232,11 @@ Content-Description: Message
Content-Type: message/rfc822 Content-Type: message/rfc822
Received: by spike.porcupine.org (Postfix, from userid 1001) Received: by spike.porcupine.org (Postfix, from userid 1001)
id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT) id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
Subject: probe Subject: probe
To: postfix-users@postfix.org To: postfix-users@postfix.org
Message-Id: &lt;20040413232743.84863BC0E5@spike.porcupine.org&gt; Message-Id: &lt;20061126220101.84863BC0E5@spike.porcupine.org&gt;
Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
From: wietse@porcupine.org (Wietse Venema) From: wietse@porcupine.org (Wietse Venema)
</pre> </pre>
</blockquote> </blockquote>

View File

@@ -596,6 +596,16 @@ static void cleanup_header_done_callback(void *context)
TOK822 *token; TOK822 *token;
time_t tv; time_t tv;
/*
* XXX Workaround: when we reach the end of headers, mime_state_update()
* may execute up to three call-backs before returning to the caller:
* head_out(), head_end(), and body_out() or body_end(). As long as
* call-backs don't return a result, each call-back has to check for
* itself if the previous call-back experienced a problem.
*/
if (CLEANUP_OUT_OK(state) == 0)
return;
/* /*
* Add a missing (Resent-)Message-Id: header. The message ID gives the * Add a missing (Resent-)Message-Id: header. The message ID gives the
* time in GMT units, plus the local queue ID. * time in GMT units, plus the local queue ID.
@@ -706,6 +716,16 @@ static void cleanup_body_callback(void *context, int type,
{ {
CLEANUP_STATE *state = (CLEANUP_STATE *) context; CLEANUP_STATE *state = (CLEANUP_STATE *) context;
/*
* XXX Workaround: when we reach the end of headers, mime_state_update()
* may execute up to three call-backs before returning to the caller:
* head_out(), head_end(), and body_out() or body_end(). As long as
* call-backs don't return a result, each call-back has to check for
* itself if the previous call-back experienced a problem.
*/
if (CLEANUP_OUT_OK(state) == 0)
return;
/* /*
* Crude message body content filter for emergencies. This code has * Crude message body content filter for emergencies. This code has
* several problems: it sees one line at a time; it looks at long lines * several problems: it sees one line at a time; it looks at long lines
@@ -892,6 +912,15 @@ void cleanup_message(CLEANUP_STATE *state, int type, const char *buf, ssize_t
cleanup_mime_error_callback, cleanup_mime_error_callback,
(void *) state); (void *) state);
/*
* XXX Workaround: truncate a long message header so that we don't exceed
* the Milter request size limit of 65535.
*/
#define KLUDGE_HEADER_LIMIT 60000
if ((cleanup_milters || state->milters)
&& var_header_limit > KLUDGE_HEADER_LIMIT)
var_header_limit = KLUDGE_HEADER_LIMIT;
/* /*
* Pass control to the header processing routine. * Pass control to the header processing routine.
*/ */

View File

@@ -1697,6 +1697,8 @@ static void usage(void)
msg_warn(" del_rcpt addr"); msg_warn(" del_rcpt addr");
} }
/* flatten_args - unparse partial command line */
static void flatten_args(VSTRING *buf, char **argv) static void flatten_args(VSTRING *buf, char **argv)
{ {
char **cpp; char **cpp;
@@ -1710,6 +1712,8 @@ static void flatten_args(VSTRING *buf, char **argv)
VSTRING_TERMINATE(buf); VSTRING_TERMINATE(buf);
} }
/* open_queue_file - open an unedited queue file (all-zero dummy PTRs) */
static void open_queue_file(CLEANUP_STATE *state, const char *path) static void open_queue_file(CLEANUP_STATE *state, const char *path)
{ {
VSTRING *buf = vstring_alloc(100); VSTRING *buf = vstring_alloc(100);
@@ -1720,6 +1724,13 @@ static void open_queue_file(CLEANUP_STATE *state, const char *path)
long rcpt_count; long rcpt_count;
long qmgr_opts; long qmgr_opts;
if (state->dst != 0) {
msg_warn("closing %s", cleanup_path);
vstream_fclose(state->dst);
state->dst = 0;
myfree(cleanup_path);
cleanup_path = 0;
}
if ((state->dst = vstream_fopen(path, O_RDWR, 0)) == 0) { if ((state->dst = vstream_fopen(path, O_RDWR, 0)) == 0) {
msg_warn("open %s: %m", path); msg_warn("open %s: %m", path);
} else { } else {
@@ -1794,6 +1805,7 @@ int main(int unused_argc, char **argv)
msg_vstream_init(argv[0], VSTREAM_ERR); msg_vstream_init(argv[0], VSTREAM_ERR);
var_line_limit = DEF_LINE_LIMIT; var_line_limit = DEF_LINE_LIMIT;
var_header_limit = DEF_HEADER_LIMIT;
for (;;) { for (;;) {
ARGV *argv; ARGV *argv;

View File

@@ -175,9 +175,22 @@ void cleanup_out_header(CLEANUP_STATE *state, VSTRING *header_buf)
* of such header lines. NB: This code destroys the header. We could try * of such header lines. NB: This code destroys the header. We could try
* to avoid clobbering it, but we're not going to use the data any * to avoid clobbering it, but we're not going to use the data any
* further. * further.
*
* XXX We prefer to truncate a header at the last line boundary before the
* header size limit. If this would undershoot the limit by more than
* 10%, we truncate between line boundaries to avoid losing too much
* text. This "unkind cut" may result in syntax errors and may trigger
* warnings from down-stream MTAs.
*/ */
for (line = start; line; line = next_line) { for (line = start; line; line = next_line) {
next_line = split_at(line, '\n'); next_line = split_at(line, '\n');
if ((next_line ? next_line - 1 : line + strlen(line))
> start + var_header_limit) {
if (line - start > 0.9 * var_header_limit) /* nice cut */
break;
start[var_header_limit] = 0; /* unkind cut */
next_line = 0;
}
if (line == start || IS_SPACE_TAB(*line)) { if (line == start || IS_SPACE_TAB(*line)) {
cleanup_out_string(state, REC_TYPE_NORM, line); cleanup_out_string(state, REC_TYPE_NORM, line);
} else { } else {

View File

@@ -90,6 +90,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
DICT_PROXY *dict_proxy = (DICT_PROXY *) dict; DICT_PROXY *dict_proxy = (DICT_PROXY *) dict;
VSTREAM *stream; VSTREAM *stream;
int status; int status;
int count = 0;
/* /*
* The client and server live in separate processes that may start and * The client and server live in separate processes that may start and
@@ -103,6 +104,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
for (;;) { for (;;) {
stream = clnt_stream_access(proxy_stream); stream = clnt_stream_access(proxy_stream);
errno = 0; errno = 0;
count += 1;
if (attr_print(stream, ATTR_FLAG_NONE, if (attr_print(stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_LOOKUP, ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_LOOKUP,
ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict->name, ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict->name,
@@ -114,7 +116,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status, ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
ATTR_TYPE_STR, MAIL_ATTR_VALUE, dict_proxy->result, ATTR_TYPE_STR, MAIL_ATTR_VALUE, dict_proxy->result,
ATTR_TYPE_END) != 2) { ATTR_TYPE_END) != 2) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream)); msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
} else { } else {
if (msg_verbose) if (msg_verbose)

View File

@@ -20,8 +20,8 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20061101" #define MAIL_RELEASE_DATE "20061205"
#define MAIL_VERSION_NUMBER "2.3.4" #define MAIL_VERSION_NUMBER "2.3.5-RC1"
#ifdef SNAPSHOT #ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE # define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE

View File

@@ -164,6 +164,7 @@ void resolve_clnt(const char *class, const char *sender,
const char *myname = "resolve_clnt"; const char *myname = "resolve_clnt";
VSTREAM *stream; VSTREAM *stream;
int server_flags; int server_flags;
int count = 0;
/* /*
* One-entry cache. * One-entry cache.
@@ -226,6 +227,7 @@ void resolve_clnt(const char *class, const char *sender,
for (;;) { for (;;) {
stream = clnt_stream_access(rewrite_clnt_stream); stream = clnt_stream_access(rewrite_clnt_stream);
errno = 0; errno = 0;
count += 1;
if (attr_print(stream, ATTR_FLAG_NONE, if (attr_print(stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_REQ, class, ATTR_TYPE_STR, MAIL_ATTR_REQ, class,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender, ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
@@ -239,7 +241,7 @@ void resolve_clnt(const char *class, const char *sender,
ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient, ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient,
ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &reply->flags, ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &reply->flags,
ATTR_TYPE_END) != 5) { ATTR_TYPE_END) != 5) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
msg_warn("problem talking to service %s: %m", msg_warn("problem talking to service %s: %m",
var_rewrite_service); var_rewrite_service);
} else { } else {

View File

@@ -82,6 +82,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
{ {
VSTREAM *stream; VSTREAM *stream;
int server_flags; int server_flags;
int count = 0;
/* /*
* One-entry cache. * One-entry cache.
@@ -129,6 +130,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
for (;;) { for (;;) {
stream = clnt_stream_access(rewrite_clnt_stream); stream = clnt_stream_access(rewrite_clnt_stream);
errno = 0; errno = 0;
count += 1;
if (attr_print(stream, ATTR_FLAG_NONE, if (attr_print(stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR, ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR,
ATTR_TYPE_STR, MAIL_ATTR_RULE, rule, ATTR_TYPE_STR, MAIL_ATTR_RULE, rule,
@@ -139,7 +141,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &server_flags, ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &server_flags,
ATTR_TYPE_STR, MAIL_ATTR_ADDR, result, ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
ATTR_TYPE_END) != 2) { ATTR_TYPE_END) != 2) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
msg_warn("problem talking to service %s: %m", msg_warn("problem talking to service %s: %m",
var_rewrite_service); var_rewrite_service);
} else { } else {

View File

@@ -91,6 +91,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
VSTREAM *stream; VSTREAM *stream;
int status; int status;
int tries; int tries;
int count = 0;
if (msg_verbose) if (msg_verbose)
msg_info("%s: endp=%s prop=%s fd=%d", msg_info("%s: endp=%s prop=%s fd=%d",
@@ -110,6 +111,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
for (tries = 0; sp->auto_clnt != 0; tries++) { for (tries = 0; sp->auto_clnt != 0; tries++) {
if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) { if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) {
errno = 0; errno = 0;
count += 1;
if (attr_print(stream, ATTR_FLAG_NONE, if (attr_print(stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_ENDP, ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_ENDP,
ATTR_TYPE_INT, MAIL_ATTR_TTL, endp_ttl, ATTR_TYPE_INT, MAIL_ATTR_TTL, endp_ttl,
@@ -126,7 +128,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
|| attr_scan(stream, ATTR_FLAG_STRICT, || attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status, ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
ATTR_TYPE_END) != 1) { ATTR_TYPE_END) != 1) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
msg_warn("problem talking to service %s: %m", msg_warn("problem talking to service %s: %m",
VSTREAM_PATH(stream)); VSTREAM_PATH(stream));
/* Give up or recover. */ /* Give up or recover. */
@@ -281,7 +283,7 @@ static void scache_clnt_save_dest(SCACHE *scache, int dest_ttl,
myname, status); myname, status);
break; break;
} }
} }
/* Give up or recover. */ /* Give up or recover. */
if (tries >= SCACHE_MAX_TRIES - 1) { if (tries >= SCACHE_MAX_TRIES - 1) {
msg_warn("disabling connection caching"); msg_warn("disabling connection caching");

View File

@@ -96,6 +96,7 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
{ {
VSTREAM *stream; VSTREAM *stream;
int request_status; int request_status;
int count = 0;
/* /*
* Do client-server plumbing. * Do client-server plumbing.
@@ -109,6 +110,7 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
for (;;) { for (;;) {
stream = clnt_stream_access(vrfy_clnt); stream = clnt_stream_access(vrfy_clnt);
errno = 0; errno = 0;
count += 1;
if (attr_print(stream, ATTR_FLAG_NONE, if (attr_print(stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY, ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY,
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr, ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
@@ -119,7 +121,7 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
ATTR_TYPE_INT, MAIL_ATTR_ADDR_STATUS, addr_status, ATTR_TYPE_INT, MAIL_ATTR_ADDR_STATUS, addr_status,
ATTR_TYPE_STR, MAIL_ATTR_WHY, why, ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
ATTR_TYPE_END) != 3) { ATTR_TYPE_END) != 3) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
msg_warn("problem talking to service %s: %m", msg_warn("problem talking to service %s: %m",
var_verify_service); var_verify_service);
} else { } else {

View File

@@ -858,6 +858,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
int skip_reply, int skip_reply,
ARGV *macros,...) ARGV *macros,...)
{ {
const char *myname = "milter8_event";
va_list ap; va_list ap;
ssize_t data_len; ssize_t data_len;
int err; int err;
@@ -871,6 +872,17 @@ static const char *milter8_event(MILTER8 *milter, int event,
#define DONT_SKIP_REPLY 0 #define DONT_SKIP_REPLY 0
/*
* Sanity check.
*/
if (milter->fp == 0 || milter->def_reply != 0) {
msg_warn("%s: attempt to send event %s to milter %s after error",
myname,
(smfic_name = str_name_code(smfic_table, event)) != 0 ?
smfic_name : "(unknown MTA event)", milter->m.name);
return (milter->def_reply);
}
/* /*
* Skip this event if it doesn't exist in the protocol that I announced. * Skip this event if it doesn't exist in the protocol that I announced.
*/ */
@@ -1185,7 +1197,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
(ssize_t) index, (ssize_t) index,
STR(milter->buf)); STR(milter->buf));
if (edit_resp) if (edit_resp)
return (milter8_def_reply(milter, edit_resp)); return (edit_resp);
continue; continue;
#endif #endif
@@ -1203,7 +1215,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
STR(milter->buf), STR(milter->buf),
STR(milter->body)); STR(milter->body));
if (edit_resp) if (edit_resp)
return (milter8_def_reply(milter, edit_resp)); return (edit_resp);
continue; continue;
/* /*
@@ -1232,7 +1244,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
STR(milter->buf), STR(milter->buf),
STR(milter->body)); STR(milter->body));
if (edit_resp) if (edit_resp)
return (milter8_def_reply(milter, edit_resp)); return (edit_resp);
continue; continue;
#endif #endif
@@ -1248,7 +1260,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
edit_resp = parent->add_rcpt(parent->chg_context, edit_resp = parent->add_rcpt(parent->chg_context,
STR(milter->buf)); STR(milter->buf));
if (edit_resp) if (edit_resp)
return (milter8_def_reply(milter, edit_resp)); return (edit_resp);
continue; continue;
/* /*
@@ -1263,7 +1275,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
edit_resp = parent->del_rcpt(parent->chg_context, edit_resp = parent->del_rcpt(parent->chg_context,
STR(milter->buf)); STR(milter->buf));
if (edit_resp) if (edit_resp)
return (milter8_def_reply(milter, edit_resp)); return (edit_resp);
continue; continue;
/* /*
@@ -1280,7 +1292,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
edit_resp = parent->repl_body(parent->chg_context, edit_resp = parent->repl_body(parent->chg_context,
milter->body); milter->body);
if (edit_resp) if (edit_resp)
return (milter8_def_reply(milter, edit_resp)); return (edit_resp);
continue; continue;
#endif #endif
} }
@@ -1927,6 +1939,16 @@ static void milter8_header(void *ptr, int unused_header_class,
char *cp; char *cp;
int skip_reply; int skip_reply;
/*
* XXX Workaround: mime_state_update() may invoke multiple call-backs
* before returning to the caller.
*/
#define MILTER8_MESSAGE_DONE(milter, msg_ctx) \
((milter)->state != MILTER8_STAT_MESSAGE || (msg_ctx)->resp != 0)
if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
return;
/* /*
* XXX Sendmail compatibility. Don't expose our first (received) header * XXX Sendmail compatibility. Don't expose our first (received) header
* to mail filter applications. See also cleanup_milter.c for code to * to mail filter applications. See also cleanup_milter.c for code to
@@ -1990,6 +2012,8 @@ static void milter8_eoh(void *ptr)
MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr; MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
MILTER8 *milter = msg_ctx->milter; MILTER8 *milter = msg_ctx->milter;
if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
return;
if (msg_verbose) if (msg_verbose)
msg_info("%s: eoh milter %s", myname, milter->m.name); msg_info("%s: eoh milter %s", myname, milter->m.name);
msg_ctx->resp = msg_ctx->resp =
@@ -2012,6 +2036,9 @@ static void milter8_body(void *ptr, int rec_type,
ssize_t space; ssize_t space;
ssize_t count; ssize_t count;
if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
return;
/* /*
* XXX Sendmail compatibility: don't expose our first body line. * XXX Sendmail compatibility: don't expose our first body line.
*/ */
@@ -2079,6 +2106,8 @@ static void milter8_eob(void *ptr)
MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr; MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
MILTER8 *milter = msg_ctx->milter; MILTER8 *milter = msg_ctx->milter;
if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
return;
if (msg_verbose) if (msg_verbose)
msg_info("%s: eob milter %s", myname, milter->m.name); msg_info("%s: eob milter %s", myname, milter->m.name);
msg_ctx->resp = msg_ctx->resp =
@@ -2144,7 +2173,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
/* /*
* XXX When the message (not MIME body part) does not end in CRLF * XXX When the message (not MIME body part) does not end in CRLF
* (i.e. the last record was REC_TYPE_CONT), do we send CRLF * (i.e. the last record was REC_TYPE_CONT), do we send a CRLF
* terminator before triggering the end-of-body condition? * terminator before triggering the end-of-body condition?
*/ */
for (;;) { for (;;) {
@@ -2164,9 +2193,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
msg_ctx.resp = "450 4.3.0 Queue file write error"; msg_ctx.resp = "450 4.3.0 Queue file write error";
break; break;
} }
if (msg_ctx.resp != 0) if (MILTER8_MESSAGE_DONE(milter, &msg_ctx))
break;
if (milter->state != MILTER8_STAT_MESSAGE)
break; break;
if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT) if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
break; break;

View File

@@ -237,7 +237,7 @@ void qmgr_entry_done(QMGR_ENTRY *entry, int which)
#define FUDGE(x) ((x) * (var_qmgr_fudge / 100.0)) #define FUDGE(x) ((x) * (var_qmgr_fudge / 100.0))
message->refcount--; message->refcount--;
if (message->rcpt_offset > 0 if (message->rcpt_offset > 0
&& qmgr_recipient_count < FUDGE(var_qmgr_rcpt_limit)) && qmgr_recipient_count < FUDGE(var_qmgr_rcpt_limit) - 100)
qmgr_message_realloc(message); qmgr_message_realloc(message);
if (message->refcount == 0) if (message->refcount == 0)
qmgr_active_done(message); qmgr_active_done(message);

View File

@@ -763,6 +763,16 @@ static QMGR_PEER *qmgr_job_peer_select(QMGR_JOB *job)
QMGR_PEER *peer; QMGR_PEER *peer;
QMGR_MESSAGE *message = job->message; QMGR_MESSAGE *message = job->message;
/*
* Workaround to prevent queue manager starvation until the last slow
* batch of multi-recipient mail is finished. Postfix 2.4 has a final
* solution, but that involves major changes.
*/
if (message->rcpt_offset != 0
&& message->rcpt_limit > message->rcpt_count + 100
&& message->refcount > 0) {
qmgr_message_realloc(message);
}
if (HAS_ENTRIES(job) && (peer = qmgr_peer_select(job)) != 0) if (HAS_ENTRIES(job) && (peer = qmgr_peer_select(job)) != 0)
return (peer); return (peer);

View File

@@ -361,6 +361,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
if (recipient_limit < message->rcpt_limit) if (recipient_limit < message->rcpt_limit)
recipient_limit = message->rcpt_limit; recipient_limit = message->rcpt_limit;
} }
/* Keep interrupt latency in check. */
if (recipient_limit > 5000)
recipient_limit = 5000;
if (recipient_limit <= 0) if (recipient_limit <= 0)
msg_panic("%s: no recipient slots available", message->queue_id); msg_panic("%s: no recipient slots available", message->queue_id);

View File

@@ -305,7 +305,8 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session)
*/ */
session->error_mask |= MAIL_ERROR_PROTOCOL; session->error_mask |= MAIL_ERROR_PROTOCOL;
if (session->features & SMTP_FEATURE_PIPELINING) { if (session->features & SMTP_FEATURE_PIPELINING) {
msg_warn("non-%s response from %s: %.100s", msg_warn("%s: non-%s response from %s: %.100s",
session->state->request->queue_id,
(session->state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) ? (session->state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) ?
"LMTP" : "ESMTP", session->namaddrport, "LMTP" : "ESMTP", session->namaddrport,
STR(session->buffer)); STR(session->buffer));

View File

@@ -379,7 +379,11 @@ static void smtp_cleanup_session(SMTP_STATE *state)
bad_session = THIS_SESSION_IS_BAD; /* smtp_quit() may fail */ bad_session = THIS_SESSION_IS_BAD; /* smtp_quit() may fail */
if (THIS_SESSION_IS_EXPIRED) if (THIS_SESSION_IS_EXPIRED)
smtp_quit(state); /* also disables caching */ smtp_quit(state); /* also disables caching */
if (THIS_SESSION_IS_CACHED) { if (THIS_SESSION_IS_CACHED
/* Redundant tests for safety... */
&& vstream_ferror(session->stream) == 0
&& vstream_ftimeout(session->stream) == 0
&& vstream_feof(session->stream) == 0) {
smtp_save_session(state); smtp_save_session(state);
} else { } else {
smtp_session_free(session); smtp_session_free(session);
@@ -493,6 +497,7 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path)
&& smtp_helo(state) != 0) { && smtp_helo(state) != 0) {
if (!THIS_SESSION_IS_DEAD if (!THIS_SESSION_IS_DEAD
&& vstream_ferror(session->stream) == 0 && vstream_ferror(session->stream) == 0
&& vstream_ftimeout(session->stream) == 0
&& vstream_feof(session->stream) == 0) && vstream_feof(session->stream) == 0)
smtp_quit(state); smtp_quit(state);
} else { } else {
@@ -871,6 +876,7 @@ static void smtp_connect_remote(SMTP_STATE *state, const char *nexthop,
*/ */
if (!THIS_SESSION_IS_DEAD if (!THIS_SESSION_IS_DEAD
&& vstream_ferror(session->stream) == 0 && vstream_ferror(session->stream) == 0
&& vstream_ftimeout(session->stream) == 0
&& vstream_feof(session->stream) == 0) && vstream_feof(session->stream) == 0)
smtp_quit(state); smtp_quit(state);
} else { } else {

View File

@@ -1014,6 +1014,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
} while (0) } while (0)
#define RETURN(x) do { \ #define RETURN(x) do { \
if (recv_state != SMTP_STATE_LAST) \
DONT_CACHE_THIS_SESSION; \
vstring_free(next_command); \ vstring_free(next_command); \
if (survivors) \ if (survivors) \
myfree((char *) survivors); \ myfree((char *) survivors); \