summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2012-04-08 02:57:41 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2012-04-08 02:57:41 +0000
commit536249810d25ff35ae2a55ee056be1cc4f2da291 (patch)
tree4080d8debd07ef596639c3ef8362740b3a5eae10 /usr.sbin
parent54f5934ff924e86e14e38a5901142ffa95a37394 (diff)
add the evtimout rate-limiting code for accept() here too.
eyed a little by joel
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/snmpd/control.c44
-rw-r--r--usr.sbin/snmpd/snmpd.h3
2 files changed, 36 insertions, 11 deletions
diff --git a/usr.sbin/snmpd/control.c b/usr.sbin/snmpd/control.c
index 57e69e57a2b..88cdc7c0076 100644
--- a/usr.sbin/snmpd/control.c
+++ b/usr.sbin/snmpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.13 2010/05/14 11:52:19 claudio Exp $ */
+/* $OpenBSD: control.c,v 1.14 2012/04/08 02:57:40 deraadt Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -41,7 +41,7 @@
struct ctl_connlist ctl_conns;
struct ctl_conn *control_connbyfd(int);
-void control_close(int);
+void control_close(int, struct control_sock *);
int
control_init(struct control_sock *cs)
@@ -113,9 +113,10 @@ control_listen(struct control_sock *cs)
return (-1);
}
- event_set(&cs->cs_ev, cs->cs_fd, EV_READ | EV_PERSIST,
+ event_set(&cs->cs_ev, cs->cs_fd, EV_READ,
control_accept, cs);
event_add(&cs->cs_ev, NULL);
+ evtimer_set(&cs->cs_evt, control_accept, cs);
return (0);
}
@@ -125,6 +126,9 @@ control_cleanup(struct control_sock *cs)
{
if (cs->cs_name == NULL)
return;
+ event_del(&cs->cs_ev);
+ if (evtimer_pending(&cs->cs_evt, NULL))
+ event_del(&cs->cs_evt);
(void)unlink(cs->cs_name);
}
@@ -138,10 +142,23 @@ control_accept(int listenfd, short event, void *arg)
struct sockaddr_un sun;
struct ctl_conn *c;
+ event_add(&cs->cs_ev, NULL);
+ if ((event & EV_TIMEOUT))
+ return;
+
len = sizeof(sun);
if ((connfd = accept(listenfd,
(struct sockaddr *)&sun, &len)) == -1) {
- if (errno != EWOULDBLOCK && errno != EINTR)
+ /*
+ * Pause accept if we are out of file descriptors, or
+ * libevent will haunt us here too.
+ */
+ if (errno == ENFILE || errno == EMFILE) {
+ struct timeval evtpause = { 1, 0 };
+
+ event_del(&cs->cs_ev);
+ evtimer_add(&cs->cs_evt, &evtpause);
+ } else if (errno != EWOULDBLOCK && errno != EINTR)
log_warn("control_accept: accept");
return;
}
@@ -177,7 +194,7 @@ control_connbyfd(int fd)
}
void
-control_close(int fd)
+control_close(int fd, struct control_sock *cs)
{
struct ctl_conn *c;
@@ -191,6 +208,13 @@ control_close(int fd)
event_del(&c->iev.ev);
close(c->iev.ibuf.fd);
+
+ /* Some file descriptors are available again. */
+ if (evtimer_pending(&cs->cs_evt, NULL)) {
+ evtimer_del(&cs->cs_evt);
+ event_add(&cs->cs_ev, NULL);
+ }
+
free(c);
}
@@ -211,13 +235,13 @@ control_dispatch_imsg(int fd, short event, void *arg)
switch (event) {
case EV_READ:
if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
- control_close(fd);
+ control_close(fd, cs);
return;
}
break;
case EV_WRITE:
if (msgbuf_write(&c->iev.ibuf.w) < 0) {
- control_close(fd);
+ control_close(fd, cs);
return;
}
imsg_event_add(&c->iev);
@@ -228,7 +252,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
for (;;) {
if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
- control_close(fd);
+ control_close(fd, cs);
return;
}
@@ -246,7 +270,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
log_debug("control_dispatch_imsg: "
"client requested restricted command");
imsg_free(&imsg);
- control_close(fd);
+ control_close(fd, cs);
return;
}
}
@@ -272,7 +296,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
"received invalid trap (pid %d)",
imsg.hdr.pid);
imsg_free(&imsg);
- control_close(fd);
+ control_close(fd, cs);
return;
}
break;
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h
index ed0d1ddca7a..6b67ddd1eb6 100644
--- a/usr.sbin/snmpd/snmpd.h
+++ b/usr.sbin/snmpd/snmpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.h,v 1.33 2012/02/23 03:54:38 joel Exp $ */
+/* $OpenBSD: snmpd.h,v 1.34 2012/04/08 02:57:40 deraadt Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -67,6 +67,7 @@ enum {
struct control_sock {
const char *cs_name;
struct event cs_ev;
+ struct event cs_evt;
int cs_fd;
int cs_restricted;
};