From f0eb7761f8fb5ea0af89a633b981915c43e25a30 Mon Sep 17 00:00:00 2001
From: Wietse Venema
Specify the name of a "type:table" lookup table. The search string is a single SMTP reply line as received from the remote SMTP -server, except that the trailing <CR><LF> are removed.
+server, except that the trailing <CR><LF> are removed. +When the lookup succeeds, the result replaces the single SMTP reply +line.Examples:
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index c8467e669..b1b33649f 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -5757,6 +5757,8 @@ uses a generic enhanced status code (X.0.0) instead. Specify the name of a "type:table" lookup table. The search string is a single SMTP reply line as received from the remote SMTP server, except that the trailingSpecify the name of a "type:table" lookup table. The search string is a single SMTP reply line as received from the remote SMTP -server, except that the trailing <CR><LF> are removed.
+server, except that the trailing <CR><LF> are removed. +When the lookup succeeds, the result replaces the single SMTP reply +line.Examples:
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 013b14363..e861bf990 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 "20110820" +#define MAIL_RELEASE_DATE "20110905" #define MAIL_VERSION_NUMBER "2.9" #ifdef SNAPSHOT diff --git a/postfix/src/master/master_avail.c b/postfix/src/master/master_avail.c index 09baead1f..472b59a1a 100644 --- a/postfix/src/master/master_avail.c +++ b/postfix/src/master/master_avail.c @@ -85,7 +85,9 @@ static void master_avail_event(int event, char *context) if (event == 0) /* XXX Can this happen? */ return; - if (MASTER_THROTTLED(serv)) { /* XXX interface botch */ + /* XXX Should check these when the process or service status is changed. */ + if (!MASTER_LIMIT_OK(serv->max_proc, serv->total_proc) + || MASTER_THROTTLED(serv)) { /* XXX interface botch */ for (n = 0; n < serv->listen_fd_count; n++) event_disable_readwrite(serv->listen_fd[n]); } else { diff --git a/postfix/src/milter/milter8.c b/postfix/src/milter/milter8.c index 35accb022..22d4c419f 100644 --- a/postfix/src/milter/milter8.c +++ b/postfix/src/milter/milter8.c @@ -1255,11 +1255,13 @@ static const char *milter8_event(MILTER8 *milter, int event, MILTER8_DATA_BUFFER, milter->buf, MILTER8_DATA_END) != 0) MILTER8_EVENT_BREAK(milter->def_reply); + /* XXX Enforce this for each line of a multi-line reply. */ if ((STR(milter->buf)[0] != '4' && STR(milter->buf)[0] != '5') || !ISDIGIT(STR(milter->buf)[1]) || !ISDIGIT(STR(milter->buf)[2]) || (STR(milter->buf)[3] != ' ' && STR(milter->buf)[3] != '-') - || STR(milter->buf)[4] != STR(milter->buf)[0]) { + || (ISDIGIT(STR(milter->buf)[4]) + && (STR(milter->buf)[4] != STR(milter->buf)[0]))) { msg_warn("milter %s: malformed reply: %s", milter->m.name, STR(milter->buf)); milter8_conf_error(milter); diff --git a/postfix/src/tls/tls_bio_ops.c b/postfix/src/tls/tls_bio_ops.c index 4d1bf1a41..075b113aa 100644 --- a/postfix/src/tls/tls_bio_ops.c +++ b/postfix/src/tls/tls_bio_ops.c @@ -159,16 +159,14 @@ int tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext, int status; int err; int enable_deadline; - struct timeval time_limit; /* initial time limit */ struct timeval time_left; /* amount of time left */ - struct timeval time_entry; /* time of tls_bio() entry */ + struct timeval time_deadline; /* time of deadline */ struct timeval time_now; /* time after SSL_mumble() call */ - struct timeval time_elapsed; /* total elapsed time */ /* * Compensation for interface mis-match: With VSTREAMs, timeout <= 0 - * means wait forever; with the read/write_wait() calls below, we need - * to specify timeout < 0 instead. + * means wait forever; with the read/write_wait() calls below, we need to + * specify timeout < 0 instead. * * Safety: no time limit means no deadline. */ @@ -186,9 +184,8 @@ int tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext, enable_deadline = vstream_fstat(TLScontext->stream, VSTREAM_FLAG_DEADLINE); if (enable_deadline) { - time_limit.tv_sec = timeout; - time_limit.tv_usec = 0; - GETTIMEOFDAY(&time_entry); + GETTIMEOFDAY(&time_deadline); + time_deadline.tv_sec += timeout; } } @@ -276,8 +273,7 @@ int tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext, case SSL_ERROR_WANT_READ: if (enable_deadline) { GETTIMEOFDAY(&time_now); - timersub(&time_now, &time_entry, &time_elapsed); - timersub(&time_limit, &time_elapsed, &time_left); + timersub(&time_deadline, &time_now, &time_left); timeout = time_left.tv_sec + (time_left.tv_usec > 0); if (timeout <= 0) { errno = ETIMEDOUT; diff --git a/postfix/src/util/vstream.c b/postfix/src/util/vstream.c index 5da2f1598..fb010eed6 100644 --- a/postfix/src/util/vstream.c +++ b/postfix/src/util/vstream.c @@ -699,6 +699,13 @@ static int vstream_fflush_some(VSTREAM *stream, ssize_t to_flush) * When flushing a buffer, allow for partial writes. These can happen * while talking to a network. Update the cached file seek position, if * any. + * + * When deadlines are enabled, we count the elapsed time for each write + * operation instead of simply comparing the time-of-day clock with a + * per-stream deadline. The latter could result in anomalies when an + * application does lengthy processing between write operations. Keep in + * mind that a receiver may not be able to keep up when a sender suddenly + * floods it with a lot of data as it tries to catch up with a deadline. */ for (data = (char *) bp->data, len = to_flush; len > 0; len -= n, data += n) { if (bp->flags & VSTREAM_FLAG_DEADLINE) { @@ -852,6 +859,14 @@ static int vstream_buf_get_ready(VBUF *bp) * Fill the buffer with as much data as we can handle, or with as much * data as is available right now, whichever is less. Update the cached * file seek position, if any. + * + * When deadlines are enabled, we count the elapsed time for each read + * operation instead of simply comparing the time-of-day clock with a + * per-stream deadline. The latter could result in anomalies when an + * application does lengthy processing between read operations. Keep in + * mind that a sender may get blocked, and may not be able to keep up + * when a receiver suddenly wants to read a lot of data as it tries to + * catch up with a deadline. */ if (bp->flags & VSTREAM_FLAG_DEADLINE) { timeout = stream->time_limit.tv_sec + (stream->time_limit.tv_usec > 0); diff --git a/postfix/src/util/vstream_tweak.c b/postfix/src/util/vstream_tweak.c index a9dc8bd1b..83340d237 100644 --- a/postfix/src/util/vstream_tweak.c +++ b/postfix/src/util/vstream_tweak.c @@ -40,6 +40,7 @@ #include