tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit ceddc39c597c7d794cc4b875820e872fbaad5a4b
parent 033f8044292b74e6a46a719476b9633e5d79d978
Author: Nick Mathewson <nickm@torproject.org>
Date:   Mon, 22 Jun 2020 15:33:27 -0400

Merge branch 'pr_1930_squashed'

Diffstat:
Achanges/ticket33816 | 4++++
Msrc/feature/relay/circuitbuild_relay.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/feature/relay/circuitbuild_relay.h | 2++
Msrc/test/test_circuitbuild.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/changes/ticket33816 b/changes/ticket33816 @@ -0,0 +1,4 @@ + o Code simplification and refactoring: + - When an extend cell is missing an IPv4 or IPv6 address, fill in the address + from the extend info. This is similar to what was done in ticket 33633 for + ed25519 keys. Closes ticket 33816. Patch by Neel Chauhan. diff --git a/src/feature/relay/circuitbuild_relay.c b/src/feature/relay/circuitbuild_relay.c @@ -122,6 +122,52 @@ circuit_extend_add_ed25519_helper(struct extend_cell_t *ec) return 0; } +/* Make sure the extend cell <b>ec</b> has an IPv4 address if the relay + * supports in, and if not, fill it in. */ +STATIC int +circuit_extend_add_ipv4_helper(struct extend_cell_t *ec) +{ + IF_BUG_ONCE(!ec) { + return -1; + } + + const node_t *node = node_get_by_id((const char *) ec->node_id); + if (node) { + tor_addr_port_t node_ipv4; + node_get_prim_orport(node, &node_ipv4); + if (tor_addr_is_null(&ec->orport_ipv4.addr) && + !tor_addr_is_null(&node_ipv4.addr)) { + tor_addr_copy(&ec->orport_ipv4.addr, &node_ipv4.addr); + ec->orport_ipv4.port = node_ipv4.port; + } + } + + return 0; +} + +/* Make sure the extend cell <b>ec</b> has an IPv6 address if the relay + * supports in, and if not, fill it in. */ +STATIC int +circuit_extend_add_ipv6_helper(struct extend_cell_t *ec) +{ + IF_BUG_ONCE(!ec) { + return -1; + } + + const node_t *node = node_get_by_id((const char *) ec->node_id); + if (node) { + tor_addr_port_t node_ipv6; + node_get_pref_ipv6_orport(node, &node_ipv6); + if (tor_addr_is_null(&ec->orport_ipv6.addr) && + !tor_addr_is_null(&node_ipv6.addr)) { + tor_addr_copy(&ec->orport_ipv6.addr, &node_ipv6.addr); + ec->orport_ipv6.port = node_ipv6.port; + } + } + + return 0; +} + /* Check if the address and port in the tor_addr_port_t <b>ap</b> are valid, * and are allowed by the current ExtendAllowPrivateAddresses config. * @@ -412,6 +458,12 @@ circuit_extend(struct cell_t *cell, struct circuit_t *circ) if (circuit_extend_lspec_valid_helper(&ec, circ) < 0) return -1; + if (circuit_extend_add_ipv4_helper(&ec) < 0) + return -1; + + if (circuit_extend_add_ipv6_helper(&ec) < 0) + return -1; + /* Check the addresses, without logging */ const int ipv4_valid = circuit_extend_addr_port_is_valid(&ec.orport_ipv4, false, false, 0); diff --git a/src/feature/relay/circuitbuild_relay.h b/src/feature/relay/circuitbuild_relay.h @@ -73,6 +73,8 @@ onionskin_answer(struct or_circuit_t *circ, STATIC int circuit_extend_state_valid_helper(const struct circuit_t *circ); STATIC int circuit_extend_add_ed25519_helper(struct extend_cell_t *ec); +STATIC int circuit_extend_add_ipv4_helper(struct extend_cell_t *ec); +STATIC int circuit_extend_add_ipv6_helper(struct extend_cell_t *ec); STATIC int circuit_extend_lspec_valid_helper(const struct extend_cell_t *ec, const struct circuit_t *circ); STATIC const tor_addr_port_t * circuit_choose_ip_ap_for_extend( diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c @@ -36,6 +36,7 @@ #include "feature/relay/routermode.h" #include "feature/nodelist/node_st.h" +#include "feature/nodelist/routerinfo_st.h" /* Dummy nodes smartlist for testing */ static smartlist_t dummy_nodes; @@ -823,6 +824,77 @@ test_circuit_extend_lspec_valid(void *arg) tor_free(p_chan); } +#define NODE_SET_IPV4(node, ipv4_addr, ipv4_port) { \ + tor_addr_t addr; \ + tor_addr_parse(&addr, ipv4_addr); \ + node->ri->addr = tor_addr_to_ipv4h(&addr); \ + node->ri->or_port = ipv4_port; \ + } + +#define NODE_CLEAR_IPV4(node) { \ + node->ri->addr = 0; \ + node->ri->or_port = 0; \ + } + +#define NODE_SET_IPV6(node, ipv6_addr_str, ipv6_port) { \ + tor_addr_parse(&node->ri->ipv6_addr, ipv6_addr_str); \ + node->ri->ipv6_orport = ipv6_port; \ + } + +/* Test the different cases in circuit_extend_add_ed25519_helper(). */ +static void +test_circuit_extend_add_ip(void *arg) +{ + (void) arg; + tor_addr_t ipv4_tmp; + extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t)); + extend_cell_t *old_ec = tor_malloc_zero(sizeof(extend_cell_t)); + + node_t *fake_node = tor_malloc_zero(sizeof(node_t)); + routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t)); + + MOCK(node_get_by_id, mock_node_get_by_id); + + /* Set up the fake variables for the IPv4 test */ + fake_node->ri = ri; + mocked_node = fake_node; + memset(ec->node_id, 0xAA, sizeof(ec->node_id)); + memcpy(old_ec, ec, sizeof(extend_cell_t)); + NODE_SET_IPV4(fake_node, PUBLIC_IPV4, VALID_PORT); + + /* Do the IPv4 test */ + tt_int_op(circuit_extend_add_ipv4_helper(ec), OP_EQ, 0); + tor_addr_from_ipv4h(&ipv4_tmp, fake_node->ri->addr); + /* The IPv4 should match */ + tt_int_op(tor_addr_compare(&ec->orport_ipv4.addr, &ipv4_tmp, CMP_SEMANTIC), + OP_EQ, 0); + tt_int_op(ec->orport_ipv4.port, OP_EQ, VALID_PORT); + + /* Set up the fake variables for the IPv6 test */ + memcpy(ec, old_ec, sizeof(extend_cell_t)); + NODE_CLEAR_IPV4(fake_node); + NODE_SET_IPV6(fake_node, PUBLIC_IPV6, VALID_PORT); + + /* Do the IPv6 test */ + tt_int_op(circuit_extend_add_ipv6_helper(ec), OP_EQ, 0); + /* The IPv6 should match */ + tt_int_op(tor_addr_compare(&ec->orport_ipv6.addr, &fake_node->ri->ipv6_addr, + CMP_SEMANTIC), OP_EQ, 0); + tt_int_op(ec->orport_ipv6.port, OP_EQ, VALID_PORT); + + /* Cleanup */ + mocked_node = NULL; + + done: + UNMOCK(node_get_by_id); + + tor_free(ec); + tor_free(old_ec); + + tor_free(ri); + tor_free(fake_node); +} + static bool can_extend_over_ipv6_result = false; static int mock_router_can_extend_over_ipv6_calls = 0; static bool @@ -1902,6 +1974,7 @@ struct testcase_t circuitbuild_tests[] = { TEST_CIRCUIT(extend_state_valid, TT_FORK), TEST_CIRCUIT(extend_add_ed25519, TT_FORK), TEST_CIRCUIT(extend_lspec_valid, TT_FORK), + TEST_CIRCUIT(extend_add_ip, TT_FORK), TEST_CIRCUIT(choose_ip_ap_for_extend, 0), TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "4"),