summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric <eric@openbsd.org>2014-07-08 15:45:32 +0000
committereric <eric@openbsd.org>2014-07-08 15:45:32 +0000
commit98f67d1688f1b9fc1ab749b00f67fbe7f50e49a3 (patch)
treef8a8e9f7be599fee14e2d5170c13cfc872a38163
parentremove dead code. these imsgs are handled in pony.c. (diff)
downloadwireguard-openbsd-98f67d1688f1b9fc1ab749b00f67fbe7f50e49a3.tar.xz
wireguard-openbsd-98f67d1688f1b9fc1ab749b00f67fbe7f50e49a3.zip
various queue improvements:
- add a "close" hook to the backend API. - improve the sync() pattern in queue_fs: only sync at commit time and not for every envelope creation - various fixes to the experimental external queue API.
-rw-r--r--usr.sbin/smtpd/queue.c3
-rw-r--r--usr.sbin/smtpd/queue_api.c73
-rw-r--r--usr.sbin/smtpd/queue_backend.c35
-rw-r--r--usr.sbin/smtpd/queue_fs.c9
-rw-r--r--usr.sbin/smtpd/queue_null.c4
-rw-r--r--usr.sbin/smtpd/queue_proc.c63
-rw-r--r--usr.sbin/smtpd/queue_ram.c4
-rw-r--r--usr.sbin/smtpd/smtpd-api.h7
-rw-r--r--usr.sbin/smtpd/smtpd.h5
9 files changed, 128 insertions, 75 deletions
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c
index 5f68ad86f86..4e26fe600c3 100644
--- a/usr.sbin/smtpd/queue.c
+++ b/usr.sbin/smtpd/queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.c,v 1.162 2014/04/19 13:40:24 gilles Exp $ */
+/* $OpenBSD: queue.c,v 1.163 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -561,6 +561,7 @@ static void
queue_shutdown(void)
{
log_info("info: queue handler exiting");
+ queue_close();
_exit(0);
}
diff --git a/usr.sbin/smtpd/queue_api.c b/usr.sbin/smtpd/queue_api.c
index 5c42537d236..80561410203 100644
--- a/usr.sbin/smtpd/queue_api.c
+++ b/usr.sbin/smtpd/queue_api.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_api.c,v 1.4 2014/04/19 17:47:40 gilles Exp $ */
+/* $OpenBSD: queue_api.c,v 1.5 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -31,6 +31,7 @@
#include "smtpd-api.h"
#include "log.h"
+static int (*handler_close)(void);
static int (*handler_message_create)(uint32_t *);
static int (*handler_message_commit)(uint32_t, const char *);
static int (*handler_message_delete)(uint32_t);
@@ -47,8 +48,8 @@ static struct imsg imsg;
static size_t rlen;
static char *rdata;
static struct ibuf *buf;
-static char *rootpath = PATH_SPOOL;
-static char *user = SMTPD_QUEUE_USER;
+static const char *rootpath = PATH_SPOOL;
+static const char *user = SMTPD_QUEUE_USER;
static void
queue_msg_get(void *dst, size_t len)
@@ -105,7 +106,7 @@ queue_msg_dispatch(void)
{
uint64_t evpid;
uint32_t msgid, version;
- size_t n;
+ size_t n, m;
char buffer[8192], path[SMTPD_MAXPATHLEN];
int r, fd;
FILE *ifile, *ofile;
@@ -123,6 +124,17 @@ queue_msg_dispatch(void)
imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, NULL, 0);
break;
+ case PROC_QUEUE_CLOSE:
+ queue_msg_end();
+
+ if (handler_close)
+ r = handler_close();
+ else
+ r = 1;
+
+ imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, &r, sizeof(r));
+ break;
+
case PROC_QUEUE_MESSAGE_CREATE:
queue_msg_end();
@@ -157,13 +169,20 @@ queue_msg_dispatch(void)
else {
ifile = fdopen(imsg.fd, "r");
ofile = fdopen(fd, "w");
+ m = n = 0;
if (ifile && ofile) {
while (!feof(ifile)) {
n = fread(buffer, 1, sizeof(buffer),
ifile);
- fwrite(buffer, 1, n, ofile);
+ m = fwrite(buffer, 1, n, ofile);
+ if (m != n)
+ break;
+ fflush(ofile);
}
- r = handler_message_commit(msgid, path);
+ if (m != n)
+ r = 0;
+ else
+ r = handler_message_commit(msgid, path);
}
if (ifile)
fclose(ifile);
@@ -242,6 +261,7 @@ queue_msg_dispatch(void)
queue_msg_add(buffer, r);
}
queue_msg_close();
+ break;
default:
log_warnx("warn: queue-api: bad message %d", imsg.hdr.type);
@@ -250,6 +270,12 @@ queue_msg_dispatch(void)
}
void
+queue_api_on_close(int(*cb)(void))
+{
+ handler_close = cb;
+}
+
+void
queue_api_on_message_create(int(*cb)(uint32_t *))
{
handler_message_create = cb;
@@ -309,16 +335,36 @@ queue_api_on_envelope_walk(int(*cb)(uint64_t *, char *, size_t))
handler_envelope_walk = cb;
}
+void
+queue_api_no_chroot(void)
+{
+ rootpath = NULL;
+}
+
+void
+queue_api_set_chroot(const char *path)
+{
+ rootpath = path;
+}
+
+void
+queue_api_set_user(const char *username)
+{
+ user = username;
+}
+
int
queue_api_dispatch(void)
{
- struct passwd *pw;
+ struct passwd *pw = NULL;
ssize_t n;
- pw = getpwnam(user);
- if (pw == NULL) {
- log_warn("queue-api: getpwnam");
- fatalx("queue-api: exiting");
+ if (user) {
+ pw = getpwnam(user);
+ if (pw == NULL) {
+ log_warn("queue-api: getpwnam");
+ fatalx("queue-api: exiting");
+ }
}
if (rootpath) {
@@ -332,9 +378,10 @@ queue_api_dispatch(void)
}
}
- if (setgroups(1, &pw->pw_gid) ||
+ if (pw &&
+ (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)) {
+ setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))) {
log_warn("queue-api: cannot drop privileges");
fatalx("queue-api: exiting");
}
diff --git a/usr.sbin/smtpd/queue_backend.c b/usr.sbin/smtpd/queue_backend.c
index 27a0ea56537..d70213cebbb 100644
--- a/usr.sbin/smtpd/queue_backend.c
+++ b/usr.sbin/smtpd/queue_backend.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_backend.c,v 1.51 2014/07/07 09:11:24 eric Exp $ */
+/* $OpenBSD: queue_backend.c,v 1.52 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
@@ -57,6 +57,7 @@ static struct tree evpcache_tree;
static struct evplst evpcache_list;
static struct queue_backend *backend;
+static int (*handler_close)(void);
static int (*handler_message_create)(uint32_t *);
static int (*handler_message_commit)(uint32_t, const char*);
static int (*handler_message_delete)(uint32_t);
@@ -122,17 +123,12 @@ queue_init(const char *name, int server)
if (!strcmp(name, "fs"))
backend = &queue_backend_fs;
- if (!strcmp(name, "null"))
+ else if (!strcmp(name, "null"))
backend = &queue_backend_null;
- if (!strcmp(name, "proc"))
- backend = &queue_backend_proc;
- if (!strcmp(name, "ram"))
+ else if (!strcmp(name, "ram"))
backend = &queue_backend_ram;
-
- if (backend == NULL) {
- log_warn("could not find queue backend \"%s\"", name);
- return (0);
- }
+ else
+ backend = &queue_backend_proc;
if (server) {
if (ckdir(PATH_SPOOL, 0711, 0, 0, 1) == 0)
@@ -148,7 +144,7 @@ queue_init(const char *name, int server)
errx(1, "error in purge directory setup");
}
- r = backend->init(pwq, server);
+ r = backend->init(pwq, server, name);
log_trace(TRACE_QUEUE, "queue-backend: queue_init(%d) -> %d", server, r);
@@ -156,6 +152,15 @@ queue_init(const char *name, int server)
}
int
+queue_close(void)
+{
+ if (handler_close)
+ return (handler_close());
+
+ return (1);
+}
+
+int
queue_message_create(uint32_t *msgid)
{
int r;
@@ -634,9 +639,9 @@ queue_envelope_walk(struct envelope *ep)
}
log_debug("debug: invalid envelope %016" PRIx64 ": %s",
ep->id, e);
+ (void)queue_message_corrupt(evpid_to_msgid(evpid));
}
- (void)queue_message_corrupt(evpid_to_msgid(evpid));
return (0);
}
@@ -690,6 +695,12 @@ envelope_validate(struct envelope *ep)
}
void
+queue_api_on_close(int(*cb)(void))
+{
+ handler_close = cb;
+}
+
+void
queue_api_on_message_create(int(*cb)(uint32_t *))
{
handler_message_create = cb;
diff --git a/usr.sbin/smtpd/queue_fs.c b/usr.sbin/smtpd/queue_fs.c
index 6bca248955d..2541e00c085 100644
--- a/usr.sbin/smtpd/queue_fs.c
+++ b/usr.sbin/smtpd/queue_fs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_fs.c,v 1.5 2014/04/19 13:48:57 gilles Exp $ */
+/* $OpenBSD: queue_fs.c,v 1.6 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
@@ -166,6 +166,9 @@ queue_fs_message_commit(uint32_t msgid, const char *path)
return 0;
}
+ /* best effort */
+ sync();
+
return 1;
}
@@ -263,7 +266,7 @@ queue_fs_envelope_create(uint32_t msgid, const char *buf, size_t len,
fsqueue_envelope_incoming_path(*evpid, path,
sizeof(path));
- r = fsqueue_envelope_dump(path, buf, len, 0, 1);
+ r = fsqueue_envelope_dump(path, buf, len, 0, 0);
if (r >= 0)
goto done;
}
@@ -615,7 +618,7 @@ fsqueue_qwalk(void *hdl, uint64_t *evpid)
}
static int
-queue_fs_init(struct passwd *pw, int server)
+queue_fs_init(struct passwd *pw, int server, const char *conf)
{
unsigned int n;
char *paths[] = { PATH_QUEUE, PATH_CORRUPT, PATH_INCOMING };
diff --git a/usr.sbin/smtpd/queue_null.c b/usr.sbin/smtpd/queue_null.c
index 31f87af0371..fcc52b845bb 100644
--- a/usr.sbin/smtpd/queue_null.c
+++ b/usr.sbin/smtpd/queue_null.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_null.c,v 1.4 2013/07/19 20:37:07 eric Exp $ */
+/* $OpenBSD: queue_null.c,v 1.5 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
@@ -104,7 +104,7 @@ queue_null_envelope_walk(uint64_t *evpid, char *buf, size_t len)
}
static int
-queue_null_init(struct passwd *pw, int server)
+queue_null_init(struct passwd *pw, int server, const char *conf)
{
queue_api_on_message_create(queue_null_message_create);
queue_api_on_message_commit(queue_null_message_commit);
diff --git a/usr.sbin/smtpd/queue_proc.c b/usr.sbin/smtpd/queue_proc.c
index 24efd905f96..da321715e16 100644
--- a/usr.sbin/smtpd/queue_proc.c
+++ b/usr.sbin/smtpd/queue_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_proc.c,v 1.2 2013/10/27 18:21:07 eric Exp $ */
+/* $OpenBSD: queue_proc.c,v 1.3 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -24,8 +24,6 @@
#include <sys/stat.h>
#include <ctype.h>
-#include <err.h>
-#include <errno.h>
#include <event.h>
#include <fcntl.h>
#include <imsg.h>
@@ -41,14 +39,11 @@
#include "smtpd.h"
#include "log.h"
-static pid_t pid;
static struct imsgbuf ibuf;
static struct imsg imsg;
static size_t rlen;
static char *rdata;
-static const char *execpath = "/usr/libexec/smtpd/backend-queue";
-
static void
queue_proc_call(void)
{
@@ -117,6 +112,20 @@ queue_proc_end(void)
*/
static int
+queue_proc_close(void)
+{
+ int r;
+
+ imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CORRUPT, 0, 0, -1, NULL, 0);
+
+ queue_proc_call();
+ queue_proc_read(&r, sizeof(r));
+ queue_proc_end();
+
+ return (r);
+}
+
+static int
queue_proc_message_create(uint32_t *msgid)
{
int r;
@@ -270,7 +279,7 @@ queue_proc_envelope_load(uint64_t evpid, char *buf, size_t len)
}
r = rlen;
- queue_proc_read(&buf, rlen);
+ queue_proc_read(buf, rlen);
queue_proc_end();
return (r);
@@ -296,7 +305,7 @@ queue_proc_envelope_walk(uint64_t *evpid, char *buf, size_t len)
log_warnx("warn: queue-proc: len mismatch");
fatalx("queue-proc: exiting");
}
- queue_proc_read(&buf, rlen);
+ queue_proc_read(buf, rlen);
}
queue_proc_end();
@@ -304,41 +313,22 @@ queue_proc_envelope_walk(uint64_t *evpid, char *buf, size_t len)
}
static int
-queue_proc_init(struct passwd *pw, int server)
+queue_proc_init(struct passwd *pw, int server, const char *conf)
{
- int sp[2];
uint32_t version;
+ int fd;
- errno = 0;
-
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
- log_warn("warn: queue-proc: socketpair");
- return (0);
- }
-
- if ((pid = fork()) == -1) {
- log_warn("warn: queue-proc: fork");
- goto err;
- }
-
- if (pid == 0) {
- /* child process */
- dup2(sp[0], STDIN_FILENO);
- if (closefrom(STDERR_FILENO + 1) < 0)
- exit(1);
-
- execl(execpath, "queue_ramproc", NULL);
- err(1, "execl");
- }
+ fd = fork_proc_backend("queue", conf, "queue-proc");
+ if (fd == -1)
+ fatalx("queue-proc: exiting");
- /* parent process */
- close(sp[0]);
- imsg_init(&ibuf, sp[1]);
+ imsg_init(&ibuf, fd);
version = PROC_QUEUE_API_VERSION;
imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1,
&version, sizeof(version));
+ queue_api_on_close(queue_proc_close);
queue_api_on_message_create(queue_proc_message_create);
queue_api_on_message_commit(queue_proc_message_commit);
queue_api_on_message_delete(queue_proc_message_delete);
@@ -354,11 +344,6 @@ queue_proc_init(struct passwd *pw, int server)
queue_proc_end();
return (1);
-
-err:
- close(sp[0]);
- close(sp[1]);
- return (0);
}
struct queue_backend queue_backend_proc = {
diff --git a/usr.sbin/smtpd/queue_ram.c b/usr.sbin/smtpd/queue_ram.c
index 41c7a39b17b..24f2f5cf381 100644
--- a/usr.sbin/smtpd/queue_ram.c
+++ b/usr.sbin/smtpd/queue_ram.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_ram.c,v 1.5 2013/07/19 20:37:07 eric Exp $ */
+/* $OpenBSD: queue_ram.c,v 1.6 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
@@ -318,7 +318,7 @@ queue_ram_envelope_walk(uint64_t *evpid, char *buf, size_t len)
}
static int
-queue_ram_init(struct passwd *pw, int server)
+queue_ram_init(struct passwd *pw, int server, const char * conf)
{
tree_init(&messages);
diff --git a/usr.sbin/smtpd/smtpd-api.h b/usr.sbin/smtpd/smtpd-api.h
index f1c9fc23d95..5b3629caf8a 100644
--- a/usr.sbin/smtpd/smtpd-api.h
+++ b/usr.sbin/smtpd/smtpd-api.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd-api.h,v 1.18 2014/07/08 14:24:16 eric Exp $ */
+/* $OpenBSD: smtpd-api.h,v 1.19 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -108,6 +108,7 @@ enum {
PROC_QUEUE_OK,
PROC_QUEUE_FAIL,
PROC_QUEUE_INIT,
+ PROC_QUEUE_CLOSE,
PROC_QUEUE_MESSAGE_CREATE,
PROC_QUEUE_MESSAGE_DELETE,
PROC_QUEUE_MESSAGE_COMMIT,
@@ -362,6 +363,7 @@ void filter_api_on_dataline(void(*)(uint64_t, const char *));
void filter_api_on_eom(int(*)(uint64_t, size_t));
/* queue */
+void queue_api_on_close(int(*)(void));
void queue_api_on_message_create(int(*)(uint32_t *));
void queue_api_on_message_commit(int(*)(uint32_t, const char*));
void queue_api_on_message_delete(int(*)(uint32_t));
@@ -372,6 +374,9 @@ void queue_api_on_envelope_delete(int(*)(uint64_t));
void queue_api_on_envelope_update(int(*)(uint64_t, const char *, size_t));
void queue_api_on_envelope_load(int(*)(uint64_t, char *, size_t));
void queue_api_on_envelope_walk(int(*)(uint64_t *, char *, size_t));
+void queue_api_no_chroot(void);
+void queue_api_set_chroot(const char *);
+void queue_api_set_user(const char *);
int queue_api_dispatch(void);
/* scheduler */
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index d39eb0e629e..b9148c88e5c 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.462 2014/07/08 13:49:09 eric Exp $ */
+/* $OpenBSD: smtpd.h,v 1.463 2014/07/08 15:45:32 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -832,7 +832,7 @@ struct mta_task {
struct passwd;
struct queue_backend {
- int (*init)(struct passwd *, int);
+ int (*init)(struct passwd *, int, const char *);
};
struct compress_backend {
@@ -1280,6 +1280,7 @@ void queue_flow_control(void);
uint32_t queue_generate_msgid(void);
uint64_t queue_generate_evpid(uint32_t);
int queue_init(const char *, int);
+int queue_close(void);
int queue_message_create(uint32_t *);
int queue_message_delete(uint32_t);
int queue_message_commit(uint32_t);