diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-01-04 22:35:10 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-01-04 22:35:10 +0000 |
commit | 92102d1d1b05d500457859fe5b0485fe1cc7868d (patch) | |
tree | 4f0652b091967145b5dea3f5d59b57a3992511df /usr.sbin | |
parent | 79dc2898a960528ca8c456fd9ef71358ff4debfe (diff) |
- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/control.c | 91 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.h | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 10 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtp.c | 86 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl.c | 18 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 14 |
7 files changed, 196 insertions, 31 deletions
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c index a1905876d4d..c0b5e06633e 100644 --- a/usr.sbin/smtpd/control.c +++ b/usr.sbin/smtpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.6 2009/01/04 19:37:41 gilles Exp $ */ +/* $OpenBSD: control.c,v 1.7 2009/01/04 22:35:09 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -57,6 +57,7 @@ void control_dispatch_lka(int, short, void *); void control_dispatch_mfa(int, short, void *); void control_dispatch_queue(int, short, void *); void control_dispatch_runner(int, short, void *); +void control_dispatch_smtp(int, short, void *); struct ctl_connlist ctl_conns; @@ -87,6 +88,7 @@ control(struct smtpd *env) struct peer peers [] = { { PROC_QUEUE, control_dispatch_queue }, { PROC_RUNNER, control_dispatch_runner }, + { PROC_SMTP, control_dispatch_smtp }, }; switch (pid = fork()) { @@ -159,7 +161,7 @@ control(struct smtpd *env) TAILQ_INIT(&ctl_conns); - config_peers(env, peers, 2); + config_peers(env, peers, 3); control_listen(env); event_dispatch(); control_shutdown(); @@ -311,51 +313,72 @@ control_dispatch_ext(int fd, short event, void *arg) env->sc_flags |= SMTPD_EXITING; imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; - case IMSG_RUNNER_PAUSE_MDA: + case IMSG_MDA_PAUSE: if (env->sc_flags & SMTPD_MDA_PAUSED) { imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags |= SMTPD_MDA_PAUSED; - imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_PAUSE_MDA, + imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_MDA_PAUSE, 0, 0, -1, NULL, 0); imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; - case IMSG_RUNNER_PAUSE_MTA: + case IMSG_MTA_PAUSE: if (env->sc_flags & SMTPD_MTA_PAUSED) { imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags |= SMTPD_MTA_PAUSED; - imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_PAUSE_MTA, + imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_MTA_PAUSE, 0, 0, -1, NULL, 0); imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; - case IMSG_RUNNER_RESUME_MDA: + case IMSG_SMTP_PAUSE: + if (env->sc_flags & SMTPD_SMTP_PAUSED) { + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, + NULL, 0); + break; + } + env->sc_flags |= SMTPD_SMTP_PAUSED; + imsg_compose(env->sc_ibufs[PROC_SMTP], IMSG_SMTP_PAUSE, + 0, 0, -1, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + break; + case IMSG_MDA_RESUME: if (! (env->sc_flags & SMTPD_MDA_PAUSED)) { imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags &= ~SMTPD_MDA_PAUSED; - imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_RESUME_MDA, + imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_MTA_RESUME, 0, 0, -1, NULL, 0); imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; - case IMSG_RUNNER_RESUME_MTA: + case IMSG_MTA_RESUME: if (!(env->sc_flags & SMTPD_MTA_PAUSED)) { imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags &= ~SMTPD_MTA_PAUSED; - imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_RESUME_MTA, + imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_MTA_RESUME, + 0, 0, -1, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + break; + case IMSG_SMTP_RESUME: + if (!(env->sc_flags & SMTPD_SMTP_PAUSED)) { + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, + NULL, 0); + break; + } + env->sc_flags &= ~SMTPD_SMTP_PAUSED; + imsg_compose(env->sc_ibufs[PROC_SMTP], IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0); imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; - default: log_debug("control_dispatch_ext: " "error handling imsg %d", imsg.hdr.type); @@ -552,6 +575,52 @@ control_dispatch_runner(int sig, short event, void *p) } void +control_dispatch_smtp(int sig, short event, void *p) +{ + struct smtpd *env = p; + struct imsgbuf *ibuf; + struct imsg imsg; + ssize_t n; + + ibuf = env->sc_ibufs[PROC_SMTP]; + switch (event) { + case 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(&ibuf->ev); + event_loopexit(NULL); + return; + } + break; + case EV_WRITE: + if (msgbuf_write(&ibuf->w) == -1) + fatal("msgbuf_write"); + imsg_event_add(ibuf); + return; + default: + fatalx("unknown event"); + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + fatal("control_dispatch_smtp: imsg_read error"); + if (n == 0) + break; + + switch (imsg.hdr.type) { + default: + log_debug("control_dispatch_smtp: unexpected imsg %d", + imsg.hdr.type); + break; + } + imsg_free(&imsg); + } + imsg_event_add(ibuf); +} + +void session_socket_blockmode(int fd, enum blockmodes bm) { int flags; diff --git a/usr.sbin/smtpd/parser.c b/usr.sbin/smtpd/parser.c index 291d2bc5272..ae1a886b307 100644 --- a/usr.sbin/smtpd/parser.c +++ b/usr.sbin/smtpd/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.4 2009/01/04 19:37:41 gilles Exp $ */ +/* $OpenBSD: parser.c,v 1.5 2009/01/04 22:35:09 gilles Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -78,12 +78,14 @@ static const struct token t_show[] = { static const struct token t_pause[] = { {KEYWORD, "local", PAUSE_MDA, NULL}, {KEYWORD, "outgoing", PAUSE_MTA, NULL}, + {KEYWORD, "incoming", PAUSE_SMTP, NULL}, {ENDTOKEN, "", NONE, NULL} }; static const struct token t_resume[] = { {KEYWORD, "local", RESUME_MDA, NULL}, {KEYWORD, "outgoing", RESUME_MTA, NULL}, + {KEYWORD, "incoming", RESUME_SMTP, NULL}, {ENDTOKEN, "", NONE, NULL} }; diff --git a/usr.sbin/smtpd/parser.h b/usr.sbin/smtpd/parser.h index 0b10607ef8a..7cf6e3bf94d 100644 --- a/usr.sbin/smtpd/parser.h +++ b/usr.sbin/smtpd/parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.h,v 1.4 2009/01/04 19:37:41 gilles Exp $ */ +/* $OpenBSD: parser.h,v 1.5 2009/01/04 22:35:09 gilles Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -25,8 +25,10 @@ enum actions { SHOW_RUNQUEUE, PAUSE_MDA, PAUSE_MTA, + PAUSE_SMTP, RESUME_MDA, RESUME_MTA, + RESUME_SMTP, }; struct parse_result { diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index c68b54ece15..2f5de6426f9 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.18 2009/01/04 22:18:23 gilles Exp $ */ +/* $OpenBSD: runner.c,v 1.19 2009/01/04 22:35:09 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -123,16 +123,16 @@ runner_dispatch_control(int sig, short event, void *p) break; switch (imsg.hdr.type) { - case IMSG_RUNNER_PAUSE_MDA: + case IMSG_MDA_PAUSE: env->sc_opts |= SMTPD_MDA_PAUSED; break; - case IMSG_RUNNER_PAUSE_MTA: + case IMSG_MTA_PAUSE: env->sc_opts |= SMTPD_MTA_PAUSED; break; - case IMSG_RUNNER_RESUME_MDA: + case IMSG_MDA_RESUME: env->sc_opts &= ~SMTPD_MDA_PAUSED; break; - case IMSG_RUNNER_RESUME_MTA: + case IMSG_MTA_RESUME: env->sc_opts &= ~SMTPD_MTA_PAUSED; break; default: diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c index a9bff9a0a78..0a6dcdc98ff 100644 --- a/usr.sbin/smtpd/smtp.c +++ b/usr.sbin/smtpd/smtp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp.c,v 1.15 2009/01/04 00:58:59 gilles Exp $ */ +/* $OpenBSD: smtp.c,v 1.16 2009/01/04 22:35:09 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -39,8 +39,11 @@ void smtp_dispatch_parent(int, short, void *); void smtp_dispatch_mfa(int, short, void *); void smtp_dispatch_lka(int, short, void *); void smtp_dispatch_queue(int, short, void *); +void smtp_dispatch_control(int, short, void *); void smtp_setup_events(struct smtpd *); void smtp_disable_events(struct smtpd *); +void smtp_pause(struct smtpd *); +void smtp_resume(struct smtpd *); void smtp_accept(int, short, void *); void session_timeout(int, short, void *); void session_auth_pickup(struct session *, char *, size_t); @@ -461,6 +464,58 @@ smtp_dispatch_queue(int sig, short event, void *p) } void +smtp_dispatch_control(int sig, short event, void *p) +{ + struct smtpd *env = p; + struct imsgbuf *ibuf; + struct imsg imsg; + ssize_t n; + + ibuf = env->sc_ibufs[PROC_CONTROL]; + switch (event) { + case 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(&ibuf->ev); + event_loopexit(NULL); + return; + } + break; + case EV_WRITE: + if (msgbuf_write(&ibuf->w) == -1) + fatal("msgbuf_write"); + imsg_event_add(ibuf); + return; + default: + fatalx("unknown event"); + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + fatal("smtp_dispatch_control: imsg_read error"); + if (n == 0) + break; + + switch (imsg.hdr.type) { + case IMSG_SMTP_PAUSE: + smtp_pause(env); + break; + case IMSG_SMTP_RESUME: + smtp_resume(env); + break; + default: + log_debug("smtp_dispatch_control: unexpected imsg %d", + imsg.hdr.type); + break; + } + imsg_free(&imsg); + } + imsg_event_add(ibuf); +} + +void smtp_shutdown(void) { log_info("smtp server exiting"); @@ -480,7 +535,8 @@ smtp(struct smtpd *env) { PROC_PARENT, smtp_dispatch_parent }, { PROC_MFA, smtp_dispatch_mfa }, { PROC_QUEUE, smtp_dispatch_queue }, - { PROC_LKA, smtp_dispatch_lka } + { PROC_LKA, smtp_dispatch_lka }, + { PROC_CONTROL, smtp_dispatch_control } }; switch (pid = fork()) { @@ -525,7 +581,7 @@ smtp(struct smtpd *env) signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); - config_peers(env, peers, 4); + config_peers(env, peers, 5); smtp_setup_events(env); event_dispatch(); @@ -575,6 +631,30 @@ smtp_disable_events(struct smtpd *env) } void +smtp_pause(struct smtpd *env) +{ + struct listener *l; + + log_debug("smtp_pause_listeners: pausing listening sockets"); + TAILQ_FOREACH(l, &env->sc_listeners, entry) { + event_del(&l->ev); + } + env->sc_opts |= SMTPD_SMTP_PAUSED; +} + +void +smtp_resume(struct smtpd *env) +{ + struct listener *l; + + log_debug("smtp_pause_listeners: resuming listening sockets"); + TAILQ_FOREACH(l, &env->sc_listeners, entry) { + event_add(&l->ev, NULL); + } + env->sc_opts &= ~SMTPD_SMTP_PAUSED; +} + +void smtp_accept(int fd, short event, void *p) { int s_fd; diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c index 51a3c2c586e..534a3fe8235 100644 --- a/usr.sbin/smtpd/smtpctl.c +++ b/usr.sbin/smtpd/smtpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpctl.c,v 1.4 2009/01/04 19:37:41 gilles Exp $ */ +/* $OpenBSD: smtpctl.c,v 1.5 2009/01/04 22:35:09 gilles Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -139,16 +139,22 @@ connected: imsg_compose(ibuf, IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0); break; case PAUSE_MDA: - imsg_compose(ibuf, IMSG_RUNNER_PAUSE_MDA, 0, 0, -1, NULL, 0); + imsg_compose(ibuf, IMSG_MDA_PAUSE, 0, 0, -1, NULL, 0); break; case PAUSE_MTA: - imsg_compose(ibuf, IMSG_RUNNER_PAUSE_MTA, 0, 0, -1, NULL, 0); + imsg_compose(ibuf, IMSG_MTA_PAUSE, 0, 0, -1, NULL, 0); + break; + case PAUSE_SMTP: + imsg_compose(ibuf, IMSG_SMTP_PAUSE, 0, 0, -1, NULL, 0); break; case RESUME_MDA: - imsg_compose(ibuf, IMSG_RUNNER_RESUME_MDA, 0, 0, -1, NULL, 0); + imsg_compose(ibuf, IMSG_MDA_RESUME, 0, 0, -1, NULL, 0); break; case RESUME_MTA: - imsg_compose(ibuf, IMSG_RUNNER_RESUME_MTA, 0, 0, -1, NULL, 0); + imsg_compose(ibuf, IMSG_MDA_RESUME, 0, 0, -1, NULL, 0); + break; + case RESUME_SMTP: + imsg_compose(ibuf, IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0); break; case MONITOR: /* XXX */ @@ -177,8 +183,10 @@ connected: case SHUTDOWN: case PAUSE_MDA: case PAUSE_MTA: + case PAUSE_SMTP: case RESUME_MDA: case RESUME_MTA: + case RESUME_SMTP: done = show_command_output(&imsg); break; case NONE: diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 6ab7fb8122c..1954c79e6cb 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.43 2009/01/04 19:37:41 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.44 2009/01/04 22:35:09 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -192,10 +192,13 @@ enum imsg_type { IMSG_PARENT_AUTHENTICATE, - IMSG_RUNNER_PAUSE_MDA, - IMSG_RUNNER_PAUSE_MTA, - IMSG_RUNNER_RESUME_MDA, - IMSG_RUNNER_RESUME_MTA + IMSG_MDA_PAUSE, + IMSG_MTA_PAUSE, + IMSG_SMTP_PAUSE, + + IMSG_MDA_RESUME, + IMSG_MTA_RESUME, + IMSG_SMTP_RESUME }; #define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) @@ -592,6 +595,7 @@ struct smtpd { #define SMTPD_EXITING 0x00000002 #define SMTPD_MDA_PAUSED 0x00000004 #define SMTPD_MTA_PAUSED 0x00000008 +#define SMTPD_SMTP_PAUSED 0x00000010 u_int32_t sc_flags; struct timeval sc_qintval; struct event sc_ev; |