diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2013-01-28 16:40:23 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2013-01-28 16:40:23 +0000 |
commit | d5242c1d67fcf1cede84a9fd3229e2dafef9a7b5 (patch) | |
tree | f665a78062b941dbbc34f266fa2d34b1c7fdf407 | |
parent | 18f081d15b57c154996bf1f53a74e94c05a550b3 (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.c | 66 | ||||
-rw-r--r-- | usr.sbin/smtpd/mta_session.c | 39 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 23 |
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 *); |