diff options
author | Linus Nordberg <linus@nordberg.se> | 2011-11-24 18:29:56 +0100 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-11-30 11:55:45 -0500 |
commit | f786307ab7f601a3cb41c46df0a09758671a0bcf (patch) | |
tree | f4176da46b8baf23f3055fc1240c0c1c4aca3ca6 /src/or/circuitbuild.c | |
parent | 5bee213d236943dac2e08e04c1525e96a62f13f7 (diff) | |
download | tor-f786307ab7f601a3cb41c46df0a09758671a0bcf.tar.gz tor-f786307ab7f601a3cb41c46df0a09758671a0bcf.zip |
First chunk of support for bridges on IPv6
Comments below focus on changes, see diff for added code.
New type tor_addr_port_t holding an IP address and a TCP/UDP port.
New flag in routerinfo_t, ipv6_preferred. This should go in the
node_t instead but not now.
Replace node_get_addr() with
- node_get_prim_addr() for primary address, i.e. IPv4 for now
- node_get_pref_addr() for preferred address, IPv4 or IPv6.
Rename node_get_addr_ipv4h() node_get_prim_addr_ipv4h() for
consistency. The primary address will not allways be an IPv4 address.
Same for node_get_orport() -> node_get_prim_orport().
Rewrite node_is_a_configured_bridge() to take all OR ports into account.
Extend argument list to extend_info_from_node and
extend_info_from_router with a flag indicating if we want to use the
routers primary address or the preferred address. Use the preferred
address in as few situtations as possible for allowing clients to
connect to bridges over IPv6.
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r-- | src/or/circuitbuild.c | 75 |
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> |