diff --git a/postfix/HISTORY b/postfix/HISTORY index 254e1d15f..bc6e7d1ad 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -12862,6 +12862,22 @@ Apologies for any names omitted. 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. Files: + smtp/smtp_proto.c, smtp/smtp_connect.c. + + Robustness: the vbuf and vstream documentation claimed that + their *error() macros reported timeout errors, but they + didn't really. The implementation was fixed, and redundant + vstream_ftimeout() calls were removed. As a result, many + Postfix daemons now properly detect write timeout errors + on internal connections. Files: util/vbuf.h. + Wish list: Investigate if clients of single-instance servers such as diff --git a/postfix/README_FILES/ADDRESS_REWRITING_README b/postfix/README_FILES/ADDRESS_REWRITING_README index 4ac6cb4e6..b7e75ad5a 100644 --- a/postfix/README_FILES/ADDRESS_REWRITING_README +++ b/postfix/README_FILES/ADDRESS_REWRITING_README @@ -831,7 +831,7 @@ no body content so none is shown in the example below. Content-Type: message/rfc822 Received: by spike.porcupine.org (Postfix, from userid 1001) - id 84863BC0E5; id DA77DBC0A9; Sun, 26 Nov 2006 17:01:01 -0500 (EST) + id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST) Subject: probe To: postfix-users@postfix.org Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org> diff --git a/postfix/html/ADDRESS_REWRITING_README.html b/postfix/html/ADDRESS_REWRITING_README.html index fd580115a..f2243516d 100644 --- a/postfix/html/ADDRESS_REWRITING_README.html +++ b/postfix/html/ADDRESS_REWRITING_README.html @@ -1232,7 +1232,7 @@ Content-Description: Message Content-Type: message/rfc822 Received: by spike.porcupine.org (Postfix, from userid 1001) - id 84863BC0E5; id DA77DBC0A9; Sun, 26 Nov 2006 17:01:01 -0500 (EST) + id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST) Subject: probe To: postfix-users@postfix.org Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org> diff --git a/postfix/proto/ADDRESS_REWRITING_README.html b/postfix/proto/ADDRESS_REWRITING_README.html index 21895ae5e..3fef90643 100644 --- a/postfix/proto/ADDRESS_REWRITING_README.html +++ b/postfix/proto/ADDRESS_REWRITING_README.html @@ -1232,7 +1232,7 @@ Content-Description: Message Content-Type: message/rfc822 Received: by spike.porcupine.org (Postfix, from userid 1001) - id 84863BC0E5; id DA77DBC0A9; Sun, 26 Nov 2006 17:01:01 -0500 (EST) + id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST) Subject: probe To: postfix-users@postfix.org Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org> diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 50368ed84..bc2d237b6 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 "20061201" +#define MAIL_RELEASE_DATE "20061203" #define MAIL_VERSION_NUMBER "2.4" #ifdef SNAPSHOT diff --git a/postfix/src/qmgr/qmgr_job.c b/postfix/src/qmgr/qmgr_job.c index cc86d0b46..6318893f4 100644 --- a/postfix/src/qmgr/qmgr_job.c +++ b/postfix/src/qmgr/qmgr_job.c @@ -769,7 +769,7 @@ static QMGR_PEER *qmgr_job_peer_select(QMGR_JOB *job) * solution, but that involves major changes. */ if (message->rcpt_offset != 0 - && message->rcpt_limit > message->rcpt_count - 100 + && message->rcpt_limit > message->rcpt_count + 100 && message->refcount > 0) { qmgr_message_realloc(message); } diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 3f87e7dc3..1430c8ced 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -379,7 +379,10 @@ static void smtp_cleanup_session(SMTP_STATE *state) bad_session = THIS_SESSION_IS_BAD; /* smtp_quit() may fail */ if (THIS_SESSION_IS_EXPIRED) 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_feof(session->stream) == 0) { smtp_save_session(state); } else { smtp_session_free(session); diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index 79fe31e1c..bdd46366c 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -1041,7 +1041,11 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state, } \ } while (0) + /* Caution: changes to RETURN() also affect code outside the main loop. */ + #define RETURN(x) do { \ + if (recv_state != SMTP_STATE_LAST) \ + DONT_CACHE_THIS_SESSION; \ vstring_free(next_command); \ if (survivors) \ myfree((char *) survivors); \ diff --git a/postfix/src/smtpd/smtpd_proxy.c b/postfix/src/smtpd/smtpd_proxy.c index 0f18fffee..345485abd 100644 --- a/postfix/src/smtpd/smtpd_proxy.c +++ b/postfix/src/smtpd/smtpd_proxy.c @@ -458,8 +458,7 @@ int smtpd_proxy_cmd(SMTPD_STATE *state, int expect, const char *fmt,...) /* * Errors first. Be prepared for delayed errors from the DATA phase. */ - if (vstream_ftimeout(state->proxy) - || vstream_ferror(state->proxy) + if (vstream_ferror(state->proxy) || vstream_feof(state->proxy) || ((err = vstream_setjmp(state->proxy)) != 0 && smtpd_proxy_rdwr_error(state->proxy, err))) { @@ -579,8 +578,7 @@ int smtpd_proxy_rec_put(VSTREAM *stream, int rec_type, /* * Errors first. */ - if (vstream_ftimeout(stream) || vstream_ferror(stream) - || vstream_feof(stream)) + if (vstream_ferror(stream) || vstream_feof(stream)) return (REC_TYPE_ERROR); if ((err = vstream_setjmp(stream)) != 0) return (smtpd_proxy_rdwr_error(stream, err), REC_TYPE_ERROR); @@ -608,8 +606,7 @@ int smtpd_proxy_rec_fprintf(VSTREAM *stream, int rec_type, /* * Errors first. */ - if (vstream_ftimeout(stream) || vstream_ferror(stream) - || vstream_feof(stream)) + if (vstream_ferror(stream) || vstream_feof(stream)) return (REC_TYPE_ERROR); if ((err = vstream_setjmp(stream)) != 0) return (smtpd_proxy_rdwr_error(stream, err), REC_TYPE_ERROR); diff --git a/postfix/src/util/vbuf.h b/postfix/src/util/vbuf.h index d5f4a426c..6052b4ed7 100644 --- a/postfix/src/util/vbuf.h +++ b/postfix/src/util/vbuf.h @@ -65,7 +65,7 @@ struct VBUF { #define VBUF_FLAG_BAD (VBUF_FLAG_ERR | VBUF_FLAG_EOF | VBUF_FLAG_TIMEOUT) #define VBUF_FLAG_FIXED (1<<3) /* fixed-size buffer */ -#define vbuf_error(v) ((v)->flags & VBUF_FLAG_ERR) +#define vbuf_error(v) ((v)->flags & (VBUF_FLAG_ERR | VBUF_FLAG_TIMEOUT)) #define vbuf_eof(v) ((v)->flags & VBUF_FLAG_EOF) #define vbuf_timeout(v) ((v)->flags & VBUF_FLAG_TIMEOUT) #define vbuf_clearerr(v) ((v)->flags &= ~VBUF_FLAG_BAD) diff --git a/postfix/src/util/vstream.c b/postfix/src/util/vstream.c index ed857b3e3..1a3373a8e 100644 --- a/postfix/src/util/vstream.c +++ b/postfix/src/util/vstream.c @@ -280,12 +280,18 @@ /* /* vstream_feof() returns non-zero when a previous operation on the /* specified stream caused an end-of-file condition. +/* Further read requests after EOF may complete succesfully, +/* even when vstream_clearerr() is not called for that stream. /* /* vstream_ferror() returns non-zero when a previous operation on the /* specified stream caused a non-EOF error condition, including timeout. +/* After a non-EOF, non-timeout, error on a stream, no I/O request will +/* complete until after vstream_clearerr() is called for that stream. /* /* vstream_ftimeout() returns non-zero when a previous operation on the /* specified stream caused a timeout error condition. +/* Further I/O requests after timeout may complete succesfully, +/* even when vstream_clearerr() is not called for that stream. /* /* vstream_clearerr() resets the timeout, error and end-of-file indication /* of the specified stream, and returns no useful result.