mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Rely on kernel errno when logging resource exhaustion
Signed-off-by: qontinuum <qontinuum@monaco.mc>
This commit is contained in:
parent
a7a90a3f11
commit
0b015c9731
3
changes/issue40613
Normal file
3
changes/issue40613
Normal 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.
|
@ -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,28 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A socket failed from TCP port exhaustion.
|
||||||
|
*
|
||||||
|
* Note down TCP port exhaustion and log a warning. */
|
||||||
|
static inline void
|
||||||
|
socket_failed_from_tcp_port_exhaustion(void)
|
||||||
|
{
|
||||||
|
rep_hist_note_tcp_exhaustion();
|
||||||
|
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 +1510,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 +1636,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 +1949,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 +2218,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",
|
||||||
@ -2255,7 +2253,7 @@ connection_connect_sockaddr,(connection_t *conn,
|
|||||||
if (bindaddr && bind(s, bindaddr, bindaddr_len) < 0) {
|
if (bindaddr && bind(s, bindaddr, bindaddr_len) < 0) {
|
||||||
*socket_error = tor_socket_errno(s);
|
*socket_error = tor_socket_errno(s);
|
||||||
if (ERRNO_IS_EADDRINUSE(*socket_error)) {
|
if (ERRNO_IS_EADDRINUSE(*socket_error)) {
|
||||||
socket_failed_from_resource_exhaustion();
|
socket_failed_from_tcp_port_exhaustion();
|
||||||
connection_check_oos(get_n_open_sockets(), 1);
|
connection_check_oos(get_n_open_sockets(), 1);
|
||||||
} else {
|
} else {
|
||||||
log_warn(LD_NET,"Error binding network socket: %s",
|
log_warn(LD_NET,"Error binding network socket: %s",
|
||||||
|
Loading…
Reference in New Issue
Block a user