mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-26 15:42:34 +01:00
hs: Move get_lspecs_from_node to nodelist.c
Also: * rename to node_get_link_specifier_smartlist * rewrite to return a smartlist * add link_specifier_smartlist_free Part of 23576.
This commit is contained in:
parent
d9010c5b67
commit
cdda3dc484
3 changed files with 105 additions and 82 deletions
|
@ -565,81 +565,6 @@ retry_service_rendezvous_point(const origin_circuit_t *circ)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Add all possible link specifiers in node to lspecs:
|
||||
* - legacy ID is mandatory thus MUST be present in node;
|
||||
* - include ed25519 link specifier if present in the node, and the node
|
||||
* supports ed25519 link authentication, even if its link versions are not
|
||||
* compatible with us;
|
||||
* - include IPv4 link specifier, if the primary address is not IPv4, log a
|
||||
* BUG() warning, and return an empty smartlist;
|
||||
* - include IPv6 link specifier if present in the node. */
|
||||
static void
|
||||
get_lspecs_from_node(const node_t *node, smartlist_t *lspecs)
|
||||
{
|
||||
link_specifier_t *ls;
|
||||
tor_addr_port_t ap;
|
||||
|
||||
tor_assert(node);
|
||||
tor_assert(lspecs);
|
||||
|
||||
/* Get the relay's IPv4 address. */
|
||||
node_get_prim_orport(node, &ap);
|
||||
|
||||
/* We expect the node's primary address to be a valid IPv4 address.
|
||||
* This conforms to the protocol, which requires either an IPv4 or IPv6
|
||||
* address (or both). */
|
||||
if (BUG(!tor_addr_is_v4(&ap.addr)) ||
|
||||
BUG(!tor_addr_port_is_valid_ap(&ap, 0))) {
|
||||
return;
|
||||
}
|
||||
|
||||
ls = link_specifier_new();
|
||||
link_specifier_set_ls_type(ls, LS_IPV4);
|
||||
link_specifier_set_un_ipv4_addr(ls, tor_addr_to_ipv4h(&ap.addr));
|
||||
link_specifier_set_un_ipv4_port(ls, ap.port);
|
||||
/* Four bytes IPv4 and two bytes port. */
|
||||
link_specifier_set_ls_len(ls, sizeof(ap.addr.addr.in_addr) +
|
||||
sizeof(ap.port));
|
||||
smartlist_add(lspecs, ls);
|
||||
|
||||
/* Legacy ID is mandatory and will always be present in node. */
|
||||
ls = link_specifier_new();
|
||||
link_specifier_set_ls_type(ls, LS_LEGACY_ID);
|
||||
memcpy(link_specifier_getarray_un_legacy_id(ls), node->identity,
|
||||
link_specifier_getlen_un_legacy_id(ls));
|
||||
link_specifier_set_ls_len(ls, link_specifier_getlen_un_legacy_id(ls));
|
||||
smartlist_add(lspecs, ls);
|
||||
|
||||
/* ed25519 ID is only included if the node has it, and the node declares a
|
||||
protocol version that supports ed25519 link authentication, even if that
|
||||
link version is not compatible with us. (We are sending the ed25519 key
|
||||
to another tor, which may support different link versions.) */
|
||||
if (!ed25519_public_key_is_zero(&node->ed25519_id) &&
|
||||
node_supports_ed25519_link_authentication(node, 0)) {
|
||||
ls = link_specifier_new();
|
||||
link_specifier_set_ls_type(ls, LS_ED25519_ID);
|
||||
memcpy(link_specifier_getarray_un_ed25519_id(ls), &node->ed25519_id,
|
||||
link_specifier_getlen_un_ed25519_id(ls));
|
||||
link_specifier_set_ls_len(ls, link_specifier_getlen_un_ed25519_id(ls));
|
||||
smartlist_add(lspecs, ls);
|
||||
}
|
||||
|
||||
/* Check for IPv6. If so, include it as well. */
|
||||
if (node_has_ipv6_orport(node)) {
|
||||
ls = link_specifier_new();
|
||||
node_get_pref_ipv6_orport(node, &ap);
|
||||
link_specifier_set_ls_type(ls, LS_IPV6);
|
||||
size_t addr_len = link_specifier_getlen_un_ipv6_addr(ls);
|
||||
const uint8_t *in6_addr = tor_addr_to_in6_addr8(&ap.addr);
|
||||
uint8_t *ipv6_array = link_specifier_getarray_un_ipv6_addr(ls);
|
||||
memcpy(ipv6_array, in6_addr, addr_len);
|
||||
link_specifier_set_un_ipv6_port(ls, ap.port);
|
||||
/* Sixteen bytes IPv6 and two bytes port. */
|
||||
link_specifier_set_ls_len(ls, addr_len + sizeof(ap.port));
|
||||
smartlist_add(lspecs, ls);
|
||||
}
|
||||
}
|
||||
|
||||
/* Using the given descriptor intro point ip, the node of the
|
||||
* rendezvous point rp_node and the service's subcredential, populate the
|
||||
* already allocated intro1_data object with the needed key material and link
|
||||
|
@ -662,10 +587,9 @@ setup_introduce1_data(const hs_desc_intro_point_t *ip,
|
|||
tor_assert(subcredential);
|
||||
tor_assert(intro1_data);
|
||||
|
||||
/* Build the link specifiers from the extend information of the rendezvous
|
||||
* circuit that we've picked previously. */
|
||||
rp_lspecs = smartlist_new();
|
||||
get_lspecs_from_node(rp_node, rp_lspecs);
|
||||
/* Build the link specifiers from the node at the end of the rendezvous
|
||||
* circuit that we opened for this introduction. */
|
||||
rp_lspecs = node_get_link_specifier_smartlist(rp_node, 0);
|
||||
if (smartlist_len(rp_lspecs) == 0) {
|
||||
/* We can't rendezvous without link specifiers. */
|
||||
smartlist_free(rp_lspecs);
|
||||
|
@ -1044,9 +968,7 @@ hs_circ_handle_introduce2(const hs_service_t *service,
|
|||
ret = 0;
|
||||
|
||||
done:
|
||||
SMARTLIST_FOREACH(data.link_specifiers, link_specifier_t *, lspec,
|
||||
link_specifier_free(lspec));
|
||||
smartlist_free(data.link_specifiers);
|
||||
link_specifier_smartlist_free(data.link_specifiers);
|
||||
memwipe(&data, 0, sizeof(data));
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1189,6 +1189,102 @@ node_get_rsa_id_digest(const node_t *node)
|
|||
return (const uint8_t*)node->identity;
|
||||
}
|
||||
|
||||
/* Returns a new smartlist with all possible link specifiers from node:
|
||||
* - legacy ID is mandatory thus MUST be present in node;
|
||||
* - include ed25519 link specifier if present in the node, and the node
|
||||
* supports ed25519 link authentication, and:
|
||||
* - if direct_conn is true, its link versions are compatible with us,
|
||||
* - if direct_conn is false, regardless of its link versions;
|
||||
* - include IPv4 link specifier, if the primary address is not IPv4, log a
|
||||
* BUG() warning, and return an empty smartlist;
|
||||
* - include IPv6 link specifier if present in the node.
|
||||
*
|
||||
* If node is NULL, returns an empty smartlist.
|
||||
*
|
||||
* The smartlist must be freed using link_specifier_smartlist_free(). */
|
||||
smartlist_t *
|
||||
node_get_link_specifier_smartlist(const node_t *node, bool direct_conn)
|
||||
{
|
||||
link_specifier_t *ls;
|
||||
tor_addr_port_t ap;
|
||||
smartlist_t *lspecs = smartlist_new();
|
||||
|
||||
if (!node)
|
||||
return lspecs;
|
||||
|
||||
/* Get the relay's IPv4 address. */
|
||||
node_get_prim_orport(node, &ap);
|
||||
|
||||
/* We expect the node's primary address to be a valid IPv4 address.
|
||||
* This conforms to the protocol, which requires either an IPv4 or IPv6
|
||||
* address (or both). */
|
||||
if (BUG(!tor_addr_is_v4(&ap.addr)) ||
|
||||
BUG(!tor_addr_port_is_valid_ap(&ap, 0))) {
|
||||
return lspecs;
|
||||
}
|
||||
|
||||
ls = link_specifier_new();
|
||||
link_specifier_set_ls_type(ls, LS_IPV4);
|
||||
link_specifier_set_un_ipv4_addr(ls, tor_addr_to_ipv4h(&ap.addr));
|
||||
link_specifier_set_un_ipv4_port(ls, ap.port);
|
||||
/* Four bytes IPv4 and two bytes port. */
|
||||
link_specifier_set_ls_len(ls, sizeof(ap.addr.addr.in_addr) +
|
||||
sizeof(ap.port));
|
||||
smartlist_add(lspecs, ls);
|
||||
|
||||
/* Legacy ID is mandatory and will always be present in node. */
|
||||
ls = link_specifier_new();
|
||||
link_specifier_set_ls_type(ls, LS_LEGACY_ID);
|
||||
memcpy(link_specifier_getarray_un_legacy_id(ls), node->identity,
|
||||
link_specifier_getlen_un_legacy_id(ls));
|
||||
link_specifier_set_ls_len(ls, link_specifier_getlen_un_legacy_id(ls));
|
||||
smartlist_add(lspecs, ls);
|
||||
|
||||
/* ed25519 ID is only included if the node has it, and the node declares a
|
||||
protocol version that supports ed25519 link authentication.
|
||||
If direct_conn is true, we also require that the node's link version is
|
||||
compatible with us. (Otherwise, we will be sending the ed25519 key
|
||||
to another tor, which may support different link versions.) */
|
||||
if (!ed25519_public_key_is_zero(&node->ed25519_id) &&
|
||||
node_supports_ed25519_link_authentication(node, direct_conn)) {
|
||||
ls = link_specifier_new();
|
||||
link_specifier_set_ls_type(ls, LS_ED25519_ID);
|
||||
memcpy(link_specifier_getarray_un_ed25519_id(ls), &node->ed25519_id,
|
||||
link_specifier_getlen_un_ed25519_id(ls));
|
||||
link_specifier_set_ls_len(ls, link_specifier_getlen_un_ed25519_id(ls));
|
||||
smartlist_add(lspecs, ls);
|
||||
}
|
||||
|
||||
/* Check for IPv6. If so, include it as well. */
|
||||
if (node_has_ipv6_orport(node)) {
|
||||
ls = link_specifier_new();
|
||||
node_get_pref_ipv6_orport(node, &ap);
|
||||
link_specifier_set_ls_type(ls, LS_IPV6);
|
||||
size_t addr_len = link_specifier_getlen_un_ipv6_addr(ls);
|
||||
const uint8_t *in6_addr = tor_addr_to_in6_addr8(&ap.addr);
|
||||
uint8_t *ipv6_array = link_specifier_getarray_un_ipv6_addr(ls);
|
||||
memcpy(ipv6_array, in6_addr, addr_len);
|
||||
link_specifier_set_un_ipv6_port(ls, ap.port);
|
||||
/* Sixteen bytes IPv6 and two bytes port. */
|
||||
link_specifier_set_ls_len(ls, addr_len + sizeof(ap.port));
|
||||
smartlist_add(lspecs, ls);
|
||||
}
|
||||
|
||||
return lspecs;
|
||||
}
|
||||
|
||||
/* Free a link specifier list. */
|
||||
void
|
||||
link_specifier_smartlist_free_(smartlist_t *ls_list)
|
||||
{
|
||||
if (!ls_list)
|
||||
return;
|
||||
|
||||
SMARTLIST_FOREACH(ls_list, link_specifier_t *, lspec,
|
||||
link_specifier_free(lspec));
|
||||
smartlist_free(ls_list);
|
||||
}
|
||||
|
||||
/** Return the nickname of <b>node</b>, or NULL if we can't find one. */
|
||||
const char *
|
||||
node_get_nickname(const node_t *node)
|
||||
|
|
|
@ -77,6 +77,11 @@ int node_supports_v3_hsdir(const node_t *node);
|
|||
int node_supports_ed25519_hs_intro(const node_t *node);
|
||||
int node_supports_v3_rendezvous_point(const node_t *node);
|
||||
const uint8_t *node_get_rsa_id_digest(const node_t *node);
|
||||
smartlist_t *node_get_link_specifier_smartlist(const node_t *node,
|
||||
bool direct_conn);
|
||||
void link_specifier_smartlist_free_(smartlist_t *ls_list);
|
||||
#define link_specifier_smartlist_free(ls_list) \
|
||||
FREE_AND_NULL(smartlist_t, link_specifier_smartlist_free_, (ls_list))
|
||||
|
||||
int node_has_ipv6_addr(const node_t *node);
|
||||
int node_has_ipv6_orport(const node_t *node);
|
||||
|
|
Loading…
Add table
Reference in a new issue