This works just like OutboundBindAddress, but instead of excluding connections to loopback addresses, it affects only connections to loopback addresses.
The whitespace in this commit is a bit nutty, in order to put whitespace changes into a separate commit. --- doc/tor.1.txt | 11 +++++++++++ src/or/config.c | 25 ++++++++++++++++--------- src/or/connection.c | 17 ++++++++++------- src/or/or.h | 6 ++++++ 4 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 1e1ff1e..f25234d 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -477,6 +477,17 @@ GENERAL OPTIONS This setting will be ignored for connections to the loopback addresses (127.0.0.0/8 and ::1).
+**LocalOutboundBindAddress** __IP__:: + Like OutboundBindAddress, but _only_ for connections to loopback + addresses (e.g., inbound connections to local hidden services). + This is useful to distinguish Tor traffic from local traffic in + the log files of your hidden services. + + + + The IP should be in the 127.0.0.0/8 range for maximum compatibility. + I recommend using 127.84.111.114, since 84.111.114 is the ASCII + encoding of "Tor". I also recommend adding '127.84.111.114 tor' to + your /etc/hosts file. + **PidFile** __FILE__:: On startup, write our PID to FILE. On clean shutdown, remove FILE. diff --git a/src/or/config.c b/src/or/config.c index 206ccc8..03e07f9 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -285,6 +285,7 @@ static config_var_t option_vars_[] = { OBSOLETE("IgnoreVersion"), V(KeepalivePeriod, INTERVAL, "5 minutes"), VAR("Log", LINELIST, Logs, NULL), + V(LocalOutboundBindAddress, LINELIST, NULL), V(LogMessageDomains, BOOL, "0"), OBSOLETE("LinkPadding"), OBSOLETE("LogLevel"), @@ -5556,15 +5557,20 @@ getinfo_helper_config(control_connection_t *conn, static int parse_outbound_addresses(or_options_t *options, int validate_only, char **msg) { - const config_line_t *lines = options->OutboundBindAddress; - int found_v4 = 0, found_v6 = 0; + int i; + for (i=0; i<2; ++i) { + + tor_addr_t *out4 = i ? &options->OutboundBindAddressIPv4_ : &options->LocalOutboundBindAddressIPv4_; + tor_addr_t *out6 = i ? &options->OutboundBindAddressIPv6_ : &options->LocalOutboundBindAddressIPv6_;
if (!validate_only) { - memset(&options->OutboundBindAddressIPv4_, 0, - sizeof(options->OutboundBindAddressIPv4_)); - memset(&options->OutboundBindAddressIPv6_, 0, - sizeof(options->OutboundBindAddressIPv6_)); + memset(out4, 0, sizeof(*out4)); + memset(out6, 0, sizeof(*out6)); } + + const config_line_t *lines = i ? options->OutboundBindAddress : options->LocalOutboundBindAddress; + int found_v4 = 0, found_v6 = 0; + while (lines) { tor_addr_t addr, *dst_addr = NULL; int af = tor_addr_parse(&addr, lines->value); @@ -5577,7 +5583,7 @@ parse_outbound_addresses(or_options_t *options, int validate_only, char **msg) return -1; } found_v4 = 1; - dst_addr = &options->OutboundBindAddressIPv4_; + dst_addr = out4; break; case AF_INET6: if (found_v6) { @@ -5587,7 +5593,7 @@ parse_outbound_addresses(or_options_t *options, int validate_only, char **msg) return -1; } found_v6 = 1; - dst_addr = &options->OutboundBindAddressIPv6_; + dst_addr = out6; break; default: if (msg) @@ -5599,7 +5605,8 @@ parse_outbound_addresses(or_options_t *options, int validate_only, char **msg) tor_addr_copy(dst_addr, &addr); lines = lines->next; } - return 0; + } + return 0; }
/** Load one of the geoip files, <a>family</a> determining which diff --git a/src/or/connection.c b/src/or/connection.c index dbcfc41..397a2dc 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1451,14 +1451,17 @@ connection_connect(connection_t *conn, const char *address,
make_socket_reuseable(s);
- if (!tor_addr_is_loopback(addr)) { + { + const int is_local = tor_addr_is_loopback(addr); const tor_addr_t *ext_addr = NULL; - if (protocol_family == AF_INET && - !tor_addr_is_null(&options->OutboundBindAddressIPv4_)) - ext_addr = &options->OutboundBindAddressIPv4_; - else if (protocol_family == AF_INET6 && - !tor_addr_is_null(&options->OutboundBindAddressIPv6_)) - ext_addr = &options->OutboundBindAddressIPv6_; + const tor_addr_t *maybe_ext_addr4 = is_local ? &options->LocalOutboundBindAddressIPv4_ : &options->OutboundBindAddressIPv4_; + const tor_addr_t *maybe_ext_addr6 = is_local ? &options->LocalOutboundBindAddressIPv6_ : &options->OutboundBindAddressIPv6_; + + if (protocol_family == AF_INET && !tor_addr_is_null(maybe_ext_addr4)) + ext_addr = maybe_ext_addr4; + else if (protocol_family == AF_INET6 && !tor_addr_is_null(maybe_ext_addr6)) + ext_addr = maybe_ext_addr6; + if (ext_addr) { struct sockaddr_storage ext_addr_sa; socklen_t ext_addr_len = 0; diff --git a/src/or/or.h b/src/or/or.h index a8645f8..a832e4f 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3181,6 +3181,12 @@ typedef struct { tor_addr_t OutboundBindAddressIPv4_; /** IPv6 address derived from OutboundBindAddress. */ tor_addr_t OutboundBindAddressIPv6_; + /** Local address to bind outbound sockets -- for loopback connections (e.g., hidden services) */ + config_line_t *LocalOutboundBindAddress; + /** IPv4 address derived from LocalOutboundBindAddress. */ + tor_addr_t LocalOutboundBindAddressIPv4_; + /** IPv6 address derived from LocalOutboundBindAddress. */ + tor_addr_t LocalOutboundBindAddressIPv6_; /** Directory server only: which versions of * Tor should we tell users to run? */ config_line_t *RecommendedVersions;