diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2012-04-10 07:56:55 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2012-04-10 07:56:55 +0000 |
commit | 11f779a7907d0dbca7653b462a05ca2a2778e1ce (patch) | |
tree | a3324188e8f7d0ae82834625e9ec19945ac4a692 | |
parent | e28e185032a9204a235a0b9df0f4ab444af013e7 (diff) |
Handle file descriptor exhaustion in the accept() case.
ok claudio
-rw-r--r-- | usr.sbin/dvmrpd/control.c | 30 | ||||
-rw-r--r-- | usr.sbin/dvmrpd/control.h | 3 | ||||
-rw-r--r-- | usr.sbin/ospf6d/control.c | 30 | ||||
-rw-r--r-- | usr.sbin/ospf6d/control.h | 3 | ||||
-rw-r--r-- | usr.sbin/ospfd/control.c | 35 | ||||
-rw-r--r-- | usr.sbin/ospfd/control.h | 3 | ||||
-rw-r--r-- | usr.sbin/ripd/control.c | 30 | ||||
-rw-r--r-- | usr.sbin/ripd/control.h | 3 |
8 files changed, 119 insertions, 18 deletions
diff --git a/usr.sbin/dvmrpd/control.c b/usr.sbin/dvmrpd/control.c index b655306426b..2e2b52370ab 100644 --- a/usr.sbin/dvmrpd/control.c +++ b/usr.sbin/dvmrpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.14 2010/09/02 14:03:21 sobrado Exp $ */ +/* $OpenBSD: control.c,v 1.15 2012/04/10 07:56:54 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -93,9 +93,10 @@ control_listen(void) return (-1); } - event_set(&control_state.ev, control_state.fd, EV_READ | EV_PERSIST, + event_set(&control_state.ev, control_state.fd, EV_READ, control_accept, NULL); event_add(&control_state.ev, NULL); + evtimer_set(&control_state.evt, control_accept, NULL); return (0); } @@ -103,6 +104,9 @@ control_listen(void) void control_cleanup(void) { + event_del(&control_state.ev); + if (evtimer_pending(&control_state.evt, NULL)) + event_del(&control_state.evt); unlink(DVMRPD_SOCKET); } @@ -115,10 +119,23 @@ control_accept(int listenfd, short event, void *bula) struct sockaddr_un sun; struct ctl_conn *c; + event_add(&control_state.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(&control_state.ev); + evtimer_add(&control_state.evt, &evtpause); + } else if (errno != EWOULDBLOCK && errno != EINTR) log_warn("control_accept: accept"); return; } @@ -180,6 +197,13 @@ control_close(int fd) event_del(&c->iev.ev); close(c->iev.ibuf.fd); + + /* Some file descriptors are available again. */ + if (evtimer_pending(&control_state.evt, NULL)) { + evtimer_del(&control_state.evt); + event_add(&control_state.ev, NULL); + } + free(c); } diff --git a/usr.sbin/dvmrpd/control.h b/usr.sbin/dvmrpd/control.h index 7840bf9b1a6..6eeef82e7e6 100644 --- a/usr.sbin/dvmrpd/control.h +++ b/usr.sbin/dvmrpd/control.h @@ -1,4 +1,4 @@ -/* $OpenBSD: control.h,v 1.2 2009/06/06 07:52:04 pyr Exp $ */ +/* $OpenBSD: control.h,v 1.3 2012/04/10 07:56:54 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -25,6 +25,7 @@ struct { struct event ev; + struct event evt; int fd; } control_state; diff --git a/usr.sbin/ospf6d/control.c b/usr.sbin/ospf6d/control.c index 61327fc5635..a6e2107f3d6 100644 --- a/usr.sbin/ospf6d/control.c +++ b/usr.sbin/ospf6d/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.16 2010/07/01 19:47:04 bluhm Exp $ */ +/* $OpenBSD: control.c,v 1.17 2012/04/10 07:56:50 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -91,9 +91,10 @@ control_listen(void) return (-1); } - event_set(&control_state.ev, control_state.fd, EV_READ | EV_PERSIST, + event_set(&control_state.ev, control_state.fd, EV_READ, control_accept, NULL); event_add(&control_state.ev, NULL); + evtimer_set(&control_state.evt, control_accept, NULL); return (0); } @@ -101,6 +102,9 @@ control_listen(void) void control_cleanup(void) { + event_del(&control_state.ev); + if (evtimer_pending(&control_state.evt, NULL)) + event_del(&control_state.evt); unlink(OSPF6D_SOCKET); } @@ -113,10 +117,23 @@ control_accept(int listenfd, short event, void *bula) struct sockaddr_un sun; struct ctl_conn *c; + event_add(&control_state.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(&control_state.ev); + evtimer_add(&control_state.evt, &evtpause); + } else if (errno != EWOULDBLOCK && errno != EINTR) log_warn("control_accept: accept"); return; } @@ -178,6 +195,13 @@ control_close(int fd) event_del(&c->iev.ev); close(c->iev.ibuf.fd); + + /* Some file descriptors are available again. */ + if (evtimer_pending(&control_state.evt, NULL)) { + evtimer_del(&control_state.evt); + event_add(&control_state.ev, NULL); + } + free(c); } diff --git a/usr.sbin/ospf6d/control.h b/usr.sbin/ospf6d/control.h index 0d8d1e2805c..d552d3e1b67 100644 --- a/usr.sbin/ospf6d/control.h +++ b/usr.sbin/ospf6d/control.h @@ -1,4 +1,4 @@ -/* $OpenBSD: control.h,v 1.2 2009/06/06 09:02:46 eric Exp $ */ +/* $OpenBSD: control.h,v 1.3 2012/04/10 07:56:50 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -25,6 +25,7 @@ struct { struct event ev; + struct event evt; int fd; } control_state; diff --git a/usr.sbin/ospfd/control.c b/usr.sbin/ospfd/control.c index 44157b5f659..a06a9b4e9b4 100644 --- a/usr.sbin/ospfd/control.c +++ b/usr.sbin/ospfd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.35 2011/05/09 12:24:41 claudio Exp $ */ +/* $OpenBSD: control.c,v 1.36 2012/04/10 07:56:54 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -92,9 +92,10 @@ control_listen(void) return (-1); } - event_set(&control_state.ev, control_state.fd, EV_READ | EV_PERSIST, + event_set(&control_state.ev, control_state.fd, EV_READ, control_accept, NULL); event_add(&control_state.ev, NULL); + evtimer_set(&control_state.evt, control_accept, NULL); return (0); } @@ -102,8 +103,12 @@ control_listen(void) void control_cleanup(char *path) { - if (path) - unlink(path); + if (path == NULL) + return; + event_del(&control_state.ev); + if (evtimer_pending(&control_state.evt, NULL)) + event_del(&control_state.evt); + unlink(path); } /* ARGSUSED */ @@ -115,10 +120,23 @@ control_accept(int listenfd, short event, void *bula) struct sockaddr_un sun; struct ctl_conn *c; + event_add(&control_state.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(&control_state.ev); + evtimer_add(&control_state.evt, &evtpause); + } else if (errno != EWOULDBLOCK && errno != EINTR) log_warn("control_accept: accept"); return; } @@ -180,6 +198,13 @@ control_close(int fd) event_del(&c->iev.ev); close(c->iev.ibuf.fd); + + /* Some file descriptors are available again. */ + if (evtimer_pending(&control_state.evt, NULL)) { + evtimer_del(&control_state.evt); + event_add(&control_state.ev, NULL); + } + free(c); } diff --git a/usr.sbin/ospfd/control.h b/usr.sbin/ospfd/control.h index b439e645938..8f70ef63ebc 100644 --- a/usr.sbin/ospfd/control.h +++ b/usr.sbin/ospfd/control.h @@ -1,4 +1,4 @@ -/* $OpenBSD: control.h,v 1.4 2009/06/06 07:31:26 eric Exp $ */ +/* $OpenBSD: control.h,v 1.5 2012/04/10 07:56:54 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -25,6 +25,7 @@ struct { struct event ev; + struct event evt; int fd; } control_state; diff --git a/usr.sbin/ripd/control.c b/usr.sbin/ripd/control.c index a38edcb4350..f3ea65d4ff1 100644 --- a/usr.sbin/ripd/control.c +++ b/usr.sbin/ripd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.15 2010/05/14 11:52:19 claudio Exp $ */ +/* $OpenBSD: control.c,v 1.16 2012/04/10 07:56:54 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -92,9 +92,10 @@ control_listen(void) return (-1); } - event_set(&control_state.ev, control_state.fd, EV_READ | EV_PERSIST, + event_set(&control_state.ev, control_state.fd, EV_READ, control_accept, NULL); event_add(&control_state.ev, NULL); + evtimer_set(&control_state.evt, control_accept, NULL); return (0); } @@ -102,6 +103,9 @@ control_listen(void) void control_cleanup(void) { + event_del(&control_state.ev); + if (evtimer_pending(&control_state.evt, NULL)) + event_del(&control_state.evt); unlink(RIPD_SOCKET); } @@ -114,10 +118,23 @@ control_accept(int listenfd, short event, void *bula) struct sockaddr_un sun; struct ctl_conn *c; + event_add(&control_state.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(&control_state.ev); + evtimer_add(&control_state.evt, &evtpause); + } else if (errno != EWOULDBLOCK && errno != EINTR) log_warn("control_accept: accept"); return; } @@ -179,6 +196,13 @@ control_close(int fd) event_del(&c->iev.ev); close(c->iev.ibuf.fd); + + /* Some file descriptors are available again. */ + if (evtimer_pending(&control_state.evt, NULL)) { + evtimer_del(&control_state.evt); + event_add(&control_state.ev, NULL); + } + free(c); } diff --git a/usr.sbin/ripd/control.h b/usr.sbin/ripd/control.h index 23240d367ae..6eeef82e7e6 100644 --- a/usr.sbin/ripd/control.h +++ b/usr.sbin/ripd/control.h @@ -1,4 +1,4 @@ -/* $OpenBSD: control.h,v 1.2 2009/06/06 08:20:55 eric Exp $ */ +/* $OpenBSD: control.h,v 1.3 2012/04/10 07:56:54 deraadt Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -25,6 +25,7 @@ struct { struct event ev; + struct event evt; int fd; } control_state; |