mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Don't use OutboundBindAddress to connect to localhost
The OutboundBindAddress option is useful for making sure that all of your outbond connections use a given interface. But when connecting to 127.0.0.1 (or ::1 even) it's important to actually have the connection come _from_ localhost, since lots of programs running on localhost use the source address to authenticate that the connection is really coming from the same host. Our old code always bound to OutboundBindAddress, whether connecting to localhost or not. This would potentially break DNS servers on localhost, and socks proxies on localhost. This patch changes the behavior so that we only look at OutboundBindAddress when connecting to a non-loopback address.
This commit is contained in:
parent
c939509051
commit
d4354b506b
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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.");
|
||||
|
Loading…
Reference in New Issue
Block a user