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;
--
1.7.10.4