|
@@ -131,6 +131,11 @@
|
|
#include "strlcat.c"
|
|
#include "strlcat.c"
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * descriptor value so we can use it to check the limit when opening a new
|
|
|
|
+ * socket. Default value is what Debian sets as the default hard limit. */
|
|
|
|
+static int max_sockets = 1024;
|
|
|
|
+
|
|
|
|
|
|
* set. */
|
|
* set. */
|
|
int
|
|
int
|
|
@@ -1187,6 +1192,18 @@ tor_open_socket_with_extensions(int domain, int type, int protocol,
|
|
int cloexec, int nonblock)
|
|
int cloexec, int nonblock)
|
|
{
|
|
{
|
|
tor_socket_t s;
|
|
tor_socket_t s;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * enough of them. */
|
|
|
|
+ if (get_n_open_sockets() >= max_sockets - 1) {
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+ WSASetLastError(WSAEMFILE);
|
|
|
|
+#else
|
|
|
|
+ errno = EMFILE;
|
|
|
|
+#endif
|
|
|
|
+ return TOR_INVALID_SOCKET;
|
|
|
|
+ }
|
|
|
|
+
|
|
#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
|
|
#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
|
|
int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
|
|
int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
|
|
(nonblock ? SOCK_NONBLOCK : 0);
|
|
(nonblock ? SOCK_NONBLOCK : 0);
|
|
@@ -1258,6 +1275,18 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
|
|
socklen_t *len, int cloexec, int nonblock)
|
|
socklen_t *len, int cloexec, int nonblock)
|
|
{
|
|
{
|
|
tor_socket_t s;
|
|
tor_socket_t s;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * enough of them. */
|
|
|
|
+ if (get_n_open_sockets() >= max_sockets - 1) {
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+ WSASetLastError(WSAEMFILE);
|
|
|
|
+#else
|
|
|
|
+ errno = EMFILE;
|
|
|
|
+#endif
|
|
|
|
+ return TOR_INVALID_SOCKET;
|
|
|
|
+ }
|
|
|
|
+
|
|
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
|
|
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
|
|
int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
|
|
int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
|
|
(nonblock ? SOCK_NONBLOCK : 0);
|
|
(nonblock ? SOCK_NONBLOCK : 0);
|
|
@@ -1553,6 +1582,12 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
|
int
|
|
int
|
|
set_max_file_descriptors(rlim_t limit, int *max_out)
|
|
set_max_file_descriptors(rlim_t limit, int *max_out)
|
|
{
|
|
{
|
|
|
|
+ if (limit < ULIMIT_BUFFER) {
|
|
|
|
+ log_warn(LD_CONFIG,
|
|
|
|
+ "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
* automatically determine a limit. Re Cygwin, see
|
|
* automatically determine a limit. Re Cygwin, see
|
|
* http:
|
|
* http:
|
|
@@ -1592,7 +1627,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
|
limit = rlim.rlim_max;
|
|
limit = rlim.rlim_max;
|
|
if (limit > INT_MAX)
|
|
if (limit > INT_MAX)
|
|
limit = INT_MAX;
|
|
limit = INT_MAX;
|
|
- *max_out = (int)limit - ULIMIT_BUFFER;
|
|
+ *max_out = max_sockets = (int)limit - ULIMIT_BUFFER;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
if (rlim.rlim_max < limit) {
|
|
if (rlim.rlim_max < limit) {
|
|
@@ -1606,6 +1641,9 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
|
log_info(LD_NET,"Raising max file descriptors from %lu to %lu.",
|
|
log_info(LD_NET,"Raising max file descriptors from %lu to %lu.",
|
|
(unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max);
|
|
(unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ * max fails at least we'll have a valid value of maximum sockets. */
|
|
|
|
+ max_sockets = rlim.rlim_cur - ULIMIT_BUFFER;
|
|
rlim.rlim_cur = rlim.rlim_max;
|
|
rlim.rlim_cur = rlim.rlim_max;
|
|
|
|
|
|
if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
|
|
if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
|
|
@@ -1639,15 +1677,10 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
|
limit = rlim.rlim_cur;
|
|
limit = rlim.rlim_cur;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- if (limit < ULIMIT_BUFFER) {
|
|
|
|
- log_warn(LD_CONFIG,
|
|
|
|
- "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER);
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
if (limit > INT_MAX)
|
|
if (limit > INT_MAX)
|
|
limit = INT_MAX;
|
|
limit = INT_MAX;
|
|
tor_assert(max_out);
|
|
tor_assert(max_out);
|
|
- *max_out = (int)limit - ULIMIT_BUFFER;
|
|
+ *max_out = max_sockets = (int)limit - ULIMIT_BUFFER;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|