aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/config/config.c32
-rw-r--r--src/app/config/or_options_st.h29
-rw-r--r--src/core/mainloop/connection.c8
-rw-r--r--src/feature/client/transports.c74
-rw-r--r--src/feature/client/transports.h2
-rw-r--r--src/feature/dircache/dircache_stub.c2
-rw-r--r--src/feature/relay/router.c5
-rw-r--r--src/test/test_connection.c13
8 files changed, 139 insertions, 26 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 5c8a3792ee..0706a0dbdc 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -580,6 +580,7 @@ static const config_var_t option_vars_[] = {
V(OutboundBindAddress, LINELIST, NULL),
V(OutboundBindAddressOR, LINELIST, NULL),
V(OutboundBindAddressExit, LINELIST, NULL),
+ V(OutboundBindAddressPT, LINELIST, NULL),
OBSOLETE("PathBiasDisableRate"),
V(PathBiasCircThreshold, INT, "-1"),
@@ -2104,6 +2105,16 @@ options_act,(const or_options_t *old_options))
"in a non-anonymous mode. It will provide NO ANONYMITY.");
}
+ /* 31851: OutboundBindAddressExit is relay-only */
+ if (parse_outbound_addresses(options, 0, &msg) < 0) {
+ // LCOV_EXCL_START
+ log_warn(LD_BUG, "Failed parsing previously validated outbound "
+ "bind addresses: %s", msg);
+ tor_free(msg);
+ return -1;
+ // LCOV_EXCL_STOP
+ }
+
if (options->Bridges) {
mark_bridge_list();
for (cl = options->Bridges; cl; cl = cl->next) {
@@ -2265,16 +2276,6 @@ options_act,(const or_options_t *old_options))
tor_free(http_authenticator);
}
- /* 31851: OutboundBindAddressExit is relay-only */
- if (parse_outbound_addresses(options, 0, &msg) < 0) {
- // LCOV_EXCL_START
- log_warn(LD_BUG, "Failed parsing previously validated outbound "
- "bind addresses: %s", msg);
- tor_free(msg);
- return -1;
- // LCOV_EXCL_STOP
- }
-
config_maybe_load_geoip_files_(options, old_options);
if (geoip_is_loaded(AF_INET) && options->GeoIPExcludeUnknown) {
@@ -7180,7 +7181,8 @@ parse_outbound_address_lines(const config_line_t *lines, outbound_addr_t type,
"configured: %s",
family==AF_INET?" IPv4":(family==AF_INET6?" IPv6":""),
type==OUTBOUND_ADDR_OR?" OR":
- (type==OUTBOUND_ADDR_EXIT?" exit":""), lines->value);
+ (type==OUTBOUND_ADDR_EXIT?" exit":
+ (type==OUTBOUND_ADDR_PT?" PT":"")), lines->value);
return -1;
}
lines = lines->next;
@@ -7203,7 +7205,7 @@ parse_outbound_addresses(or_options_t *options, int validate_only, char **msg)
}
if (parse_outbound_address_lines(options->OutboundBindAddress,
- OUTBOUND_ADDR_EXIT_AND_OR, options,
+ OUTBOUND_ADDR_ANY, options,
validate_only, msg) < 0) {
goto err;
}
@@ -7220,6 +7222,12 @@ parse_outbound_addresses(or_options_t *options, int validate_only, char **msg)
goto err;
}
+ if (parse_outbound_address_lines(options->OutboundBindAddressPT,
+ OUTBOUND_ADDR_PT, options, validate_only,
+ msg) < 0) {
+ goto err;
+ }
+
return 0;
err:
return -1;
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index 3b84e5e1f2..7f201b8dd7 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -24,10 +24,29 @@ struct config_suite_t;
struct routerset_t;
/** Enumeration of outbound address configuration types:
- * Exit-only, OR-only, or both */
-typedef enum {OUTBOUND_ADDR_EXIT, OUTBOUND_ADDR_OR,
- OUTBOUND_ADDR_EXIT_AND_OR,
- OUTBOUND_ADDR_MAX} outbound_addr_t;
+ * Exit-only, OR-only, PT-only, or any of them */
+typedef enum {
+ /** Outbound IP address for Exit connections. Controlled by the
+ * `OutboundBindAddressExit` configuration entry in torrc. */
+ OUTBOUND_ADDR_EXIT,
+
+ /** Outbound IP address for OR connections. Controlled by the
+ * `OutboundBindAddressOR` configuration entry in torrc. */
+ OUTBOUND_ADDR_OR,
+
+ /** Outbound IP address for PT connections. Controlled by the
+ * `OutboundBindAddressPT` configuration entry in torrc. */
+ OUTBOUND_ADDR_PT,
+
+ /** Outbound IP address for any outgoing connections. Controlled by the
+ * OutboundBindAddress configuration entry in torrc. This value is used as
+ * fallback if the more specific OUTBOUND_ADDR_EXIT, OUTBOUND_ADDR_OR, and
+ * OUTBOUND_ADDR_PT are unset. */
+ OUTBOUND_ADDR_ANY,
+
+ /** Max value for this enum. Must be the last element in this enum. */
+ OUTBOUND_ADDR_MAX
+} outbound_addr_t;
/** Which protocol to use for TCPProxy. */
typedef enum {
@@ -131,6 +150,8 @@ struct or_options_t {
struct config_line_t *OutboundBindAddressOR;
/** Local address to bind outbound exit sockets */
struct config_line_t *OutboundBindAddressExit;
+ /** Local address to bind outbound PT sockets */
+ struct config_line_t *OutboundBindAddressPT;
/** Addresses derived from the various OutboundBindAddress lines.
* [][0] is IPv4, [][1] is IPv6
*/
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 29ffdaaf4e..c043b1ccec 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -2331,9 +2331,9 @@ conn_get_outbound_address(sa_family_t family,
ext_addr = &options->OutboundBindAddresses[OUTBOUND_ADDR_EXIT]
[fam_index];
} else if (!tor_addr_is_null(
- &options->OutboundBindAddresses[OUTBOUND_ADDR_EXIT_AND_OR]
+ &options->OutboundBindAddresses[OUTBOUND_ADDR_ANY]
[fam_index])) {
- ext_addr = &options->OutboundBindAddresses[OUTBOUND_ADDR_EXIT_AND_OR]
+ ext_addr = &options->OutboundBindAddresses[OUTBOUND_ADDR_ANY]
[fam_index];
}
} else { // All non-exit connections
@@ -2342,9 +2342,9 @@ conn_get_outbound_address(sa_family_t family,
ext_addr = &options->OutboundBindAddresses[OUTBOUND_ADDR_OR]
[fam_index];
} else if (!tor_addr_is_null(
- &options->OutboundBindAddresses[OUTBOUND_ADDR_EXIT_AND_OR]
+ &options->OutboundBindAddresses[OUTBOUND_ADDR_ANY]
[fam_index])) {
- ext_addr = &options->OutboundBindAddresses[OUTBOUND_ADDR_EXIT_AND_OR]
+ ext_addr = &options->OutboundBindAddresses[OUTBOUND_ADDR_ANY]
[fam_index];
}
}
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c
index 2eb05d6a67..0e4361a210 100644
--- a/src/feature/client/transports.c
+++ b/src/feature/client/transports.c
@@ -1447,6 +1447,37 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
*/
smartlist_add_asprintf(envs, "TOR_PT_EXIT_ON_STDIN_CLOSE=1");
+ /* Specify which IPv4 and IPv6 addresses the PT should make its outgoing
+ * connections from. See: https://bugs.torproject.org/5304 for more
+ * information about this. */
+ {
+ /* Set TOR_PT_OUTBOUND_BIND_ADDRESS_V4. */
+ const tor_addr_t *ipv4_addr = managed_proxy_outbound_address(options,
+ AF_INET);
+
+ /* managed_proxy_outbound_address() only returns a non-NULL value if
+ * tor_addr_is_null() was false, which means we don't have to check that
+ * here. */
+ if (ipv4_addr) {
+ char *ipv4_addr_str = tor_addr_to_str_dup(ipv4_addr);
+ smartlist_add_asprintf(envs,
+ "TOR_PT_OUTBOUND_BIND_ADDRESS_V4=%s",
+ ipv4_addr_str);
+ tor_free(ipv4_addr_str);
+ }
+
+ /* Set TOR_PT_OUTBOUND_BIND_ADDRESS_V6. */
+ const tor_addr_t *ipv6_addr = managed_proxy_outbound_address(options,
+ AF_INET6);
+ if (ipv6_addr) {
+ char *ipv6_addr_str = tor_addr_to_str_dup(ipv6_addr);
+ smartlist_add_asprintf(envs,
+ "TOR_PT_OUTBOUND_BIND_ADDRESS_V6=[%s]",
+ ipv6_addr_str);
+ tor_free(ipv6_addr_str);
+ }
+ }
+
SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {
set_environment_variable_in_smartlist(merged_env_vars, env_var,
tor_free_, 1);
@@ -1919,3 +1950,46 @@ managed_proxy_severity_parse(const char *severity)
return -1;
}
+
+/** Return the outbound address from the given <b>family</b>. Returns NULL if
+ * the user haven't specified a specific outbound address in either
+ * OutboundBindAddress or OutboundBindAddressPT. */
+STATIC const tor_addr_t *
+managed_proxy_outbound_address(const or_options_t *options, sa_family_t family)
+{
+ tor_assert(options);
+
+ const tor_addr_t *address = NULL;
+ int family_index;
+
+ switch (family) {
+ case AF_INET:
+ family_index = 0;
+ break;
+ case AF_INET6:
+ family_index = 1;
+ break;
+ default:
+ /* LCOV_EXCL_START */
+ tor_assert_unreached();
+ return NULL;
+ /* LCOV_EXCL_STOP */
+ }
+
+ /* We start by checking if the user specified an address in
+ * OutboundBindAddressPT. */
+ address = &options->OutboundBindAddresses[OUTBOUND_ADDR_PT][family_index];
+
+ if (! tor_addr_is_null(address))
+ return address;
+
+ /* We fallback to check if the user specified an address in
+ * OutboundBindAddress. */
+ address = &options->OutboundBindAddresses[OUTBOUND_ADDR_ANY][family_index];
+
+ if (! tor_addr_is_null(address))
+ return address;
+
+ /* The user have not specified a preference for outgoing connections. */
+ return NULL;
+}
diff --git a/src/feature/client/transports.h b/src/feature/client/transports.h
index 1ed942c175..3aff1cb248 100644
--- a/src/feature/client/transports.h
+++ b/src/feature/client/transports.h
@@ -149,6 +149,8 @@ STATIC void managed_proxy_stderr_callback(process_t *, const char *, size_t);
STATIC bool managed_proxy_exit_callback(process_t *, process_exit_code_t);
STATIC int managed_proxy_severity_parse(const char *);
+STATIC const tor_addr_t *managed_proxy_outbound_address(const or_options_t *,
+ sa_family_t);
#endif /* defined(PT_PRIVATE) */
diff --git a/src/feature/dircache/dircache_stub.c b/src/feature/dircache/dircache_stub.c
index 87811597d1..725c44bd4d 100644
--- a/src/feature/dircache/dircache_stub.c
+++ b/src/feature/dircache/dircache_stub.c
@@ -14,6 +14,7 @@
#include "feature/dircache/dirserv.h"
#include "feature/dircommon/dir_connection_st.h"
+DISABLE_GCC_WARNING("-Wmissing-noreturn")
int
directory_handle_command(dir_connection_t *conn)
{
@@ -29,6 +30,7 @@ connection_dirserv_flushed_some(dir_connection_t *conn)
tor_assert_nonfatal_unreached_once();
return -1;
}
+ENABLE_GCC_WARNING("-Wmissing-noreturn")
void
dir_conn_clear_spool(dir_connection_t *conn)
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 8233ebe47f..5ca21964b6 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -2607,6 +2607,10 @@ check_descriptor_bandwidth_changed(time_t now)
}
}
+// This function can be "noreturn" if relay mode is disabled and
+// ALL_BUGS_ARE_FATAL is set.
+DISABLE_GCC_WARNING("-Wmissing-noreturn")
+
/** Note at log level severity that our best guess of address has changed from
* <b>prev</b> to <b>cur</b>. */
void
@@ -2636,6 +2640,7 @@ log_addr_has_changed(int severity,
"Guessed our IP address as %s (source: %s).",
addrbuf_cur, source);
}
+ENABLE_GCC_WARNING("-Wmissing-noreturn")
/** Check whether our own address has changed versus the one we have in our
* current descriptor.
diff --git a/src/test/test_connection.c b/src/test/test_connection.c
index 954aeb82e3..178a37adf6 100644
--- a/src/test/test_connection.c
+++ b/src/test/test_connection.c
@@ -617,7 +617,8 @@ test_conn_download_status(void *arg)
connection_t *ap_conn = NULL;
const struct testcase_t *tc = arg;
- consensus_flavor_t usable_flavor = (consensus_flavor_t)tc->setup_data;
+ consensus_flavor_t usable_flavor =
+ networkstatus_parse_flavor_name((const char*) tc->setup_data);
/* The "other flavor" trick only works if there are two flavors */
tor_assert(N_CONSENSUS_FLAVORS == 2);
@@ -1093,17 +1094,17 @@ struct testcase_t connection_tests[] = {
CONNECTION_TESTCASE(get_rend, TT_FORK, test_conn_get_rend_st),
CONNECTION_TESTCASE(get_rsrc, TT_FORK, test_conn_get_rsrc_st),
- CONNECTION_TESTCASE_ARG(download_status, TT_FORK,
- test_conn_download_status_st, FLAV_MICRODESC),
- CONNECTION_TESTCASE_ARG(download_status, TT_FORK,
- test_conn_download_status_st, FLAV_NS),
+ CONNECTION_TESTCASE_ARG(download_status, TT_FORK,
+ test_conn_download_status_st, "microdesc"),
+ CONNECTION_TESTCASE_ARG(download_status, TT_FORK,
+ test_conn_download_status_st, "ns"),
CONNECTION_TESTCASE_ARG(https_proxy_connect, TT_FORK,
test_conn_proxy_connect_st, &PROXY_CONNECT_ARG),
CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, TT_FORK,
test_conn_proxy_connect_st, &PROXY_HAPROXY_ARG),
-//CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
+ //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
{ "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
{ "describe", test_conn_describe, TT_FORK, NULL, NULL },
END_OF_TESTCASES