aboutsummaryrefslogtreecommitdiff
path: root/src/or/circuitbuild.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r--src/or/circuitbuild.c75
1 files changed, 51 insertions, 24 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 1cfeb030d3..fbd55ddfee 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -3012,7 +3012,7 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit)
log_warn(LD_CIRC,"failed to choose an exit server");
return -1;
}
- exit = extend_info_from_node(node);
+ exit = extend_info_from_node(node, 0);
tor_assert(exit);
}
state->chosen_exit = exit;
@@ -3254,14 +3254,19 @@ onion_extend_cpath(origin_circuit_t *circ)
} else if (cur_len == 0) { /* picking first node */
const node_t *r = choose_good_entry_server(purpose, state);
if (r) {
- info = extend_info_from_node(r);
+ /* If we're extending to a bridge, use the preferred address
+ rather than the primary, for potentially extending to an IPv6
+ bridge. */
+ int use_pref_addr = (r->ri != NULL &&
+ r->ri->purpose == ROUTER_PURPOSE_BRIDGE);
+ info = extend_info_from_node(r, use_pref_addr);
tor_assert(info);
}
} else {
const node_t *r =
choose_good_middle_server(purpose, state, circ->cpath, cur_len);
if (r) {
- info = extend_info_from_node(r);
+ info = extend_info_from_node(r, 0);
tor_assert(info);
}
}
@@ -3320,28 +3325,37 @@ extend_info_alloc(const char *nickname, const char *digest,
return info;
}
-/** Allocate and return a new extend_info_t that can be used to build a
- * circuit to or through the router <b>r</b>. */
+/** Allocate and return a new extend_info_t that can be used to build
+ * a circuit to or through the router <b>r</b>. Use the primary
+ * address of the router unless <b>for_direct_connect</b> is true, in
+ * which case the preferred address is used instead. */
extend_info_t *
-extend_info_from_router(const routerinfo_t *r)
+extend_info_from_router(const routerinfo_t *r, int for_direct_connect)
{
tor_addr_t addr;
+ uint16_t port;
tor_assert(r);
- tor_addr_from_ipv4h(&addr, r->addr);
+
+ if (for_direct_connect)
+ router_get_pref_addr_port(r, &addr, &port);
+ else
+ router_get_prim_addr_port(r, &addr, &port);
return extend_info_alloc(r->nickname, r->cache_info.identity_digest,
- r->onion_pkey, &addr, r->or_port);
+ r->onion_pkey, &addr, port);
}
-/** Allocate and return a new extend_info that can be used to build a ircuit
- * to or through the node <b>node</b>. 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.
+/** Allocate and return a new extend_info that can be used to build a
+ * ircuit to or through the node <b>node</b>. Use the primary address
+ * of the node unless <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.
**/
extend_info_t *
-extend_info_from_node(const node_t *node)
+extend_info_from_node(const node_t *node, int for_direct_connect)
{
if (node->ri) {
- return extend_info_from_router(node->ri);
+ return extend_info_from_router(node->ri, for_direct_connect);
} else if (node->rs && node->md) {
tor_addr_t addr;
tor_addr_from_ipv4h(&addr, node->rs->addr);
@@ -4858,18 +4872,31 @@ routerinfo_is_a_configured_bridge(const routerinfo_t *ri)
int
node_is_a_configured_bridge(const node_t *node)
{
- tor_addr_t addr;
- uint16_t orport;
+ int retval = 0; /* Negative. */
+ smartlist_t *orports = NULL;
+
if (!node)
- return 0;
- if (node_get_addr(node, &addr) < 0)
- return 0;
- orport = node_get_orport(node);
- if (orport == 0)
- return 0;
+ goto out;
+
+ orports = node_get_all_orports(node);
+ if (orports == NULL)
+ goto out;
- return get_configured_bridge_by_addr_port_digest(
- &addr, orport, node->identity) != NULL;
+ SMARTLIST_FOREACH_BEGIN(orports, tor_addr_port_t *, orport) {
+ if (get_configured_bridge_by_addr_port_digest(&orport->addr, orport->port,
+ node->identity) != NULL) {
+ retval = 1;
+ goto out;
+ }
+ } SMARTLIST_FOREACH_END(orport);
+
+out:
+ if (orports != NULL) {
+ SMARTLIST_FOREACH(orports, tor_addr_port_t *, p, tor_free(p));
+ smartlist_free(orports);
+ orports = NULL;
+ }
+ return retval;
}
/** We made a connection to a router at <b>addr</b>:<b>port</b>