diff options
author | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2012-06-16 00:08:33 +0000 |
---|---|---|
committer | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2012-06-16 00:08:33 +0000 |
commit | 13e1995d2d480fdedfbd4d24b123246496d85e86 (patch) | |
tree | 5871128642d3205945aded9f753bc11aee4b4ec1 /usr.sbin/ldapd/conn.c | |
parent | e9e58745c35db60fc74c0f849458bcad5e111207 (diff) |
Protect against fd exhaustion when reopening database files. Only accept
client or control connections when there are at least 8 fds available,
and close a connection before calling imsg_read if it would be unable to
accept an fd from the parent process.
ok gilles@
Diffstat (limited to 'usr.sbin/ldapd/conn.c')
-rw-r--r-- | usr.sbin/ldapd/conn.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/usr.sbin/ldapd/conn.c b/usr.sbin/ldapd/conn.c index e2ed882015e..e36b5192cbb 100644 --- a/usr.sbin/ldapd/conn.c +++ b/usr.sbin/ldapd/conn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conn.c,v 1.9 2012/04/11 08:31:37 deraadt Exp $ */ +/* $OpenBSD: conn.c,v 1.10 2012/06/16 00:08:32 jmatthew Exp $ */ /* * Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se> @@ -261,7 +261,8 @@ conn_accept(int fd, short event, void *data) return; addrlen = sizeof(remote_addr); - afd = accept(fd, (struct sockaddr *)&remote_addr, &addrlen); + afd = accept_reserve(fd, (struct sockaddr *)&remote_addr, &addrlen, + FD_RESERVE); if (afd == -1) { /* * Pause accept if we are out of file descriptors, or @@ -345,3 +346,25 @@ conn_by_fd(int fd) return NULL; } +int +conn_close_any() +{ + struct conn *conn; + + /* Close oldest idle connection */ + TAILQ_FOREACH_REVERSE(conn, &conn_list, conn_list, next) { + if (namespace_conn_queue_count(conn) == 0) { + conn_close(conn); + return 0; + } + } + + /* Close oldest connection */ + conn = TAILQ_LAST(&conn_list, conn_list); + if (conn != NULL) { + conn_close(conn); + return 0; + } + + return -1; +} |