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;
|
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
|
/* Using the given descriptor intro point ip, the node of the
|
||||||
* rendezvous point rp_node and the service's subcredential, populate the
|
* rendezvous point rp_node and the service's subcredential, populate the
|
||||||
* already allocated intro1_data object with the needed key material and link
|
* 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(subcredential);
|
||||||
tor_assert(intro1_data);
|
tor_assert(intro1_data);
|
||||||
|
|
||||||
/* Build the link specifiers from the extend information of the rendezvous
|
/* Build the link specifiers from the node at the end of the rendezvous
|
||||||
* circuit that we've picked previously. */
|
* circuit that we opened for this introduction. */
|
||||||
rp_lspecs = smartlist_new();
|
rp_lspecs = node_get_link_specifier_smartlist(rp_node, 0);
|
||||||
get_lspecs_from_node(rp_node, rp_lspecs);
|
|
||||||
if (smartlist_len(rp_lspecs) == 0) {
|
if (smartlist_len(rp_lspecs) == 0) {
|
||||||
/* We can't rendezvous without link specifiers. */
|
/* We can't rendezvous without link specifiers. */
|
||||||
smartlist_free(rp_lspecs);
|
smartlist_free(rp_lspecs);
|
||||||
|
@ -1044,9 +968,7 @@ hs_circ_handle_introduce2(const hs_service_t *service,
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
SMARTLIST_FOREACH(data.link_specifiers, link_specifier_t *, lspec,
|
link_specifier_smartlist_free(data.link_specifiers);
|
||||||
link_specifier_free(lspec));
|
|
||||||
smartlist_free(data.link_specifiers);
|
|
||||||
memwipe(&data, 0, sizeof(data));
|
memwipe(&data, 0, sizeof(data));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1189,6 +1189,102 @@ node_get_rsa_id_digest(const node_t *node)
|
||||||
return (const uint8_t*)node->identity;
|
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. */
|
/** Return the nickname of <b>node</b>, or NULL if we can't find one. */
|
||||||
const char *
|
const char *
|
||||||
node_get_nickname(const node_t *node)
|
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_ed25519_hs_intro(const node_t *node);
|
||||||
int node_supports_v3_rendezvous_point(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);
|
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_addr(const node_t *node);
|
||||||
int node_has_ipv6_orport(const node_t *node);
|
int node_has_ipv6_orport(const node_t *node);
|
||||||
|
|
Loading…
Add table
Reference in a new issue