global/dict_mongodb.c, global/dict_mongodb.h, global/mail_dict.c,
global/Makefile.in, postconf/Makefile.in, proto/INSTALL.html,
postfix/postfix.c.
+
+20240209
+
+ Safety: enforce a sane but generous upper bound (100) for
+ the number of DNS resource records that the Postfix DNS
+ client library will admit into a list. This is 20x the
+ default smtp_mx_address_limit value for the number of DNS
+ records that the Postfix SMTP client is willing to consider.
+ Log a warning "dropping records after qname=X qtype=Y" when
+ a list cannot accept more elements. This prevents a tail
+ recursion crash that degrades mail delivery performance.
+ Problem report by Toshifumi Sakaguchi. Files: dns/dns_rr.[hc],
+ global/mail_params.h.
+
+ Performance: eliminate worst-case behavior where the queue
+ manager defers delivery to all destinations over a specific
+ delivery transport, after only a single delivery agent
+ failure. The scheduler now throttles one destination, and
+ allows deliveries to other destinations to keep making
+ progress. Files: *qmgr/qmgr_deliver.c.
</blockquote>
<p> The file /etc/postfix/mongo-aliases.cf can specify a number of
-parameters. For a complete description, see the mongodb_table(5)
+parameters. For a complete description, see the <a href="mongodb_table.5.html">mongodb_table(5)</a>
manual page. </p>
<h2><a name="example_virtual">Example: virtual(5) alias maps</a></h2>
Dextrous
Mongo
SUD
+qtype
MONGODB
Refactored
Vijay
+Sakaguchi
+Toshifumi
dns_lookup.o: dns.h
dns_lookup.o: dns_lookup.c
dns_rr.o: ../../include/check_arg.h
+dns_rr.o: ../../include/mail_params.h
dns_rr.o: ../../include/msg.h
dns_rr.o: ../../include/myaddrinfo.h
dns_rr.o: ../../include/mymalloc.h
/*
/* DNS_RR *dns_srv_rr_sort(list)
/* DNS_RR *list;
+/*
+/* int var_dns_rr_list_limit;
/* AUXILIARY FUNCTIONS
/* DNS_RR *dns_rr_create_nopref(qname, rname, type, class, ttl,
/* data, data_len)
/* dns_rr_append() appends a resource record to a (list of) resource
/* record(s).
/* A null input list is explicitly allowed.
+/* This function will log a warning and will discard the
+/* resource record, when a list already contains var_dns_rr_list_limit
+/* elements (default: 100).
/*
/* dns_rr_sort() sorts a list of resource records into ascending
/* order according to a user-specified criterion. The result is the
#include <mymalloc.h>
#include <myrand.h>
+/* Global library. */
+
+#include <mail_params.h>
+
/* DNS library. */
#include "dns.h"
+ /*
+ * Global, to make code testable.
+ */
+int var_dns_rr_list_limit = DEF_DNS_RR_LIST_LIMIT;
+
/* dns_rr_create - fill in resource record structure */
DNS_RR *dns_rr_create(const char *qname, const char *rname,
return (dst);
}
-/* dns_rr_append - append resource record to list */
+/* dns_rr_append_with_limit - append resource record to limited list */
-DNS_RR *dns_rr_append(DNS_RR *list, DNS_RR *rr)
+static DNS_RR *dns_rr_append_with_limit(DNS_RR *list, DNS_RR *rr, int limit)
{
+
+ /*
+ * To avoid log spam, remember a limited amount of information about a
+ * past warning. When anomalies happen frequently, then it is OK that
+ * some anomaly will not be logged, as long as the limit is enforced.
+ */
if (list == 0) {
list = rr;
+ } else if (limit > 1) {
+ list->next = dns_rr_append_with_limit(list->next, rr, limit - 1);
} else {
- list->next = dns_rr_append(list->next, rr);
+ static DNS_RR *logged_node;
+
+ if (logged_node != list) {
+ logged_node = list;
+ msg_warn("dns_rr_append: dropping records after qname=%s qtype=%s",
+ list->qname, dns_strtype(list->type));
+ }
+ dns_rr_free(rr);
}
return (list);
}
+/* dns_rr_append - append resource record to list */
+
+DNS_RR *dns_rr_append(DNS_RR *list, DNS_RR *rr)
+{
+ return (dns_rr_append_with_limit(list, rr, var_dns_rr_list_limit));
+}
+
/* dns_rr_compare_pref_ipv6 - compare records by preference, ipv6 preferred */
int dns_rr_compare_pref_ipv6(DNS_RR *a, DNS_RR *b)
var_dnssec_probe = "";
msg_vstream_init(argv[0], VSTREAM_ERR);
- while ((ch = GETOPT(argc, argv, "f:npvs")) > 0) {
+ while ((ch = GETOPT(argc, argv, "f:l:npvs")) > 0) {
switch (ch) {
case 'v':
msg_verbose++;
case 'f':
dns_rr_filter_compile("DNS reply filter", optarg);
break;
+ case 'l':
+ var_dns_rr_list_limit = atoi(optarg);
+ break;
case 'n':
lflags |= DNS_REQ_FLAG_NCACHE_TTL;
break;
#define DEF_DNS_NCACHE_TTL_FIX 0
extern bool var_dns_ncache_ttl_fix;
+ /*
+ * A generous safety limit for the number of DNS resource records that the
+ * Postfix DNS client library will admit into a list. The default is 20x the
+ * default limit on the number address records that the Postfix SMTP client
+ * is willing to consider.
+ */
+#define VAR_DNS_RR_LIST_LIMIT "dns_resource_list_limit"
+#define DEF_DNS_RR_LIST_LIMIT 100
+extern int var_dns_rr_list_limit;
+
/*
* Logging. As systems evolve over time, logging becomes more challenging.
*/
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20240208"
+#define MAIL_RELEASE_DATE "20240209"
#define MAIL_VERSION_NUMBER "3.9"
#ifdef SNAPSHOT
* The queue itself won't go away before we dispose of the current queue
* entry.
*/
+#if 0
if (status == DELIVER_STAT_CRASH) {
message->flags |= DELIVER_STAT_DEFER;
#if 0
qmgr_defer_transport(transport, &dsb->dsn);
return;
}
+#endif
/*
* This message must be tried again.
*/
#define SUSPENDED "delivery temporarily suspended: "
- if (status == DELIVER_STAT_DEFER) {
+ if (status == DELIVER_STAT_CRASH)
+ (void) DSN_SIMPLE(&dsb->dsn, "4.3.0", "unknown mail transport error");
+ if (status == DELIVER_STAT_CRASH || status == DELIVER_STAT_DEFER) {
message->flags |= DELIVER_STAT_DEFER;
if (VSTRING_LEN(dsb->status)) {
/* Sanitize the DSN status/reason from the delivery agent. */
* The queue itself won't go away before we dispose of the current queue
* entry.
*/
+#if 0
if (status == DELIVER_STAT_CRASH) {
message->flags |= DELIVER_STAT_DEFER;
#if 0
qmgr_defer_transport(transport, &dsb->dsn);
return;
}
+#endif
/*
* This message must be tried again.
*/
#define SUSPENDED "delivery temporarily suspended: "
- if (status == DELIVER_STAT_DEFER) {
+ if (status == DELIVER_STAT_CRASH)
+ (void) DSN_SIMPLE(&dsb->dsn, "4.3.0", "unknown mail transport error");
+ if (status == DELIVER_STAT_CRASH || status == DELIVER_STAT_DEFER) {
message->flags |= DELIVER_STAT_DEFER;
if (VSTRING_LEN(dsb->status)) {
/* Sanitize the DSN status/reason from the delivery agent. */