localpart, as in "-t localpart+@domain" or "-t localpart+"
where "+" is the Postfix recipient address delimiter. File:
smtpstone/smtp-source.c.
+
+20230924
+
+ Cleanup: simplified the smtp-source numbered recipient
+ implementation and documentation. File: smtpstone/smtp-source.c.
+
+ Documentation: added smtp_balance_inet_protocols to the
+ text with smtp_address_preference caveats. File:
+ proto/postconf.proto.
<ul>
<li> <p> The setting "<a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> = ipv6" is unsafe.
-It can fail to deliver mail when there is an outage that affects
-IPv6, while the destination is still reachable over IPv4. </p>
+All deliveries will suffer delays when IPv6 is not available even
+while the destination is still reachable over IPv4. Mail may be
+stuck in the queue with Postfix versions < 3.3 that do not
+implement "<a href="postconf.5.html#smtp_balance_inet_protocols">smtp_balance_inet_protocols</a>". For similar reasons, the
+setting "<a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> = ipv4" is also unsafe. </p>
<li> <p> The setting "<a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> = any" is safe. With
-this, mail will eventually be delivered even if there is an outage
+this, and "<a href="postconf.5.html#smtp_balance_inet_protocols">smtp_balance_inet_protocols</a> = yes" (the default), only
+half of deliveries will suffer delays if there is an outage
that affects IPv6 or IPv4, as long as it does not affect both. </p>
</ul>
over the same connection.
<b>-f</b> <i>from</i>
- Use the specified sender address (default: <foo@<a href="postconf.5.html#myhostname">myhostname</a>>).
+ Use the specified sender address (default: <foo@my-hostname>).
<b>-F</b> <i>file</i>
Send the pre-formatted message header and body in the specified
<b>-m</b> <i>message</i><b>_</b><i>count</i>
Send the specified number of messages (default: 1).
- <b>-M</b> <i><a href="postconf.5.html#myhostname">myhostname</a></i>
+ <b>-M</b> <i>my-hostname</i>
Use the specified hostname or [address] in the HELO command and
in the default sender and recipient addresses, instead of the
machine hostname.
<b>-N</b> Generate each recipient address by appending a number (a
per-process recipient counter) to the recipient address local-
- part specified with the <b>-t</b> option. This avoids an artificial
- 100% hit rate in the trivial-rewrite daemon's resolve and re-
- write client caches, better approximating Postfix performance
- under real-life work-loads.
+ part specified with the <b>-t</b> option.
- Note: to use the number as an address extension, specify an
- explicit address delimiter at the end of the recipient local-
+ Note: to use the number as an address extension, specify an
+ explicit address delimiter at the end of the recipient local-
part, as in "<b>-t localpart+@domain</b>" or "<b>-t localpart+</b>", where "<b>+</b>"
- is the recipient address delimiter.
+ is a Postfix recipient address delimiter.
+
+ Benefits:
+
+ <b>o</b> A non-constant recipient address avoids an unrealistic
+ 100% cache hit rate in clients of the Postfix trivial-re-
+ write service, better approximating performance under
+ real-life work-loads.
+
+ <b>o</b> A fixed recipient address local-part with a non-constant
+ address extension avoids the need to configure a large
+ number of valid recipient addresses in the receiving
+ Postfix server.
<b>-o</b> Old mode: don't send HELO, and don't send message headers.
<b>-r</b> <i>recipient</i><b>_</b><i>count</i>
- Send the specified number of recipients per transaction
- (default: 1). Generate each recipient address by appending a
- number (a per-connection recipient counter) to the recipient
- address localpart specified with the <b>-t</b> option.
-
- Note: to use the number as an address extension, specify an
- explicit address delimiter at the end of the recipient local-
- part, as in "<b>-t localpart+@domain</b>" or "<b>-t localpart+</b>", where "<b>+</b>"
- is the recipient address delimiter.
+ Send the specified number of recipients per transaction
+ (default: 1), and generate recipient addresses as described
+ under the <b>-N</b> option.
<b>-R</b> <i>interval</i>
- Wait a random time (0 <= n <= <i>interval</i>) between messages. Sus-
+ Wait a random time (0 <= n <= <i>interval</i>) between messages. Sus-
pending one thread does not affect other delivery threads.
<b>-s</b> <i>session</i><b>_</b><i>count</i>
- Run the specified number of SMTP sessions in parallel (default:
+ Run the specified number of SMTP sessions in parallel (default:
1).
<b>-S</b> <i>subject</i>
Send mail with the named subject line (default: none).
- <b>-t</b> <i>to</i> Use the specified recipient address (default: <foo@<a href="postconf.5.html#myhostname">myhostname</a>>).
+ <b>-t</b> <i>to</i> Use the specified recipient address (default: <foo@my-host-
+ name>).
<b>-T</b> <i>windowsize</i>
- Override the default TCP window size. To work around broken TCP
+ Override the default TCP window size. To work around broken TCP
window scaling implementations, specify a value > 0 and < 65536.
<b>-v</b> Make the program more verbose, for debugging purposes.
<b>-w</b> <i>interval</i>
- Wait a fixed time between messages. Suspending one thread does
+ Wait a fixed time between messages. Suspending one thread does
not affect other delivery threads.
[<b>inet:</b>]<i>host</i>[:<i>port</i>]
- Connect via TCP to host <i>host</i>, port <i>port</i>. The default port is
+ Connect via TCP to host <i>host</i>, port <i>port</i>. The default port is
<b>smtp</b>.
<b>unix:</b><i>pathname</i>
Don't disconnect after sending a message; send the next
message over the same connection.
.IP "\fB\-f \fIfrom\fR"
-Use the specified sender address (default: <foo@myhostname>).
+Use the specified sender address (default: <foo@my\-hostname>).
.IP "\fB\-F \fIfile\fR"
Send the pre\-formatted message header and body in the
specified \fIfile\fR, while prepending '.' before lines that
Speak LMTP rather than SMTP.
.IP "\fB\-m \fImessage_count\fR"
Send the specified number of messages (default: 1).
-.IP "\fB\-M \fImyhostname\fR"
+.IP "\fB\-M \fImy\-hostname\fR"
Use the specified hostname or [address] in the HELO command
and in the default sender and recipient addresses, instead
of the machine hostname.
.IP "\fB\-N\fR"
Generate each recipient address by appending a number (a
per\-process recipient counter) to the recipient address
-localpart specified with the \fB\-t\fR option. This avoids
-an artificial 100% hit rate in the trivial\-rewrite daemon's
-resolve and rewrite client caches, better approximating
-Postfix performance under real\-life work\-loads.
+localpart specified with the \fB\-t\fR option.
Note: to use the number as an address extension, specify
an explicit address delimiter at the end of the recipient
localpart, as in "\fB\-t localpart+@domain\fR" or "\fB\-t
-localpart+\fR", where "\fB+\fR" is the recipient address
-delimiter.
+localpart+\fR", where "\fB+\fR" is a Postfix recipient
+address delimiter.
+
+Benefits:
+.RS
+.IP \(bu
+A non\-constant recipient address avoids an unrealistic 100%
+cache hit rate in clients of the Postfix trivial\-rewrite
+service, better approximating performance under real\-life
+work\-loads.
+.IP \(bu
+A fixed recipient address local\-part with a non\-constant
+address extension avoids the need to configure a large
+number of valid recipient addresses in the receiving Postfix
+server.
+.RE
.IP \fB\-o\fR
Old mode: don't send HELO, and don't send message headers.
.IP "\fB\-r \fIrecipient_count\fR"
-Send the specified number of recipients per transaction (default: 1).
-Generate each recipient address by appending a number (a
-per\-connection recipient counter) to the recipient address
-localpart specified with the \fB\-t\fR option.
-
-Note: to use the number as an address extension, specify
-an explicit address delimiter at the end of the recipient
-localpart, as in "\fB\-t localpart+@domain\fR" or "\fB\-t
-localpart+\fR", where "\fB+\fR" is the recipient address
-delimiter.
+Send the specified number of recipients per transaction
+(default: 1), and generate recipient addresses as described
+under the \fB\-N\fR option.
.IP "\fB\-R \fIinterval\fR"
Wait a random time (0 <= n <= \fIinterval\fR) between messages.
Suspending one thread does not affect other delivery threads.
.IP "\fB\-S \fIsubject\fR"
Send mail with the named subject line (default: none).
.IP "\fB\-t \fIto\fR"
-Use the specified recipient address (default: <foo@myhostname>).
+Use the specified recipient address (default: <foo@my\-hostname>).
.IP "\fB\-T \fIwindowsize\fR"
Override the default TCP window size. To work around
broken TCP window scaling implementations, specify a
IPv6 connectivity:
.IP \(bu
The setting "smtp_address_preference = ipv6" is unsafe.
-It can fail to deliver mail when there is an outage that affects
-IPv6, while the destination is still reachable over IPv4.
+All deliveries will suffer delays when IPv6 is not available even
+while the destination is still reachable over IPv4. Mail may be
+stuck in the queue with Postfix versions < 3.3 that do not
+implement "smtp_balance_inet_protocols". For similar reasons, the
+setting "smtp_address_preference = ipv4" is also unsafe.
.IP \(bu
The setting "smtp_address_preference = any" is safe. With
-this, mail will eventually be delivered even if there is an outage
+this, and "smtp_balance_inet_protocols = yes" (the default), only
+half of deliveries will suffer delays if there is an outage
that affects IPv6 or IPv4, as long as it does not affect both.
.br
.PP
<ul>
<li> <p> The setting "smtp_address_preference = ipv6" is unsafe.
-It can fail to deliver mail when there is an outage that affects
-IPv6, while the destination is still reachable over IPv4. </p>
+All deliveries will suffer delays when IPv6 is not available even
+while the destination is still reachable over IPv4. Mail may be
+stuck in the queue with Postfix versions < 3.3 that do not
+implement "smtp_balance_inet_protocols". For similar reasons, the
+setting "smtp_address_preference = ipv4" is also unsafe. </p>
<li> <p> The setting "smtp_address_preference = any" is safe. With
-this, mail will eventually be delivered even if there is an outage
+this, and "smtp_balance_inet_protocols = yes" (the default), only
+half of deliveries will suffer delays if there is an outage
that affects IPv6 or IPv4, as long as it does not affect both. </p>
</ul>
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20230923"
+#define MAIL_RELEASE_DATE "20230924"
#define MAIL_VERSION_NUMBER "3.9"
#ifdef SNAPSHOT
/* Don't disconnect after sending a message; send the next
/* message over the same connection.
/* .IP "\fB-f \fIfrom\fR"
-/* Use the specified sender address (default: <foo@myhostname>).
+/* Use the specified sender address (default: <foo@my-hostname>).
/* .IP "\fB-F \fIfile\fR"
/* Send the pre-formatted message header and body in the
/* specified \fIfile\fR, while prepending '.' before lines that
/* Speak LMTP rather than SMTP.
/* .IP "\fB-m \fImessage_count\fR"
/* Send the specified number of messages (default: 1).
-/* .IP "\fB-M \fImyhostname\fR"
+/* .IP "\fB-M \fImy-hostname\fR"
/* Use the specified hostname or [address] in the HELO command
/* and in the default sender and recipient addresses, instead
/* of the machine hostname.
/* .IP "\fB-N\fR"
/* Generate each recipient address by appending a number (a
/* per-process recipient counter) to the recipient address
-/* localpart specified with the \fB-t\fR option. This avoids
-/* an artificial 100% hit rate in the trivial-rewrite daemon's
-/* resolve and rewrite client caches, better approximating
-/* Postfix performance under real-life work-loads.
+/* localpart specified with the \fB-t\fR option.
/*
/* Note: to use the number as an address extension, specify
/* an explicit address delimiter at the end of the recipient
/* localpart, as in "\fB-t localpart+@domain\fR" or "\fB-t
-/* localpart+\fR", where "\fB+\fR" is the recipient address
-/* delimiter.
+/* localpart+\fR", where "\fB+\fR" is a Postfix recipient
+/* address delimiter.
+/*
+/* Benefits:
+/* .RS
+/* .IP \(bu
+/* A non-constant recipient address avoids an unrealistic 100%
+/* cache hit rate in clients of the Postfix trivial-rewrite
+/* service, better approximating performance under real-life
+/* work-loads.
+/* .IP \(bu
+/* A fixed recipient address local-part with a non-constant
+/* address extension avoids the need to configure a large
+/* number of valid recipient addresses in the receiving Postfix
+/* server.
+/* .RE
/* .IP \fB-o\fR
/* Old mode: don't send HELO, and don't send message headers.
/* .IP "\fB-r \fIrecipient_count\fR"
-/* Send the specified number of recipients per transaction (default: 1).
-/* Generate each recipient address by appending a number (a
-/* per-connection recipient counter) to the recipient address
-/* localpart specified with the \fB-t\fR option.
-/*
-/* Note: to use the number as an address extension, specify
-/* an explicit address delimiter at the end of the recipient
-/* localpart, as in "\fB-t localpart+@domain\fR" or "\fB-t
-/* localpart+\fR", where "\fB+\fR" is the recipient address
-/* delimiter.
+/* Send the specified number of recipients per transaction
+/* (default: 1), and generate recipient addresses as described
+/* under the \fB-N\fR option.
/* .IP "\fB-R \fIinterval\fR"
/* Wait a random time (0 <= n <= \fIinterval\fR) between messages.
/* Suspending one thread does not affect other delivery threads.
/* .IP "\fB-S \fIsubject\fR"
/* Send mail with the named subject line (default: none).
/* .IP "\fB-t \fIto\fR"
-/* Use the specified recipient address (default: <foo@myhostname>).
+/* Use the specified recipient address (default: <foo@my-hostname>).
/* .IP "\fB-T \fIwindowsize\fR"
/* Override the default TCP window size. To work around
/* broken TCP window scaling implementations, specify a
#include <valid_hostname.h>
#include <valid_mailhost_addr.h>
#include <compat_va_copy.h>
-#include <mymalloc.h>
/* Global library. */
int rcpt_done; /* # of recipients done */
int rcpt_count; /* # of recipients to go */
int rcpt_accepted; /* # of recipients accepted */
+ int rcpt_sample; /* Sample recipient # for To: header */
VSTREAM *stream; /* open connection */
int connect_count; /* # of connect()s to retry */
struct SESSION *next; /* connect() queue linkage */
static struct sockaddr *sa;
static int sa_length;
static int recipients = 1;
-static int session_rcpt_suffix = 0;
static char *defaddr;
typedef struct {
char *local;
if ((except = vstream_setjmp(session->stream)) != 0)
msg_fatal("%s while sending recipient", exception_text(except));
- if (session_rcpt_suffix)
+ if (global_rcpt_suffix)
command(session->stream, "RCPT TO:<%s%d%s>",
- recipient->local, session->rcpt_done, recipient->at_domain);
- else if (global_rcpt_suffix)
- command(session->stream, "RCPT TO:<%s%d%s>",
- recipient->local, global_rcpt_done++, recipient->at_domain);
+ recipient->local, session->rcpt_sample = global_rcpt_done++,
+ recipient->at_domain);
else
command(session->stream, "RCPT TO:<%s%s>",
recipient->local, recipient->at_domain);
smtp_printf(session->stream, "From: <%s>", sender);
if (global_rcpt_suffix)
smtp_printf(session->stream, "To: <%s%d%s>", recipient->local,
- global_rcpt_done - 1, recipient->at_domain);
- else if (session_rcpt_suffix)
- smtp_printf(session->stream, "To: <%s%d%s>", recipient->local,
- session->rcpt_done - 1, recipient->at_domain);
+ session->rcpt_sample, recipient->at_domain);
else
smtp_printf(session->stream, "To: <%s%s>",
recipient->local, recipient->at_domain);
var_myhostname = optarg;
break;
case 'N':
- if (session_rcpt_suffix)
- msg_fatal("do not use -N and -r options at the same time");
global_rcpt_suffix = 1;
break;
case 'o':
send_headers = 0;
break;
case 'r':
- if (global_rcpt_suffix)
- msg_fatal("do not use -N and -r options at the same time");
- if (session_rcpt_suffix)
- msg_fatal("do not use -r option multiple times");
if ((recipients = atoi(optarg)) <= 0)
msg_fatal("bad recipient count: %s", optarg);
- session_rcpt_suffix = 1;
+ global_rcpt_suffix = 1;
break;
case 'R':
if (fixed_delay > 0)