diff --git a/postfix/HISTORY b/postfix/HISTORY index cd536e6ab..7df5b84bb 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -13267,6 +13267,25 @@ Apologies for any names omitted. src/smtpd/smtpd.c, src/tls/tls.h, src/tls/tls_client.c, src/tls/tls_misc.c and src/tls/tls_server.c. +20070222 + + Workaround: delayed "postfix reload" with ancient FreeBSD4 + kqueue implementations, causing the first external or + internal clients after "postfix reload" to experience a + quick disconnect. Apparently, these kqueue implementations + do not deliver a read notification when the master closes + the per-service shared master/child status pipe (even when + there is only one child; note that the master keeps a handle + to both ends of each status pipe). A child process remains + ignorant that the status pipe was closed until the arrival + of the next client request, and then terminates. The + workaround is to ignore master status write errors before + handling a service request. Files: master/*_server.c. + + Cleanup: fix race condition that caused unnecessary "premature + end-of-input" warning messages when "postfix reload" was + issued on a busy mail server. Files: util/attr_scan*c. + Wish list: Update message content length when adding/removing headers. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 553171c02..940efae07 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 "20070221" +#define MAIL_RELEASE_DATE "20070222" #define MAIL_VERSION_NUMBER "2.4" #ifdef SNAPSHOT diff --git a/postfix/src/master/multi_server.c b/postfix/src/master/multi_server.c index 77d024e39..06f58c06f 100644 --- a/postfix/src/master/multi_server.c +++ b/postfix/src/master/multi_server.c @@ -302,11 +302,13 @@ static void multi_server_execute(int unused_event, char *context) msg_fatal("select unlock: %m"); /* - * Do not bother the application when the client disconnected. + * Do not bother the application when the client disconnected. Don't drop + * the already accepted client request after "postfix reload"; that would + * be rude. */ if (peekfd(vstream_fileno(stream)) > 0) { if (master_notify(var_pid, multi_server_generation, MASTER_STAT_TAKEN) < 0) - multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT); + /* void */ ; multi_server_service(stream, multi_server_name, multi_server_argv); if (master_notify(var_pid, multi_server_generation, MASTER_STAT_AVAIL) < 0) multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT); diff --git a/postfix/src/master/single_server.c b/postfix/src/master/single_server.c index 82fec73d1..62c366f04 100644 --- a/postfix/src/master/single_server.c +++ b/postfix/src/master/single_server.c @@ -238,7 +238,8 @@ static void single_server_wakeup(int fd) * If the accept() succeeds, be sure to disable non-blocking I/O, because * the application is supposed to be single-threaded. Notice the master * of our (un)availability to service connection requests. Commit suicide - * when the master process disconnected from us. + * when the master process disconnected from us. Don't drop the already + * accepted client request after "postfix reload"; that would be rude. */ if (msg_verbose) msg_info("connection established"); @@ -250,7 +251,7 @@ static void single_server_wakeup(int fd) myfree(tmp); timed_ipc_setup(stream); if (master_notify(var_pid, single_server_generation, MASTER_STAT_TAKEN) < 0) - single_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT); + /* void */ ; if (single_server_in_flow_delay && mail_flow_get(1) < 0) doze(var_in_flow_delay * 1000000); single_server_service(stream, single_server_name, single_server_argv); diff --git a/postfix/src/master/trigger_server.c b/postfix/src/master/trigger_server.c index bdf042d61..77c044f3d 100644 --- a/postfix/src/master/trigger_server.c +++ b/postfix/src/master/trigger_server.c @@ -242,10 +242,12 @@ static void trigger_server_wakeup(int fd) int len; /* - * Commit suicide when the master process disconnected from us. + * Commit suicide when the master process disconnected from us. Don't + * drop the already accepted client request after "postfix reload"; that + * would be rude. */ if (master_notify(var_pid, trigger_server_generation, MASTER_STAT_TAKEN) < 0) - trigger_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT); + /* void */ ; if (trigger_server_in_flow_delay && mail_flow_get(1) < 0) doze(var_in_flow_delay * 1000000); if ((len = read(fd, buf, sizeof(buf))) >= 0) diff --git a/postfix/src/util/attr_scan0.c b/postfix/src/util/attr_scan0.c index 8297e7a18..379dce7ed 100644 --- a/postfix/src/util/attr_scan0.c +++ b/postfix/src/util/attr_scan0.c @@ -266,6 +266,13 @@ int attr_vscan0(VSTREAM *fp, int flags, va_list ap) if (flags & ~ATTR_FLAG_ALL) msg_panic("%s: bad flags: 0x%x", myname, flags); + /* + * EOF check. + */ + if ((ch = VSTREAM_GETC(fp)) == VSTREAM_EOF) + return (0); + vstream_ungetc(fp, ch); + /* * Initialize. */ diff --git a/postfix/src/util/attr_scan64.c b/postfix/src/util/attr_scan64.c index d148e6d8f..860f8b371 100644 --- a/postfix/src/util/attr_scan64.c +++ b/postfix/src/util/attr_scan64.c @@ -269,6 +269,13 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap) if (flags & ~ATTR_FLAG_ALL) msg_panic("%s: bad flags: 0x%x", myname, flags); + /* + * EOF check. + */ + if ((ch = VSTREAM_GETC(fp)) == VSTREAM_EOF) + return (0); + vstream_ungetc(fp, ch); + /* * Initialize. */ diff --git a/postfix/src/util/attr_scan_plain.c b/postfix/src/util/attr_scan_plain.c index 2d8f1a288..619bfae64 100644 --- a/postfix/src/util/attr_scan_plain.c +++ b/postfix/src/util/attr_scan_plain.c @@ -282,6 +282,13 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap) if (flags & ~ATTR_FLAG_ALL) msg_panic("%s: bad flags: 0x%x", myname, flags); + /* + * EOF check. + */ + if ((ch = VSTREAM_GETC(fp)) == VSTREAM_EOF) + return (0); + vstream_ungetc(fp, ch); + /* * Initialize. */