diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2012-04-12 17:26:10 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2012-04-12 17:26:10 +0000 |
commit | acce912764e9985f31fb5c8fca801c6ca6567469 (patch) | |
tree | f07b904e7223c341dc9874dc9911c628bd7df2c9 /usr.sbin/bgpd/session.c | |
parent | 9fcb2f01c668956044de8fbda3588daa44668125 (diff) |
accept() pacing for bgpd based on similar work done on other daemons.
OK henning@ sthen@
Diffstat (limited to 'usr.sbin/bgpd/session.c')
-rw-r--r-- | usr.sbin/bgpd/session.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index c24eb9b3dc3..02d3840d84a 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.320 2012/01/06 17:33:11 sthen Exp $ */ +/* $OpenBSD: session.c,v 1.321 2012/04/12 17:26:09 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -107,6 +107,7 @@ struct imsgbuf *ibuf_rde_ctl; struct imsgbuf *ibuf_main; struct mrt_head mrthead; +time_t pauseaccept; void session_sighdlr(int sig) @@ -372,17 +373,25 @@ session_main(int pipe_m2s[2], int pipe_s2r[2], int pipe_m2r[2], * messages if the ctl sockets are getting full. */ pfd[PFD_PIPE_ROUTE_CTL].events = POLLIN; - pfd[PFD_SOCK_CTL].fd = csock; - pfd[PFD_SOCK_CTL].events = POLLIN; - pfd[PFD_SOCK_RCTL].fd = rcsock; - pfd[PFD_SOCK_RCTL].events = POLLIN; + if (pauseaccept == 0) { + pfd[PFD_SOCK_CTL].fd = csock; + pfd[PFD_SOCK_CTL].events = POLLIN; + pfd[PFD_SOCK_RCTL].fd = rcsock; + pfd[PFD_SOCK_RCTL].events = POLLIN; + } else { + pfd[PFD_SOCK_CTL].fd = -1; + pfd[PFD_SOCK_RCTL].fd = -1; + } pfd[PFD_SOCK_PFKEY].fd = pfkeysock; pfd[PFD_SOCK_PFKEY].events = POLLIN; i = PFD_LISTENERS_START; TAILQ_FOREACH(la, conf->listen_addrs, entry) { - pfd[i].fd = la->fd; - pfd[i].events = POLLIN; + if (pauseaccept == 0) { + pfd[i].fd = la->fd; + pfd[i].events = POLLIN; + } else + pfd[i].fd = -1; i++; } idx_listeners = i; @@ -469,12 +478,21 @@ session_main(int pipe_m2s[2], int pipe_s2r[2], int pipe_m2r[2], i++; } + if (pauseaccept && timeout > 1) + timeout = 1; if (timeout < 0) timeout = 0; if ((nfds = poll(pfd, i, timeout * 1000)) == -1) if (errno != EINTR) fatal("poll error"); + /* + * If we previously saw fd exhaustion, we stop accept() + * for 1 second to throttle the accept() loop. + */ + if (pauseaccept && getmonotime() > pauseaccept + 1) + pauseaccept = 0; + if (nfds > 0 && pfd[PFD_PIPE_MAIN].revents & POLLOUT) if (msgbuf_write(&ibuf_main->w) < 0) fatal("pipe write error"); @@ -869,9 +887,10 @@ start_timer_keepalive(struct peer *peer) void session_close_connection(struct peer *peer) { - if (peer->fd != -1) + if (peer->fd != -1) { close(peer->fd); - + pauseaccept = 0; + } peer->fd = peer->wbuf.fd = -1; } @@ -975,7 +994,10 @@ session_accept(int listenfd) len = sizeof(cliaddr); if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len)) == -1) { - if (errno == EWOULDBLOCK || errno == EINTR) + if (errno == ENFILE || errno == EMFILE) { + pauseaccept = getmonotime(); + return; + } else if (errno == EWOULDBLOCK || errno == EINTR) return; else log_warn("accept"); |