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;
--- src/or/config.c | 88 +++++++++++++++++++++++++-------------------------- src/or/connection.c | 60 +++++++++++++++++------------------ 2 files changed, 73 insertions(+), 75 deletions(-)
diff --git a/src/or/config.c b/src/or/config.c index 03e07f9..12f4f79 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -5557,55 +5557,55 @@ getinfo_helper_config(control_connection_t *conn, static int parse_outbound_addresses(or_options_t *options, int validate_only, char **msg) { - int i; - for (i=0; i<2; ++i) { + 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_; + tor_addr_t *out4 = i ? &options->OutboundBindAddressIPv4_ : &options->LocalOutboundBindAddressIPv4_; + tor_addr_t *out6 = i ? &options->OutboundBindAddressIPv6_ : &options->LocalOutboundBindAddressIPv6_;
- if (!validate_only) { - 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); - switch (af) { - case AF_INET: - if (found_v4) { - if (msg) - tor_asprintf(msg, "Multiple IPv4 outbound bind addresses " - "configured: %s", lines->value); - return -1; - } - found_v4 = 1; - dst_addr = out4; - break; - case AF_INET6: - if (found_v6) { - if (msg) - tor_asprintf(msg, "Multiple IPv6 outbound bind addresses " - "configured: %s", lines->value); - return -1; + if (!validate_only) { + 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); + switch (af) { + case AF_INET: + if (found_v4) { + if (msg) + tor_asprintf(msg, "Multiple IPv4 outbound bind addresses " + "configured: %s", lines->value); + return -1; + } + found_v4 = 1; + dst_addr = out4; + break; + case AF_INET6: + if (found_v6) { + if (msg) + tor_asprintf(msg, "Multiple IPv6 outbound bind addresses " + "configured: %s", lines->value); + return -1; + } + found_v6 = 1; + dst_addr = out6; + break; + default: + if (msg) + tor_asprintf(msg, "Outbound bind address '%s' didn't parse.", + lines->value); + return -1; } - found_v6 = 1; - dst_addr = out6; - break; - default: - if (msg) - tor_asprintf(msg, "Outbound bind address '%s' didn't parse.", - lines->value); - return -1; + if (!validate_only) + tor_addr_copy(dst_addr, &addr); + lines = lines->next; } - if (!validate_only) - tor_addr_copy(dst_addr, &addr); - lines = lines->next; } - } return 0; }
diff --git a/src/or/connection.c b/src/or/connection.c index 397a2dc..021f7ab 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1451,37 +1451,35 @@ connection_connect(connection_t *conn, const char *address,
make_socket_reuseable(s);
- { - const int is_local = tor_addr_is_loopback(addr); - const tor_addr_t *ext_addr = NULL; - 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; - memset(&ext_addr_sa, 0, sizeof(ext_addr_sa)); - ext_addr_len = tor_addr_to_sockaddr(ext_addr, 0, - (struct sockaddr *) &ext_addr_sa, - sizeof(ext_addr_sa)); - if (ext_addr_len == 0) { - log_warn(LD_NET, - "Error converting OutboundBindAddress %s into sockaddr. " - "Ignoring.", fmt_and_decorate_addr(ext_addr)); - } else { - if (bind(s, (struct sockaddr *) &ext_addr_sa, ext_addr_len) < 0) { - *socket_error = tor_socket_errno(s); - log_warn(LD_NET,"Error binding network socket to %s: %s", - fmt_and_decorate_addr(ext_addr), - tor_socket_strerror(*socket_error)); - tor_close_socket(s); - return -1; - } + const int is_local = tor_addr_is_loopback(addr); + const tor_addr_t *ext_addr = NULL; + 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; + memset(&ext_addr_sa, 0, sizeof(ext_addr_sa)); + ext_addr_len = tor_addr_to_sockaddr(ext_addr, 0, + (struct sockaddr *) &ext_addr_sa, + sizeof(ext_addr_sa)); + if (ext_addr_len == 0) { + log_warn(LD_NET, + "Error converting OutboundBindAddress %s into sockaddr. " + "Ignoring.", fmt_and_decorate_addr(ext_addr)); + } else { + if (bind(s, (struct sockaddr *) &ext_addr_sa, ext_addr_len) < 0) { + *socket_error = tor_socket_errno(s); + log_warn(LD_NET,"Error binding network socket to %s: %s", + fmt_and_decorate_addr(ext_addr), + tor_socket_strerror(*socket_error)); + tor_close_socket(s); + return -1; } } }