diff --git a/ChangeLog b/ChangeLog index 44af8ec5de..aff869333c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Changes in version 0.2.2.8-alpha - 2010-??-?? + o Minor bugfixes: + - Ignore OutboundBindAddress when connecting to localhost. + Connections to localhost need to come _from_ localhost, or else + local servers (like DNS and outgoing HTTP/SOCKS proxies) will often + refuse to listen. + + Changes in version 0.2.1.23 - 2010-0?-?? o Major bugfixes (performance): - We were selecting our guards uniformly at random, and then weighting diff --git a/src/or/connection.c b/src/or/connection.c index 6506cf81fd..eeb25c1828 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1236,7 +1236,7 @@ connection_connect(connection_t *conn, const char *address, return -1; } - if (options->OutboundBindAddress) { + if (options->OutboundBindAddress && !tor_addr_is_loopback(addr)) { struct sockaddr_in ext_addr; memset(&ext_addr, 0, sizeof(ext_addr)); diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 83bff671aa..a504224c54 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -2238,6 +2238,21 @@ evdns_resume(void) return 0; } +static int +sockaddr_is_loopback(const struct sockaddr *addr) +{ + static const char LOOPBACK_S6[16] = + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"; + if (addr->sa_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *)addr; + return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000; + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; + return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16); + } + return 0; +} + static int _evdns_nameserver_add_impl(const struct sockaddr *address, socklen_t addrlen) { @@ -2279,7 +2294,8 @@ _evdns_nameserver_add_impl(const struct sockaddr *address, fcntl(ns->socket, F_SETFL, O_NONBLOCK); #endif - if (global_bind_addr_is_set) { + if (global_bind_addr_is_set && + !sockaddr_is_loopback((struct sockaddr*)&global_bind_address)) { if (bind(ns->socket, (struct sockaddr *)&global_bind_address, global_bind_addrlen) < 0) { log(EVDNS_LOG_DEBUG, "Couldn't bind to outgoing address.");