Loading .gitignore +2 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,8 @@ uptime-*.json /src/lib/libtor-math-testing.a /src/lib/libtor-memarea.a /src/lib/libtor-memarea-testing.a /src/lib/libtor-meminfo.a /src/lib/libtor-meminfo-testing.a /src/lib/libtor-net.a /src/lib/libtor-net-testing.a /src/lib/libtor-process.a Loading Makefile.am +2 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ TOR_UTIL_LIBS = \ src/lib/libtor-thread.a \ src/lib/libtor-memarea.a \ src/lib/libtor-math.a \ src/lib/libtor-meminfo.a \ src/lib/libtor-log.a \ src/lib/libtor-lock.a \ src/lib/libtor-fdio.a \ Loading @@ -75,6 +76,7 @@ TOR_UTIL_TESTING_LIBS = \ src/lib/libtor-thread-testing.a \ src/lib/libtor-memarea-testing.a \ src/lib/libtor-math-testing.a \ src/lib/libtor-meminfo-testing.a \ src/lib/libtor-log-testing.a \ src/lib/libtor-lock-testing.a \ src/lib/libtor-fdio-testing.a \ Loading src/common/compat.c +0 −246 Original line number Diff line number Diff line Loading @@ -128,132 +128,6 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt) #include "lib/net/address.h" #include "lib/sandbox/sandbox.h" /** Number of extra file descriptors to keep in reserve beyond those that we * tell Tor it's allowed to use. */ #define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond ConnLimit_ */ /** Learn the maximum allowed number of file descriptors, and tell the * system we want to use up to that number. (Some systems have a low soft * limit, and let us set it higher.) We compute this by finding the largest * number that we can use. * * If the limit is below the reserved file descriptor value (ULIMIT_BUFFER), * return -1 and <b>max_out</b> is untouched. * * If we can't find a number greater than or equal to <b>limit</b>, then we * fail by returning -1 and <b>max_out</b> is untouched. * * If we are unable to set the limit value because of setrlimit() failing, * return 0 and <b>max_out</b> is set to the current maximum value returned * by getrlimit(). * * Otherwise, return 0 and store the maximum we found inside <b>max_out</b> * and set <b>max_sockets</b> with that value as well.*/ int 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; } /* Define some maximum connections values for systems where we cannot * automatically determine a limit. Re Cygwin, see * http://archives.seul.org/or/talk/Aug-2006/msg00210.html * For an iPhone, 9999 should work. For Windows and all other unknown * systems we use 15000 as the default. */ #ifndef HAVE_GETRLIMIT #if defined(CYGWIN) || defined(__CYGWIN__) const char *platform = "Cygwin"; const unsigned long MAX_CONNECTIONS = 3200; #elif defined(_WIN32) const char *platform = "Windows"; const unsigned long MAX_CONNECTIONS = 15000; #else const char *platform = "unknown platforms with no getrlimit()"; const unsigned long MAX_CONNECTIONS = 15000; #endif /* defined(CYGWIN) || defined(__CYGWIN__) || ... */ log_fn(LOG_INFO, LD_NET, "This platform is missing getrlimit(). Proceeding."); if (limit > MAX_CONNECTIONS) { log_warn(LD_CONFIG, "We do not support more than %lu file descriptors " "on %s. Tried to raise to %lu.", (unsigned long)MAX_CONNECTIONS, platform, (unsigned long)limit); return -1; } limit = MAX_CONNECTIONS; #else /* !(!defined(HAVE_GETRLIMIT)) */ struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { log_warn(LD_NET, "Could not get maximum number of file descriptors: %s", strerror(errno)); return -1; } if (rlim.rlim_max < limit) { log_warn(LD_CONFIG,"We need %lu file descriptors available, and we're " "limited to %lu. Please change your ulimit -n.", (unsigned long)limit, (unsigned long)rlim.rlim_max); return -1; } if (rlim.rlim_max > rlim.rlim_cur) { log_info(LD_NET,"Raising max file descriptors from %lu to %lu.", (unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max); } /* Set the current limit value so if the attempt to set the limit to the * max fails at least we'll have a valid value of maximum sockets. */ *max_out = (int)rlim.rlim_cur - ULIMIT_BUFFER; set_max_sockets(*max_out); rlim.rlim_cur = rlim.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { int couldnt_set = 1; const int setrlimit_errno = errno; #ifdef OPEN_MAX uint64_t try_limit = OPEN_MAX - ULIMIT_BUFFER; if (errno == EINVAL && try_limit < (uint64_t) rlim.rlim_cur) { /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is * full of nasty lies. I'm looking at you, OSX 10.5.... */ rlim.rlim_cur = MIN((rlim_t) try_limit, rlim.rlim_cur); if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) { if (rlim.rlim_cur < (rlim_t)limit) { log_warn(LD_CONFIG, "We are limited to %lu file descriptors by " "OPEN_MAX (%lu), and ConnLimit is %lu. Changing " "ConnLimit; sorry.", (unsigned long)try_limit, (unsigned long)OPEN_MAX, (unsigned long)limit); } else { log_info(LD_CONFIG, "Dropped connection limit to %lu based on " "OPEN_MAX (%lu); Apparently, %lu was too high and rlimit " "lied to us.", (unsigned long)try_limit, (unsigned long)OPEN_MAX, (unsigned long)rlim.rlim_max); } couldnt_set = 0; } } #endif /* defined(OPEN_MAX) */ if (couldnt_set) { log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s", strerror(setrlimit_errno)); } } /* leave some overhead for logs, etc, */ limit = rlim.rlim_cur; #endif /* !defined(HAVE_GETRLIMIT) */ if (limit > INT_MAX) limit = INT_MAX; tor_assert(max_out); *max_out = (int)limit - ULIMIT_BUFFER; set_max_sockets(*max_out); return 0; } /** Hold the result of our call to <b>uname</b>. */ static char uname_result[256]; /** True iff uname_result is set. */ Loading Loading @@ -351,126 +225,6 @@ get_uname,(void)) * Process control */ #if defined(HW_PHYSMEM64) /* This appears to be an OpenBSD thing */ #define INT64_HW_MEM HW_PHYSMEM64 #elif defined(HW_MEMSIZE) /* OSX defines this one */ #define INT64_HW_MEM HW_MEMSIZE #endif /* defined(HW_PHYSMEM64) || ... */ /** * Helper: try to detect the total system memory, and return it. On failure, * return 0. */ static uint64_t get_total_system_memory_impl(void) { #if defined(__linux__) /* On linux, sysctl is deprecated. Because proc is so awesome that you * shouldn't _want_ to write portable code, I guess? */ unsigned long long result=0; int fd = -1; char *s = NULL; const char *cp; size_t file_size=0; if (-1 == (fd = tor_open_cloexec("/proc/meminfo",O_RDONLY,0))) return 0; s = read_file_to_str_until_eof(fd, 65536, &file_size); if (!s) goto err; cp = strstr(s, "MemTotal:"); if (!cp) goto err; /* Use the system sscanf so that space will match a wider number of space */ if (sscanf(cp, "MemTotal: %llu kB\n", &result) != 1) goto err; close(fd); tor_free(s); return result * 1024; /* LCOV_EXCL_START Can't reach this unless proc is broken. */ err: tor_free(s); close(fd); return 0; /* LCOV_EXCL_STOP */ #elif defined (_WIN32) /* Windows has MEMORYSTATUSEX; pretty straightforward. */ MEMORYSTATUSEX ms; memset(&ms, 0, sizeof(ms)); ms.dwLength = sizeof(ms); if (! GlobalMemoryStatusEx(&ms)) return 0; return ms.ullTotalPhys; #elif defined(HAVE_SYSCTL) && defined(INT64_HW_MEM) /* On many systems, HW_PYHSMEM is clipped to 32 bits; let's use a better * variant if we know about it. */ uint64_t memsize = 0; size_t len = sizeof(memsize); int mib[2] = {CTL_HW, INT64_HW_MEM}; if (sysctl(mib,2,&memsize,&len,NULL,0)) return 0; return memsize; #elif defined(HAVE_SYSCTL) && defined(HW_PHYSMEM) /* On some systems (like FreeBSD I hope) you can use a size_t with * HW_PHYSMEM. */ size_t memsize=0; size_t len = sizeof(memsize); int mib[2] = {CTL_HW, HW_USERMEM}; if (sysctl(mib,2,&memsize,&len,NULL,0)) return 0; return memsize; #else /* I have no clue. */ return 0; #endif /* defined(__linux__) || ... */ } /** * Try to find out how much physical memory the system has. On success, * return 0 and set *<b>mem_out</b> to that value. On failure, return -1. */ MOCK_IMPL(int, get_total_system_memory, (size_t *mem_out)) { static size_t mem_cached=0; uint64_t m = get_total_system_memory_impl(); if (0 == m) { /* LCOV_EXCL_START -- can't make this happen without mocking. */ /* We couldn't find our memory total */ if (0 == mem_cached) { /* We have no cached value either */ *mem_out = 0; return -1; } *mem_out = mem_cached; return 0; /* LCOV_EXCL_STOP */ } #if SIZE_MAX != UINT64_MAX if (m > SIZE_MAX) { /* I think this could happen if we're a 32-bit Tor running on a 64-bit * system: we could have more system memory than would fit in a * size_t. */ m = SIZE_MAX; } #endif /* SIZE_MAX != UINT64_MAX */ *mem_out = mem_cached = (size_t) m; return 0; } /** Emit the password prompt <b>prompt</b>, then read up to <b>buflen</b> * bytes of passphrase into <b>output</b>. Return the number of bytes in * the passphrase, excluding terminating NUL. Loading src/common/compat.h +0 −6 Original line number Diff line number Diff line Loading @@ -87,12 +87,6 @@ typedef enum { /* ===== OS compatibility */ MOCK_DECL(const char *, get_uname, (void)); #if !defined(HAVE_RLIM_T) typedef unsigned long rlim_t; #endif int set_max_file_descriptors(rlim_t limit, int *max); MOCK_DECL(int, get_total_system_memory, (size_t *mem_out)); ssize_t tor_getpass(const char *prompt, char *output, size_t buflen); /* This needs some of the declarations above so we include it here. */ Loading src/common/util.c +0 −24 Original line number Diff line number Diff line Loading @@ -99,30 +99,6 @@ /* ===== * Memory management * ===== */ DISABLE_GCC_WARNING(aggregate-return) /** Call the platform malloc info function, and dump the results to the log at * level <b>severity</b>. If no such function exists, do nothing. */ void tor_log_mallinfo(int severity) { #ifdef HAVE_MALLINFO struct mallinfo mi; memset(&mi, 0, sizeof(mi)); mi = mallinfo(); tor_log(severity, LD_MM, "mallinfo() said: arena=%d, ordblks=%d, smblks=%d, hblks=%d, " "hblkhd=%d, usmblks=%d, fsmblks=%d, uordblks=%d, fordblks=%d, " "keepcost=%d", mi.arena, mi.ordblks, mi.smblks, mi.hblks, mi.hblkhd, mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks, mi.keepcost); #else /* !(defined(HAVE_MALLINFO)) */ (void)severity; #endif /* defined(HAVE_MALLINFO) */ } ENABLE_GCC_WARNING(aggregate-return) /* ===== * Math * ===== */ Loading Loading
.gitignore +2 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,8 @@ uptime-*.json /src/lib/libtor-math-testing.a /src/lib/libtor-memarea.a /src/lib/libtor-memarea-testing.a /src/lib/libtor-meminfo.a /src/lib/libtor-meminfo-testing.a /src/lib/libtor-net.a /src/lib/libtor-net-testing.a /src/lib/libtor-process.a Loading
Makefile.am +2 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ TOR_UTIL_LIBS = \ src/lib/libtor-thread.a \ src/lib/libtor-memarea.a \ src/lib/libtor-math.a \ src/lib/libtor-meminfo.a \ src/lib/libtor-log.a \ src/lib/libtor-lock.a \ src/lib/libtor-fdio.a \ Loading @@ -75,6 +76,7 @@ TOR_UTIL_TESTING_LIBS = \ src/lib/libtor-thread-testing.a \ src/lib/libtor-memarea-testing.a \ src/lib/libtor-math-testing.a \ src/lib/libtor-meminfo-testing.a \ src/lib/libtor-log-testing.a \ src/lib/libtor-lock-testing.a \ src/lib/libtor-fdio-testing.a \ Loading
src/common/compat.c +0 −246 Original line number Diff line number Diff line Loading @@ -128,132 +128,6 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt) #include "lib/net/address.h" #include "lib/sandbox/sandbox.h" /** Number of extra file descriptors to keep in reserve beyond those that we * tell Tor it's allowed to use. */ #define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond ConnLimit_ */ /** Learn the maximum allowed number of file descriptors, and tell the * system we want to use up to that number. (Some systems have a low soft * limit, and let us set it higher.) We compute this by finding the largest * number that we can use. * * If the limit is below the reserved file descriptor value (ULIMIT_BUFFER), * return -1 and <b>max_out</b> is untouched. * * If we can't find a number greater than or equal to <b>limit</b>, then we * fail by returning -1 and <b>max_out</b> is untouched. * * If we are unable to set the limit value because of setrlimit() failing, * return 0 and <b>max_out</b> is set to the current maximum value returned * by getrlimit(). * * Otherwise, return 0 and store the maximum we found inside <b>max_out</b> * and set <b>max_sockets</b> with that value as well.*/ int 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; } /* Define some maximum connections values for systems where we cannot * automatically determine a limit. Re Cygwin, see * http://archives.seul.org/or/talk/Aug-2006/msg00210.html * For an iPhone, 9999 should work. For Windows and all other unknown * systems we use 15000 as the default. */ #ifndef HAVE_GETRLIMIT #if defined(CYGWIN) || defined(__CYGWIN__) const char *platform = "Cygwin"; const unsigned long MAX_CONNECTIONS = 3200; #elif defined(_WIN32) const char *platform = "Windows"; const unsigned long MAX_CONNECTIONS = 15000; #else const char *platform = "unknown platforms with no getrlimit()"; const unsigned long MAX_CONNECTIONS = 15000; #endif /* defined(CYGWIN) || defined(__CYGWIN__) || ... */ log_fn(LOG_INFO, LD_NET, "This platform is missing getrlimit(). Proceeding."); if (limit > MAX_CONNECTIONS) { log_warn(LD_CONFIG, "We do not support more than %lu file descriptors " "on %s. Tried to raise to %lu.", (unsigned long)MAX_CONNECTIONS, platform, (unsigned long)limit); return -1; } limit = MAX_CONNECTIONS; #else /* !(!defined(HAVE_GETRLIMIT)) */ struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { log_warn(LD_NET, "Could not get maximum number of file descriptors: %s", strerror(errno)); return -1; } if (rlim.rlim_max < limit) { log_warn(LD_CONFIG,"We need %lu file descriptors available, and we're " "limited to %lu. Please change your ulimit -n.", (unsigned long)limit, (unsigned long)rlim.rlim_max); return -1; } if (rlim.rlim_max > rlim.rlim_cur) { log_info(LD_NET,"Raising max file descriptors from %lu to %lu.", (unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max); } /* Set the current limit value so if the attempt to set the limit to the * max fails at least we'll have a valid value of maximum sockets. */ *max_out = (int)rlim.rlim_cur - ULIMIT_BUFFER; set_max_sockets(*max_out); rlim.rlim_cur = rlim.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { int couldnt_set = 1; const int setrlimit_errno = errno; #ifdef OPEN_MAX uint64_t try_limit = OPEN_MAX - ULIMIT_BUFFER; if (errno == EINVAL && try_limit < (uint64_t) rlim.rlim_cur) { /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is * full of nasty lies. I'm looking at you, OSX 10.5.... */ rlim.rlim_cur = MIN((rlim_t) try_limit, rlim.rlim_cur); if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) { if (rlim.rlim_cur < (rlim_t)limit) { log_warn(LD_CONFIG, "We are limited to %lu file descriptors by " "OPEN_MAX (%lu), and ConnLimit is %lu. Changing " "ConnLimit; sorry.", (unsigned long)try_limit, (unsigned long)OPEN_MAX, (unsigned long)limit); } else { log_info(LD_CONFIG, "Dropped connection limit to %lu based on " "OPEN_MAX (%lu); Apparently, %lu was too high and rlimit " "lied to us.", (unsigned long)try_limit, (unsigned long)OPEN_MAX, (unsigned long)rlim.rlim_max); } couldnt_set = 0; } } #endif /* defined(OPEN_MAX) */ if (couldnt_set) { log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s", strerror(setrlimit_errno)); } } /* leave some overhead for logs, etc, */ limit = rlim.rlim_cur; #endif /* !defined(HAVE_GETRLIMIT) */ if (limit > INT_MAX) limit = INT_MAX; tor_assert(max_out); *max_out = (int)limit - ULIMIT_BUFFER; set_max_sockets(*max_out); return 0; } /** Hold the result of our call to <b>uname</b>. */ static char uname_result[256]; /** True iff uname_result is set. */ Loading Loading @@ -351,126 +225,6 @@ get_uname,(void)) * Process control */ #if defined(HW_PHYSMEM64) /* This appears to be an OpenBSD thing */ #define INT64_HW_MEM HW_PHYSMEM64 #elif defined(HW_MEMSIZE) /* OSX defines this one */ #define INT64_HW_MEM HW_MEMSIZE #endif /* defined(HW_PHYSMEM64) || ... */ /** * Helper: try to detect the total system memory, and return it. On failure, * return 0. */ static uint64_t get_total_system_memory_impl(void) { #if defined(__linux__) /* On linux, sysctl is deprecated. Because proc is so awesome that you * shouldn't _want_ to write portable code, I guess? */ unsigned long long result=0; int fd = -1; char *s = NULL; const char *cp; size_t file_size=0; if (-1 == (fd = tor_open_cloexec("/proc/meminfo",O_RDONLY,0))) return 0; s = read_file_to_str_until_eof(fd, 65536, &file_size); if (!s) goto err; cp = strstr(s, "MemTotal:"); if (!cp) goto err; /* Use the system sscanf so that space will match a wider number of space */ if (sscanf(cp, "MemTotal: %llu kB\n", &result) != 1) goto err; close(fd); tor_free(s); return result * 1024; /* LCOV_EXCL_START Can't reach this unless proc is broken. */ err: tor_free(s); close(fd); return 0; /* LCOV_EXCL_STOP */ #elif defined (_WIN32) /* Windows has MEMORYSTATUSEX; pretty straightforward. */ MEMORYSTATUSEX ms; memset(&ms, 0, sizeof(ms)); ms.dwLength = sizeof(ms); if (! GlobalMemoryStatusEx(&ms)) return 0; return ms.ullTotalPhys; #elif defined(HAVE_SYSCTL) && defined(INT64_HW_MEM) /* On many systems, HW_PYHSMEM is clipped to 32 bits; let's use a better * variant if we know about it. */ uint64_t memsize = 0; size_t len = sizeof(memsize); int mib[2] = {CTL_HW, INT64_HW_MEM}; if (sysctl(mib,2,&memsize,&len,NULL,0)) return 0; return memsize; #elif defined(HAVE_SYSCTL) && defined(HW_PHYSMEM) /* On some systems (like FreeBSD I hope) you can use a size_t with * HW_PHYSMEM. */ size_t memsize=0; size_t len = sizeof(memsize); int mib[2] = {CTL_HW, HW_USERMEM}; if (sysctl(mib,2,&memsize,&len,NULL,0)) return 0; return memsize; #else /* I have no clue. */ return 0; #endif /* defined(__linux__) || ... */ } /** * Try to find out how much physical memory the system has. On success, * return 0 and set *<b>mem_out</b> to that value. On failure, return -1. */ MOCK_IMPL(int, get_total_system_memory, (size_t *mem_out)) { static size_t mem_cached=0; uint64_t m = get_total_system_memory_impl(); if (0 == m) { /* LCOV_EXCL_START -- can't make this happen without mocking. */ /* We couldn't find our memory total */ if (0 == mem_cached) { /* We have no cached value either */ *mem_out = 0; return -1; } *mem_out = mem_cached; return 0; /* LCOV_EXCL_STOP */ } #if SIZE_MAX != UINT64_MAX if (m > SIZE_MAX) { /* I think this could happen if we're a 32-bit Tor running on a 64-bit * system: we could have more system memory than would fit in a * size_t. */ m = SIZE_MAX; } #endif /* SIZE_MAX != UINT64_MAX */ *mem_out = mem_cached = (size_t) m; return 0; } /** Emit the password prompt <b>prompt</b>, then read up to <b>buflen</b> * bytes of passphrase into <b>output</b>. Return the number of bytes in * the passphrase, excluding terminating NUL. Loading
src/common/compat.h +0 −6 Original line number Diff line number Diff line Loading @@ -87,12 +87,6 @@ typedef enum { /* ===== OS compatibility */ MOCK_DECL(const char *, get_uname, (void)); #if !defined(HAVE_RLIM_T) typedef unsigned long rlim_t; #endif int set_max_file_descriptors(rlim_t limit, int *max); MOCK_DECL(int, get_total_system_memory, (size_t *mem_out)); ssize_t tor_getpass(const char *prompt, char *output, size_t buflen); /* This needs some of the declarations above so we include it here. */ Loading
src/common/util.c +0 −24 Original line number Diff line number Diff line Loading @@ -99,30 +99,6 @@ /* ===== * Memory management * ===== */ DISABLE_GCC_WARNING(aggregate-return) /** Call the platform malloc info function, and dump the results to the log at * level <b>severity</b>. If no such function exists, do nothing. */ void tor_log_mallinfo(int severity) { #ifdef HAVE_MALLINFO struct mallinfo mi; memset(&mi, 0, sizeof(mi)); mi = mallinfo(); tor_log(severity, LD_MM, "mallinfo() said: arena=%d, ordblks=%d, smblks=%d, hblks=%d, " "hblkhd=%d, usmblks=%d, fsmblks=%d, uordblks=%d, fordblks=%d, " "keepcost=%d", mi.arena, mi.ordblks, mi.smblks, mi.hblks, mi.hblkhd, mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks, mi.keepcost); #else /* !(defined(HAVE_MALLINFO)) */ (void)severity; #endif /* defined(HAVE_MALLINFO) */ } ENABLE_GCC_WARNING(aggregate-return) /* ===== * Math * ===== */ Loading