be fixed; it must be specified before the message content
is received. Files: smtpd/smtpd.c, smtpd/smtpd_check.c,
cleanup/cleanup_extracted.c, pickup/pickup.c.
+
+20051201
+
+ Bugfix: the LMTP client would reuse a session after negative
+ reply to the RSET command (which may happen when client and
+ server somehow get out of sync). Problem found by Christian
+ Theune. Files: lmtp/lmtp.c, lmtp/lmtp_proto.c.
+
+20051207
+
+ Bugfix: race condition in the connection caching protocol,
+ causing the SMTP delivery agent to hang after delivering
+ mail, while trying to save a connection. Introduced with
+ Postfix 2.2.5. Files: scache/scache.c.
+
+20051208
+
+ Bugfix: the best_mx_transport, mailbox_transport and
+ fallback_transport features did not write a per-recipient
+ defer logfile record when the target delivery agent was
+ broken. This the analog of queue manager bugfix 20051119.
+ Files: global/deliver_pass.c.
#include <mail_params.h>
#include <deliver_pass.h>
+#define DELIVER_PASS_DEFER 1
+#define DELIVER_PASS_UNKNOWN 2
+
/* deliver_pass_initial_reply - retrieve initial delivery process response */
static int deliver_pass_initial_reply(VSTREAM *stream)
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
ATTR_TYPE_END) != 2) {
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
- stat = -1;
+ return (DELIVER_PASS_UNKNOWN);
+ } else {
+ return (stat ? DELIVER_PASS_DEFER : 0);
}
- return (stat);
}
/* deliver_pass - deliver one per-site queue entry */
* XXX Can't pass back hop status info because the problem is with a
* different transport.
*/
- if ((status = deliver_pass_initial_reply(stream)) == 0
- && (status = deliver_pass_send_request(stream, request, nexthop,
- orig_addr, addr, offs)) == 0)
- status = deliver_pass_final_reply(stream, reason);
+ if (deliver_pass_initial_reply(stream) != 0
+ || deliver_pass_send_request(stream, request, nexthop,
+ orig_addr, addr, offs) != 0) {
+ status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
+ request->queue_id, orig_addr, addr,
+ offs, "none", request->arrival_time,
+ "mail transport unavailable");
+ } else if ((status = deliver_pass_final_reply(stream, reason))
+ == DELIVER_PASS_UNKNOWN) {
+ status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
+ request->queue_id, orig_addr, addr,
+ offs, "none", request->arrival_time,
+ "unknown mail transport error");
+ }
/*
* Clean up.
* Patches change the patchlevel and the release date. Snapshots change the
* release date only.
*/
-#define MAIL_RELEASE_DATE "20051130"
-#define MAIL_VERSION_NUMBER "2.2.6"
+#define MAIL_RELEASE_DATE "20051208"
+#define MAIL_VERSION_NUMBER "2.2.7"
#define VAR_MAIL_VERSION "mail_version"
#ifdef SNAPSHOT
* Disconnect if RSET can't be sent over an existing connection.
* Discard transcript and status information for sending RSET.
*/
- else if (lmtp_rset(state) != 0) {
+ else if (lmtp_rset(state) != 0
+ || (state->features & LMTP_FEATURE_RSET_REJECTED) != 0) {
lmtp_chat_reset(state);
state->session = lmtp_session_free(state->session);
#ifdef USE_SASL_AUTH
#define LMTP_FEATURE_XFORWARD_PROTO (1<<8)
#define LMTP_FEATURE_XFORWARD_HELO (1<<9)
#define LMTP_FEATURE_XFORWARD_DOMAIN (1<<10)
+#define LMTP_FEATURE_RSET_REJECTED (1<<11)
/*
* lmtp.c
/* accordingly.
/*
/* lmtp_rset() sends a lone RSET command and waits for the response.
+/* In case of a negative reply it sets the CANT_RSET_THIS_SESSION flag.
/*
/* lmtp_quit() sends a lone QUIT command and waits for the response
/* only if waiting for QUIT replies is enabled.
#define SENDING_MAIL \
(recv_state <= LMTP_STATE_DOT)
+#define CANT_RSET_THIS_SESSION \
+ (state->features |= LMTP_FEATURE_RSET_REJECTED)
+
/*
* Pipelining support requires two loops: one loop for sending and one
* for receiving. Each loop has its own independent state. Most of the
* Ignore the RSET response.
*/
case LMTP_STATE_RSET:
+ if (resp->code / 100 != 2)
+ CANT_RSET_THIS_SESSION;
recv_state = LMTP_STATE_LAST;
break;
* dedicated to the scache service. All connection-management stuff is
* handled by the common code in multi_server.c.
*/
+do {
if (attr_scan(client_stream,
ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_REQ, scache_request,
ATTR_TYPE_END);
}
}
+} while (vstream_peek(client_stream) > 0);
vstream_fflush(client_stream);
}