diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-08-06 13:40:46 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-08-06 13:40:46 +0000 |
commit | 2ae4b5918b8e7e071b3421e081923a1f8d357c56 (patch) | |
tree | a9345247824966cb257b493c0a151b01bb024bfa /usr.sbin/smtpd/runner.c | |
parent | 939e6d47367841cb1f3ca05dbfb46c0f17c07331 (diff) |
This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)
ok jacekm@
Diffstat (limited to 'usr.sbin/smtpd/runner.c')
-rw-r--r-- | usr.sbin/smtpd/runner.c | 115 |
1 files changed, 102 insertions, 13 deletions
diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index 16847cd4fe6..510786537b9 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.54 2009/07/28 22:03:55 gilles Exp $ */ +/* $OpenBSD: runner.c,v 1.55 2009/08/06 13:40:45 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -55,6 +55,7 @@ void runner_dispatch_queue(int, short, void *); void runner_dispatch_mda(int, short, void *); void runner_dispatch_mta(int, short, void *); void runner_dispatch_lka(int, short, void *); +void runner_dispatch_smtp(int, short, void *); void runner_setup_events(struct smtpd *); void runner_disable_events(struct smtpd *); @@ -405,6 +406,67 @@ runner_dispatch_lka(int sig, short event, void *p) } void +runner_dispatch_smtp(int sig, short event, void *p) +{ + struct smtpd *env = p; + struct imsgev *iev; + struct imsgbuf *ibuf; + struct imsg imsg; + ssize_t n; + + iev = env->sc_ievs[PROC_SMTP]; + ibuf = &iev->ibuf; + + if (event & EV_READ) { + if ((n = imsg_read(ibuf)) == -1) + fatal("imsg_read_error"); + if (n == 0) { + /* this pipe is dead, so remove the event handler */ + event_del(&iev->ev); + event_loopexit(NULL); + return; + } + } + + if (event & EV_WRITE) { + if (msgbuf_write(&ibuf->w) == -1) + fatal("msgbuf_write"); + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + fatalx("runner_dispatch_smtp: imsg_get error"); + if (n == 0) + break; + + switch (imsg.hdr.type) { + case IMSG_SMTP_ENQUEUE: { + struct message *messagep = imsg.data; + if (imsg.fd == -1) { + messagep->flags &= ~F_MESSAGE_SCHEDULED; + messagep->flags &= ~F_MESSAGE_PROCESSING; + + while (! queue_update_envelope(messagep)) + sleep(1); + break; + } + + if (bounce_session(env, imsg.fd, messagep)) + queue_remove_envelope(messagep); + + break; + } + default: + log_warnx("runner_dispatch_smtp: got imsg %d", + imsg.hdr.type); + fatalx("runner_dispatch_smtp: unexpected imsg"); + } + imsg_free(&imsg); + } + imsg_event_add(iev); +} + +void runner_shutdown(void) { log_info("runner handler"); @@ -444,6 +506,7 @@ runner(struct smtpd *env) { PROC_MTA, runner_dispatch_mta }, { PROC_QUEUE, runner_dispatch_queue }, { PROC_LKA, runner_dispatch_lka }, + { PROC_SMTP, runner_dispatch_smtp } }; switch (pid = fork()) { @@ -587,7 +650,7 @@ runner_process_queue(struct smtpd *env) continue; if (runner_check_loop(&message)) { - /*daemon_record_message(&message);*/ + bounce_record_message(&message); queue_remove_envelope(&message); continue; } @@ -685,9 +748,22 @@ runner_batch_dispatch(struct smtpd *env, struct batch *batchp, time_t curtime) u_int8_t proctype; struct message *messagep; - if ((batchp->type & (T_MDA_BATCH|T_MTA_BATCH)) == 0) + if ((batchp->type & (T_DAEMON_BATCH|T_MDA_BATCH|T_MTA_BATCH)) == 0) fatal("runner_batch_dispatch: unknown batch type"); + log_debug("in batch dispatch"); + if (batchp->type == T_DAEMON_BATCH) { + while ((messagep = TAILQ_FIRST(&batchp->messages))) { + log_debug("starting"); + bounce_process(env, messagep); + TAILQ_REMOVE(&batchp->messages, messagep, entry); + log_debug("ending"); + bzero(messagep, sizeof(*messagep)); + free(messagep); + } + return; + } + if (batchp->type & T_MDA_BATCH) proctype = PROC_MDA; else if (batchp->type & T_MTA_BATCH) @@ -713,6 +789,9 @@ runner_message_schedule(struct message *messagep, time_t tm) { time_t delay; + if (messagep->type == T_DAEMON_MESSAGE) + return 1; + if (messagep->flags & (F_MESSAGE_SCHEDULED|F_MESSAGE_PROCESSING)) return 0; @@ -908,12 +987,14 @@ batch_record(struct smtpd *env, struct message *messagep) (void)strlcpy(batchp->hostname, path->domain, sizeof(batchp->hostname)); - if (IS_MAILBOX(path->rule.r_action) || - IS_EXT(path->rule.r_action)) { - batchp->type |= T_MDA_BATCH; - } - else { - batchp->type |= T_MTA_BATCH; + if (batchp->type != T_DAEMON_BATCH) { + if (IS_MAILBOX(path->rule.r_action) || + IS_EXT(path->rule.r_action)) { + batchp->type = T_MDA_BATCH; + } + else { + batchp->type = T_MTA_BATCH; + } } } @@ -928,8 +1009,10 @@ batch_lookup(struct smtpd *env, struct message *message) struct batch *batchp; struct batch lookup; - /* We only support delivery of one message at a time, in MDA */ - if (message->type & T_MDA_MESSAGE) + /* We only support delivery of one message at a time, in MDA + * and bounces messages. + */ + if (message->type & (T_DAEMON_MESSAGE|T_MDA_MESSAGE)) return NULL; /* If message->batch_id != 0, we can retrieve batch by id */ @@ -1016,12 +1099,18 @@ runner_check_loop(struct message *messagep) } else if (strncasecmp("X-OpenSMTPD-Loop: ", buf, 18) == 0) { + struct path rcpt; + bzero(&chkpath, sizeof (struct path)); if (! recipient_to_path(&chkpath, buf + 18)) continue; - if (strcasecmp(chkpath.user, messagep->recipient.user) == 0 && - strcasecmp(chkpath.domain, messagep->recipient.domain) == 0) { + rcpt = messagep->recipient; + if (messagep->type == T_DAEMON_MESSAGE) + rcpt = messagep->sender; + + if (strcasecmp(chkpath.user, rcpt.user) == 0 && + strcasecmp(chkpath.domain, rcpt.domain) == 0) { log_debug("LOOP DETECTED THROUGH X-OPENSMTPD-LOOP HEADER: %s@%s", chkpath.user, chkpath.domain); ret = 1; |