summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/smtpd/bounce.c6
-rw-r--r--usr.sbin/smtpd/control.c12
-rw-r--r--usr.sbin/smtpd/queue.c40
-rw-r--r--usr.sbin/smtpd/runner.c612
-rw-r--r--usr.sbin/smtpd/scheduler.c586
-rw-r--r--usr.sbin/smtpd/scheduler_backend.c58
-rw-r--r--usr.sbin/smtpd/smtpctl.c24
-rw-r--r--usr.sbin/smtpd/smtpd.c14
-rw-r--r--usr.sbin/smtpd/smtpd.h16
-rw-r--r--usr.sbin/smtpd/smtpd/Makefile7
10 files changed, 688 insertions, 687 deletions
diff --git a/usr.sbin/smtpd/bounce.c b/usr.sbin/smtpd/bounce.c
index a235a7ee3d4..c2147d12297 100644
--- a/usr.sbin/smtpd/bounce.c
+++ b/usr.sbin/smtpd/bounce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bounce.c,v 1.41 2012/06/20 20:45:23 eric Exp $ */
+/* $OpenBSD: bounce.c,v 1.42 2012/07/09 09:57:53 gilles Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org>
@@ -229,8 +229,8 @@ bounce_free(struct bounce *bounce)
io_clear(&bounce->io);
free(bounce);
- stat_decrement(STATS_RUNNER);
- stat_decrement(STATS_RUNNER_BOUNCES);
+ stat_decrement(STATS_SCHEDULER);
+ stat_decrement(STATS_SCHEDULER_BOUNCES);
}
static void
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c
index ace689b4e11..875bf2a081e 100644
--- a/usr.sbin/smtpd/control.c
+++ b/usr.sbin/smtpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.64 2012/01/12 18:06:18 eric Exp $ */
+/* $OpenBSD: control.c,v 1.65 2012/07/09 09:57:53 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -109,7 +109,7 @@ control(void)
struct event ev_sigint;
struct event ev_sigterm;
struct peer peers [] = {
- { PROC_RUNNER, imsg_dispatch },
+ { PROC_SCHEDULER, imsg_dispatch },
{ PROC_QUEUE, imsg_dispatch },
{ PROC_SMTP, imsg_dispatch },
{ PROC_MFA, imsg_dispatch },
@@ -470,7 +470,7 @@ control_dispatch_ext(int fd, short event, void *arg)
imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
break;
- case IMSG_RUNNER_SCHEDULE: {
+ case IMSG_SCHEDULER_SCHEDULE: {
u_int64_t ullval;
if (euid)
@@ -478,14 +478,14 @@ control_dispatch_ext(int fd, short event, void *arg)
ullval = *(u_int64_t *)imsg.data;
- imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_SCHEDULE,
+ imsg_compose_event(env->sc_ievs[PROC_SCHEDULER], IMSG_SCHEDULER_SCHEDULE,
0, 0, -1, &ullval, sizeof(ullval));
imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
break;
}
- case IMSG_RUNNER_REMOVE: {
+ case IMSG_SCHEDULER_REMOVE: {
u_int64_t ullval;
if (euid)
@@ -493,7 +493,7 @@ control_dispatch_ext(int fd, short event, void *arg)
ullval = *(u_int64_t *)imsg.data;
- imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_REMOVE,
+ imsg_compose_event(env->sc_ievs[PROC_SCHEDULER], IMSG_SCHEDULER_REMOVE,
0, 0, -1, &ullval, sizeof(ullval));
imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c
index 6fb660bfb71..d0e9549607b 100644
--- a/usr.sbin/smtpd/queue.c
+++ b/usr.sbin/smtpd/queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.c,v 1.120 2012/07/08 18:13:08 chl Exp $ */
+/* $OpenBSD: queue.c,v 1.121 2012/07/09 09:57:53 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -39,7 +39,7 @@
#include "log.h"
static void queue_imsg(struct imsgev *, struct imsg *);
-static void queue_pass_to_runner(struct imsgev *, struct imsg *);
+static void queue_pass_to_scheduler(struct imsgev *, struct imsg *);
static void queue_shutdown(void);
static void queue_sig_handler(int, short, void *);
@@ -85,7 +85,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
&ss, sizeof ss);
if (ss.code != 421)
- queue_pass_to_runner(iev, imsg);
+ queue_pass_to_scheduler(iev, imsg);
return;
@@ -99,7 +99,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
return;
case IMSG_SMTP_ENQUEUE:
- queue_pass_to_runner(iev, imsg);
+ queue_pass_to_scheduler(iev, imsg);
return;
}
}
@@ -129,8 +129,8 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
}
}
- if (iev->proc == PROC_RUNNER) {
- /* forward imsgs from runner on its behalf */
+ if (iev->proc == PROC_SCHEDULER) {
+ /* forward imsgs from scheduler on its behalf */
imsg_compose_event(env->sc_ievs[imsg->hdr.peerid], imsg->hdr.type,
0, imsg->hdr.pid, imsg->fd, (char *)imsg->data,
imsg->hdr.len - sizeof imsg->hdr);
@@ -150,7 +150,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
case IMSG_QUEUE_DELIVERY_TEMPFAIL:
case IMSG_QUEUE_DELIVERY_PERMFAIL:
case IMSG_BATCH_DONE:
- queue_pass_to_runner(iev, imsg);
+ queue_pass_to_scheduler(iev, imsg);
return;
}
}
@@ -161,7 +161,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
case IMSG_QUEUE_DELIVERY_TEMPFAIL:
case IMSG_QUEUE_DELIVERY_PERMFAIL:
case IMSG_MDA_SESS_NEW:
- queue_pass_to_runner(iev, imsg);
+ queue_pass_to_scheduler(iev, imsg);
return;
}
}
@@ -174,7 +174,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
case IMSG_QUEUE_RESUME_MTA:
case IMSG_QUEUE_SCHEDULE:
case IMSG_QUEUE_REMOVE:
- queue_pass_to_runner(iev, imsg);
+ queue_pass_to_scheduler(iev, imsg);
return;
}
}
@@ -183,7 +183,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
switch (imsg->hdr.type) {
case IMSG_CTL_VERBOSE:
log_verbose(*(int *)imsg->data);
- queue_pass_to_runner(iev, imsg);
+ queue_pass_to_scheduler(iev, imsg);
return;
}
}
@@ -192,9 +192,9 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
}
static void
-queue_pass_to_runner(struct imsgev *iev, struct imsg *imsg)
+queue_pass_to_scheduler(struct imsgev *iev, struct imsg *imsg)
{
- imsg_compose_event(env->sc_ievs[PROC_RUNNER], imsg->hdr.type,
+ imsg_compose_event(env->sc_ievs[PROC_SCHEDULER], imsg->hdr.type,
iev->proc, imsg->hdr.pid, imsg->fd, imsg->data,
imsg->hdr.len - sizeof imsg->hdr);
}
@@ -229,13 +229,13 @@ queue(void)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, imsg_dispatch },
- { PROC_CONTROL, imsg_dispatch },
- { PROC_SMTP, imsg_dispatch },
- { PROC_MDA, imsg_dispatch },
- { PROC_MTA, imsg_dispatch },
- { PROC_LKA, imsg_dispatch },
- { PROC_RUNNER, imsg_dispatch }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_CONTROL, imsg_dispatch },
+ { PROC_SMTP, imsg_dispatch },
+ { PROC_MDA, imsg_dispatch },
+ { PROC_MTA, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch },
+ { PROC_SCHEDULER, imsg_dispatch }
};
switch (pid = fork()) {
@@ -281,7 +281,7 @@ queue(void)
*/
fdlimit(1.0);
if ((env->sc_maxconn = availdesc() / 4) < 1)
- fatalx("runner: fd starvation");
+ fatalx("queue: fd starvation");
config_pipes(peers, nitems(peers));
config_peers(peers, nitems(peers));
diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c
deleted file mode 100644
index 6c4e0644e50..00000000000
--- a/usr.sbin/smtpd/runner.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/* $OpenBSD: runner.c,v 1.144 2012/07/09 08:08:29 gilles Exp $ */
-
-/*
- * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
- * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
- * Copyright (c) 2008-2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <dirent.h>
-#include <err.h>
-#include <errno.h>
-#include <event.h>
-#include <imsg.h>
-#include <inttypes.h>
-#include <libgen.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "smtpd.h"
-#include "log.h"
-
-static void runner_imsg(struct imsgev *, struct imsg *);
-static void runner_shutdown(void);
-static void runner_sig_handler(int, short, void *);
-static void runner_setup_events(void);
-static void runner_reset_events(void);
-static void runner_disable_events(void);
-static void runner_timeout(int, short, void *);
-static void runner_remove(u_int64_t);
-static void runner_remove_envelope(u_int64_t);
-static int runner_process_envelope(u_int64_t);
-static int runner_process_batch(enum delivery_type, u_int64_t);
-static int runner_check_loop(struct envelope *);
-static int runner_message_to_scheduler(u_int32_t);
-
-static struct scheduler_backend *scheduler = NULL;
-
-extern const char *backend_scheduler;
-
-void
-runner_imsg(struct imsgev *iev, struct imsg *imsg)
-{
- struct envelope *e, bounce;
- struct scheduler_info si;
-
- log_imsg(PROC_RUNNER, iev->proc, imsg);
-
- switch (imsg->hdr.type) {
- case IMSG_QUEUE_COMMIT_MESSAGE:
- e = imsg->data;
- runner_message_to_scheduler(evpid_to_msgid(e->id));
- runner_reset_events();
- return;
-
- case IMSG_QUEUE_DELIVERY_OK:
- stat_decrement(STATS_RUNNER);
- e = imsg->data;
- log_debug("queue_delivery_ok: %016"PRIx64, e->id);
- scheduler->remove(e->id);
- queue_envelope_delete(e);
- return;
-
- case IMSG_QUEUE_DELIVERY_TEMPFAIL:
- stat_decrement(STATS_RUNNER);
- e = imsg->data;
- e->retry++;
- queue_envelope_update(e);
- log_debug("queue_delivery_tempfail: %016"PRIx64, e->id);
- scheduler_info(&si, e);
- scheduler->insert(&si);
- runner_reset_events();
- return;
-
- case IMSG_QUEUE_DELIVERY_PERMFAIL:
- stat_decrement(STATS_RUNNER);
- e = imsg->data;
- if (e->type != D_BOUNCE && e->sender.user[0] != '\0') {
- bounce_record_message(e, &bounce);
- log_debug("queue_delivery_permfail: %016"PRIx64,
- bounce.id);
- scheduler_info(&si, &bounce);
- scheduler->insert(&si);
- runner_reset_events();
- }
- scheduler->remove(e->id);
- queue_envelope_delete(e);
- return;
-
- case IMSG_MDA_SESS_NEW:
- stat_decrement(STATS_MDA_SESSION);
- if (env->sc_maxconn - stat_get(STATS_MDA_SESSION, STAT_ACTIVE))
- env->sc_flags &= ~SMTPD_MDA_BUSY;
- runner_reset_events();
- return;
-
- case IMSG_BATCH_DONE:
- stat_decrement(STATS_MTA_SESSION);
- if (env->sc_maxconn - stat_get(STATS_MTA_SESSION, STAT_ACTIVE))
- env->sc_flags &= ~SMTPD_MTA_BUSY;
- runner_reset_events();
- return;
-
- case IMSG_SMTP_ENQUEUE:
- e = imsg->data;
- if (imsg->fd < 0 || !bounce_session(imsg->fd, e)) {
- queue_envelope_update(e);
- log_debug("smtp_enqueue: %016"PRIx64, e->id);
- scheduler_info(&si, e);
- scheduler->insert(&si);
- runner_reset_events();
- return;
- }
- return;
-
- case IMSG_QUEUE_PAUSE_MDA:
- env->sc_flags |= SMTPD_MDA_PAUSED;
- return;
-
- case IMSG_QUEUE_RESUME_MDA:
- env->sc_flags &= ~SMTPD_MDA_PAUSED;
- runner_reset_events();
- return;
-
- case IMSG_QUEUE_PAUSE_MTA:
- env->sc_flags |= SMTPD_MTA_PAUSED;
- return;
-
- case IMSG_QUEUE_RESUME_MTA:
- env->sc_flags &= ~SMTPD_MTA_PAUSED;
- runner_reset_events();
- return;
-
- case IMSG_CTL_VERBOSE:
- log_verbose(*(int *)imsg->data);
- return;
-
- case IMSG_RUNNER_SCHEDULE:
- scheduler->force(*(u_int64_t *)imsg->data);
- runner_reset_events();
- return;
-
- case IMSG_RUNNER_REMOVE: {
- runner_remove(*(u_int64_t *)imsg->data);
- runner_reset_events();
- return;
- }
- }
-
- errx(1, "runner_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
-}
-
-void
-runner_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- runner_shutdown();
- break;
- default:
- fatalx("runner_sig_handler: unexpected signal");
- }
-}
-
-void
-runner_shutdown(void)
-{
- log_info("runner handler exiting");
- _exit(0);
-}
-
-void
-runner_setup_events(void)
-{
- struct timeval tv;
-
- evtimer_set(&env->sc_ev, runner_timeout, NULL);
- tv.tv_sec = 0;
- tv.tv_usec = 10;
- evtimer_add(&env->sc_ev, &tv);
-}
-
-void
-runner_reset_events(void)
-{
- struct timeval tv;
-
- tv.tv_sec = 0;
- tv.tv_usec = 10;
- evtimer_add(&env->sc_ev, &tv);
-}
-
-void
-runner_disable_events(void)
-{
- evtimer_del(&env->sc_ev);
-}
-
-pid_t
-runner(void)
-{
- pid_t pid;
- struct passwd *pw;
-
- struct event ev_sigint;
- struct event ev_sigterm;
-
- struct peer peers[] = {
- { PROC_CONTROL, imsg_dispatch },
- { PROC_QUEUE, imsg_dispatch }
- };
-
- switch (pid = fork()) {
- case -1:
- fatal("runner: cannot fork");
- case 0:
- break;
- default:
- return (pid);
- }
-
- purge_config(PURGE_EVERYTHING);
-
- pw = env->sc_pw;
-
- if (chroot(PATH_SPOOL) == -1)
- fatal("runner: chroot");
- if (chdir("/") == -1)
- fatal("runner: chdir(\"/\")");
-
- smtpd_process = PROC_RUNNER;
- setproctitle("%s", env->sc_title[smtpd_process]);
-
- if (setgroups(1, &pw->pw_gid) ||
- setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
- setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
- fatal("runner: cannot drop privileges");
-
- /* see fdlimit()-related comment in queue.c */
- fdlimit(1.0);
- if ((env->sc_maxconn = availdesc() / 4) < 1)
- fatalx("runner: fd starvation");
-
- env->sc_scheduler = scheduler_backend_lookup(backend_scheduler);
- if (env->sc_scheduler == NULL)
- errx(1, "cannot find scheduler backend \"%s\"", backend_scheduler);
- scheduler = env->sc_scheduler;
-
- scheduler->init();
-
- imsg_callback = runner_imsg;
- event_init();
-
- signal_set(&ev_sigint, SIGINT, runner_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, runner_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
- signal(SIGPIPE, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
-
- config_pipes(peers, nitems(peers));
- config_peers(peers, nitems(peers));
-
- runner_setup_events();
- event_dispatch();
- runner_disable_events();
- runner_shutdown();
-
- return (0);
-}
-
-void
-runner_timeout(int fd, short event, void *p)
-{
- struct timeval tv;
- static int rq_done = 0;
- time_t nsched;
- time_t curtm;
- u_int64_t evpid;
-
- nsched = 0;
-
-again:
-/*
- if (scheduler->display)
- scheduler->display();
-*/
-
- curtm = time(NULL);
-
- /* set nsched to the time() of next schedulable envelope */
- scheduler->next(NULL, &nsched);
-
- /* load as many envelopes as possible from disk-queue to
- * ram-queue until a schedulable envelope is found.
- */
- if (! rq_done)
- rq_done = scheduler->setup(curtm, nsched);
-
- if (rq_done) {
- if (! scheduler->next(NULL, &nsched))
- goto scheduler_sleep;
- if (curtm < nsched)
- goto scheduler_pause;
- }
-
- /* let's do the schedule dance baby ! */
- while (scheduler->next(&evpid, &nsched)) {
- if (curtm < nsched)
- goto scheduler_pause;
-
- runner_process_envelope(evpid);
- }
-
- if (rq_done)
- goto scheduler_sleep;
-
- goto again;
-
-
-scheduler_pause:
- nsched = nsched - curtm;
-
- log_debug("runner: nothing to do for the next %lld seconds, zZzZzZ",
- (long long int) nsched);
-
- tv.tv_sec = nsched;
- tv.tv_usec = 0;
- evtimer_add(&env->sc_ev, &tv);
- return;
-
-
-scheduler_sleep:
- log_debug("runner: nothing to schedule, wake me up. zZzZzZ");
- return;
-}
-
-static int
-runner_process_envelope(u_int64_t evpid)
-{
- struct envelope envelope;
- size_t mta_av, mda_av, bnc_av;
- struct scheduler_info si;
-
- mta_av = env->sc_maxconn - stat_get(STATS_MTA_SESSION, STAT_ACTIVE);
- mda_av = env->sc_maxconn - stat_get(STATS_MDA_SESSION, STAT_ACTIVE);
- bnc_av = env->sc_maxconn - stat_get(STATS_RUNNER_BOUNCES, STAT_ACTIVE);
-
- if (! queue_envelope_load(evpid, &envelope))
- return 0;
-
- if (envelope.type == D_MDA)
- if (mda_av == 0) {
- env->sc_flags |= SMTPD_MDA_BUSY;
- return 0;
- }
-
- if (envelope.type == D_MTA)
- if (mta_av == 0) {
- env->sc_flags |= SMTPD_MTA_BUSY;
- return 0;
- }
-
- if (envelope.type == D_BOUNCE)
- if (bnc_av == 0) {
- env->sc_flags |= SMTPD_BOUNCE_BUSY;
- return 0;
- }
-
- if (runner_check_loop(&envelope)) {
- struct envelope bounce;
-
- envelope_set_errormsg(&envelope, "loop has been detected");
- if (bounce_record_message(&envelope, &bounce)) {
- scheduler_info(&si, &bounce);
- scheduler->insert(&si);
- }
- scheduler->remove(evpid);
- queue_envelope_delete(&envelope);
-
- runner_reset_events();
-
- return 0;
- }
-
-
- return runner_process_batch(envelope.type, evpid);
-}
-
-static int
-runner_process_batch(enum delivery_type type, u_int64_t evpid)
-{
- struct envelope evp;
- void *batch;
- int fd;
-
- batch = scheduler->batch(evpid);
- switch (type) {
- case D_BOUNCE:
- while (scheduler->fetch(batch, &evpid)) {
- if (! queue_envelope_load(evpid, &evp))
- goto end;
-
- evp.lasttry = time(NULL);
- imsg_compose_event(env->sc_ievs[PROC_QUEUE],
- IMSG_SMTP_ENQUEUE, PROC_SMTP, 0, -1, &evp,
- sizeof evp);
- scheduler->schedule(evpid);
- }
- stat_increment(STATS_RUNNER);
- stat_increment(STATS_RUNNER_BOUNCES);
- break;
-
- case D_MDA:
- scheduler->fetch(batch, &evpid);
- if (! queue_envelope_load(evpid, &evp))
- goto end;
-
- evp.lasttry = time(NULL);
- fd = queue_message_fd_r(evpid_to_msgid(evpid));
- imsg_compose_event(env->sc_ievs[PROC_QUEUE],
- IMSG_MDA_SESS_NEW, PROC_MDA, 0, fd, &evp,
- sizeof evp);
- scheduler->schedule(evpid);
-
- stat_increment(STATS_RUNNER);
- stat_increment(STATS_MDA_SESSION);
- break;
-
- case D_MTA: {
- struct mta_batch mta_batch;
-
- /* FIXME */
- if (! scheduler->fetch(batch, &evpid))
- goto end;
- if (! queue_envelope_load(evpid, &evp))
- goto end;
-
- bzero(&mta_batch, sizeof mta_batch);
- mta_batch.id = arc4random();
- mta_batch.relay = evp.agent.mta.relay;
-
- imsg_compose_event(env->sc_ievs[PROC_QUEUE],
- IMSG_BATCH_CREATE, PROC_MTA, 0, -1, &mta_batch,
- sizeof mta_batch);
-
- while (scheduler->fetch(batch, &evpid)) {
- if (! queue_envelope_load(evpid, &evp))
- goto end;
- evp.lasttry = time(NULL); /* FIXME */
- evp.batch_id = mta_batch.id;
-
- imsg_compose_event(env->sc_ievs[PROC_QUEUE],
- IMSG_BATCH_APPEND, PROC_MTA, 0, -1, &evp,
- sizeof evp);
-
- scheduler->schedule(evpid);
- stat_increment(STATS_RUNNER);
- }
-
- imsg_compose_event(env->sc_ievs[PROC_QUEUE],
- IMSG_BATCH_CLOSE, PROC_MTA, 0, -1, &mta_batch,
- sizeof mta_batch);
-
- stat_increment(STATS_MTA_SESSION);
- break;
- }
-
- default:
- fatalx("runner_process_batchqueue: unknown type");
- }
-
-end:
- scheduler->close(batch);
- return 1;
-}
-
-static int
-runner_message_to_scheduler(u_int32_t msgid)
-{
- struct qwalk *q;
- u_int64_t evpid;
- struct envelope envelope;
- struct scheduler_info si;
-
- q = qwalk_new(msgid);
- while (qwalk(q, &evpid)) {
- if (! queue_envelope_load(evpid, &envelope))
- continue;
- scheduler_info(&si, &envelope);
- scheduler->insert(&si);
- }
- qwalk_close(q);
-
- return 1;
-}
-
-static int
-runner_check_loop(struct envelope *ep)
-{
- int fd;
- FILE *fp;
- char *buf, *lbuf;
- size_t len;
- struct mailaddr maddr;
- int ret = 0;
- int rcvcount = 0;
-
- fd = queue_message_fd_r(evpid_to_msgid(ep->id));
- if ((fp = fdopen(fd, "r")) == NULL)
- fatal("fdopen");
-
- lbuf = NULL;
- while ((buf = fgetln(fp, &len))) {
- if (buf[len - 1] == '\n')
- buf[len - 1] = '\0';
- else {
- /* EOF without EOL, copy and add the NUL */
- if ((lbuf = malloc(len + 1)) == NULL)
- err(1, NULL);
- memcpy(lbuf, buf, len);
- lbuf[len] = '\0';
- buf = lbuf;
- }
-
- if (strchr(buf, ':') == NULL && !isspace((int)*buf))
- break;
-
- if (strncasecmp("Received: ", buf, 10) == 0) {
- rcvcount++;
- if (rcvcount == MAX_HOPS_COUNT) {
- ret = 1;
- break;
- }
- }
-
- else if (strncasecmp("Delivered-To: ", buf, 14) == 0) {
- struct mailaddr dest;
-
- bzero(&maddr, sizeof (struct mailaddr));
- if (! email_to_mailaddr(&maddr, buf + 14))
- continue;
-
- dest = ep->dest;
- if (ep->type == D_BOUNCE)
- dest = ep->sender;
-
- if (strcasecmp(maddr.user, dest.user) == 0 &&
- strcasecmp(maddr.domain, dest.domain) == 0) {
- ret = 1;
- break;
- }
- }
- }
- free(lbuf);
-
- fclose(fp);
- return ret;
-}
-
-static void
-runner_remove(u_int64_t id)
-{
- void *msg;
-
- /* removing by evpid */
- if (id > 0xffffffffL) {
- runner_remove_envelope(id);
- return;
- }
-
- /* removing by msgid */
- msg = scheduler->message(id);
- while (scheduler->fetch(msg, &id))
- runner_remove_envelope(id);
- scheduler->close(msg);
-}
-
-static void
-runner_remove_envelope(u_int64_t evpid)
-{
- struct envelope evp;
-
- evp.id = evpid;
- queue_envelope_delete(&evp);
- scheduler->remove(evpid);
-}
diff --git a/usr.sbin/smtpd/scheduler.c b/usr.sbin/smtpd/scheduler.c
index 3c835db6927..7f9b5e33e8c 100644
--- a/usr.sbin/smtpd/scheduler.c
+++ b/usr.sbin/smtpd/scheduler.c
@@ -1,7 +1,9 @@
-/* $OpenBSD: scheduler.c,v 1.3 2012/07/02 17:00:05 eric Exp $ */
+/* $OpenBSD: scheduler.c,v 1.4 2012/07/09 09:57:53 gilles Exp $ */
/*
- * Copyright (c) 2012 Gilles Chehade <gilles@openbsd.org>
+ * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
+ * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
+ * Copyright (c) 2008-2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,38 +23,590 @@
#include <sys/tree.h>
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <ctype.h>
+#include <dirent.h>
#include <err.h>
+#include <errno.h>
#include <event.h>
-#include <fcntl.h>
#include <imsg.h>
+#include <inttypes.h>
+#include <libgen.h>
+#include <pwd.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
+#include <unistd.h>
#include "smtpd.h"
#include "log.h"
-extern struct scheduler_backend scheduler_backend_ramqueue;
+static void scheduler_imsg(struct imsgev *, struct imsg *);
+static void scheduler_shutdown(void);
+static void scheduler_sig_handler(int, short, void *);
+static void scheduler_setup_events(void);
+static void scheduler_reset_events(void);
+static void scheduler_disable_events(void);
+static void scheduler_timeout(int, short, void *);
+static void scheduler_remove(u_int64_t);
+static void scheduler_remove_envelope(u_int64_t);
+static int scheduler_process_envelope(u_int64_t);
+static int scheduler_process_batch(enum delivery_type, u_int64_t);
+static int scheduler_check_loop(struct envelope *);
+static int scheduler_message_to_scheduler(u_int32_t);
-struct scheduler_backend *
-scheduler_backend_lookup(const char *name)
+static struct scheduler_backend *backend = NULL;
+
+extern const char *backend_scheduler;
+
+void
+scheduler_imsg(struct imsgev *iev, struct imsg *imsg)
{
- if (!strcmp(name, "ramqueue"))
- return &scheduler_backend_ramqueue;
+ struct envelope *e, bounce;
+ struct scheduler_info si;
+
+ log_imsg(PROC_SCHEDULER, iev->proc, imsg);
+
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_COMMIT_MESSAGE:
+ e = imsg->data;
+ scheduler_message_to_scheduler(evpid_to_msgid(e->id));
+ scheduler_reset_events();
+ return;
+
+ case IMSG_QUEUE_DELIVERY_OK:
+ stat_decrement(STATS_SCHEDULER);
+ e = imsg->data;
+ log_debug("queue_delivery_ok: %016"PRIx64, e->id);
+ backend->remove(e->id);
+ queue_envelope_delete(e);
+ return;
+
+ case IMSG_QUEUE_DELIVERY_TEMPFAIL:
+ stat_decrement(STATS_SCHEDULER);
+ e = imsg->data;
+ e->retry++;
+ queue_envelope_update(e);
+ log_debug("queue_delivery_tempfail: %016"PRIx64, e->id);
+ scheduler_info(&si, e);
+ backend->insert(&si);
+ scheduler_reset_events();
+ return;
+
+ case IMSG_QUEUE_DELIVERY_PERMFAIL:
+ stat_decrement(STATS_SCHEDULER);
+ e = imsg->data;
+ if (e->type != D_BOUNCE && e->sender.user[0] != '\0') {
+ bounce_record_message(e, &bounce);
+ log_debug("queue_delivery_permfail: %016"PRIx64,
+ bounce.id);
+ scheduler_info(&si, &bounce);
+ backend->insert(&si);
+ scheduler_reset_events();
+ }
+ backend->remove(e->id);
+ queue_envelope_delete(e);
+ return;
+
+ case IMSG_MDA_SESS_NEW:
+ stat_decrement(STATS_MDA_SESSION);
+ if (env->sc_maxconn - stat_get(STATS_MDA_SESSION, STAT_ACTIVE))
+ env->sc_flags &= ~SMTPD_MDA_BUSY;
+ scheduler_reset_events();
+ return;
+
+ case IMSG_BATCH_DONE:
+ stat_decrement(STATS_MTA_SESSION);
+ if (env->sc_maxconn - stat_get(STATS_MTA_SESSION, STAT_ACTIVE))
+ env->sc_flags &= ~SMTPD_MTA_BUSY;
+ scheduler_reset_events();
+ return;
+
+ case IMSG_SMTP_ENQUEUE:
+ e = imsg->data;
+ if (imsg->fd < 0 || !bounce_session(imsg->fd, e)) {
+ queue_envelope_update(e);
+ log_debug("smtp_enqueue: %016"PRIx64, e->id);
+ scheduler_info(&si, e);
+ backend->insert(&si);
+ scheduler_reset_events();
+ return;
+ }
+ return;
+
+ case IMSG_QUEUE_PAUSE_MDA:
+ env->sc_flags |= SMTPD_MDA_PAUSED;
+ return;
+
+ case IMSG_QUEUE_RESUME_MDA:
+ env->sc_flags &= ~SMTPD_MDA_PAUSED;
+ scheduler_reset_events();
+ return;
+
+ case IMSG_QUEUE_PAUSE_MTA:
+ env->sc_flags |= SMTPD_MTA_PAUSED;
+ return;
+
+ case IMSG_QUEUE_RESUME_MTA:
+ env->sc_flags &= ~SMTPD_MTA_PAUSED;
+ scheduler_reset_events();
+ return;
+
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
+ return;
+
+ case IMSG_SCHEDULER_SCHEDULE:
+ backend->force(*(u_int64_t *)imsg->data);
+ scheduler_reset_events();
+ return;
- return NULL;
+ case IMSG_SCHEDULER_REMOVE: {
+ scheduler_remove(*(u_int64_t *)imsg->data);
+ scheduler_reset_events();
+ return;
+ }
+ }
+
+ errx(1, "scheduler_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
+}
+
+void
+scheduler_sig_handler(int sig, short event, void *p)
+{
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ scheduler_shutdown();
+ break;
+ default:
+ fatalx("scheduler_sig_handler: unexpected signal");
+ }
+}
+
+void
+scheduler_shutdown(void)
+{
+ log_info("scheduler handler exiting");
+ _exit(0);
+}
+
+void
+scheduler_setup_events(void)
+{
+ struct timeval tv;
+
+ evtimer_set(&env->sc_ev, scheduler_timeout, NULL);
+ tv.tv_sec = 0;
+ tv.tv_usec = 10;
+ evtimer_add(&env->sc_ev, &tv);
}
void
-scheduler_info(struct scheduler_info *sched, struct envelope *evp)
+scheduler_reset_events(void)
+{
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 10;
+ evtimer_add(&env->sc_ev, &tv);
+}
+
+void
+scheduler_disable_events(void)
+{
+ evtimer_del(&env->sc_ev);
+}
+
+pid_t
+scheduler(void)
+{
+ pid_t pid;
+ struct passwd *pw;
+
+ struct event ev_sigint;
+ struct event ev_sigterm;
+
+ struct peer peers[] = {
+ { PROC_CONTROL, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch }
+ };
+
+ switch (pid = fork()) {
+ case -1:
+ fatal("scheduler: cannot fork");
+ case 0:
+ break;
+ default:
+ return (pid);
+ }
+
+ purge_config(PURGE_EVERYTHING);
+
+ pw = env->sc_pw;
+
+ if (chroot(PATH_SPOOL) == -1)
+ fatal("scheduler: chroot");
+ if (chdir("/") == -1)
+ fatal("scheduler: chdir(\"/\")");
+
+ smtpd_process = PROC_SCHEDULER;
+ setproctitle("%s", env->sc_title[smtpd_process]);
+
+ if (setgroups(1, &pw->pw_gid) ||
+ setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
+ setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
+ fatal("scheduler: cannot drop privileges");
+
+ /* see fdlimit()-related comment in queue.c */
+ fdlimit(1.0);
+ if ((env->sc_maxconn = availdesc() / 4) < 1)
+ fatalx("scheduler: fd starvation");
+
+ env->sc_scheduler = scheduler_backend_lookup(backend_scheduler);
+ if (env->sc_scheduler == NULL)
+ errx(1, "cannot find scheduler backend \"%s\"", backend_scheduler);
+ backend = env->sc_scheduler;
+
+ backend->init();
+
+ imsg_callback = scheduler_imsg;
+ event_init();
+
+ signal_set(&ev_sigint, SIGINT, scheduler_sig_handler, NULL);
+ signal_set(&ev_sigterm, SIGTERM, scheduler_sig_handler, NULL);
+ signal_add(&ev_sigint, NULL);
+ signal_add(&ev_sigterm, NULL);
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+
+ config_pipes(peers, nitems(peers));
+ config_peers(peers, nitems(peers));
+
+ scheduler_setup_events();
+ event_dispatch();
+ scheduler_disable_events();
+ scheduler_shutdown();
+
+ return (0);
+}
+
+void
+scheduler_timeout(int fd, short event, void *p)
+{
+ struct timeval tv;
+ static int rq_done = 0;
+ time_t nsched;
+ time_t curtm;
+ u_int64_t evpid;
+
+ nsched = 0;
+
+again:
+/*
+ if (scheduler->display)
+ scheduler->display();
+*/
+
+ curtm = time(NULL);
+
+ /* set nsched to the time() of next schedulable envelope */
+ backend->next(NULL, &nsched);
+
+ /* load as many envelopes as possible from disk-queue to
+ * ram-queue until a schedulable envelope is found.
+ */
+ if (! rq_done)
+ rq_done = backend->setup(curtm, nsched);
+
+ if (rq_done) {
+ if (! backend->next(NULL, &nsched))
+ goto scheduler_sleep;
+ if (curtm < nsched)
+ goto scheduler_pause;
+ }
+
+ /* let's do the schedule dance baby ! */
+ while (backend->next(&evpid, &nsched)) {
+ if (curtm < nsched)
+ goto scheduler_pause;
+
+ scheduler_process_envelope(evpid);
+ }
+
+ if (rq_done)
+ goto scheduler_sleep;
+
+ goto again;
+
+
+scheduler_pause:
+ nsched = nsched - curtm;
+
+ log_debug("scheduler: nothing to do for the next %lld seconds, zZzZzZ",
+ (long long int) nsched);
+
+ tv.tv_sec = nsched;
+ tv.tv_usec = 0;
+ evtimer_add(&env->sc_ev, &tv);
+ return;
+
+
+scheduler_sleep:
+ log_debug("scheduler: nothing to schedule, wake me up. zZzZzZ");
+ return;
+}
+
+static int
+scheduler_process_envelope(u_int64_t evpid)
+{
+ struct envelope envelope;
+ size_t mta_av, mda_av, bnc_av;
+ struct scheduler_info si;
+
+ mta_av = env->sc_maxconn - stat_get(STATS_MTA_SESSION, STAT_ACTIVE);
+ mda_av = env->sc_maxconn - stat_get(STATS_MDA_SESSION, STAT_ACTIVE);
+ bnc_av = env->sc_maxconn - stat_get(STATS_SCHEDULER_BOUNCES, STAT_ACTIVE);
+
+ if (! queue_envelope_load(evpid, &envelope))
+ return 0;
+
+ if (envelope.type == D_MDA)
+ if (mda_av == 0) {
+ env->sc_flags |= SMTPD_MDA_BUSY;
+ return 0;
+ }
+
+ if (envelope.type == D_MTA)
+ if (mta_av == 0) {
+ env->sc_flags |= SMTPD_MTA_BUSY;
+ return 0;
+ }
+
+ if (envelope.type == D_BOUNCE)
+ if (bnc_av == 0) {
+ env->sc_flags |= SMTPD_BOUNCE_BUSY;
+ return 0;
+ }
+
+ if (scheduler_check_loop(&envelope)) {
+ struct envelope bounce;
+
+ envelope_set_errormsg(&envelope, "loop has been detected");
+ if (bounce_record_message(&envelope, &bounce)) {
+ scheduler_info(&si, &bounce);
+ backend->insert(&si);
+ }
+ backend->remove(evpid);
+ queue_envelope_delete(&envelope);
+
+ scheduler_reset_events();
+
+ return 0;
+ }
+
+
+ return scheduler_process_batch(envelope.type, evpid);
+}
+
+static int
+scheduler_process_batch(enum delivery_type type, u_int64_t evpid)
+{
+ struct envelope evp;
+ void *batch;
+ int fd;
+
+ batch = backend->batch(evpid);
+ switch (type) {
+ case D_BOUNCE:
+ while (backend->fetch(batch, &evpid)) {
+ if (! queue_envelope_load(evpid, &evp))
+ goto end;
+
+ evp.lasttry = time(NULL);
+ imsg_compose_event(env->sc_ievs[PROC_QUEUE],
+ IMSG_SMTP_ENQUEUE, PROC_SMTP, 0, -1, &evp,
+ sizeof evp);
+ backend->schedule(evpid);
+ }
+ stat_increment(STATS_SCHEDULER);
+ stat_increment(STATS_SCHEDULER_BOUNCES);
+ break;
+
+ case D_MDA:
+ backend->fetch(batch, &evpid);
+ if (! queue_envelope_load(evpid, &evp))
+ goto end;
+
+ evp.lasttry = time(NULL);
+ fd = queue_message_fd_r(evpid_to_msgid(evpid));
+ imsg_compose_event(env->sc_ievs[PROC_QUEUE],
+ IMSG_MDA_SESS_NEW, PROC_MDA, 0, fd, &evp,
+ sizeof evp);
+ backend->schedule(evpid);
+
+ stat_increment(STATS_SCHEDULER);
+ stat_increment(STATS_MDA_SESSION);
+ break;
+
+ case D_MTA: {
+ struct mta_batch mta_batch;
+
+ /* FIXME */
+ if (! backend->fetch(batch, &evpid))
+ goto end;
+ if (! queue_envelope_load(evpid, &evp))
+ goto end;
+
+ bzero(&mta_batch, sizeof mta_batch);
+ mta_batch.id = arc4random();
+ mta_batch.relay = evp.agent.mta.relay;
+
+ imsg_compose_event(env->sc_ievs[PROC_QUEUE],
+ IMSG_BATCH_CREATE, PROC_MTA, 0, -1, &mta_batch,
+ sizeof mta_batch);
+
+ while (backend->fetch(batch, &evpid)) {
+ if (! queue_envelope_load(evpid, &evp))
+ goto end;
+ evp.lasttry = time(NULL); /* FIXME */
+ evp.batch_id = mta_batch.id;
+
+ imsg_compose_event(env->sc_ievs[PROC_QUEUE],
+ IMSG_BATCH_APPEND, PROC_MTA, 0, -1, &evp,
+ sizeof evp);
+
+ backend->schedule(evpid);
+ stat_increment(STATS_SCHEDULER);
+ }
+
+ imsg_compose_event(env->sc_ievs[PROC_QUEUE],
+ IMSG_BATCH_CLOSE, PROC_MTA, 0, -1, &mta_batch,
+ sizeof mta_batch);
+
+ stat_increment(STATS_MTA_SESSION);
+ break;
+ }
+
+ default:
+ fatalx("scheduler_process_batchqueue: unknown type");
+ }
+
+end:
+ backend->close(batch);
+ return 1;
+}
+
+static int
+scheduler_message_to_scheduler(u_int32_t msgid)
+{
+ struct qwalk *q;
+ u_int64_t evpid;
+ struct envelope envelope;
+ struct scheduler_info si;
+
+ q = qwalk_new(msgid);
+ while (qwalk(q, &evpid)) {
+ if (! queue_envelope_load(evpid, &envelope))
+ continue;
+ scheduler_info(&si, &envelope);
+ backend->insert(&si);
+ }
+ qwalk_close(q);
+
+ return 1;
+}
+
+static int
+scheduler_check_loop(struct envelope *ep)
+{
+ int fd;
+ FILE *fp;
+ char *buf, *lbuf;
+ size_t len;
+ struct mailaddr maddr;
+ int ret = 0;
+ int rcvcount = 0;
+
+ fd = queue_message_fd_r(evpid_to_msgid(ep->id));
+ if ((fp = fdopen(fd, "r")) == NULL)
+ fatal("fdopen");
+
+ lbuf = NULL;
+ while ((buf = fgetln(fp, &len))) {
+ if (buf[len - 1] == '\n')
+ buf[len - 1] = '\0';
+ else {
+ /* EOF without EOL, copy and add the NUL */
+ if ((lbuf = malloc(len + 1)) == NULL)
+ err(1, NULL);
+ memcpy(lbuf, buf, len);
+ lbuf[len] = '\0';
+ buf = lbuf;
+ }
+
+ if (strchr(buf, ':') == NULL && !isspace((int)*buf))
+ break;
+
+ if (strncasecmp("Received: ", buf, 10) == 0) {
+ rcvcount++;
+ if (rcvcount == MAX_HOPS_COUNT) {
+ ret = 1;
+ break;
+ }
+ }
+
+ else if (strncasecmp("Delivered-To: ", buf, 14) == 0) {
+ struct mailaddr dest;
+
+ bzero(&maddr, sizeof (struct mailaddr));
+ if (! email_to_mailaddr(&maddr, buf + 14))
+ continue;
+
+ dest = ep->dest;
+ if (ep->type == D_BOUNCE)
+ dest = ep->sender;
+
+ if (strcasecmp(maddr.user, dest.user) == 0 &&
+ strcasecmp(maddr.domain, dest.domain) == 0) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ free(lbuf);
+
+ fclose(fp);
+ return ret;
+}
+
+static void
+scheduler_remove(u_int64_t id)
+{
+ void *msg;
+
+ /* removing by evpid */
+ if (id > 0xffffffffL) {
+ scheduler_remove_envelope(id);
+ return;
+ }
+
+ /* removing by msgid */
+ msg = backend->message(id);
+ while (backend->fetch(msg, &id))
+ scheduler_remove_envelope(id);
+ backend->close(msg);
+}
+
+static void
+scheduler_remove_envelope(u_int64_t evpid)
{
- strlcpy(sched->destination, evp->dest.domain, sizeof sched->destination);
+ struct envelope evp;
- sched->evpid = evp->id;
- sched->creation = evp->creation;
- sched->lasttry = evp->lasttry;
- sched->expire = evp->expire;
- sched->retry = evp->retry;
+ evp.id = evpid;
+ queue_envelope_delete(&evp);
+ backend->remove(evpid);
}
diff --git a/usr.sbin/smtpd/scheduler_backend.c b/usr.sbin/smtpd/scheduler_backend.c
new file mode 100644
index 00000000000..68187756b1f
--- /dev/null
+++ b/usr.sbin/smtpd/scheduler_backend.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: scheduler_backend.c,v 1.1 2012/07/09 09:57:53 gilles Exp $ */
+
+/*
+ * Copyright (c) 2012 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <event.h>
+#include <fcntl.h>
+#include <imsg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+extern struct scheduler_backend scheduler_backend_ramqueue;
+
+struct scheduler_backend *
+scheduler_backend_lookup(const char *name)
+{
+ if (!strcmp(name, "ramqueue"))
+ return &scheduler_backend_ramqueue;
+
+ return NULL;
+}
+
+void
+scheduler_info(struct scheduler_info *sched, struct envelope *evp)
+{
+ strlcpy(sched->destination, evp->dest.domain, sizeof sched->destination);
+
+ sched->evpid = evp->id;
+ sched->creation = evp->creation;
+ sched->lasttry = evp->lasttry;
+ sched->expire = evp->expire;
+ sched->retry = evp->retry;
+}
diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c
index cd06a80bf0f..0ea226dcb29 100644
--- a/usr.sbin/smtpd/smtpctl.c
+++ b/usr.sbin/smtpd/smtpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpctl.c,v 1.82 2012/07/02 17:00:05 eric Exp $ */
+/* $OpenBSD: smtpctl.c,v 1.83 2012/07/09 09:57:53 gilles Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -175,10 +175,10 @@ connected:
errx(1, "invalid msgid/evpid");
if (res->action == SCHEDULE)
- imsg_compose(ibuf, IMSG_RUNNER_SCHEDULE, 0, 0, -1, &ulval,
+ imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval,
sizeof(ulval));
if (res->action == REMOVE)
- imsg_compose(ibuf, IMSG_RUNNER_REMOVE, 0, 0, -1, &ulval,
+ imsg_compose(ibuf, IMSG_SCHEDULER_REMOVE, 0, 0, -1, &ulval,
sizeof(ulval));
break;
}
@@ -186,7 +186,7 @@ connected:
case SCHEDULE_ALL: {
u_int64_t ulval = 0;
- imsg_compose(ibuf, IMSG_RUNNER_SCHEDULE, 0, 0, -1, &ulval,
+ imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval,
sizeof(ulval));
break;
}
@@ -320,8 +320,8 @@ stat_print(int stat, int what)
"lka.sessions.cname",
"lka.sessions.failure",
- "runner",
- "runner.bounces",
+ "scheduler",
+ "scheduler.bounces",
"queue.inserts.local",
"queue.inserts.remote",
@@ -383,13 +383,13 @@ show_stats_output(struct imsg *imsg)
stat_print(STATS_QUEUE_LOCAL, STAT_COUNT);
stat_print(STATS_QUEUE_REMOTE, STAT_COUNT);
- stat_print(STATS_RUNNER, STAT_COUNT);
- stat_print(STATS_RUNNER, STAT_ACTIVE);
- stat_print(STATS_RUNNER, STAT_MAXACTIVE);
+ stat_print(STATS_SCHEDULER, STAT_COUNT);
+ stat_print(STATS_SCHEDULER, STAT_ACTIVE);
+ stat_print(STATS_SCHEDULER, STAT_MAXACTIVE);
- stat_print(STATS_RUNNER_BOUNCES, STAT_COUNT);
- stat_print(STATS_RUNNER_BOUNCES, STAT_ACTIVE);
- stat_print(STATS_RUNNER_BOUNCES, STAT_MAXACTIVE);
+ stat_print(STATS_SCHEDULER_BOUNCES, STAT_COUNT);
+ stat_print(STATS_SCHEDULER_BOUNCES, STAT_ACTIVE);
+ stat_print(STATS_SCHEDULER_BOUNCES, STAT_MAXACTIVE);
stat_print(STATS_RAMQUEUE_HOST, STAT_ACTIVE);
stat_print(STATS_RAMQUEUE_BATCH, STAT_ACTIVE);
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index fc84a771b73..4bf6b203910 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.153 2012/07/08 18:13:08 chl Exp $ */
+/* $OpenBSD: smtpd.c,v 1.154 2012/07/09 09:57:53 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -642,7 +642,7 @@ fork_peers(void)
env->sc_instances[PROC_MTA] = 1;
env->sc_instances[PROC_PARENT] = 1;
env->sc_instances[PROC_QUEUE] = 1;
- env->sc_instances[PROC_RUNNER] = 1;
+ env->sc_instances[PROC_SCHEDULER] = 1;
env->sc_instances[PROC_SMTP] = 1;
init_pipes();
@@ -653,7 +653,7 @@ fork_peers(void)
env->sc_title[PROC_MFA] = "mail filter agent";
env->sc_title[PROC_MTA] = "mail transfer agent";
env->sc_title[PROC_QUEUE] = "queue";
- env->sc_title[PROC_RUNNER] = "runner";
+ env->sc_title[PROC_SCHEDULER] = "scheduler";
env->sc_title[PROC_SMTP] = "smtp server";
child_add(control(), CHILD_DAEMON, PROC_CONTROL);
@@ -662,7 +662,7 @@ fork_peers(void)
child_add(mfa(), CHILD_DAEMON, PROC_MFA);
child_add(mta(), CHILD_DAEMON, PROC_MTA);
child_add(queue(), CHILD_DAEMON, PROC_QUEUE);
- child_add(runner(), CHILD_DAEMON, PROC_RUNNER);
+ child_add(scheduler(), CHILD_DAEMON, PROC_SCHEDULER);
child_add(smtp(), CHILD_DAEMON, PROC_SMTP);
setproctitle("[priv]");
@@ -1178,7 +1178,7 @@ proc_to_str(int proc)
CASE(PROC_MDA);
CASE(PROC_MTA);
CASE(PROC_CONTROL);
- CASE(PROC_RUNNER);
+ CASE(PROC_SCHEDULER);
default:
return "PROC_???";
}
@@ -1241,8 +1241,8 @@ imsg_to_str(int type)
CASE(IMSG_QUEUE_SCHEDULE);
CASE(IMSG_QUEUE_REMOVE);
- CASE(IMSG_RUNNER_REMOVE);
- CASE(IMSG_RUNNER_SCHEDULE);
+ CASE(IMSG_SCHEDULER_REMOVE);
+ CASE(IMSG_SCHEDULER_SCHEDULE);
CASE(IMSG_BATCH_CREATE);
CASE(IMSG_BATCH_APPEND);
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index e279059de48..f4379162016 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.304 2012/07/09 08:08:29 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.305 2012/07/09 09:57:53 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -164,8 +164,8 @@ enum imsg_type {
IMSG_QUEUE_SCHEDULE,
IMSG_QUEUE_REMOVE,
- IMSG_RUNNER_REMOVE,
- IMSG_RUNNER_SCHEDULE,
+ IMSG_SCHEDULER_REMOVE,
+ IMSG_SCHEDULER_SCHEDULE,
IMSG_BATCH_CREATE,
IMSG_BATCH_APPEND,
@@ -225,7 +225,7 @@ enum smtp_proc_type {
PROC_MDA,
PROC_MTA,
PROC_CONTROL,
- PROC_RUNNER,
+ PROC_SCHEDULER,
} smtpd_process;
struct peer {
@@ -642,8 +642,8 @@ enum {
STATS_LKA_SESSION_CNAME,
STATS_LKA_FAILURE,
- STATS_RUNNER,
- STATS_RUNNER_BOUNCES,
+ STATS_SCHEDULER,
+ STATS_SCHEDULER_BOUNCES,
STATS_QUEUE_LOCAL,
STATS_QUEUE_REMOTE,
@@ -1129,8 +1129,8 @@ int qwalk(void *, u_int64_t *);
void qwalk_close(void *);
-/* runner.c */
-pid_t runner(void);
+/* scheduler.c */
+pid_t scheduler(void);
void message_reset_flags(struct envelope *);
diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile
index 2e61e72bc66..33a65ead442 100644
--- a/usr.sbin/smtpd/smtpd/Makefile
+++ b/usr.sbin/smtpd/smtpd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.42 2012/05/29 19:53:10 gilles Exp $
+# $OpenBSD: Makefile,v 1.43 2012/07/09 09:57:53 gilles Exp $
PROG= smtpd
SRCS= aliases.c auth.c auth_bsd.c auth_pwd.c bounce.c \
@@ -8,11 +8,12 @@ SRCS= aliases.c auth.c auth_bsd.c auth_pwd.c bounce.c \
config.c control.c dns.c expand.c envelope.c forward.c \
lka.c lka_session.c log.c map.c map_db.c map_stdio.c \
mda.c mfa.c mfa_session.c mta.c mta_session.c parse.y \
- queue.c ruleset.c runner.c smtp.c \
+ queue.c ruleset.c scheduler.c scheduler_backend.c \
+ smtp.c \
smtp_session.c smtpd.c ssl.c ssl_privsep.c util.c asr.c \
print.c pack.c dname.c res_random.c sockaddr.c \
queue_backend.c queue_fsqueue.c \
- user.c user_pwd.c stats.c scheduler.c scheduler_ramqueue.c \
+ user.c user_pwd.c stats.c scheduler_ramqueue.c \
map_static.c
MAN= smtpd.8 smtpd.conf.5