diff options
-rw-r--r-- | src/common/util.c | 41 | ||||
-rw-r--r-- | src/common/util.h | 1 | ||||
-rw-r--r-- | src/or/main.c | 3 |
3 files changed, 43 insertions, 2 deletions
diff --git a/src/common/util.c b/src/common/util.c index 2d7ebbe68..06ad5d91f 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -87,6 +87,12 @@ #ifdef HAVE_NETDB_H #include <netdb.h> #endif +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -1971,6 +1977,39 @@ void write_pidfile(char *filename) { #endif } +/** Get the maximum allowed number of file descriptors. (Some systems + * have a low soft limit.) Make sure we set it to at least + * <b>required_min</b>. Return 0 if we can, or -1 if we fail. */ +int set_max_file_descriptors(int required_min) { + struct rlimit rlim; + +#ifndef HAVE_GETRLIMIT + log_fn(LOG_INFO,"This platform is missing getrlimit(). Proceeding."); + return 0; /* hope we'll be ok */ +#endif + + if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { + log_fn(LOG_WARN, "Could not get maximum number of file descriptors: %s", + strerror(errno)); + return -1; + } + if(required_min > rlim.rlim_max) { + log_fn(LOG_WARN,"We need %d file descriptors available, and we're limited to %d. Please change your ulimit.", required_min, (int)rlim.rlim_max); + return -1; + } + if(required_min > rlim.rlim_cur) { + log_fn(LOG_INFO,"Raising max file descriptors from %d to %d.", + (int)rlim.rlim_cur, (int)rlim.rlim_max); + } + rlim.rlim_cur = rlim.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { + log_fn(LOG_WARN, "Could not set maximum number of file descriptors: %s", + strerror(errno)); + return -1; + } + return 0; +} + /** Call setuid and setgid to run as <b>user</b>:<b>group</b>. Return 0 on * success. On failure, log and return -1. */ @@ -2246,7 +2285,6 @@ parse_addr_and_port_range(const char *s, uint32_t *addr_out, return -1; } - /** Extract a long from the start of s, in the given numeric base. If * there is unconverted data and next is provided, set *next to the * first unconverted character. An error has occurred if no characters @@ -2391,7 +2429,6 @@ void tor_mutex_release(tor_mutex_t *m) log_fn(LOG_WARN, "Failed to release mutex: %d", GetLastError()); } } - #endif void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen) diff --git a/src/common/util.h b/src/common/util.h index 0b6ffd77e..4fd31612a 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -255,6 +255,7 @@ void start_daemon(const char *desired_cwd); void finish_daemon(void); void write_pidfile(char *filename); +int set_max_file_descriptors(int required_min); int switch_id(char *user, char *group); struct in_addr; diff --git a/src/or/main.c b/src/or/main.c index d28c5497a..942e6cd33 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1078,6 +1078,9 @@ static int tor_init(int argc, char *argv[]) { handle_signals(1); + if (set_max_file_descriptors(options.MaxConn) < 0) + return -1; + crypto_global_init(); crypto_seed_rng(); return 0; |