Merge branch 'tor-gitlab/mr/667' into maint-0.4.7

This commit is contained in:
David Goulet 2022-12-12 15:07:00 -05:00
commit da48104c99
2 changed files with 20 additions and 30 deletions

3
changes/issue40613 Normal file
View File

@ -0,0 +1,3 @@
o Code simplifications and refactoring:
- Rely on actual error returned by the kernel when choosing what resource
exhaustion to log. Fixes issue 40613; Fix on tor-0.4.6.1-alpha.

View File

@ -1256,34 +1256,10 @@ create_unix_sockaddr(const char *listenaddress, char **readable_address,
} }
#endif /* defined(HAVE_SYS_UN_H) || defined(RUNNING_DOXYGEN) */ #endif /* defined(HAVE_SYS_UN_H) || defined(RUNNING_DOXYGEN) */
/** /* Log a rate-limited warning about resource exhaustion */
* A socket failed from resource exhaustion.
*
* Among other actions, warn that an accept or a connect has failed because
* we're running out of TCP sockets we can use on current system. Rate-limit
* these warnings so that we don't spam the log. */
static void static void
socket_failed_from_resource_exhaustion(void) warn_about_resource_exhaution(void)
{ {
/* When we get to this point we know that a socket could not be
* established. However the kernel does not let us know whether the reason is
* because we ran out of TCP source ports, or because we exhausted all the
* FDs on this system, or for any other reason.
*
* For this reason, we are going to use the following heuristic: If our
* system supports a lot of sockets, we will assume that it's a problem of
* TCP port exhaustion. Otherwise, if our system does not support many
* sockets, we will assume that this is because of file descriptor
* exhaustion.
*/
if (get_max_sockets() > 65535) {
/* TCP port exhaustion */
rep_hist_note_tcp_exhaustion();
} else {
/* File descriptor exhaustion */
rep_hist_note_overload(OVERLOAD_FD_EXHAUSTED);
}
#define WARN_TOO_MANY_CONNS_INTERVAL (6*60*60) #define WARN_TOO_MANY_CONNS_INTERVAL (6*60*60)
static ratelim_t last_warned = RATELIM_INIT(WARN_TOO_MANY_CONNS_INTERVAL); static ratelim_t last_warned = RATELIM_INIT(WARN_TOO_MANY_CONNS_INTERVAL);
char *m; char *m;
@ -1297,6 +1273,17 @@ socket_failed_from_resource_exhaustion(void)
} }
} }
/**
* A socket failed from file descriptor exhaustion.
*
* Note down file descriptor exhaustion and log a warning. */
static inline void
socket_failed_from_fd_exhaustion(void)
{
rep_hist_note_overload(OVERLOAD_FD_EXHAUSTED);
warn_about_resource_exhaution();
}
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
#define UNIX_SOCKET_PURPOSE_CONTROL_SOCKET 0 #define UNIX_SOCKET_PURPOSE_CONTROL_SOCKET 0
@ -1512,7 +1499,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
if (!SOCKET_OK(s)) { if (!SOCKET_OK(s)) {
int e = tor_socket_errno(s); int e = tor_socket_errno(s);
if (ERRNO_IS_RESOURCE_LIMIT(e)) { if (ERRNO_IS_RESOURCE_LIMIT(e)) {
socket_failed_from_resource_exhaustion(); socket_failed_from_fd_exhaustion();
/* /*
* We'll call the OOS handler at the error exit, so set the * We'll call the OOS handler at the error exit, so set the
* exhaustion flag for it. * exhaustion flag for it.
@ -1638,7 +1625,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
if (! SOCKET_OK(s)) { if (! SOCKET_OK(s)) {
int e = tor_socket_errno(s); int e = tor_socket_errno(s);
if (ERRNO_IS_RESOURCE_LIMIT(e)) { if (ERRNO_IS_RESOURCE_LIMIT(e)) {
socket_failed_from_resource_exhaustion(); socket_failed_from_fd_exhaustion();
/* /*
* We'll call the OOS handler at the error exit, so set the * We'll call the OOS handler at the error exit, so set the
* exhaustion flag for it. * exhaustion flag for it.
@ -1951,7 +1938,7 @@ connection_handle_listener_read(connection_t *conn, int new_type)
connection_check_oos(get_n_open_sockets(), 0); connection_check_oos(get_n_open_sockets(), 0);
return 0; return 0;
} else if (ERRNO_IS_RESOURCE_LIMIT(e)) { } else if (ERRNO_IS_RESOURCE_LIMIT(e)) {
socket_failed_from_resource_exhaustion(); socket_failed_from_fd_exhaustion();
/* Exhaustion; tell the OOS handler */ /* Exhaustion; tell the OOS handler */
connection_check_oos(get_n_open_sockets(), 1); connection_check_oos(get_n_open_sockets(), 1);
return 0; return 0;
@ -2220,7 +2207,7 @@ connection_connect_sockaddr,(connection_t *conn,
*/ */
*socket_error = tor_socket_errno(s); *socket_error = tor_socket_errno(s);
if (ERRNO_IS_RESOURCE_LIMIT(*socket_error)) { if (ERRNO_IS_RESOURCE_LIMIT(*socket_error)) {
socket_failed_from_resource_exhaustion(); socket_failed_from_fd_exhaustion();
connection_check_oos(get_n_open_sockets(), 1); connection_check_oos(get_n_open_sockets(), 1);
} else { } else {
log_warn(LD_NET,"Error creating network socket: %s", log_warn(LD_NET,"Error creating network socket: %s",