Merge branch 'pr_1930_squashed'

This commit is contained in:
Nick Mathewson
2020-06-22 15:33:27 -04:00
4 changed files with 131 additions and 0 deletions
+4
View File
@@ -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.
+52
View File
@@ -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);
+2
View File
@@ -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(
+73
View File
@@ -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"),