Skip to content

Commit 61764bd

Browse files
committed
limit file descriptors to FD_SETSIZE
* in the event handlers, so that we don't over-run it when using FD_SET. The previous code checked for > FD_SETSIZE, not >= FD_SETSIZE * in new incoming sockets, after accept(). So that we don't go through a huge amount of work, and then discover that the FD is too large. * in new outgoing sockets, after socket(), for the same reasons. * update / clarify documentation around limits for idle_timeout
1 parent d71a2d3 commit 61764bd

4 files changed

Lines changed: 45 additions & 14 deletions

File tree

raddb/proxy.conf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,16 @@ home_server localhost {
552552
# this time, the connection will be closed.
553553
#
554554
# Setting this to 0 means "no timeout".
555+
#
556+
# We STRONGLY RECOMMEND that you set an idle timeout.
557+
#
558+
# Systems with many outgoing connections (500+) should
559+
# set this value to a low number such as "5". There
560+
# are only a limited number of usable file descriptors
561+
# (usually 1024) due to Posix API issues. If many
562+
# sockets are idle, it can prevent the server from
563+
# opening new connections.
564+
#
555565
idle_timeout = 0
556566
}
557567

raddb/sites-available/default

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ listen {
206206
# We STRONGLY RECOMMEND that you set an idle timeout.
207207
#
208208
# Systems with many incoming connections (500+) should
209-
# set this value to a lower number. There are only a
210-
# limited number of usable file descriptors (usually
211-
# 1024) due to Posix API issues. If many sockets are
212-
# idle, it can prevent the server from opening new
213-
# connections.
209+
# set this value to a low number, such as "5". There
210+
# are only a limited number of usable file descriptors
211+
# (usually 1024) due to Posix API issues. If many
212+
# sockets are idle, it can prevent the server from
213+
# opening new connections.
214214
#
215215
idle_timeout = 900
216216
}

src/lib/event.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,13 @@ int fr_event_fd_insert(fr_event_list_t *el, int type, int fd,
358358
return 0;
359359
}
360360

361+
#ifndef HAVE_KQUEUE
362+
if (fd >= FD_SETSIZE) {
363+
fr_strerror_printf("Too many file descriptors! (FD %i >= %u)", fd, FD_SETSIZE);
364+
return 0;
365+
}
366+
#endif
367+
361368
if (type != 0) {
362369
fr_strerror_printf("Invalid type %i", type);
363370
return 0;
@@ -409,15 +416,7 @@ int fr_event_fd_insert(fr_event_list_t *el, int type, int fd,
409416

410417
#else /* HAVE_KQUEUE */
411418

412-
/*
413-
* select() has limits.
414-
*/
415-
if (fd > FD_SETSIZE) {
416-
fprintf(stderr, "FD is larger than FD_SETSIZE");
417-
return 0;
418-
}
419-
420-
if (fd > fr_ev_max_fds) {
419+
if (fd >= fr_ev_max_fds) {
421420
fprintf(stderr, "FD is larger than MAX FDs");
422421
return 0;
423422
}

src/main/listen.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ RCSID("$Id$")
5252
#include <sys/stat.h>
5353
#endif
5454

55+
#ifdef HAVE_KQUEUE
56+
#include <sys/select.h>
57+
#endif
58+
5559
#ifdef WITH_TLS
5660
#include <netinet/tcp.h>
5761

@@ -1141,6 +1145,14 @@ static int dual_tcp_accept(rad_listen_t *listener)
11411145
return -1;
11421146
}
11431147

1148+
#ifndef HAVE_KQUEUE
1149+
if (newfd >= FD_SETSIZE) {
1150+
RATE_LIMIT(INFO("Ignoring new connection from client %s too many connections are open", client->shortname));
1151+
close(newfd);
1152+
return 0;
1153+
}
1154+
#endif
1155+
11441156
if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
11451157
close(newfd);
11461158
DEBUG2(" ... unknown address family");
@@ -3727,6 +3739,16 @@ rad_listen_t *proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t
37273739
return NULL;
37283740
}
37293741

3742+
#ifndef HAVE_KQUEUE
3743+
if (this->fd >= FD_SETSIZE) {
3744+
this->print(this, buffer,sizeof(buffer));
3745+
ERROR("Failed opening new proxy socket '%s' : FD %d is larger than maximum %u",
3746+
buffer, this->fd, FD_SETSIZE);
3747+
home->last_failed_open = now;
3748+
listen_free(&this);
3749+
return NULL;
3750+
}
3751+
#endif
37303752

37313753
#ifdef WITH_TCP
37323754
#ifdef SO_KEEPALIVE

0 commit comments

Comments
 (0)