diff options
-rw-r--r-- | changes/bug5304 | 6 | ||||
-rw-r--r-- | scripts/maint/practracker/exceptions.txt | 2 | ||||
-rw-r--r-- | src/feature/client/transports.c | 74 | ||||
-rw-r--r-- | src/feature/client/transports.h | 2 |
4 files changed, 83 insertions, 1 deletions
diff --git a/changes/bug5304 b/changes/bug5304 new file mode 100644 index 0000000000..9afa838129 --- /dev/null +++ b/changes/bug5304 @@ -0,0 +1,6 @@ + o Minor features (pluggable transports): + - Added option OutboundBindAddressPT to torrc. This option allows users to + specify which IPv4 and IPv6 address they want pluggable transports to use + for outgoing IP packets. Tor does not have a way to enforce that the pluggable + transport honors this option so each pluggable transport will have to + implement support for this feature. Closes ticket 5304. diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt index eeef0bd668..0373641b60 100644 --- a/scripts/maint/practracker/exceptions.txt +++ b/scripts/maint/practracker/exceptions.txt @@ -189,7 +189,7 @@ problem function-size /src/feature/client/entrynodes.c:entry_guard_parse_from_st problem file-size /src/feature/client/entrynodes.h 700 problem function-size /src/feature/client/transports.c:handle_proxy_line() 108 problem function-size /src/feature/client/transports.c:parse_method_line_helper() 110 -problem function-size /src/feature/client/transports.c:create_managed_proxy_environment() 111 +problem function-size /src/feature/client/transports.c:create_managed_proxy_environment() 140 problem function-size /src/feature/control/control.c:connection_control_process_inbuf() 113 problem function-size /src/feature/control/control_auth.c:handle_control_authenticate() 186 problem function-size /src/feature/control/control_cmd.c:handle_control_extendcircuit() 150 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) */ |