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:
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"),