aboutsummaryrefslogtreecommitdiffstats
path: root/smtpd/queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'smtpd/queue.c')
-rw-r--r--smtpd/queue.c750
1 files changed, 0 insertions, 750 deletions
diff --git a/smtpd/queue.c b/smtpd/queue.c
deleted file mode 100644
index 434e3647..00000000
--- a/smtpd/queue.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* $OpenBSD: queue.c,v 1.190 2020/04/22 11:35:34 eric Exp $ */
-
-/*
- * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
- * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
- * Copyright (c) 2012 Eric Faurot <eric@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 "includes.h"
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <event.h>
-#include <fcntl.h>
-#include <grp.h> /* needed for setgroups */
-#include <imsg.h>
-#include <inttypes.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include "smtpd.h"
-#include "log.h"
-
-static void queue_imsg(struct mproc *, struct imsg *);
-static void queue_timeout(int, short, void *);
-static void queue_bounce(struct envelope *, struct delivery_bounce *);
-static void queue_shutdown(void);
-static void queue_log(const struct envelope *, const char *, const char *);
-static void queue_msgid_walk(int, short, void *);
-
-
-static void
-queue_imsg(struct mproc *p, struct imsg *imsg)
-{
- struct delivery_bounce bounce;
- struct msg_walkinfo *wi;
- struct timeval tv;
- struct bounce_req_msg *req_bounce;
- struct envelope evp;
- struct msg m;
- const char *reason;
- uint64_t reqid, evpid, holdq;
- uint32_t msgid;
- time_t nexttry;
- size_t n_evp;
- int fd, mta_ext, ret, v, flags, code;
-
- if (imsg == NULL)
- queue_shutdown();
-
- memset(&bounce, 0, sizeof(struct delivery_bounce));
-
- switch (imsg->hdr.type) {
- case IMSG_SMTP_MESSAGE_CREATE:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_end(&m);
-
- ret = queue_message_create(&msgid);
-
- m_create(p, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1);
- m_add_id(p, reqid);
- if (ret == 0)
- m_add_int(p, 0);
- else {
- m_add_int(p, 1);
- m_add_msgid(p, msgid);
- }
- m_close(p);
- return;
-
- case IMSG_SMTP_MESSAGE_ROLLBACK:
- m_msg(&m, imsg);
- m_get_msgid(&m, &msgid);
- m_end(&m);
-
- queue_message_delete(msgid);
-
- m_create(p_scheduler, IMSG_QUEUE_MESSAGE_ROLLBACK,
- 0, 0, -1);
- m_add_msgid(p_scheduler, msgid);
- m_close(p_scheduler);
- return;
-
- case IMSG_SMTP_MESSAGE_COMMIT:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_msgid(&m, &msgid);
- m_end(&m);
-
- ret = queue_message_commit(msgid);
-
- m_create(p, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1);
- m_add_id(p, reqid);
- m_add_int(p, (ret == 0) ? 0 : 1);
- m_close(p);
-
- if (ret) {
- m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT,
- 0, 0, -1);
- m_add_msgid(p_scheduler, msgid);
- m_close(p_scheduler);
- }
- return;
-
- case IMSG_SMTP_MESSAGE_OPEN:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_msgid(&m, &msgid);
- m_end(&m);
-
- fd = queue_message_fd_rw(msgid);
-
- m_create(p, IMSG_SMTP_MESSAGE_OPEN, 0, 0, fd);
- m_add_id(p, reqid);
- m_add_int(p, (fd == -1) ? 0 : 1);
- m_close(p);
- return;
-
- case IMSG_QUEUE_SMTP_SESSION:
- bounce_fd(imsg->fd);
- return;
-
- case IMSG_LKA_ENVELOPE_SUBMIT:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_envelope(&m, &evp);
- m_end(&m);
-
- if (evp.id == 0)
- log_warnx("warn: imsg_queue_submit_envelope: evpid=0");
- if (evpid_to_msgid(evp.id) == 0)
- log_warnx("warn: imsg_queue_submit_envelope: msgid=0, "
- "evpid=%016"PRIx64, evp.id);
- ret = queue_envelope_create(&evp);
- m_create(p_pony, IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
- m_add_id(p_pony, reqid);
- if (ret == 0)
- m_add_int(p_pony, 0);
- else {
- m_add_int(p_pony, 1);
- m_add_evpid(p_pony, evp.id);
- }
- m_close(p_pony);
- if (ret) {
- m_create(p_scheduler,
- IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
- m_add_envelope(p_scheduler, &evp);
- m_close(p_scheduler);
- }
- return;
-
- case IMSG_LKA_ENVELOPE_COMMIT:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_end(&m);
- m_create(p_pony, IMSG_QUEUE_ENVELOPE_COMMIT, 0, 0, -1);
- m_add_id(p_pony, reqid);
- m_add_int(p_pony, 1);
- m_close(p_pony);
- return;
-
- case IMSG_SCHED_ENVELOPE_REMOVE:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_end(&m);
-
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_ACK, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_close(p_scheduler);
-
- /* already removed by scheduler */
- if (queue_envelope_load(evpid, &evp) == 0)
- return;
-
- queue_log(&evp, "Remove", "Removed by administrator");
- queue_envelope_delete(evpid);
- return;
-
- case IMSG_SCHED_ENVELOPE_EXPIRE:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_end(&m);
-
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_ACK, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_close(p_scheduler);
-
- /* already removed by scheduler*/
- if (queue_envelope_load(evpid, &evp) == 0)
- return;
-
- bounce.type = B_FAILED;
- envelope_set_errormsg(&evp, "Envelope expired");
- envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
- envelope_set_esc_code(&evp, ESC_DELIVERY_TIME_EXPIRED);
- queue_bounce(&evp, &bounce);
- queue_log(&evp, "Expire", "Envelope expired");
- queue_envelope_delete(evpid);
- return;
-
- case IMSG_SCHED_ENVELOPE_BOUNCE:
- CHECK_IMSG_DATA_SIZE(imsg, sizeof *req_bounce);
- req_bounce = imsg->data;
- evpid = req_bounce->evpid;
-
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warnx("queue: bounce: failed to load envelope");
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_add_u32(p_scheduler, 0); /* not in-flight */
- m_close(p_scheduler);
- return;
- }
- queue_bounce(&evp, &req_bounce->bounce);
- evp.lastbounce = req_bounce->timestamp;
- if (!queue_envelope_update(&evp))
- log_warnx("warn: could not update envelope %016"PRIx64, evpid);
- return;
-
- case IMSG_SCHED_ENVELOPE_DELIVER:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_end(&m);
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warnx("queue: deliver: failed to load envelope");
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_add_u32(p_scheduler, 1); /* in-flight */
- m_close(p_scheduler);
- return;
- }
- evp.lasttry = time(NULL);
- m_create(p_pony, IMSG_QUEUE_DELIVER, 0, 0, -1);
- m_add_envelope(p_pony, &evp);
- m_close(p_pony);
- return;
-
- case IMSG_SCHED_ENVELOPE_INJECT:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_end(&m);
- bounce_add(evpid);
- return;
-
- case IMSG_SCHED_ENVELOPE_TRANSFER:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_end(&m);
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warnx("queue: failed to load envelope");
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_add_u32(p_scheduler, 1); /* in-flight */
- m_close(p_scheduler);
- return;
- }
- evp.lasttry = time(NULL);
- m_create(p_pony, IMSG_QUEUE_TRANSFER, 0, 0, -1);
- m_add_envelope(p_pony, &evp);
- m_close(p_pony);
- return;
-
- case IMSG_CTL_LIST_ENVELOPES:
- if (imsg->hdr.len == sizeof imsg->hdr) {
- m_forward(p_control, imsg);
- return;
- }
-
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_get_int(&m, &flags);
- m_get_time(&m, &nexttry);
- m_end(&m);
-
- if (queue_envelope_load(evpid, &evp) == 0)
- return; /* Envelope is gone, drop it */
-
- /*
- * XXX consistency: The envelope might already be on
- * its way back to the scheduler. We need to detect
- * this properly and report that state.
- */
- if (flags & EF_INFLIGHT) {
- /*
- * Not exactly correct but pretty close: The
- * value is not recorded on the envelope unless
- * a tempfail occurs.
- */
- evp.lasttry = nexttry;
- }
-
- m_create(p_control, IMSG_CTL_LIST_ENVELOPES,
- imsg->hdr.peerid, 0, -1);
- m_add_int(p_control, flags);
- m_add_time(p_control, nexttry);
- m_add_envelope(p_control, &evp);
- m_close(p_control);
- return;
-
- case IMSG_MDA_OPEN_MESSAGE:
- case IMSG_MTA_OPEN_MESSAGE:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_msgid(&m, &msgid);
- m_end(&m);
- fd = queue_message_fd_r(msgid);
- m_create(p, imsg->hdr.type, 0, 0, fd);
- m_add_id(p, reqid);
- m_close(p);
- return;
-
- case IMSG_MDA_DELIVERY_OK:
- case IMSG_MTA_DELIVERY_OK:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- if (imsg->hdr.type == IMSG_MTA_DELIVERY_OK)
- m_get_int(&m, &mta_ext);
- m_end(&m);
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warn("queue: dsn: failed to load envelope");
- return;
- }
- if (evp.dsn_notify & DSN_SUCCESS) {
- bounce.type = B_DELIVERED;
- bounce.dsn_ret = evp.dsn_ret;
- envelope_set_esc_class(&evp, ESC_STATUS_OK);
- if (imsg->hdr.type == IMSG_MDA_DELIVERY_OK)
- queue_bounce(&evp, &bounce);
- else if (imsg->hdr.type == IMSG_MTA_DELIVERY_OK &&
- (mta_ext & MTA_EXT_DSN) == 0) {
- bounce.mta_without_dsn = 1;
- queue_bounce(&evp, &bounce);
- }
- }
- queue_envelope_delete(evpid);
- m_create(p_scheduler, IMSG_QUEUE_DELIVERY_OK, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_close(p_scheduler);
- return;
-
- case IMSG_MDA_DELIVERY_TEMPFAIL:
- case IMSG_MTA_DELIVERY_TEMPFAIL:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_get_string(&m, &reason);
- m_get_int(&m, &code);
- m_end(&m);
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warnx("queue: tempfail: failed to load envelope");
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_add_u32(p_scheduler, 1); /* in-flight */
- m_close(p_scheduler);
- return;
- }
- envelope_set_errormsg(&evp, "%s", reason);
- envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
- envelope_set_esc_code(&evp, code);
- evp.retry++;
- if (!queue_envelope_update(&evp))
- log_warnx("warn: could not update envelope %016"PRIx64, evpid);
- m_create(p_scheduler, IMSG_QUEUE_DELIVERY_TEMPFAIL, 0, 0, -1);
- m_add_envelope(p_scheduler, &evp);
- m_close(p_scheduler);
- return;
-
- case IMSG_MDA_DELIVERY_PERMFAIL:
- case IMSG_MTA_DELIVERY_PERMFAIL:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_get_string(&m, &reason);
- m_get_int(&m, &code);
- m_end(&m);
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warnx("queue: permfail: failed to load envelope");
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_add_u32(p_scheduler, 1); /* in-flight */
- m_close(p_scheduler);
- return;
- }
- bounce.type = B_FAILED;
- envelope_set_errormsg(&evp, "%s", reason);
- envelope_set_esc_class(&evp, ESC_STATUS_PERMFAIL);
- envelope_set_esc_code(&evp, code);
- queue_bounce(&evp, &bounce);
- queue_envelope_delete(evpid);
- m_create(p_scheduler, IMSG_QUEUE_DELIVERY_PERMFAIL, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_close(p_scheduler);
- return;
-
- case IMSG_MDA_DELIVERY_LOOP:
- case IMSG_MTA_DELIVERY_LOOP:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_end(&m);
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warnx("queue: loop: failed to load envelope");
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
- m_add_evpid(p_scheduler, evpid);
- m_add_u32(p_scheduler, 1); /* in-flight */
- m_close(p_scheduler);
- return;
- }
- envelope_set_errormsg(&evp, "%s", "Loop detected");
- envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
- envelope_set_esc_code(&evp, ESC_ROUTING_LOOP_DETECTED);
- bounce.type = B_FAILED;
- queue_bounce(&evp, &bounce);
- queue_envelope_delete(evp.id);
- m_create(p_scheduler, IMSG_QUEUE_DELIVERY_LOOP, 0, 0, -1);
- m_add_evpid(p_scheduler, evp.id);
- m_close(p_scheduler);
- return;
-
- case IMSG_MTA_DELIVERY_HOLD:
- case IMSG_MDA_DELIVERY_HOLD:
- imsg->hdr.type = IMSG_QUEUE_HOLDQ_HOLD;
- m_forward(p_scheduler, imsg);
- return;
-
- case IMSG_MTA_SCHEDULE:
- imsg->hdr.type = IMSG_QUEUE_ENVELOPE_SCHEDULE;
- m_forward(p_scheduler, imsg);
- return;
-
- case IMSG_MTA_HOLDQ_RELEASE:
- case IMSG_MDA_HOLDQ_RELEASE:
- m_msg(&m, imsg);
- m_get_id(&m, &holdq);
- m_get_int(&m, &v);
- m_end(&m);
- m_create(p_scheduler, IMSG_QUEUE_HOLDQ_RELEASE, 0, 0, -1);
- if (imsg->hdr.type == IMSG_MTA_HOLDQ_RELEASE)
- m_add_int(p_scheduler, D_MTA);
- else
- m_add_int(p_scheduler, D_MDA);
- m_add_id(p_scheduler, holdq);
- m_add_int(p_scheduler, v);
- m_close(p_scheduler);
- return;
-
- case IMSG_CTL_PAUSE_MDA:
- case IMSG_CTL_PAUSE_MTA:
- case IMSG_CTL_RESUME_MDA:
- case IMSG_CTL_RESUME_MTA:
- m_forward(p_scheduler, imsg);
- return;
-
- case IMSG_CTL_VERBOSE:
- m_msg(&m, imsg);
- m_get_int(&m, &v);
- m_end(&m);
- log_trace_verbose(v);
- return;
-
- case IMSG_CTL_PROFILE:
- m_msg(&m, imsg);
- m_get_int(&m, &v);
- m_end(&m);
- profiling = v;
- return;
-
- case IMSG_CTL_DISCOVER_EVPID:
- m_msg(&m, imsg);
- m_get_evpid(&m, &evpid);
- m_end(&m);
- if (queue_envelope_load(evpid, &evp) == 0) {
- log_warnx("queue: discover: failed to load "
- "envelope %016" PRIx64, evpid);
- n_evp = 0;
- m_compose(p_control, imsg->hdr.type,
- imsg->hdr.peerid, 0, -1,
- &n_evp, sizeof n_evp);
- return;
- }
-
- m_create(p_scheduler, IMSG_QUEUE_DISCOVER_EVPID,
- 0, 0, -1);
- m_add_envelope(p_scheduler, &evp);
- m_close(p_scheduler);
-
- m_create(p_scheduler, IMSG_QUEUE_DISCOVER_MSGID,
- 0, 0, -1);
- m_add_msgid(p_scheduler, evpid_to_msgid(evpid));
- m_close(p_scheduler);
- n_evp = 1;
- m_compose(p_control, imsg->hdr.type, imsg->hdr.peerid,
- 0, -1, &n_evp, sizeof n_evp);
- return;
-
- case IMSG_CTL_DISCOVER_MSGID:
- m_msg(&m, imsg);
- m_get_msgid(&m, &msgid);
- m_end(&m);
- /* handle concurrent walk requests */
- wi = xcalloc(1, sizeof *wi);
- wi->msgid = msgid;
- wi->peerid = imsg->hdr.peerid;
- evtimer_set(&wi->ev, queue_msgid_walk, wi);
- tv.tv_sec = 0;
- tv.tv_usec = 10;
- evtimer_add(&wi->ev, &tv);
- return;
- }
-
- errx(1, "queue_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
-}
-
-static void
-queue_msgid_walk(int fd, short event, void *arg)
-{
- struct envelope evp;
- struct timeval tv;
- struct msg_walkinfo *wi = arg;
- int r;
-
- r = queue_message_walk(&evp, wi->msgid, &wi->done, &wi->data);
- if (r == -1) {
- if (wi->n_evp) {
- m_create(p_scheduler, IMSG_QUEUE_DISCOVER_MSGID,
- 0, 0, -1);
- m_add_msgid(p_scheduler, wi->msgid);
- m_close(p_scheduler);
- }
-
- m_compose(p_control, IMSG_CTL_DISCOVER_MSGID, wi->peerid, 0, -1,
- &wi->n_evp, sizeof wi->n_evp);
- evtimer_del(&wi->ev);
- free(wi);
- return;
- }
-
- if (r) {
- m_create(p_scheduler, IMSG_QUEUE_DISCOVER_EVPID, 0, 0, -1);
- m_add_envelope(p_scheduler, &evp);
- m_close(p_scheduler);
- wi->n_evp += 1;
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 10;
- evtimer_set(&wi->ev, queue_msgid_walk, wi);
- evtimer_add(&wi->ev, &tv);
-}
-
-static void
-queue_bounce(struct envelope *e, struct delivery_bounce *d)
-{
- struct envelope b;
-
- b = *e;
- b.type = D_BOUNCE;
- b.agent.bounce = *d;
- b.retry = 0;
- b.lasttry = 0;
- b.creation = time(NULL);
- b.ttl = 3600 * 24 * 7;
-
- if (e->dsn_notify & DSN_NEVER)
- return;
-
- if (b.id == 0)
- log_warnx("warn: queue_bounce: evpid=0");
- if (evpid_to_msgid(b.id) == 0)
- log_warnx("warn: queue_bounce: msgid=0, evpid=%016"PRIx64,
- b.id);
- if (e->type == D_BOUNCE) {
- log_warnx("warn: queue: double bounce!");
- } else if (e->sender.user[0] == '\0') {
- log_warnx("warn: queue: no return path!");
- } else if (!queue_envelope_create(&b)) {
- log_warnx("warn: queue: cannot bounce!");
- } else {
- log_debug("debug: queue: bouncing evp:%016" PRIx64
- " as evp:%016" PRIx64, e->id, b.id);
-
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
- m_add_envelope(p_scheduler, &b);
- m_close(p_scheduler);
-
- m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT, 0, 0, -1);
- m_add_msgid(p_scheduler, evpid_to_msgid(b.id));
- m_close(p_scheduler);
-
- stat_increment("queue.bounce", 1);
- }
-}
-
-static void
-queue_shutdown(void)
-{
- log_debug("debug: queue agent exiting");
- queue_close();
- _exit(0);
-}
-
-int
-queue(void)
-{
- struct passwd *pw;
- struct timeval tv;
- struct event ev_qload;
-
- purge_config(PURGE_EVERYTHING & ~PURGE_DISPATCHERS);
-
- if ((pw = getpwnam(SMTPD_QUEUE_USER)) == NULL)
- if ((pw = getpwnam(SMTPD_USER)) == NULL)
- fatalx("unknown user " SMTPD_USER);
-
- env->sc_queue_flags |= QUEUE_EVPCACHE;
- env->sc_queue_evpcache_size = 1024;
-
- if (chroot(PATH_SPOOL) == -1)
- fatal("queue: chroot");
- if (chdir("/") == -1)
- fatal("queue: chdir(\"/\")");
-
- config_process(PROC_QUEUE);
-
- if (env->sc_queue_flags & QUEUE_COMPRESSION)
- log_info("queue: queue compression enabled");
-
- if (env->sc_queue_key) {
- if (!crypto_setup(env->sc_queue_key, strlen(env->sc_queue_key)))
- fatalx("crypto_setup: invalid key for queue encryption");
- log_info("queue: queue encryption enabled");
- }
-
- 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("queue: cannot drop privileges");
-
- imsg_callback = queue_imsg;
- event_init();
-
- signal(SIGINT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
-
- config_peer(PROC_PARENT);
- config_peer(PROC_CONTROL);
- config_peer(PROC_LKA);
- config_peer(PROC_SCHEDULER);
- config_peer(PROC_PONY);
-
- /* setup queue loading task */
- evtimer_set(&ev_qload, queue_timeout, &ev_qload);
- tv.tv_sec = 0;
- tv.tv_usec = 10;
- evtimer_add(&ev_qload, &tv);
-
-#if HAVE_PLEDGE
- if (pledge("stdio rpath wpath cpath flock recvfd sendfd", NULL) == -1)
- err(1, "pledge");
-#endif
-
- event_dispatch();
- fatalx("exited event loop");
-
- return (0);
-}
-
-static void
-queue_timeout(int fd, short event, void *p)
-{
- static uint32_t msgid = 0;
- struct envelope evp;
- struct event *ev = p;
- struct timeval tv;
- int r;
-
- r = queue_envelope_walk(&evp);
- if (r == -1) {
- if (msgid) {
- m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT,
- 0, 0, -1);
- m_add_msgid(p_scheduler, msgid);
- m_close(p_scheduler);
- }
- log_debug("debug: queue: done loading queue into scheduler");
- return;
- }
-
- if (r) {
- if (msgid && evpid_to_msgid(evp.id) != msgid) {
- m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT,
- 0, 0, -1);
- m_add_msgid(p_scheduler, msgid);
- m_close(p_scheduler);
- }
- msgid = evpid_to_msgid(evp.id);
- m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
- m_add_envelope(p_scheduler, &evp);
- m_close(p_scheduler);
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 10;
- evtimer_add(ev, &tv);
-}
-
-static void
-queue_log(const struct envelope *e, const char *prefix, const char *status)
-{
- char rcpt[LINE_MAX];
-
- (void)strlcpy(rcpt, "-", sizeof rcpt);
- if (strcmp(e->rcpt.user, e->dest.user) ||
- strcmp(e->rcpt.domain, e->dest.domain))
- (void)snprintf(rcpt, sizeof rcpt, "%s@%s",
- e->rcpt.user, e->rcpt.domain);
-
- log_info("%s: %s for %016" PRIx64 ": from=<%s@%s>, to=<%s@%s>, "
- "rcpt=<%s>, delay=%s, stat=%s",
- e->type == D_MDA ? "delivery" : "relay",
- prefix,
- e->id, e->sender.user, e->sender.domain,
- e->dest.user, e->dest.domain,
- rcpt,
- duration_to_text(time(NULL) - e->creation),
- status);
-}