summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2013-01-28 16:40:23 +0000
committerEric Faurot <eric@cvs.openbsd.org>2013-01-28 16:40:23 +0000
commitd5242c1d67fcf1cede84a9fd3229e2dafef9a7b5 (patch)
treef665a78062b941dbbc34f266fa2d34b1c7fdf407
parent18f081d15b57c154996bf1f53a74e94c05a550b3 (diff)
use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages. ok gilles@
-rw-r--r--usr.sbin/smtpd/mta.c66
-rw-r--r--usr.sbin/smtpd/mta_session.c39
-rw-r--r--usr.sbin/smtpd/smtpd.h23
3 files changed, 77 insertions, 51 deletions
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index 2e740692513..7421803f2d8 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.150 2013/01/28 11:09:53 gilles Exp $ */
+/* $OpenBSD: mta.c,v 1.151 2013/01/28 16:40:22 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -71,7 +71,7 @@ static void mta_relay_schedule(struct mta_relay *, unsigned int);
static void mta_relay_timeout(int, short, void *);
static void mta_flush(struct mta_relay *, int, const char *);
static struct mta_route *mta_find_route(struct mta_connector *);
-static void mta_log(const struct envelope *, const char *, const char *,
+static void mta_log(const struct mta_envelope *, const char *, const char *,
const char *);
SPLAY_HEAD(mta_relay_tree, mta_relay);
@@ -141,12 +141,14 @@ mta_imsg(struct mproc *p, struct imsg *imsg)
struct mta_source *source;
struct mta_domain *domain;
struct mta_mx *mx, *imx;
+ struct mta_envelope *e;
struct sockaddr_storage ss;
struct tree *batch;
- struct envelope *e;
+ struct envelope evp;
struct msg m;
const char *secret;
uint64_t reqid;
+ char buf[MAX_LINE_SIZE];
int dnserror, preference, v, status;
if (p->proc == PROC_QUEUE) {
@@ -164,13 +166,12 @@ mta_imsg(struct mproc *p, struct imsg *imsg)
return;
case IMSG_MTA_BATCH_ADD:
- e = xmalloc(sizeof(*e), "mta:envelope");
m_msg(&m, imsg);
m_get_id(&m, &reqid);
- m_get_envelope(&m, e);
+ m_get_envelope(&m, &evp);
m_end(&m);
- relay = mta_relay(e);
+ relay = mta_relay(&evp);
batch = tree_xget(&batches, reqid);
if ((task = tree_get(batch, relay->id)) == NULL) {
@@ -180,8 +181,13 @@ mta_imsg(struct mproc *p, struct imsg *imsg)
TAILQ_INIT(&task->envelopes);
task->relay = relay;
tree_xset(batch, relay->id, task);
- task->msgid = evpid_to_msgid(e->id);
- task->sender = e->sender;
+ task->msgid = evpid_to_msgid(evp.id);
+ if (evp.sender.user[0] || evp.sender.domain[0])
+ snprintf(buf, sizeof buf, "%s@%s",
+ evp.sender.user, evp.sender.domain);
+ else
+ buf[0] = '\0';
+ task->sender = xstrdup(buf, "mta_task:sender");
} else
mta_relay_unref(relay); /* from here */
@@ -190,15 +196,25 @@ mta_imsg(struct mproc *p, struct imsg *imsg)
* level, but the batch sent by the scheduler should
* be valid.
*/
- if (task->msgid != evpid_to_msgid(e->id))
+ if (task->msgid != evpid_to_msgid(evp.id))
errx(1, "msgid mismatch in batch");
+ e = xcalloc(1, sizeof *e, "mta_envelope");
+ e->id = evp.id;
+ e->creation = evp.creation;
+ snprintf(buf, sizeof buf, "%s@%s",
+ evp.dest.user, evp.dest.domain);
+ e->dest = xstrdup(buf, "mta_envelope:dest");
+ snprintf(buf, sizeof buf, "%s@%s",
+ evp.rcpt.user, evp.rcpt.domain);
+ if (strcmp(buf, e->dest))
+ e->rcpt = xstrdup(buf, "mta_envelope:rcpt");
+ e->task = task;
/* XXX honour relay->maxrcpt */
TAILQ_INSERT_TAIL(&task->envelopes, e, entry);
stat_increment("mta.envelope", 1);
log_debug("debug: mta: received evp:%016" PRIx64
- " for <%s@%s>",
- e->id, e->dest.user, e->dest.domain);
+ " for <%s>", e->id, e->dest);
return;
case IMSG_MTA_BATCH_END:
@@ -561,7 +577,7 @@ mta_route_next_task(struct mta_relay *relay, struct mta_route *route)
}
void
-mta_delivery(struct envelope *e, const char *relay, int delivery,
+mta_delivery(struct mta_envelope *e, const char *relay, int delivery,
const char *status)
{
if (delivery == IMSG_DELIVERY_OK) {
@@ -964,10 +980,10 @@ mta_drain(struct mta_relay *r)
static void
mta_flush(struct mta_relay *relay, int fail, const char *error)
{
- struct envelope *e;
- struct mta_task *task;
- const char *pfx;
- size_t n;
+ struct mta_envelope *e;
+ struct mta_task *task;
+ const char *pfx;
+ size_t n;
log_debug("debug: mta_flush(%s, %i, \"%s\")",
mta_relay_to_text(relay), fail, error);
@@ -985,9 +1001,12 @@ mta_flush(struct mta_relay *relay, int fail, const char *error)
while ((e = TAILQ_FIRST(&task->envelopes))) {
TAILQ_REMOVE(&task->envelopes, e, entry);
mta_delivery(e, relay->domain->name, fail, error);
+ free(e->dest);
+ free(e->rcpt);
free(e);
n++;
}
+ free(task->sender);
free(task);
}
@@ -1119,22 +1138,21 @@ mta_find_route(struct mta_connector *c)
}
static void
-mta_log(const struct envelope *evp, const char *prefix, const char *relay,
+mta_log(const struct mta_envelope *evp, const char *prefix, const char *relay,
const char *status)
{
char rcpt[MAX_LINE_SIZE];
rcpt[0] = '\0';
- if (strcmp(evp->rcpt.user, evp->dest.user) ||
- strcmp(evp->rcpt.domain, evp->dest.domain))
- snprintf(rcpt, sizeof rcpt, "rcpt=<%s@%s>, ",
- evp->rcpt.user, evp->rcpt.domain);
+ if (evp->rcpt)
+ snprintf(rcpt, sizeof rcpt, "rcpt=<%s>, ", evp->rcpt);
- log_info("relay: %s for %016" PRIx64 ": from=<%s@%s>, to=<%s@%s>, "
+ log_info("relay: %s for %016" PRIx64 ": from=<%s>, to=<%s>, "
"%srelay=%s delay=%s, stat=%s",
prefix,
- evp->id, evp->sender.user, evp->sender.domain,
- evp->dest.user, evp->dest.domain,
+ evp->id,
+ evp->task->sender,
+ evp->dest,
rcpt,
relay,
duration_to_text(time(NULL) - evp->creation),
diff --git a/usr.sbin/smtpd/mta_session.c b/usr.sbin/smtpd/mta_session.c
index 366d8d3ea84..71c85947033 100644
--- a/usr.sbin/smtpd/mta_session.c
+++ b/usr.sbin/smtpd/mta_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta_session.c,v 1.29 2013/01/28 11:58:57 gilles Exp $ */
+/* $OpenBSD: mta_session.c,v 1.30 2013/01/28 16:40:22 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -110,7 +110,7 @@ struct mta_session {
enum mta_state state;
struct mta_task *task;
- struct envelope *currevp;
+ struct mta_envelope *currevp;
FILE *datafp;
};
@@ -571,19 +571,13 @@ mta_enter_state(struct mta_session *s, int newstate)
break;
case MTA_MAIL:
- if (s->task->sender.user[0] && s->task->sender.domain[0])
- mta_send(s, "MAIL FROM: <%s@%s>",
- s->task->sender.user, s->task->sender.domain);
- else
- mta_send(s, "MAIL FROM: <>");
+ mta_send(s, "MAIL FROM: <%s>", s->task->sender);
break;
case MTA_RCPT:
if (s->currevp == NULL)
s->currevp = TAILQ_FIRST(&s->task->envelopes);
- mta_send(s, "RCPT TO: <%s@%s>",
- s->currevp->dest.user,
- s->currevp->dest.domain);
+ mta_send(s, "RCPT TO: <%s>", s->currevp->dest);
break;
case MTA_DATA:
@@ -634,9 +628,9 @@ mta_enter_state(struct mta_session *s, int newstate)
static void
mta_response(struct mta_session *s, char *line)
{
- struct envelope *evp;
- char buf[MAX_LINE_SIZE];
- int delivery;
+ struct mta_envelope *e;
+ char buf[MAX_LINE_SIZE];
+ int delivery;
switch (s->state) {
@@ -709,7 +703,7 @@ mta_response(struct mta_session *s, char *line)
break;
case MTA_RCPT:
- evp = s->currevp;
+ e = s->currevp;
s->currevp = TAILQ_NEXT(s->currevp, entry);
if (line[0] != '2') {
if (line[0] == '5')
@@ -717,11 +711,13 @@ mta_response(struct mta_session *s, char *line)
else
delivery = IMSG_DELIVERY_TEMPFAIL;
- TAILQ_REMOVE(&s->task->envelopes, evp, entry);
+ TAILQ_REMOVE(&s->task->envelopes, e, entry);
snprintf(buf, sizeof(buf), "%s",
mta_host_to_text(s->route->dst));
- mta_delivery(evp, buf, delivery, line);
- free(evp);
+ mta_delivery(e, buf, delivery, line);
+ free(e->dest);
+ free(e->rcpt);
+ free(e);
stat_decrement("mta.envelope", 1);
if (TAILQ_EMPTY(&s->task->envelopes)) {
@@ -994,9 +990,9 @@ mta_queue_data(struct mta_session *s)
static void
mta_flush_task(struct mta_session *s, int delivery, const char *error)
{
- struct envelope *e;
- char relay[MAX_LINE_SIZE];
- size_t n;
+ struct mta_envelope *e;
+ char relay[MAX_LINE_SIZE];
+ size_t n;
snprintf(relay, sizeof relay, "%s", mta_host_to_text(s->route->dst));
@@ -1004,10 +1000,13 @@ mta_flush_task(struct mta_session *s, int delivery, const char *error)
while ((e = TAILQ_FIRST(&s->task->envelopes))) {
TAILQ_REMOVE(&s->task->envelopes, e, entry);
mta_delivery(e, relay, delivery, error);
+ free(e->dest);
+ free(e->rcpt);
free(e);
n++;
}
+ free(s->task->sender);
free(s->task);
s->task = NULL;
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 186265be527..ac5fcfe2fcb 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.399 2013/01/28 11:09:53 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.400 2013/01/28 16:40:22 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -735,12 +735,21 @@ struct mta_relay {
size_t maxconn;
};
+struct mta_envelope {
+ TAILQ_ENTRY(mta_envelope) entry;
+ uint64_t id;
+ time_t creation;
+ char *dest;
+ char *rcpt;
+ struct mta_task *task;
+};
+
struct mta_task {
- TAILQ_ENTRY(mta_task) entry;
- struct mta_relay *relay;
- uint32_t msgid;
- TAILQ_HEAD(, envelope) envelopes;
- struct mailaddr sender;
+ TAILQ_ENTRY(mta_task) entry;
+ struct mta_relay *relay;
+ uint32_t msgid;
+ TAILQ_HEAD(, mta_envelope) envelopes;
+ char *sender;
};
enum queue_op {
@@ -1193,7 +1202,7 @@ void mta_route_ok(struct mta_relay *, struct mta_route *);
void mta_route_error(struct mta_relay *, struct mta_route *);
void mta_route_collect(struct mta_relay *, struct mta_route *);
void mta_source_error(struct mta_relay *, struct mta_route *, const char *);
-void mta_delivery(struct envelope *, const char *, int, const char *);
+void mta_delivery(struct mta_envelope *, const char *, int, const char *);
struct mta_task *mta_route_next_task(struct mta_relay *, struct mta_route *);
const char *mta_host_to_text(struct mta_host *);
const char *mta_relay_to_text(struct mta_relay *);