Merge remote-tracking branch 'public/bug2850' into maint-0.2.2

Fixed a trivial conflict where this and the ControlSocketGroupWritable
code both added different functions to the same part of connection.c.

Conflicts:
	src/or/connection.c
This commit is contained in:
Nick Mathewson 2011-05-16 11:10:17 -04:00
commit 919bf6ff3c
2 changed files with 28 additions and 11 deletions

5
changes/bug2850 Normal file
View File

@ -0,0 +1,5 @@
- Minor features
o Set SO_REUSEADDR on all sockets, not just listeners. This should
help busy exit nodes avoid running out of useable ports just because
all the ports have been used in the near past. Resolves issue 2850.

View File

@ -890,6 +890,25 @@ check_location_for_unix_socket(or_options_t *options, const char *path)
} }
#endif #endif
/** Tell the TCP stack that it shouldn't wait for a long time after
* <b>sock</b> has closed before reusing its port. */
static void
make_socket_reuseable(int sock)
{
#ifdef MS_WINDOWS
(void) sock;
#else
int one=1;
/* REUSEADDR on normal places means you can rebind to the port
* right after somebody else has let it go. But REUSEADDR on win32
* means you can bind to the port _even when somebody else
* already has it bound_. So, don't do that on Win32. */
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
(socklen_t)sizeof(one));
#endif
}
/** Bind a new non-blocking socket listening to the socket described /** Bind a new non-blocking socket listening to the socket described
* by <b>listensockaddr</b>. * by <b>listensockaddr</b>.
* *
@ -914,9 +933,6 @@ connection_create_listener(const struct sockaddr *listensockaddr,
if (listensockaddr->sa_family == AF_INET) { if (listensockaddr->sa_family == AF_INET) {
tor_addr_t addr; tor_addr_t addr;
int is_tcp = (type != CONN_TYPE_AP_DNS_LISTENER); int is_tcp = (type != CONN_TYPE_AP_DNS_LISTENER);
#ifndef MS_WINDOWS
int one=1;
#endif
if (is_tcp) if (is_tcp)
start_reading = 1; start_reading = 1;
@ -933,14 +949,7 @@ connection_create_listener(const struct sockaddr *listensockaddr,
goto err; goto err;
} }
#ifndef MS_WINDOWS make_socket_reuseable(s);
/* REUSEADDR on normal places means you can rebind to the port
* right after somebody else has let it go. But REUSEADDR on win32
* means you can bind to the port _even when somebody else
* already has it bound_. So, don't do that on Win32. */
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
(socklen_t)sizeof(one));
#endif
if (bind(s,listensockaddr,socklen) < 0) { if (bind(s,listensockaddr,socklen) < 0) {
const char *helpfulhint = ""; const char *helpfulhint = "";
@ -1159,6 +1168,7 @@ connection_handle_listener_read(connection_t *conn, int new_type)
"Connection accepted on socket %d (child of fd %d).", "Connection accepted on socket %d (child of fd %d).",
news,conn->s); news,conn->s);
make_socket_reuseable(news);
set_socket_nonblocking(news); set_socket_nonblocking(news);
if (options->ConstrainedSockets) if (options->ConstrainedSockets)
@ -1368,6 +1378,8 @@ connection_connect(connection_t *conn, const char *address,
log_debug(LD_NET, "Connecting to %s:%u.", log_debug(LD_NET, "Connecting to %s:%u.",
escaped_safe_str_client(address), port); escaped_safe_str_client(address), port);
make_socket_reuseable(s);
if (connect(s, dest_addr, dest_addr_len) < 0) { if (connect(s, dest_addr, dest_addr_len) < 0) {
int e = tor_socket_errno(s); int e = tor_socket_errno(s);
if (!ERRNO_IS_CONN_EINPROGRESS(e)) { if (!ERRNO_IS_CONN_EINPROGRESS(e)) {