reported by Sahil Tandon, predicate error found by Viktor,
redundant connection restore request eliminated by Wietse.
File: smtp/smtp_connect.c.
+
+ Cleanup: the macros that control SMTP connection reuse
+ poorly reflected their purpose. "DEAD" is replaced with
+ "FORBIDDEN" (no I/O allowed) and "BAD" is replaced with
+ "THROTTLED" (anything that causes the queue manager to back
+ off from some destination). Files: smtp.h, smtp_coonnect.c,
+ smtp_proto.c, smtp_trouble.c.
+
+ Cleanup: enable SMTP connection cache lookup by destination
+ while a surge of mail is drying up. File: smtp_connect.c.
stress=
P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 2\b2.\b.9\b9 a\ban\bnd\bd l\bla\bat\bte\ber\br:\b:
ccert_pubkey_fingerprint=68:B3:29:DA:98:93:E3:40:99:C7:D8:AD:5C:B9:C9:40
+ P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 2\b2.\b.1\b12\b2 a\ban\bnd\bd l\bla\bat\bte\ber\br:\b:
+ client_port=1234
[empty line]
Notes:
stress=
<b>Postfix version 2.9 and later:</b>
ccert_pubkey_fingerprint=68:B3:29:DA:98:93:E3:40:99:C7:D8:AD:5C:B9:C9:40
+<b>Postfix version 2.12 and later:</b>
+client_port=1234
[empty line]
</pre>
</blockquote>
stress=
<b>Postfix version 2.9 and later:</b>
ccert_pubkey_fingerprint=68:B3:29:DA:98:93:E3:40:99:C7:D8:AD:5C:B9:C9:40
+<b>Postfix version 2.12 and later:</b>
+client_port=1234
[empty line]
</pre>
</blockquote>
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20140507"
+#define MAIL_RELEASE_DATE "20140508"
#define MAIL_VERSION_NUMBER "2.12"
#ifdef SNAPSHOT
time_t expire_time; /* session reuse expiration time */
int reuse_count; /* # of times reused (for logging) */
- int dead; /* No further I/O allowed */
+ int forbidden; /* No further I/O allowed */
#ifdef USE_SASL_AUTH
char *sasl_mechanism_list; /* server mechanism list */
* connections and other reasons why connections cannot be cached.
*/
#define THIS_SESSION_IS_CACHED \
- (!THIS_SESSION_IS_DEAD && session->expire_time > 0)
+ (!THIS_SESSION_IS_FORBIDDEN && session->expire_time > 0)
#define THIS_SESSION_IS_EXPIRED \
(THIS_SESSION_IS_CACHED \
|| (var_smtp_reuse_count > 0 \
&& session->reuse_count >= var_smtp_reuse_count)))
-#define THIS_SESSION_IS_BAD \
- (!THIS_SESSION_IS_DEAD && session->expire_time < 0)
+#define THIS_SESSION_IS_THROTTLED \
+ (!THIS_SESSION_IS_FORBIDDEN && session->expire_time < 0)
-#define THIS_SESSION_IS_DEAD \
- (session->dead != 0)
+#define THIS_SESSION_IS_FORBIDDEN \
+ (session->forbidden != 0)
/* Bring the bad news. */
#define DONT_CACHE_THIS_SESSION \
(session->expire_time = 0)
-#define DONT_CACHE_BAD_SESSION \
+#define DONT_CACHE_THROTTLED_SESSION \
(session->expire_time = -1)
-#define DONT_USE_DEAD_SESSION \
- (session->dead = 1)
+#define DONT_USE_FORBIDDEN_SESSION \
+ (session->forbidden = 1)
/* Initialization. */
#define USE_NEWBORN_SESSION \
- (session->dead = 0)
+ (session->forbidden = 0)
#define CACHE_THIS_SESSION_UNTIL(when) \
(session->expire_time = (when))
{
DELIVER_REQUEST *request = state->request;
SMTP_SESSION *session = state->session;
- int bad_session;
+ int throttled;
/*
* Inform the postmaster of trouble.
* physical bindings; caching a session under its own hostname provides
* no performance benefit, given the way smtp_connect() works.
*/
- bad_session = THIS_SESSION_IS_BAD; /* smtp_quit() may fail */
+ throttled = THIS_SESSION_IS_THROTTLED; /* smtp_quit() may fail */
if (THIS_SESSION_IS_EXPIRED)
smtp_quit(state); /* also disables caching */
if (THIS_SESSION_IS_CACHED
* next-hop destination. Otherwise we could end up skipping over the
* available and more preferred servers.
*/
- if (HAVE_NEXTHOP_STATE(state) && !bad_session)
+ if (HAVE_NEXTHOP_STATE(state) && !throttled)
FREE_NEXTHOP_STATE(state);
/*
*/
if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
&& smtp_helo(state) != 0) {
- if (!THIS_SESSION_IS_DEAD
+ if (!THIS_SESSION_IS_FORBIDDEN
&& vstream_ferror(session->stream) == 0
&& vstream_feof(session->stream) == 0)
smtp_quit(state);
*
* Opportunistic (a.k.a. on-demand) session caching on request by the
* queue manager. This is turned temporarily when a destination has a
- * high volume of mail in the active queue.
+ * high volume of mail in the active queue. When the surge reaches
+ * its end, the queue manager requests that connections be retrieved
+ * but not stored.
*/
if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
smtp_cache_policy(state, domain);
- if (state->misc_flags & SMTP_MISC_FLAG_CONN_STORE)
+ if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
SET_NEXTHOP_STATE(state, dest);
}
* When a TLS handshake fails, the stream is marked
* "dead" to avoid further I/O over a broken channel.
*/
- if (!THIS_SESSION_IS_DEAD
+ if (!THIS_SESSION_IS_FORBIDDEN
&& vstream_ferror(session->stream) == 0
&& vstream_feof(session->stream) == 0)
smtp_quit(state);
* We must avoid further I/O, the peer is in an undefined state.
*/
(void) vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
- DONT_USE_DEAD_SESSION;
+ DONT_USE_FORBIDDEN_SESSION;
/*
* If TLS is optional, try delivery to the same server over a
"unreadable mail queue entry");
/* Bailing out, abort stream with prejudice */
(void) vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
- DONT_USE_DEAD_SESSION;
+ DONT_USE_FORBIDDEN_SESSION;
/* If bounce_append() succeeded, status is still 0 */
if (state->status == 0)
(void) mark_corrupt(state->src);
* Don't cache this session. We can't talk to this server.
*/
if (throttle_queue && session)
- DONT_CACHE_BAD_SESSION;
+ DONT_CACHE_THROTTLED_SESSION;
return (-1);
}