diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app/config/config.c | 32 | ||||
-rw-r--r-- | src/app/config/or_options_st.h | 29 | ||||
-rw-r--r-- | src/core/mainloop/connection.c | 8 | ||||
-rw-r--r-- | src/feature/client/transports.c | 74 | ||||
-rw-r--r-- | src/feature/client/transports.h | 2 | ||||
-rw-r--r-- | src/feature/dircache/dircache_stub.c | 2 | ||||
-rw-r--r-- | src/feature/relay/router.c | 5 | ||||
-rw-r--r-- | src/test/test_connection.c | 13 |
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 |