summaryrefslogtreecommitdiffstats
path: root/src/smtpstone
diff options
context:
space:
mode:
Diffstat (limited to 'src/smtpstone')
-rw-r--r--src/smtpstone/smtp-source.c94
1 files changed, 70 insertions, 24 deletions
diff --git a/src/smtpstone/smtp-source.c b/src/smtpstone/smtp-source.c
index be388d6..f9fa64f 100644
--- a/src/smtpstone/smtp-source.c
+++ b/src/smtpstone/smtp-source.c
@@ -42,7 +42,7 @@
/* 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
@@ -54,31 +54,49 @@
/* 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"
-/* Prepend a non-repeating sequence number to each recipient
-/* address. This avoids the artificial 100% hit rate in the
-/* resolve and rewrite client caches and exercises the
-/* trivial-rewrite daemon, better approximating Postfix
-/* performance under real-life work-loads.
+/* 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.
+/*
+/* 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 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).
-/* Recipient names are generated by prepending a number to the
-/* recipient address.
+/* 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 for a random period of time 0 <= n <= interval between messages.
+/* Wait a random time (0 <= n <= \fIinterval\fR) between messages.
/* Suspending one thread does not affect other delivery threads.
/* .IP "\fB-s \fIsession_count\fR"
/* Run the specified number of SMTP sessions in parallel (default: 1).
/* .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
@@ -172,6 +190,7 @@ typedef struct SESSION {
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 */
@@ -202,7 +221,11 @@ static struct sockaddr *sa;
static int sa_length;
static int recipients = 1;
static char *defaddr;
-static char *recipient;
+typedef struct {
+ char *local;
+ char *at_domain;
+} RECIPIENT;
+static RECIPIENT *recipient;
static char *sender;
static char *message_data;
static int message_length;
@@ -216,7 +239,8 @@ static int random_delay = 0;
static int fixed_delay = 0;
static int talk_lmtp = 0;
static char *subject = 0;
-static int number_rcpts = 0;
+static int global_rcpt_suffix = 0;
+static int global_rcpt_done = 0;
static int allow_reject = 0;
static void enqueue_connect(SESSION *);
@@ -238,6 +262,20 @@ static void send_quit(SESSION *);
static void quit_done(int, void *);
static void close_session(SESSION *);
+/* make_recipient - parse recipient into localpart and at_domain */
+
+static RECIPIENT *make_recipient(const char *address)
+{
+ RECIPIENT *rp = (RECIPIENT *) mymalloc(sizeof(*rp));
+ const char *at;
+
+ if ((at = strrchr(address, '@')) == 0)
+ at = address + strlen(address);
+ rp->local = mystrndup(address, at - address);
+ rp->at_domain = mystrdup(at);
+ return (rp);
+}
+
/* random_interval - generate a random value in 0 .. (small) interval */
static int random_interval(int interval)
@@ -655,12 +693,13 @@ static void send_rcpt(int unused_event, void *context)
if ((except = vstream_setjmp(session->stream)) != 0)
msg_fatal("%s while sending recipient", exception_text(except));
- if (session->rcpt_count > 1 || number_rcpts > 0)
- command(session->stream, "RCPT TO:<%d%s>",
- number_rcpts ? number_rcpts++ : session->rcpt_count,
- recipient);
+ if (global_rcpt_suffix)
+ command(session->stream, "RCPT TO:<%s%d%s>",
+ recipient->local, session->rcpt_sample = global_rcpt_done++,
+ recipient->at_domain);
else
- command(session->stream, "RCPT TO:<%s>", recipient);
+ command(session->stream, "RCPT TO:<%s%s>",
+ recipient->local, recipient->at_domain);
session->rcpt_count--;
session->rcpt_done++;
@@ -765,10 +804,16 @@ static void data_done(int unused, void *context)
mypid = getpid();
}
smtp_printf(session->stream, "From: <%s>", sender);
- smtp_printf(session->stream, "To: <%s>", recipient);
+ if (global_rcpt_suffix)
+ smtp_printf(session->stream, "To: <%s%d%s>", recipient->local,
+ session->rcpt_sample, recipient->at_domain);
+ else
+ smtp_printf(session->stream, "To: <%s%s>",
+ recipient->local, recipient->at_domain);
smtp_printf(session->stream, "Date: %s", mydate);
smtp_printf(session->stream, "Message-Id: <%04x.%04x.%04x@%s>",
- mypid, vstream_fileno(session->stream), message_count, var_myhostname);
+ mypid, vstream_fileno(session->stream), message_count,
+ var_myhostname);
if (subject)
smtp_printf(session->stream, "Subject: %s", subject);
smtp_fputs("", 0, session->stream);
@@ -1021,7 +1066,7 @@ int main(int argc, char **argv)
var_myhostname = optarg;
break;
case 'N':
- number_rcpts = 1;
+ global_rcpt_suffix = 1;
break;
case 'o':
send_helo_first = 0;
@@ -1030,6 +1075,7 @@ int main(int argc, char **argv)
case 'r':
if ((recipients = atoi(optarg)) <= 0)
msg_fatal("bad recipient count: %s", optarg);
+ global_rcpt_suffix = 1;
break;
case 'R':
if (fixed_delay > 0)
@@ -1045,7 +1091,7 @@ int main(int argc, char **argv)
subject = optarg;
break;
case 't':
- recipient = optarg;
+ recipient = make_recipient(optarg);
break;
case 'T':
if ((inet_windowsize = atoi(optarg)) <= 0)
@@ -1160,7 +1206,7 @@ int main(int argc, char **argv)
if (sender == 0)
sender = defaddr;
if (recipient == 0)
- recipient = defaddr;
+ recipient = make_recipient(defaddr);
}
/*