summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Longeau <chl@cvs.openbsd.org>2010-06-10 19:34:52 +0000
committerCharles Longeau <chl@cvs.openbsd.org>2010-06-10 19:34:52 +0000
commitc7c886a4b2afb217f78a66469ff3364eec5b8b2e (patch)
tree635034009607d1f9f2416a8dffb7566bb8104c15
parent6b09f25b8e40028bddd549d1fb46eeb16f880327 (diff)
allow configure queue expiry
with help from jacekm@ ok gilles@ jacekm@
-rw-r--r--usr.sbin/smtpd/parse.y80
-rw-r--r--usr.sbin/smtpd/queue.c6
-rw-r--r--usr.sbin/smtpd/smtpd.conf.512
-rw-r--r--usr.sbin/smtpd/smtpd.h3
4 files changed, 75 insertions, 26 deletions
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index e96e85ca7b1..1bdce823ed0 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.62 2010/06/01 23:06:23 jacekm Exp $ */
+/* $OpenBSD: parse.y,v 1.63 2010/06/10 19:34:51 chl Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -101,6 +101,7 @@ int host(const char *, const char *, const char *,
int interface(const char *, const char *, const char *,
struct listenerlist *, int, in_port_t, u_int8_t);
void set_localaddrs(void);
+int delaytonum(char *);
typedef struct {
union {
@@ -116,7 +117,7 @@ typedef struct {
%}
-%token SIZE LISTEN ON ALL PORT
+%token EXPIRE SIZE LISTEN ON ALL PORT
%token MAP TYPE HASH LIST SINGLE SSL SMTPS CERTIFICATE
%token DNS DB PLAIN EXTERNAL DOMAIN CONFIG SOURCE
%token RELAY VIA DELIVER TO MAILDIR MBOX HOSTNAME
@@ -125,9 +126,8 @@ typedef struct {
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.map> map
-%type <v.number> quantifier decision port from auth ssl size
+%type <v.number> decision port from auth ssl size
%type <v.cond> condition
-%type <v.tv> interval
%type <v.object> mapref
%type <v.string> certname user tag on alias
@@ -178,21 +178,6 @@ optnl : '\n' optnl
nl : '\n' optnl
;
-quantifier : /* empty */ { $$ = 1; }
- | 'm' { $$ = 60; }
- | 'h' { $$ = 3600; }
- | 'd' { $$ = 86400; }
- ;
-
-interval : NUMBER quantifier {
- if ($1 < 0) {
- yyerror("invalid interval: %lld", $1);
- YYERROR;
- }
- $$.tv_usec = 0;
- $$.tv_sec = $1 * $2;
- }
-
size : NUMBER {
if ($1 < 0) {
yyerror("invalid size: %lld", $1);
@@ -266,7 +251,14 @@ tag : TAG STRING {
| /* empty */ { $$ = NULL; }
;
-main : SIZE size {
+main : EXPIRE STRING {
+ conf->sc_qexpire = delaytonum($2);
+ if (conf->sc_qexpire == -1) {
+ yyerror("invalid expire delay: %s", $2);
+ YYERROR;
+ }
+ }
+ | SIZE size {
conf->sc_maxsize = $2;
}
| LISTEN ON STRING port ssl certname auth tag {
@@ -1050,6 +1042,7 @@ lookup(char *s)
{ "dns", DNS },
{ "domain", DOMAIN },
{ "enable", ENABLE },
+ { "expire", EXPIRE },
{ "external", EXTERNAL },
{ "for", FOR },
{ "from", FROM },
@@ -1458,6 +1451,7 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts)
SPLAY_INIT(conf->sc_ssl);
SPLAY_INIT(&conf->sc_sessions);
+ conf->sc_qexpire = SMTPD_EXPIRE;
conf->sc_opts = opts;
if ((file = pushfile(filename, 0)) == NULL) {
@@ -1840,3 +1834,49 @@ set_localaddrs(void)
freeifaddrs(ifap);
}
+
+int
+delaytonum(char *str)
+{
+ unsigned int factor;
+ size_t len;
+ const char *errstr = NULL;
+ int delay;
+
+ /* we need at least 1 digit and 1 unit */
+ len = strlen(str);
+ if (len < 2)
+ goto bad;
+
+ switch(str[len - 1]) {
+
+ case 's':
+ factor = 1;
+ break;
+
+ case 'm':
+ factor = 60;
+ break;
+
+ case 'h':
+ factor = 60 * 60;
+ break;
+
+ case 'd':
+ factor = 24 * 60 * 60;
+ break;
+
+ default:
+ goto bad;
+ }
+
+ str[len - 1] = '\0';
+ delay = strtonum(str, 1, INT_MAX / factor, &errstr);
+ if (errstr)
+ goto bad;
+
+ return (delay * factor);
+
+bad:
+ return (-1);
+}
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c
index 029dfd3bd39..f6a56da3479 100644
--- a/usr.sbin/smtpd/queue.c
+++ b/usr.sbin/smtpd/queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.c,v 1.87 2010/06/02 19:16:53 chl Exp $ */
+/* $OpenBSD: queue.c,v 1.88 2010/06/10 19:34:51 chl Exp $ */
/*
* Copyright (c) 2008-2010 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -741,7 +741,7 @@ queue_mem_init(struct smtpd *env)
batch->retry = queue_retry(rq, a.birth,
batch->retry);
- if (batch->retry > a.birth + SMTPD_EXPIRE)
+ if (batch->retry > a.birth + env->sc_qexpire)
batch->retry = NO_RETRY_EXPIRED;
SLIST_INSERT_HEAD(&bhash[a.content_id & 4095], batch,
@@ -1077,7 +1077,7 @@ queue_done(int rq, int i)
action->id) < 0)
fatal("queue: action read error");
batch->retry = queue_retry(rq, a.birth, batch->retry);
- if (batch->retry > a.birth + SMTPD_EXPIRE)
+ if (batch->retry > a.birth + runqs[rq].env->sc_qexpire)
batch->retry = NO_RETRY_EXPIRED;
queue_schedule(rq, batch);
}
diff --git a/usr.sbin/smtpd/smtpd.conf.5 b/usr.sbin/smtpd/smtpd.conf.5
index a195880f795..09170185ae9 100644
--- a/usr.sbin/smtpd/smtpd.conf.5
+++ b/usr.sbin/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.32 2010/04/27 14:39:24 jmc Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.33 2010/06/10 19:34:51 chl Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -16,7 +16,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\"
-.Dd $Mdocdate: April 27 2010 $
+.Dd $Mdocdate: June 10 2010 $
.Dt SMTPD.CONF 5
.Os
.Sh NAME
@@ -201,6 +201,14 @@ is desired, use the
.Ic enable auth
parameter.
.El
+.It Ic expire Ar n {s|m|h|d}
+Specify how long a message can stay in the queue.
+The default value is 4 days.
+For example:
+.Bd -literal -offset indent
+expire 4d # expire after 4 days
+expire 10h # expire after 10 hours
+.Ed
.It Ic hostname Ar name
Specify the domain name of the server.
By default the current host name is used,
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index c5e0c293c61..c5008d42b21 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.192 2010/06/09 20:00:55 zinovik Exp $ */
+/* $OpenBSD: smtpd.h,v 1.193 2010/06/10 19:34:51 chl Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -604,6 +604,7 @@ struct smtpd {
#define SMTPD_SMTP_PAUSED 0x00000010
u_int32_t sc_flags;
u_int32_t sc_maxconn;
+ int sc_qexpire;
struct event sc_ev;
int *sc_pipes[PROC_COUNT]
[PROC_COUNT];