aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-09-11 13:30:45 -0400
committerNick Mathewson <nickm@torproject.org>2013-09-11 13:30:45 -0400
commita2754d418dffb6188717d5e84d9bea59a2c9853b (patch)
tree5f806e1777a26fc70f33fb3063ce16f5c52fa5a3 /src/or
parenta60d21a85deacad98fa04d20fb4e83b57ad191d7 (diff)
downloadtor-a2754d418dffb6188717d5e84d9bea59a2c9853b.tar
tor-a2754d418dffb6188717d5e84d9bea59a2c9853b.tar.gz
Try using INT_MAX, not SOMAXCONN, to set listen() backlog.
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.
Diffstat (limited to 'src/or')
-rw-r--r--src/or/connection.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 6e754a0f7..41946e448 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -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);