summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2011-04-15 17:01:06 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2011-04-15 17:01:06 +0000
commit90577f3ea3ac8dd575ea47a6cab5ca32ea6f379e (patch)
tree3a4f7b0efe70331a6e8a0c5ab18b1325bf438032 /usr.sbin
parentb36a9bc6cf702ad5f5f043755f100e39d0db2a83 (diff)
kill message_id and message_uid
smtpd now has an evpid associated to each delivery message, the evpid is an u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the envelope unique identifier for that message. this results in lots of space saved in both disk-based and ram-based queues, but also simplifies a lot of code. change has been stressed on my desktop, and has ran on my MX for the entire afternoon without a regression.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/smtpd/bounce.c8
-rw-r--r--usr.sbin/smtpd/mda.c6
-rw-r--r--usr.sbin/smtpd/mfa.c5
-rw-r--r--usr.sbin/smtpd/mta.c11
-rw-r--r--usr.sbin/smtpd/queue.c36
-rw-r--r--usr.sbin/smtpd/queue_backend.c32
-rw-r--r--usr.sbin/smtpd/queue_fsqueue.c167
-rw-r--r--usr.sbin/smtpd/queue_shared.c18
-rw-r--r--usr.sbin/smtpd/ramqueue.c17
-rw-r--r--usr.sbin/smtpd/runner.c74
-rw-r--r--usr.sbin/smtpd/smtp.c5
-rw-r--r--usr.sbin/smtpd/smtp_session.c23
-rw-r--r--usr.sbin/smtpd/smtpd.h34
-rw-r--r--usr.sbin/smtpd/util.c52
14 files changed, 290 insertions, 198 deletions
diff --git a/usr.sbin/smtpd/bounce.c b/usr.sbin/smtpd/bounce.c
index 7889f10f36b..6130e7d3c95 100644
--- a/usr.sbin/smtpd/bounce.c
+++ b/usr.sbin/smtpd/bounce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bounce.c,v 1.28 2011/04/14 21:53:45 gilles Exp $ */
+/* $OpenBSD: bounce.c,v 1.29 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org>
@@ -53,10 +53,12 @@ bounce_session(struct smtpd *env, int fd, struct message *messagep)
int msgfd = -1;
char *reason;
FILE *msgfp = NULL;
+ u_int32_t msgid;
+
+ msgid = evpid_to_msgid(messagep->evpid);
/* get message content */
- if ((msgfd = queue_message_fd_r(env, Q_QUEUE,
- messagep->message_id)) == -1)
+ if ((msgfd = queue_message_fd_r(env, Q_QUEUE, msgid)) == -1)
goto fail;
msgfp = fdopen(msgfd, "r");
if (msgfp == NULL)
diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c
index b4407200ecd..5ac6326286d 100644
--- a/usr.sbin/smtpd/mda.c
+++ b/usr.sbin/smtpd/mda.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mda.c,v 1.51 2010/11/28 14:35:58 gilles Exp $ */
+/* $OpenBSD: mda.c,v 1.52 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -212,8 +212,8 @@ mda_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
/* log status */
if (error && asprintf(&error, "Error (%s)", error) < 0)
fatal("mda: asprintf");
- log_info("%s: to=<%s@%s>, delay=%d, stat=%s",
- s->msg.message_id, path->user, path->domain,
+ log_info("%016llx: to=<%s@%s>, delay=%d, stat=%s",
+ s->msg.evpid, path->user, path->domain,
time(NULL) - s->msg.creation,
error ? error : "Sent");
free(error);
diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c
index e983086ce8e..72dac373691 100644
--- a/usr.sbin/smtpd/mfa.c
+++ b/usr.sbin/smtpd/mfa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfa.c,v 1.54 2010/11/28 14:35:58 gilles Exp $ */
+/* $OpenBSD: mfa.c,v 1.55 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -206,9 +206,6 @@ mfa_test_rcpt(struct smtpd *env, struct message *m)
{
struct submit_status ss;
- if (! valid_message_id(m->message_id))
- fatalx("mfa_test_rcpt: received corrupted message_id");
-
ss.id = m->session_id;
ss.code = 530;
ss.u.path = m->session_rcpt;
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index d37c3938cdd..24d20942a6a 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.101 2011/04/13 20:53:18 gilles Exp $ */
+/* $OpenBSD: mta.c,v 1.102 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -705,8 +705,8 @@ mta_message_log(struct mta_session *s, struct message *m)
struct mta_relay *relay = TAILQ_FIRST(&s->relays);
char *status = m->session_errorline;
- log_info("%s: to=<%s@%s>, delay=%d, relay=%s [%s], stat=%s (%s)",
- m->message_id, m->recipient.user,
+ log_info("%016llx: to=<%s@%s>, delay=%d, relay=%s [%s], stat=%s (%s)",
+ m->evpid, m->recipient.user,
m->recipient.domain, time(NULL) - m->creation,
relay ? relay->fqdn : "(none)",
relay ? ss_to_text(&relay->sa) : "",
@@ -749,9 +749,10 @@ mta_request_datafd(struct mta_session *s)
struct ramqueue_batch rq_batch;
struct message *m;
- rq_batch.b_id = s->id;
m = TAILQ_FIRST(&s->recipients);
- strlcpy(rq_batch.m_id, m->message_id, sizeof(rq_batch.m_id));
+
+ rq_batch.b_id = s->id;
+ rq_batch.msgid = evpid_to_msgid(m->evpid);
imsg_compose_event(s->env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_MESSAGE_FD,
0, 0, -1, &rq_batch, sizeof(rq_batch));
}
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c
index c18ab232e48..717ff2e14d2 100644
--- a/usr.sbin/smtpd/queue.c
+++ b/usr.sbin/smtpd/queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.c,v 1.98 2011/04/14 23:26:16 gilles Exp $ */
+/* $OpenBSD: queue.c,v 1.99 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -42,6 +42,9 @@ __dead void queue_shutdown(void);
void queue_sig_handler(int, short, void *);
void queue_purge(struct smtpd *, enum queue_kind, char *);
+u_int32_t filename_to_msgid(char *);
+u_int64_t filename_to_evpid(char *);
+
void
queue_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
@@ -57,11 +60,11 @@ queue_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
case IMSG_QUEUE_CREATE_MESSAGE:
ss.id = m->session_id;
ss.code = 250;
- bzero(ss.u.msgid, sizeof ss.u.msgid);
+ ss.u.msgid = 0;
if (m->flags & F_MESSAGE_ENQUEUED)
- ret = queue_message_create(env, Q_ENQUEUE, ss.u.msgid);
+ ret = queue_message_create(env, Q_ENQUEUE, &ss.u.msgid);
else
- ret = queue_message_create(env, Q_INCOMING, ss.u.msgid);
+ ret = queue_message_create(env, Q_INCOMING, &ss.u.msgid);
if (ret == 0)
ss.code = 421;
imsg_compose_event(iev, IMSG_QUEUE_CREATE_MESSAGE, 0, 0, -1,
@@ -70,20 +73,20 @@ queue_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
case IMSG_QUEUE_REMOVE_MESSAGE:
if (m->flags & F_MESSAGE_ENQUEUED)
- queue_message_purge(env, Q_ENQUEUE, m->message_id);
+ queue_message_purge(env, Q_ENQUEUE, evpid_to_msgid(m->evpid));
else
- queue_message_purge(env, Q_INCOMING, m->message_id);
+ queue_message_purge(env, Q_INCOMING, evpid_to_msgid(m->evpid));
return;
case IMSG_QUEUE_COMMIT_MESSAGE:
ss.id = m->session_id;
if (m->flags & F_MESSAGE_ENQUEUED) {
- if (queue_message_commit(env, Q_ENQUEUE, m->message_id))
+ if (queue_message_commit(env, Q_ENQUEUE, evpid_to_msgid(m->evpid)))
env->stats->queue.inserts_local++;
else
ss.code = 421;
} else {
- if (queue_message_commit(env, Q_INCOMING, m->message_id))
+ if (queue_message_commit(env, Q_INCOMING, evpid_to_msgid(m->evpid)))
env->stats->queue.inserts_remote++;
else
ss.code = 421;
@@ -99,9 +102,9 @@ queue_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
case IMSG_QUEUE_MESSAGE_FILE:
ss.id = m->session_id;
if (m->flags & F_MESSAGE_ENQUEUED)
- fd = queue_message_fd_rw(env, Q_ENQUEUE, m->message_id);
+ fd = queue_message_fd_rw(env, Q_ENQUEUE, evpid_to_msgid(m->evpid));
else
- fd = queue_message_fd_rw(env, Q_INCOMING, m->message_id);
+ fd = queue_message_fd_rw(env, Q_INCOMING, evpid_to_msgid(m->evpid));
if (fd == -1)
ss.code = 421;
imsg_compose_event(iev, IMSG_QUEUE_MESSAGE_FILE, 0, 0, fd,
@@ -163,7 +166,7 @@ queue_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
switch (imsg->hdr.type) {
case IMSG_QUEUE_MESSAGE_FD:
rq_batch = imsg->data;
- fd = queue_message_fd_r(env, Q_QUEUE, rq_batch->m_id);
+ fd = queue_message_fd_r(env, Q_QUEUE, rq_batch->msgid);
imsg_compose_event(iev, IMSG_QUEUE_MESSAGE_FD, 0, 0,
fd, rq_batch, sizeof *rq_batch);
return;
@@ -326,8 +329,15 @@ queue_purge(struct smtpd *env, enum queue_kind qkind, char *queuepath)
q = qwalk_new(queuepath);
- while (qwalk(q, path))
- queue_message_purge(env, qkind, basename(path));
+ while (qwalk(q, path)) {
+ u_int32_t msgid;
+
+ if ((msgid = filename_to_msgid(basename(path))) == 0) {
+ log_warnx("queue_purge: invalid evpid");
+ continue;
+ }
+ queue_message_purge(env, qkind, msgid);
+ }
qwalk_close(q);
}
diff --git a/usr.sbin/smtpd/queue_backend.c b/usr.sbin/smtpd/queue_backend.c
index 5d8a588055c..555a9d08d08 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.7 2011/04/14 23:26:16 gilles Exp $ */
+/* $OpenBSD: queue_backend.c,v 1.8 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -38,7 +38,7 @@
/* fsqueue backend */
int fsqueue_init(struct smtpd *);
int fsqueue_message(struct smtpd *, enum queue_kind,
- enum queue_op, char *);
+ enum queue_op, u_int32_t *);
int fsqueue_envelope(struct smtpd *, enum queue_kind,
enum queue_op , struct message *);
@@ -66,39 +66,39 @@ queue_backend_lookup(enum queue_type type)
}
int
-queue_message_create(struct smtpd *env, enum queue_kind qkind, char *msgid)
+queue_message_create(struct smtpd *env, enum queue_kind qkind, u_int32_t *msgid)
{
return env->sc_queue->message(env, qkind, QOP_CREATE, msgid);
}
int
-queue_message_delete(struct smtpd *env, enum queue_kind qkind, char *msgid)
+queue_message_delete(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
- return env->sc_queue->message(env, qkind, QOP_DELETE, msgid);
+ return env->sc_queue->message(env, qkind, QOP_DELETE, &msgid);
}
int
-queue_message_commit(struct smtpd *env, enum queue_kind qkind, char *msgid)
+queue_message_commit(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
- return env->sc_queue->message(env, qkind, QOP_COMMIT, msgid);
+ return env->sc_queue->message(env, qkind, QOP_COMMIT, &msgid);
}
int
-queue_message_purge(struct smtpd *env, enum queue_kind qkind, char *msgid)
+queue_message_purge(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
- return env->sc_queue->message(env, qkind, QOP_PURGE, msgid);
+ return env->sc_queue->message(env, qkind, QOP_PURGE, &msgid);
}
int
-queue_message_fd_r(struct smtpd *env, enum queue_kind qkind, char *msgid)
+queue_message_fd_r(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
- return env->sc_queue->message(env, qkind, QOP_FD_R, msgid);
+ return env->sc_queue->message(env, qkind, QOP_FD_R, &msgid);
}
int
-queue_message_fd_rw(struct smtpd *env, enum queue_kind qkind, char *msgid)
+queue_message_fd_rw(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
- return env->sc_queue->message(env, qkind, QOP_FD_RW, msgid);
+ return env->sc_queue->message(env, qkind, QOP_FD_RW, &msgid);
}
int
@@ -117,11 +117,9 @@ queue_envelope_delete(struct smtpd *env, enum queue_kind qkind,
int
queue_envelope_load(struct smtpd *env, enum queue_kind qkind,
- char *evpid, struct message *envelope)
+ u_int64_t evpid, struct message *envelope)
{
- if (strlcpy(envelope->message_uid, evpid, sizeof(envelope->message_uid))
- >= sizeof(envelope->message_uid))
- fatalx("queue_envelope_load: envelope ID truncation.");
+ envelope->evpid = evpid;
return env->sc_queue->envelope(env, qkind, QOP_LOAD, envelope);
}
diff --git a/usr.sbin/smtpd/queue_fsqueue.c b/usr.sbin/smtpd/queue_fsqueue.c
index 3bd722cd5d5..268c6dd6960 100644
--- a/usr.sbin/smtpd/queue_fsqueue.c
+++ b/usr.sbin/smtpd/queue_fsqueue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_fsqueue.c,v 1.7 2011/04/14 23:29:56 gilles Exp $ */
+/* $OpenBSD: queue_fsqueue.c,v 1.8 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -39,22 +39,22 @@
#include "log.h"
static char *fsqueue_getpath(enum queue_kind);
-/*static*/ u_int16_t fsqueue_hash(char *);
+/*static*/ u_int16_t fsqueue_hash(u_int32_t);
static int fsqueue_envelope_load(struct smtpd *, enum queue_kind, struct message *);
static int fsqueue_envelope_update(struct smtpd *, enum queue_kind, struct message *);
static int fsqueue_envelope_delete(struct smtpd *, enum queue_kind, struct message *);
-static int fsqueue_message_create(struct smtpd *, enum queue_kind, char *);
-static int fsqueue_message_commit(struct smtpd *, enum queue_kind, char *);
-static int fsqueue_message_fd_r(struct smtpd *, enum queue_kind, char *);
-static int fsqueue_message_fd_rw(struct smtpd *, enum queue_kind, char *);
-static int fsqueue_message_delete(struct smtpd *, enum queue_kind, char *);
-static int fsqueue_message_purge(struct smtpd *, enum queue_kind, char *);
+static int fsqueue_message_create(struct smtpd *, enum queue_kind, u_int32_t *);
+static int fsqueue_message_commit(struct smtpd *, enum queue_kind, u_int32_t);
+static int fsqueue_message_fd_r(struct smtpd *, enum queue_kind, u_int32_t);
+static int fsqueue_message_fd_rw(struct smtpd *, enum queue_kind, u_int32_t);
+static int fsqueue_message_delete(struct smtpd *, enum queue_kind, u_int32_t);
+static int fsqueue_message_purge(struct smtpd *, enum queue_kind, u_int32_t);
int fsqueue_init(struct smtpd *);
int fsqueue_message(struct smtpd *, enum queue_kind,
- enum queue_op, char *);
+ enum queue_op, u_int32_t *);
int fsqueue_envelope(struct smtpd *, enum queue_kind,
enum queue_op , struct message *);
@@ -87,13 +87,8 @@ fsqueue_getpath(enum queue_kind kind)
}
/*static*/ u_int16_t
-fsqueue_hash(char *msgid)
+fsqueue_hash(u_int32_t h)
{
- u_int16_t h;
-
- for (h = 5381; *msgid; msgid++)
- h = ((h << 5) + h) + *msgid;
-
return (h % DIRHASH_BUCKETS);
}
@@ -104,14 +99,21 @@ fsqueue_envelope_create(struct smtpd *env, enum queue_kind qkind,
char evpname[MAXPATHLEN];
FILE *fp;
int fd;
+ u_int32_t rnd;
+ u_int64_t evpid;
fp = NULL;
again:
- if (! bsnprintf(evpname, sizeof(evpname), "%s/%s%s/%s.%qu",
- fsqueue_getpath(qkind), envelope->message_id,
- PATH_ENVELOPES, envelope->message_id,
- (u_int64_t)arc4random()))
+ rnd = (u_int32_t)arc4random();
+ if (rnd == 0)
+ goto again;
+ evpid = envelope->evpid | rnd;
+
+ if (! bsnprintf(evpname, sizeof(evpname), "%s/%08x%s/%016llx",
+ fsqueue_getpath(qkind),
+ evpid_to_msgid(evpid),
+ PATH_ENVELOPES, evpid))
fatalx("fsqueue_envelope_create: snprintf");
fd = open(evpname, O_WRONLY|O_CREAT|O_EXCL, 0600);
@@ -128,9 +130,7 @@ again:
fatal("fsqueue_envelope_create: fdopen");
envelope->creation = time(NULL);
- if (strlcpy(envelope->message_uid, strrchr(evpname, '/') + 1,
- sizeof(envelope->message_uid)) >= sizeof(envelope->message_uid))
- fatalx("fsqueue_envelope_create: truncation");
+ envelope->evpid = evpid;
if (qkind == Q_BOUNCE) {
envelope->lasttry = 0;
@@ -158,7 +158,7 @@ tempfail:
else if (fd != -1)
close(fd);
envelope->creation = 0;
- envelope->message_uid[0] = '\0';
+ envelope->evpid = 0;
return 0;
}
@@ -168,16 +168,13 @@ fsqueue_envelope_load(struct smtpd *env, enum queue_kind qkind,
struct message *envelope)
{
char pathname[MAXPATHLEN];
- char msgid[MAX_ID_SIZE];
FILE *fp;
- if (strlcpy(msgid, envelope->message_uid, sizeof(msgid)) >= sizeof(msgid))
- return 0;
-
- *strrchr(msgid, '.') = '\0';
- if (! bsnprintf(pathname, sizeof(pathname), "%s/%d/%s%s/%s",
+ if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s/%016llx",
fsqueue_getpath(qkind),
- fsqueue_hash(msgid), msgid, PATH_ENVELOPES, envelope->message_uid))
+ fsqueue_hash(evpid_to_msgid(envelope->evpid)),
+ evpid_to_msgid(envelope->evpid),
+ PATH_ENVELOPES, envelope->evpid))
fatalx("fsqueue_envelope_load: snprintf");
fp = fopen(pathname, "r");
@@ -207,11 +204,11 @@ fsqueue_envelope_update(struct smtpd *env, enum queue_kind qkind,
if (! bsnprintf(temp, sizeof(temp), "%s/envelope.tmp", PATH_QUEUE))
fatalx("fsqueue_envelope_update");
- if (! bsnprintf(dest, sizeof(dest), "%s/%d/%s%s/%s",
+ if (! bsnprintf(dest, sizeof(dest), "%s/%04x/%08x%s/%016llx",
fsqueue_getpath(qkind),
- fsqueue_hash(envelope->message_id),
- envelope->message_id,
- PATH_ENVELOPES, envelope->message_uid))
+ fsqueue_hash(evpid_to_msgid(envelope->evpid)),
+ evpid_to_msgid(envelope->evpid),
+ PATH_ENVELOPES, envelope->evpid))
fatal("fsqueue_envelope_update: snprintf");
fp = fopen(temp, "w");
@@ -254,55 +251,58 @@ fsqueue_envelope_delete(struct smtpd *env, enum queue_kind qkind,
char pathname[MAXPATHLEN];
u_int16_t hval;
- hval = fsqueue_hash(envelope->message_id);
+ hval = fsqueue_hash(evpid_to_msgid(envelope->evpid));
- if (! bsnprintf(pathname, sizeof(pathname), "%s/%d/%s%s/%s",
+ if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s/%016llx",
fsqueue_getpath(qkind),
- hval, envelope->message_id, PATH_ENVELOPES,
- envelope->message_uid))
+ hval,
+ evpid_to_msgid(envelope->evpid),
+ PATH_ENVELOPES,
+ envelope->evpid))
fatal("fsqueue_envelope_delete: snprintf");
if (unlink(pathname) == -1)
fatal("fsqueue_envelope_delete: unlink");
- if (! bsnprintf(pathname, sizeof(pathname), "%s/%d/%s%s", PATH_QUEUE,
- hval, envelope->message_id, PATH_ENVELOPES))
+ if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s", PATH_QUEUE,
+ hval, evpid_to_msgid(envelope->evpid), PATH_ENVELOPES))
fatal("fsqueue_envelope_delete: snprintf");
if (rmdir(pathname) != -1)
- fsqueue_message_delete(env, qkind, envelope->message_id);
+ fsqueue_message_delete(env, qkind, evpid_to_msgid(envelope->evpid));
return 1;
}
static int
-fsqueue_message_create(struct smtpd *env, enum queue_kind qkind, char *msgid)
+fsqueue_message_create(struct smtpd *env, enum queue_kind qkind, u_int32_t *msgid)
{
char rootdir[MAXPATHLEN];
char evpdir[MAXPATHLEN];
char *queuepath = fsqueue_getpath(qkind);
char msgpath[MAXPATHLEN];
char lnkpath[MAXPATHLEN];
- char msgid_save[MAX_ID_SIZE];
+ u_int32_t msgid_save;
- strlcpy(msgid_save, msgid, sizeof(msgid_save));
+ msgid_save = *msgid;
- if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%d.XXXXXXXXXXXXXXXX",
- queuepath, time(NULL)))
+again:
+ *msgid = (u_int32_t)arc4random();
+ if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%08x",
+ queuepath, *msgid))
fatalx("fsqueue_message_create: snprintf");
- if (mkdtemp(rootdir) == NULL) {
+ if (mkdir(rootdir, 0700) == -1) {
+ if (errno == EEXIST)
+ goto again;
+
if (errno == ENOSPC) {
- bzero(msgid, MAX_ID_SIZE);
+ *msgid = 0;
return 0;
}
- fatal("fsqueue_message_create: mkdtemp");
+ fatal("fsqueue_message_create: mkdir");
}
- if (strlcpy(msgid, rootdir + strlen(queuepath) + 1, MAX_ID_SIZE)
- >= MAX_ID_SIZE)
- fatalx("fsqueue_message_create: truncation");
-
if (! bsnprintf(evpdir, sizeof(evpdir), "%s%s", rootdir,
PATH_ENVELOPES))
fatalx("fsqueue_message_create: snprintf");
@@ -310,20 +310,21 @@ fsqueue_message_create(struct smtpd *env, enum queue_kind qkind, char *msgid)
if (mkdir(evpdir, 0700) == -1) {
if (errno == ENOSPC) {
rmdir(rootdir);
- bzero(msgid, MAX_ID_SIZE);
+ *msgid = 0;
return 0;
}
fatal("fsqueue_message_create: mkdir");
}
if (qkind == Q_BOUNCE) {
- if (! bsnprintf(msgpath, sizeof(msgpath), "%s/%d/%s/message",
+ if (! bsnprintf(msgpath, sizeof(msgpath), "%s/%04x/%08x/message",
fsqueue_getpath(Q_QUEUE),
- fsqueue_hash(msgid_save), msgid_save))
+ fsqueue_hash(msgid_save),
+ msgid_save))
return 0;
- if (! bsnprintf(lnkpath, sizeof(lnkpath), "%s/%s/message",
- fsqueue_getpath(Q_BOUNCE), msgid))
+ if (! bsnprintf(lnkpath, sizeof(lnkpath), "%s/%08x/message",
+ fsqueue_getpath(Q_BOUNCE), *msgid))
return 0;
if (link(msgpath, lnkpath) == -1)
@@ -334,16 +335,17 @@ fsqueue_message_create(struct smtpd *env, enum queue_kind qkind, char *msgid)
}
static int
-fsqueue_message_commit(struct smtpd *env, enum queue_kind qkind, char *msgid)
+fsqueue_message_commit(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
char rootdir[MAXPATHLEN];
char queuedir[MAXPATHLEN];
+ char msgdir[MAXPATHLEN];
- if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%s",
+ if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%08x",
fsqueue_getpath(qkind), msgid))
fatal("fsqueue_message_commit: snprintf");
- if (! bsnprintf(queuedir, sizeof(queuedir), "%s/%d",
+ if (! bsnprintf(queuedir, sizeof(queuedir), "%s/%04x",
fsqueue_getpath(Q_QUEUE), fsqueue_hash(msgid)))
fatal("fsqueue_message_commit: snprintf");
@@ -354,12 +356,11 @@ fsqueue_message_commit(struct smtpd *env, enum queue_kind qkind, char *msgid)
fatal("fsqueue_message_commit: mkdir");
}
- if (strlcat(queuedir, "/", sizeof(queuedir)) >= sizeof(queuedir) ||
- strlcat(queuedir, msgid, sizeof(queuedir)) >=
- sizeof(queuedir))
- fatalx("fsqueue_message_commit: truncation");
+ if (! bsnprintf(msgdir, sizeof(msgdir),"%s/%08x",
+ queuedir, msgid))
+ fatal("fsqueue_message_commit: snprintf");
- if (rename(rootdir, queuedir) == -1) {
+ if (rename(rootdir, msgdir) == -1) {
if (errno == ENOSPC)
return 0;
fatal("fsqueue_message_commit: rename");
@@ -369,20 +370,20 @@ fsqueue_message_commit(struct smtpd *env, enum queue_kind qkind, char *msgid)
}
static int
-fsqueue_message_fd_r(struct smtpd *env, enum queue_kind qkind, char *msgid)
+fsqueue_message_fd_r(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
int fd;
char pathname[MAXPATHLEN];
u_int16_t hval;
if (qkind == Q_ENQUEUE || qkind == Q_INCOMING) {
- if (! bsnprintf(pathname, sizeof(pathname), "%s/%s/message",
+ if (! bsnprintf(pathname, sizeof(pathname), "%s/%08x/message",
fsqueue_getpath(qkind), msgid))
fatal("fsqueue_message_fd_r: snprintf");
}
else {
hval = fsqueue_hash(msgid);
- if (! bsnprintf(pathname, sizeof(pathname), "%s/%d/%s/message",
+ if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x/message",
fsqueue_getpath(qkind), hval, msgid))
fatal("fsqueue_message_fd_r: snprintf");
}
@@ -394,11 +395,11 @@ fsqueue_message_fd_r(struct smtpd *env, enum queue_kind qkind, char *msgid)
}
static int
-fsqueue_message_fd_rw(struct smtpd *env, enum queue_kind qkind, char *msgid)
+fsqueue_message_fd_rw(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
char pathname[MAXPATHLEN];
- if (! bsnprintf(pathname, sizeof(pathname), "%s/%s/message",
+ if (! bsnprintf(pathname, sizeof(pathname), "%s/%08x/message",
fsqueue_getpath(qkind),
msgid))
fatal("fsqueue_message_fd_rw: snprintf");
@@ -407,7 +408,7 @@ fsqueue_message_fd_rw(struct smtpd *env, enum queue_kind qkind, char *msgid)
}
static int
-fsqueue_message_delete(struct smtpd *env, enum queue_kind qkind, char *msgid)
+fsqueue_message_delete(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
char rootdir[MAXPATHLEN];
char evpdir[MAXPATHLEN];
@@ -415,7 +416,7 @@ fsqueue_message_delete(struct smtpd *env, enum queue_kind qkind, char *msgid)
u_int16_t hval;
hval = fsqueue_hash(msgid);
- if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%d/%s", PATH_QUEUE,
+ if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%04x/%08x", PATH_QUEUE,
hval, msgid))
fatal("queue_delete_message: snprintf");
@@ -441,7 +442,7 @@ fsqueue_message_delete(struct smtpd *env, enum queue_kind qkind, char *msgid)
if (rmdir(rootdir) == -1)
fatal("#2 queue_delete_message: rmdir");
- if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%d", PATH_QUEUE, hval))
+ if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%04x", PATH_QUEUE, hval))
fatal("queue_delete_message: snprintf");
rmdir(rootdir);
@@ -450,16 +451,16 @@ fsqueue_message_delete(struct smtpd *env, enum queue_kind qkind, char *msgid)
}
static int
-fsqueue_message_purge(struct smtpd *env, enum queue_kind qkind, char *msgid)
+fsqueue_message_purge(struct smtpd *env, enum queue_kind qkind, u_int32_t msgid)
{
char rootdir[MAXPATHLEN];
char purgedir[MAXPATHLEN];
- if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%s",
+ if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%08x",
fsqueue_getpath(qkind), msgid))
fatalx("fsqueue_message_purge: snprintf");
- if (! bsnprintf(purgedir, sizeof(purgedir), "%s/%s",
+ if (! bsnprintf(purgedir, sizeof(purgedir), "%s/%08x",
fsqueue_getpath(Q_PURGE), msgid))
fatalx("fsqueue_message_purge: snprintf");
@@ -601,26 +602,26 @@ fsqueue_init(struct smtpd *env)
int
fsqueue_message(struct smtpd *env, enum queue_kind qkind,
- enum queue_op qop, char *msgid)
+ enum queue_op qop, u_int32_t *msgid)
{
switch (qop) {
case QOP_CREATE:
return fsqueue_message_create(env, qkind, msgid);
case QOP_DELETE:
- return fsqueue_message_delete(env, qkind, msgid);
+ return fsqueue_message_delete(env, qkind, *msgid);
case QOP_COMMIT:
- return fsqueue_message_commit(env, qkind, msgid);
+ return fsqueue_message_commit(env, qkind, *msgid);
case QOP_FD_R:
- return fsqueue_message_fd_r(env, qkind, msgid);
+ return fsqueue_message_fd_r(env, qkind, *msgid);
case QOP_FD_RW:
- return fsqueue_message_fd_rw(env, qkind, msgid);
+ return fsqueue_message_fd_rw(env, qkind, *msgid);
case QOP_PURGE:
- return fsqueue_message_purge(env, qkind, msgid);
+ return fsqueue_message_purge(env, qkind, *msgid);
default:
fatalx("queue_fsqueue_message: unsupported operation.");
diff --git a/usr.sbin/smtpd/queue_shared.c b/usr.sbin/smtpd/queue_shared.c
index ff6dbc4879f..ef53b026b60 100644
--- a/usr.sbin/smtpd/queue_shared.c
+++ b/usr.sbin/smtpd/queue_shared.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_shared.c,v 1.43 2011/04/14 23:29:56 gilles Exp $ */
+/* $OpenBSD: queue_shared.c,v 1.44 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -61,7 +61,7 @@ void getflag(u_int *, int, char *, char *, size_t);
int
bounce_record_message(struct smtpd *env, struct message *messagep, struct message *mbounce)
{
- char msgid[MAX_ID_SIZE];
+ u_int32_t msgid;
if (messagep->type == T_BOUNCE_MESSAGE) {
log_debug("mailer daemons loop detected !");
@@ -72,11 +72,11 @@ bounce_record_message(struct smtpd *env, struct message *messagep, struct messag
mbounce->type = T_BOUNCE_MESSAGE;
mbounce->status &= ~S_MESSAGE_PERMFAILURE;
- strlcpy(msgid, messagep->message_id, sizeof(msgid));
- if (! queue_message_create(env, Q_BOUNCE, msgid))
+ msgid = evpid_to_msgid(messagep->evpid);
+ if (! queue_message_create(env, Q_BOUNCE, &msgid))
return 0;
- strlcpy(mbounce->message_id, msgid, sizeof(mbounce->message_id));
+ mbounce->evpid = msgid_to_evpid(msgid);
if (! queue_envelope_create(env, Q_BOUNCE, mbounce))
return 0;
@@ -283,7 +283,7 @@ display_envelope(struct message *envelope, int flags)
status, sizeof(status));
if (envelope->status)
- errx(1, "%s: unexpected status 0x%04x", envelope->message_uid,
+ errx(1, "%016llx: unexpected status 0x%04x", envelope->evpid,
envelope->status);
getflag(&envelope->flags, F_MESSAGE_BOUNCE, "BOUNCE",
@@ -300,7 +300,7 @@ display_envelope(struct message *envelope, int flags)
status, sizeof(status));
if (envelope->flags)
- errx(1, "%s: unexpected flags 0x%04x", envelope->message_uid,
+ errx(1, "%016llx: unexpected flags 0x%04x", envelope->evpid,
envelope->flags);
if (status[0])
@@ -322,8 +322,8 @@ display_envelope(struct message *envelope, int flags)
printf("UNKNOWN");
}
- printf("|%s|%s|%s@%s|%s@%s|%d|%d|%u",
- envelope->message_uid,
+ printf("|%016llx|%s|%s@%s|%s@%s|%d|%d|%u",
+ envelope->evpid,
status,
envelope->sender.user, envelope->sender.domain,
envelope->recipient.user, envelope->recipient.domain,
diff --git a/usr.sbin/smtpd/ramqueue.c b/usr.sbin/smtpd/ramqueue.c
index db57552935a..9045956d6e1 100644
--- a/usr.sbin/smtpd/ramqueue.c
+++ b/usr.sbin/smtpd/ramqueue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ramqueue.c,v 1.3 2011/04/14 22:36:09 gilles Exp $ */
+/* $OpenBSD: ramqueue.c,v 1.4 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -49,6 +49,8 @@ void ramqueue_put_host(struct ramqueue *, struct ramqueue_host *);
void ramqueue_put_batch(struct ramqueue *, struct ramqueue_batch *);
int ramqueue_load_offline(struct ramqueue *);
+u_int32_t filename_to_msgid(char *);
+u_int64_t filename_to_evpid(char *);
void
ramqueue_init(struct smtpd *env, struct ramqueue *rqueue)
@@ -138,10 +140,15 @@ ramqueue_load(struct ramqueue *rqueue, time_t *nsched)
if (q == NULL)
q = qwalk_new(PATH_QUEUE);
while (qwalk(q, path)) {
+ u_int64_t evpid;
+
curtm = time(NULL);
+ if ((evpid = filename_to_evpid(basename(path))) == 0)
+ continue;
+
if (! queue_envelope_load(rqueue->env, Q_QUEUE,
- basename(path), &envelope))
+ evpid, &envelope))
continue;
if (ramqueue_expire(rqueue->env, &envelope, curtm))
continue;
@@ -170,7 +177,7 @@ ramqueue_insert(struct ramqueue *rqueue, struct message *envelope, time_t curtm)
rq_evp = calloc(1, sizeof (*rq_evp));
if (rq_evp == NULL)
fatal("calloc");
- strlcpy(rq_evp->id, envelope->message_uid, sizeof(rq_evp->id));
+ rq_evp->evpid = envelope->evpid;
rq_evp->sched = ramqueue_next_schedule(envelope, curtm);
rq_evp->host = ramqueue_get_host(rqueue, envelope->recipient.domain);
rq_evp->batch = ramqueue_get_batch(rqueue, rq_evp->host, envelope);
@@ -295,7 +302,7 @@ ramqueue_get_batch(struct ramqueue *rqueue, struct ramqueue_host *host,
struct ramqueue_batch *rq_batch;
TAILQ_FOREACH(rq_batch, &host->batch_queue, batch_entry) {
- if (strcmp(rq_batch->m_id, envelope->message_id) == 0)
+ if (rq_batch->msgid == (u_int32_t)(envelope->evpid >> 32))
return rq_batch;
}
@@ -305,7 +312,7 @@ ramqueue_get_batch(struct ramqueue *rqueue, struct ramqueue_host *host,
rq_batch->b_id = generate_uid();
rq_batch->type = envelope->type;
rq_batch->rule = envelope->recipient.rule;
- strlcpy(rq_batch->m_id, envelope->message_id, sizeof(rq_batch->m_id));
+ rq_batch->msgid = envelope->evpid >> 32;
TAILQ_INIT(&rq_batch->envelope_queue);
TAILQ_INSERT_TAIL(&host->batch_queue, rq_batch, batch_entry);
diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c
index f2fbcc7aaaf..013bfda8b57 100644
--- a/usr.sbin/smtpd/runner.c
+++ b/usr.sbin/smtpd/runner.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: runner.c,v 1.101 2011/04/15 11:39:57 gilles Exp $ */
+/* $OpenBSD: runner.c,v 1.102 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -54,14 +54,18 @@ int runner_process_envelope(struct smtpd *, struct ramqueue_envelope *, time_t)
void runner_process_batch(struct smtpd *, struct ramqueue_envelope *, time_t);
void runner_purge_run(void);
-void runner_purge_message(char *);
+void runner_purge_message(u_int32_t);
int runner_check_loop(struct smtpd *, struct message *);
-int runner_force_message_to_ramqueue(struct ramqueue *, char *);
+int runner_force_message_to_ramqueue(struct ramqueue *, u_int32_t);
void ramqueue_insert(struct ramqueue *, struct message *, time_t);
-/*temporary*/ u_int16_t fsqueue_hash(char *);
+
+/*temporary*/
+u_int16_t fsqueue_hash(u_int32_t);
+u_int64_t filename_to_evpid(char *);
+u_int32_t filename_to_msgid(char *);
void
runner_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
@@ -71,7 +75,7 @@ runner_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
switch (imsg->hdr.type) {
case IMSG_QUEUE_COMMIT_MESSAGE:
m = imsg->data;
- runner_force_message_to_ramqueue(&env->sc_rqueue, m->message_id);
+ runner_force_message_to_ramqueue(&env->sc_rqueue, m->evpid>>32);
runner_setup_events(env);
return;
@@ -340,7 +344,7 @@ runner_process_envelope(struct smtpd *env, struct ramqueue_envelope *rq_evp, tim
mda_av = env->sc_maxconn - env->stats->mda.sessions_active;
bnc_av = env->sc_maxconn - env->stats->runner.bounces_active;
- if (! queue_envelope_load(env, Q_QUEUE, rq_evp->id, &envelope))
+ if (! queue_envelope_load(env, Q_QUEUE, rq_evp->evpid, &envelope))
return 0;
if (envelope.type & T_MDA_MESSAGE) {
@@ -375,10 +379,10 @@ runner_process_envelope(struct smtpd *env, struct ramqueue_envelope *rq_evp, tim
return 0;
}
- log_debug("dispatching host: %p, batch: %p, envelope: %p, %s",
+ log_debug("dispatching host: %p, batch: %p, envelope: %p, %016llx",
rq_evp->host,
rq_evp->batch,
- rq_evp, rq_evp->id);
+ rq_evp, rq_evp->evpid);
runner_process_batch(env, rq_evp, curtm);
return 1;
@@ -396,7 +400,7 @@ runner_process_batch(struct smtpd *env, struct ramqueue_envelope *rq_evp, time_t
switch (batch->type) {
case T_BOUNCE_MESSAGE:
while ((rq_evp = ramqueue_batch_first_envelope(batch))) {
- if (! queue_envelope_load(env, Q_QUEUE, rq_evp->id,
+ if (! queue_envelope_load(env, Q_QUEUE, rq_evp->evpid,
&envelope))
return;
envelope.lasttry = curtm;
@@ -418,11 +422,11 @@ runner_process_batch(struct smtpd *env, struct ramqueue_envelope *rq_evp, time_t
case T_MDA_MESSAGE:
rq_evp = ramqueue_batch_first_envelope(batch);
- if (! queue_envelope_load(env, Q_QUEUE, rq_evp->id,
+ if (! queue_envelope_load(env, Q_QUEUE, rq_evp->evpid,
&envelope))
return;
envelope.lasttry = curtm;
- fd = queue_message_fd_r(env, Q_QUEUE, rq_evp->batch->m_id);
+ fd = queue_message_fd_r(env, Q_QUEUE, rq_evp->evpid>>32);
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_MDA_SESS_NEW, PROC_MDA, 0, fd, &envelope,
sizeof envelope);
@@ -443,7 +447,7 @@ runner_process_batch(struct smtpd *env, struct ramqueue_envelope *rq_evp, time_t
IMSG_BATCH_CREATE, PROC_MTA, 0, -1, batch,
sizeof *batch);
while ((rq_evp = ramqueue_batch_first_envelope(batch))) {
- if (! queue_envelope_load(env, Q_QUEUE, rq_evp->id,
+ if (! queue_envelope_load(env, Q_QUEUE, rq_evp->evpid,
&envelope))
return;
envelope.lasttry = curtm;
@@ -486,7 +490,7 @@ runner_process_batch(struct smtpd *env, struct ramqueue_envelope *rq_evp, time_t
/* XXX - temporary solution */
int
-runner_force_message_to_ramqueue(struct ramqueue *rqueue, char *mid)
+runner_force_message_to_ramqueue(struct ramqueue *rqueue, u_int32_t msgid)
{
char path[MAXPATHLEN];
DIR *dirp;
@@ -494,8 +498,8 @@ runner_force_message_to_ramqueue(struct ramqueue *rqueue, char *mid)
struct message envelope;
time_t curtm;
- if (! bsnprintf(path, MAXPATHLEN, "%s/%d/%s/envelopes",
- PATH_QUEUE, fsqueue_hash(mid), mid))
+ if (! bsnprintf(path, MAXPATHLEN, "%s/%04x/%08x/envelopes",
+ PATH_QUEUE, fsqueue_hash(msgid), msgid))
return 0;
dirp = opendir(path);
@@ -504,12 +508,20 @@ runner_force_message_to_ramqueue(struct ramqueue *rqueue, char *mid)
curtm = time(NULL);
while ((dp = readdir(dirp)) != NULL) {
- if (valid_message_uid(dp->d_name)) {
- if (! queue_envelope_load(rqueue->env, Q_QUEUE, dp->d_name,
- &envelope))
- continue;
- ramqueue_insert(rqueue, &envelope, curtm);
+ u_int64_t evpid;
+
+ if (dp->d_name[0] == '.')
+ continue;
+
+ if ((evpid = filename_to_evpid(dp->d_name)) == 0) {
+ log_warnx("runner_force_message_to_ramqueue: invalid evpid: %016llx", evpid);
+ continue;
}
+
+ if (! queue_envelope_load(rqueue->env, Q_QUEUE, evpid,
+ &envelope))
+ continue;
+ ramqueue_insert(rqueue, &envelope, curtm);
}
closedir(dirp);
@@ -524,14 +536,26 @@ runner_purge_run(void)
q = qwalk_new(PATH_PURGE);
- while (qwalk(q, path))
- runner_purge_message(basename(path));
+ while (qwalk(q, path)) {
+ u_int32_t msgid;
+ char *bpath;
+
+ bpath = basename(path);
+ if (bpath[0] == '.')
+ continue;
+
+ if ((msgid = filename_to_msgid(bpath)) == 0) {
+ log_warnx("runner_purge_run: invalid msgid: %08x", msgid);
+ continue;
+ }
+ runner_purge_message(msgid);
+ }
qwalk_close(q);
}
void
-runner_purge_message(char *msgid)
+runner_purge_message(u_int32_t msgid)
{
char rootdir[MAXPATHLEN];
char evpdir[MAXPATHLEN];
@@ -540,7 +564,7 @@ runner_purge_message(char *msgid)
DIR *dirp;
struct dirent *dp;
- if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%s", PATH_PURGE, msgid))
+ if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%08x", PATH_PURGE, msgid))
fatal("runner_purge_message: snprintf");
if (! bsnprintf(evpdir, sizeof(evpdir), "%s%s", rootdir,
@@ -595,7 +619,7 @@ runner_check_loop(struct smtpd *env, struct message *messagep)
int ret = 0;
int rcvcount = 0;
- fd = queue_message_fd_r(env, Q_QUEUE, messagep->message_id);
+ fd = queue_message_fd_r(env, Q_QUEUE, messagep->evpid>>32);
if ((fp = fdopen(fd, "r")) == NULL)
fatal("fdopen");
diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c
index 83e126c77ff..1908db95caa 100644
--- a/usr.sbin/smtpd/smtp.c
+++ b/usr.sbin/smtpd/smtp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.c,v 1.81 2011/03/15 19:24:55 gilles Exp $ */
+/* $OpenBSD: smtp.c,v 1.82 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -99,8 +99,7 @@ smtp_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
s = session_lookup(env, ss->id);
if (s == NULL)
return;
- strlcpy(s->s_msg.message_id, ss->u.msgid,
- sizeof s->s_msg.message_id);
+ s->s_msg.evpid = (u_int64_t)ss->u.msgid << 32;
session_pickup(s, ss);
return;
diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c
index cd24c54d2ce..b9669e26aa5 100644
--- a/usr.sbin/smtpd/smtp_session.c
+++ b/usr.sbin/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.138 2010/11/28 14:35:58 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.139 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -683,9 +683,9 @@ session_pickup(struct session *s, struct submit_status *ss)
fprintf(s->datafp, "Received: from %s (%s [%s])\n",
s->s_msg.session_helo, s->s_hostname, ss_to_text(&s->s_ss));
- fprintf(s->datafp, "\tby %s (OpenSMTPD) with %sSMTP id %s",
+ fprintf(s->datafp, "\tby %s (OpenSMTPD) with %sSMTP id %08x",
s->s_env->sc_hostname, s->s_flags & F_EHLO ? "E" : "",
- s->s_msg.message_id);
+ (u_int32_t)(s->s_msg.evpid >> 32));
if (s->s_flags & F_SECURE) {
fprintf(s->datafp, "\n\t(version=%s cipher=%s bits=%d)",
@@ -704,11 +704,11 @@ session_pickup(struct session *s, struct submit_status *ss)
break;
case S_DONE:
- session_respond(s, "250 2.0.0 %s Message accepted for delivery",
- s->s_msg.message_id);
- log_info("%s: from=<%s%s%s>, size=%ld, nrcpts=%zd, proto=%s, "
+ session_respond(s, "250 2.0.0 %08x Message accepted for delivery",
+ (u_int32_t)(s->s_msg.evpid >> 32));
+ log_info("%08x: from=<%s%s%s>, size=%ld, nrcpts=%zd, proto=%s, "
"relay=%s [%s]",
- s->s_msg.message_id,
+ (u_int32_t)(s->s_msg.evpid >> 32),
s->s_msg.sender.user,
s->s_msg.sender.user[0] == '\0' ? "" : "@",
s->s_msg.sender.domain,
@@ -719,8 +719,7 @@ session_pickup(struct session *s, struct submit_status *ss)
ss_to_text(&s->s_ss));
s->s_state = S_HELO;
- s->s_msg.message_id[0] = '\0';
- s->s_msg.message_uid[0] = '\0';
+ s->s_msg.evpid = 0;
bzero(&s->s_nresp, sizeof(s->s_nresp));
break;
@@ -975,7 +974,7 @@ session_destroy(struct session *s)
if (s->datafp != NULL)
fclose(s->datafp);
- if (s->s_msg.message_id[0] != '\0' && s->s_state != S_DONE)
+ if (s->s_msg.evpid != 0 && s->s_state != S_DONE)
imsg_compose_event(s->s_env->sc_ievs[PROC_QUEUE],
IMSG_QUEUE_REMOVE_MESSAGE, 0, 0, -1, &s->s_msg,
sizeof(s->s_msg));
@@ -1096,8 +1095,8 @@ session_respond(struct session *s, char *fmt, ...)
switch (EVBUFFER_DATA(EVBUFFER_OUTPUT(s->s_bev))[n]) {
case '5':
case '4':
- log_info("%s: from=<%s@%s>, relay=%s [%s], stat=LocalError (%.*s)",
- s->s_msg.message_id[0] ? s->s_msg.message_id : "(none)",
+ log_info("%08x: from=<%s@%s>, relay=%s [%s], stat=LocalError (%.*s)",
+ (u_int32_t)(s->s_msg.evpid >> 32),
s->s_msg.sender.user, s->s_msg.sender.domain,
s->s_hostname, ss_to_text(&s->s_ss),
(int)EVBUFFER_LENGTH(EVBUFFER_OUTPUT(s->s_bev)) - n - 2,
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 3a11fe34341..62e2d651ab0 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.213 2011/04/14 23:26:16 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.214 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -40,7 +40,7 @@
#define MAX_LINE_SIZE 1024
#define MAX_LOCALPART_SIZE 128
#define MAX_DOMAINPART_SIZE MAXHOSTNAMELEN
-#define MAX_ID_SIZE 64
+/*#define MAX_ID_SIZE 64*/
#define MAX_TAG_SIZE 32
/* return and forward path size */
@@ -441,8 +441,9 @@ struct message {
char tag[MAX_TAG_SIZE];
- char message_id[MAX_ID_SIZE];
- char message_uid[MAX_ID_SIZE];
+ u_int64_t evpid;
+// char message_id[MAX_ID_SIZE];
+// char message_uid[MAX_ID_SIZE];
char session_helo[MAXHOSTNAMELEN];
char session_hostname[MAXHOSTNAMELEN];
@@ -588,7 +589,7 @@ struct ramqueue_batch {
enum message_type type;
u_int64_t h_id;
u_int64_t b_id;
- char m_id[MAX_ID_SIZE];
+ u_int32_t msgid;
struct rule rule;
};
struct ramqueue_envelope {
@@ -596,7 +597,7 @@ struct ramqueue_envelope {
TAILQ_ENTRY(ramqueue_envelope) batchqueue_entry;
struct ramqueue_host *host;
struct ramqueue_batch *batch;
- char id[MAX_ID_SIZE];
+ u_int64_t evpid;
time_t sched;
};
@@ -748,7 +749,8 @@ struct submit_status {
int code;
union submit_path {
struct path path;
- char msgid[MAX_ID_SIZE];
+ u_int32_t msgid;
+ u_int64_t evpid;
char errormsg[MAX_LINE_SIZE];
} u;
enum message_flags flags;
@@ -933,7 +935,7 @@ enum queue_op {
struct queue_backend {
enum queue_type type;
int (*init)(struct smtpd *);
- int (*message)(struct smtpd *, enum queue_kind, enum queue_op, char *);
+ int (*message)(struct smtpd *, enum queue_kind, enum queue_op, u_int32_t *);
int (*envelope)(struct smtpd *, enum queue_kind, enum queue_op,
struct message *);
};
@@ -1056,18 +1058,18 @@ u_int16_t queue_hash(char *);
/* queue_backend.c */
struct queue_backend *queue_backend_lookup(enum queue_type);
-int queue_message_create(struct smtpd *, enum queue_kind, char *);
-int queue_message_delete(struct smtpd *, enum queue_kind, char *);
-int queue_message_commit(struct smtpd *, enum queue_kind, char *);
-int queue_message_fd_r(struct smtpd *, enum queue_kind, char *);
-int queue_message_fd_rw(struct smtpd *, enum queue_kind, char *);
-int queue_message_purge(struct smtpd *, enum queue_kind, char *);
+int queue_message_create(struct smtpd *, enum queue_kind, u_int32_t *);
+int queue_message_delete(struct smtpd *, enum queue_kind, u_int32_t);
+int queue_message_commit(struct smtpd *, enum queue_kind, u_int32_t);
+int queue_message_fd_r(struct smtpd *, enum queue_kind, u_int32_t);
+int queue_message_fd_rw(struct smtpd *, enum queue_kind, u_int32_t);
+int queue_message_purge(struct smtpd *, enum queue_kind, u_int32_t);
int queue_envelope_create(struct smtpd *, enum queue_kind,
struct message *);
int queue_envelope_delete(struct smtpd *, enum queue_kind,
struct message *);
int queue_envelope_load(struct smtpd *, enum queue_kind,
- char *, struct message *);
+ u_int64_t, struct message *);
int queue_envelope_update(struct smtpd *, enum queue_kind,
struct message *);
@@ -1201,3 +1203,5 @@ struct path *path_dup(struct path *);
u_int64_t generate_uid(void);
void fdlimit(double);
int availdesc(void);
+u_int32_t evpid_to_msgid(u_int64_t);
+u_int64_t msgid_to_evpid(u_int32_t);
diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c
index db841e2754c..59746f79bcc 100644
--- a/usr.sbin/smtpd/util.c
+++ b/usr.sbin/smtpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.40 2011/03/29 20:43:51 eric Exp $ */
+/* $OpenBSD: util.c,v 1.41 2011/04/15 17:01:05 gilles Exp $ */
/*
* Copyright (c) 2000,2001 Markus Friedl. All rights reserved.
@@ -50,6 +50,12 @@
const char *log_in6addr(const struct in6_addr *);
const char *log_sockaddr(struct sockaddr *);
+u_int32_t filename_to_msgid(char *);
+u_int64_t filename_to_evpid(char *);
+
+u_int32_t evpid_to_msgid(u_int64_t);
+u_int64_t msgid_to_evpid(u_int32_t);
+
int
bsnprintf(char *str, size_t size, const char *format, ...)
{
@@ -573,3 +579,47 @@ log_sockaddr(struct sockaddr *sa)
else
return (buf);
}
+
+u_int32_t
+filename_to_msgid(char *filename)
+{
+ u_int32_t ulval;
+ char *ep;
+
+ errno = 0;
+ ulval = strtoul(filename, &ep, 16);
+ if (filename[0] == '\0' || *ep != '\0')
+ return 0;
+ if (errno == ERANGE && ulval == 0xffffffff)
+ return 0;
+
+ return ulval;
+}
+
+u_int64_t
+filename_to_evpid(char *filename)
+{
+ u_int64_t ullval;
+ char *ep;
+
+ errno = 0;
+ ullval = strtoull(filename, &ep, 16);
+ if (filename[0] == '\0' || *ep != '\0')
+ return 0;
+ if (errno == ERANGE && ullval == ULLONG_MAX)
+ return 0;
+
+ return ullval;
+}
+
+u_int32_t
+evpid_to_msgid(u_int64_t evpid)
+{
+ return (evpid >> 32);
+}
+
+u_int64_t
+msgid_to_evpid(u_int32_t msgid)
+{
+ return ((u_int64_t)msgid << 32);
+}