|
@@ -2241,9 +2241,11 @@ onion_extend_cpath(origin_circuit_t *circ)
|
|
|
if (r) {
|
|
|
/* If we're a client, use the preferred address rather than the
|
|
|
primary address, for potentially connecting to an IPv6 OR
|
|
|
- port. */
|
|
|
- info = extend_info_from_node(r, server_mode(get_options()) == 0);
|
|
|
- tor_assert(info);
|
|
|
+ port. Servers always want the primary (IPv4) address. */
|
|
|
+ int client = (server_mode(get_options()) == 0);
|
|
|
+ info = extend_info_from_node(r, client);
|
|
|
+ /* Clients can fail to find an allowed address */
|
|
|
+ tor_assert(info || client);
|
|
|
}
|
|
|
} else {
|
|
|
const node_t *r =
|
|
@@ -2318,34 +2320,43 @@ extend_info_new(const char *nickname, const char *digest,
|
|
|
* <b>for_direct_connect</b> is true, in which case the preferred
|
|
|
* address is used instead. May return NULL if there is not enough
|
|
|
* info about <b>node</b> to extend to it--for example, if there is no
|
|
|
- * routerinfo_t or microdesc_t.
|
|
|
+ * routerinfo_t or microdesc_t, or if for_direct_connect is true and none of
|
|
|
+ * the node's addresses are allowed by tor's firewall and IP version config.
|
|
|
**/
|
|
|
extend_info_t *
|
|
|
extend_info_from_node(const node_t *node, int for_direct_connect)
|
|
|
{
|
|
|
tor_addr_port_t ap;
|
|
|
+ int valid_addr = 0;
|
|
|
|
|
|
if (node->ri == NULL && (node->rs == NULL || node->md == NULL))
|
|
|
return NULL;
|
|
|
|
|
|
- /* Choose a preferred address first, but fall back to an allowed address*/
|
|
|
+ /* Choose a preferred address first, but fall back to an allowed address.
|
|
|
+ * choose_address returns 1 on success, but get_prim_orport returns 0. */
|
|
|
if (for_direct_connect)
|
|
|
- fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
|
|
|
+ valid_addr = fascist_firewall_choose_address_node(node,
|
|
|
+ FIREWALL_OR_CONNECTION,
|
|
|
+ 0, &ap);
|
|
|
else
|
|
|
- node_get_prim_orport(node, &ap);
|
|
|
+ valid_addr = !node_get_prim_orport(node, &ap);
|
|
|
|
|
|
- log_debug(LD_CIRC, "using %s for %s",
|
|
|
- fmt_addrport(&ap.addr, ap.port),
|
|
|
- node->ri ? node->ri->nickname : node->rs->nickname);
|
|
|
+ if (valid_addr)
|
|
|
+ log_debug(LD_CIRC, "using %s for %s",
|
|
|
+ fmt_addrport(&ap.addr, ap.port),
|
|
|
+ node->ri ? node->ri->nickname : node->rs->nickname);
|
|
|
+ else
|
|
|
+ log_warn(LD_CIRC, "Could not choose valid address for %s",
|
|
|
+ node->ri ? node->ri->nickname : node->rs->nickname);
|
|
|
|
|
|
- if (node->ri)
|
|
|
+ if (valid_addr && node->ri)
|
|
|
return extend_info_new(node->ri->nickname,
|
|
|
node->identity,
|
|
|
node->ri->onion_pkey,
|
|
|
node->ri->onion_curve25519_pkey,
|
|
|
&ap.addr,
|
|
|
ap.port);
|
|
|
- else if (node->rs && node->md)
|
|
|
+ else if (valid_addr && node->rs && node->md)
|
|
|
return extend_info_new(node->rs->nickname,
|
|
|
node->identity,
|
|
|
node->md->onion_pkey,
|