summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2009-01-30 17:34:59 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2009-01-30 17:34:59 +0000
commit2ad85d8d97e961839ddcb838af1f52104af1d030 (patch)
treeb34985d3486b1b1f122f1eb9004b267289652820 /usr.sbin
parentae280d1b5f9990fabe1466ff8e7f61df8f618db5 (diff)
bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when we hit that limit, we stop accepting connections, and when client closes a session, we start accepting connections again. this prevents us from going into a session that is likely to fail because of scarce resources. idea discussed with jacekm@, code mostly ripped from relayd
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/smtpd/smtp.c12
-rw-r--r--usr.sbin/smtpd/smtp_session.c8
-rw-r--r--usr.sbin/smtpd/smtpd.c20
-rw-r--r--usr.sbin/smtpd/smtpd.h3
4 files changed, 34 insertions, 9 deletions
diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c
index 0f5f24c18fb..a2338ab4353 100644
--- a/usr.sbin/smtpd/smtp.c
+++ b/usr.sbin/smtpd/smtp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.c,v 1.19 2009/01/30 16:37:52 gilles Exp $ */
+/* $OpenBSD: smtp.c,v 1.20 2009/01/30 17:34:58 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -698,7 +698,7 @@ smtp_accept(int fd, short event, void *p)
log_debug("smtp_accept: incoming client on listener: %p", l);
len = sizeof(struct sockaddr_storage);
if ((s_fd = accept(l->fd, (struct sockaddr *)&ss, &len)) == -1) {
- event_add(&l->ev, NULL);
+ event_del(&l->ev);
return;
}
@@ -709,10 +709,18 @@ smtp_accept(int fd, short event, void *p)
s->s_fd = s_fd;
s->s_tm = time(NULL);
+ s->s_env = l->env;
+ s->s_l = l;
+
(void)memcpy(&s->s_ss, &ss, sizeof(s->s_ss));
session_init(l, s);
event_add(&l->ev, NULL);
+
+ s_smtp.clients++;
+
+ if (s_smtp.clients == s->s_env->sc_maxconn)
+ event_del(&l->ev);
}
void
diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c
index 1340cc703e5..3b1a6552371 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.48 2009/01/30 16:37:52 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.49 2009/01/30 17:34:58 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -748,12 +748,8 @@ void
session_init(struct listener *l, struct session *s)
{
s->s_state = S_INIT;
- s->s_env = l->env;
- s->s_l = l;
s->s_id = queue_generate_id();
- s_smtp.clients++;
-
if ((s->s_bev = bufferevent_new(s->s_fd, session_read, session_write,
session_error, s)) == NULL)
fatalx("session_init: bufferevent_new failed");
@@ -912,6 +908,8 @@ session_destroy(struct session *s)
close(s->s_fd);
s_smtp.clients--;
+ if (s_smtp.clients < s->s_env->sc_maxconn)
+ event_add(&s->s_l->ev, NULL);
if (s->s_bev != NULL) {
bufferevent_free(s->s_bev);
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 6f13c500d39..4dbfcaa5c0c 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.28 2009/01/30 10:03:29 form Exp $ */
+/* $OpenBSD: smtpd.c,v 1.29 2009/01/30 17:34:58 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -25,6 +25,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/uio.h>
+#include <sys/resource.h>
#include <bsd_auth.h>
#include <err.h>
@@ -591,6 +592,7 @@ main(int argc, char *argv[])
struct event ev_sigchld;
struct event ev_sighup;
struct timeval tv;
+ struct rlimit rl;
struct peer peers[] = {
{ PROC_CONTROL, parent_dispatch_control },
{ PROC_LKA, parent_dispatch_lka },
@@ -659,6 +661,22 @@ main(int argc, char *argv[])
log_info("startup%s", (debug > 1)?" [debug mode]":"");
+ if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
+ fatal("smtpd: failed to get resource limit");
+
+ log_debug("smtpd: max open files %lld", rl.rlim_max);
+
+ /*
+ * Allow the maximum number of open file descriptors for this
+ * login class (which should be the class "daemon" by default).
+ */
+ rl.rlim_cur = rl.rlim_max;
+ if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
+ fatal("smtpd: failed to set resource limit");
+
+ env.sc_maxconn = (rl.rlim_cur / 4) * 3;
+ log_debug("smtpd: will accept at most %d clients", env.sc_maxconn);
+
init_peers(&env);
/* start subprocesses */
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 60b50aa413d..2c6da0c217d 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.63 2009/01/30 16:37:52 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.64 2009/01/30 17:34:58 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -624,6 +624,7 @@ struct smtpd {
#define SMTPD_SMTP_PAUSED 0x00000010
u_int32_t sc_flags;
struct timeval sc_qintval;
+ u_int32_t sc_maxconn;
struct event sc_ev;
int sc_pipes[PROC_COUNT]
[PROC_COUNT][2];