]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Rely on kernel errno when logging resource exhaustion
authorqontinuum <qontinuum@monaco.mc>
Mon, 21 Nov 2022 00:19:23 +0000 (01:19 +0100)
committerqontinuum <qontinuum@monaco.mc>
Fri, 25 Nov 2022 18:38:48 +0000 (19:38 +0100)
Signed-off-by: qontinuum <qontinuum@monaco.mc>
changes/issue40613 [new file with mode: 0644]
src/core/mainloop/connection.c

diff --git a/changes/issue40613 b/changes/issue40613
new file mode 100644 (file)
index 0000000..76434be
--- /dev/null
@@ -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.
index 9a91c545b2f499388df32e418391cefb75dc0987..4c9569ad5b843e3ae11031d4e198502218afd220 100644 (file)
@@ -1256,34 +1256,10 @@ create_unix_sockaddr(const char *listenaddress, char **readable_address,
 }
 #endif /* defined(HAVE_SYS_UN_H) || defined(RUNNING_DOXYGEN) */
 
-/**
- * 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. */
+/* Log a rate-limited warning about resource exhaustion */
 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)
   static ratelim_t last_warned = RATELIM_INIT(WARN_TOO_MANY_CONNS_INTERVAL);
   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
 
 #define UNIX_SOCKET_PURPOSE_CONTROL_SOCKET 0
@@ -1512,7 +1510,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
     if (!SOCKET_OK(s)) {
       int e = tor_socket_errno(s);
       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
          * exhaustion flag for it.
@@ -1638,7 +1636,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
     if (! SOCKET_OK(s)) {
       int e = tor_socket_errno(s);
       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
          * 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);
       return 0;
     } else if (ERRNO_IS_RESOURCE_LIMIT(e)) {
-      socket_failed_from_resource_exhaustion();
+      socket_failed_from_fd_exhaustion();
       /* Exhaustion; tell the OOS handler */
       connection_check_oos(get_n_open_sockets(), 1);
       return 0;
@@ -2220,7 +2218,7 @@ connection_connect_sockaddr,(connection_t *conn,
      */
     *socket_error = tor_socket_errno(s);
     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);
     } else {
       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) {
     *socket_error = tor_socket_errno(s);
     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);
     } else {
       log_warn(LD_NET,"Error binding network socket: %s",