]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Try using INT_MAX, not SOMAXCONN, to set listen() backlog.
authorNick Mathewson <nickm@torproject.org>
Wed, 11 Sep 2013 17:30:45 +0000 (13:30 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 11 Sep 2013 17:30:45 +0000 (13:30 -0400)
Fall back to SOMAXCONN if INT_MAX doesn't work.

We'd like to do this because the actual maximum is overrideable by the
kernel, and the value in the header file might not be right at all.
All implementations I can find out about claim that this is supported.

Fix for 9716; bugfix on every Tor.

changes/bug9716 [new file with mode: 0644]
src/or/connection.c

diff --git a/changes/bug9716 b/changes/bug9716
new file mode 100644 (file)
index 0000000..5e39077
--- /dev/null
@@ -0,0 +1,4 @@
+  o Bugfixes (performance):
+    - Set the listen() backlog limit to the largest actually supported
+      on the system, not to the value in a header file. Fixes bug 9716;
+      bugfix on every released Tor.
index 6e754a0f7a3223dfbf02965371eaef9425d6f0fb..41946e44854f64de69c8b8fc65f8ccd7612edc6e 100644 (file)
@@ -926,6 +926,27 @@ make_socket_reuseable(tor_socket_t sock)
 #endif
 }
 
+/** Max backlog to pass to listen.  We start at */
+static int listen_limit = INT_MAX;
+
+/* Listen on <b>fd</b> with appropriate backlog. Return as for listen. */
+static int
+tor_listen(tor_socket_t fd)
+{
+  int r;
+
+  if ((r = listen(fd, listen_limit)) < 0) {
+    if (listen_limit == SOMAXCONN)
+      return r;
+    if ((r = listen(fd, SOMAXCONN)) == 0) {
+      listen_limit = SOMAXCONN;
+      log_warn(LD_NET, "Setting listen backlog to INT_MAX connections "
+               "didn't work, but SOMAXCONN did. Lowering backlog limit.");
+    }
+  }
+  return r;
+}
+
 /** Bind a new non-blocking socket listening to the socket described
  * by <b>listensockaddr</b>.
  *
@@ -1009,7 +1030,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
     }
 
     if (is_tcp) {
-      if (listen(s,SOMAXCONN) < 0) {
+      if (tor_listen(s) < 0) {
         log_warn(LD_NET, "Could not listen on %s:%u: %s", address, usePort,
                  tor_socket_strerror(tor_socket_errno(s)));
         tor_close_socket(s);