diff options
author | teor (Tim Wilson-Brown) <teor2345@gmail.com> | 2015-12-22 10:42:09 +1100 |
---|---|---|
committer | teor (Tim Wilson-Brown) <teor2345@gmail.com> | 2016-01-29 07:13:56 +1100 |
commit | 4460feaf2850ef0fb027a2d01786a5bbaee056dc (patch) | |
tree | 8e3de118ffa8b198600cc4b8e56b37321369b69b /src/or/nodelist.c | |
parent | b9714e1366a19dff1f9abe18a22dc4367788cc3c (diff) | |
download | tor-4460feaf2850ef0fb027a2d01786a5bbaee056dc.tar.gz tor-4460feaf2850ef0fb027a2d01786a5bbaee056dc.zip |
Fix *_get_all_orports to use ipv6_orport
node_get_all_orports and router_get_all_orports incorrectly used or_port
with IPv6 addresses. They now use ipv6_orport.
Also refactor and remove duplicated code.
Diffstat (limited to 'src/or/nodelist.c')
-rw-r--r-- | src/or/nodelist.c | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/src/or/nodelist.c b/src/or/nodelist.c index fc27207851..a1d99e9899 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -754,6 +754,40 @@ node_exit_policy_is_exact(const node_t *node, sa_family_t family) return 1; } +/* Check if the "addr" and port_field fields from r are a valid non-listening + * address/port. If so, set valid to true and add a newly allocated + * tor_addr_port_t containing "addr" and port_field to sl. + * "addr" is an IPv4 host-order address and port_field is a uint16_t. + * r is typically a routerinfo_t or routerstatus_t. + */ +#define SL_ADD_NEW_IPV4_AP(r, port_field, sl, valid) \ + STMT_BEGIN \ + if (tor_addr_port_is_valid_ipv4h((r)->addr, (r)->port_field, 0)) { \ + valid = 1; \ + tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); \ + tor_addr_from_ipv4h(&ap->addr, (r)->addr); \ + ap->port = (r)->port_field; \ + smartlist_add((sl), ap); \ + } \ + STMT_END + +/* Check if the "addr" and port_field fields from r are a valid non-listening + * address/port. If so, set valid to true and add a newly allocated + * tor_addr_port_t containing "addr" and port_field to sl. + * "addr" is a tor_addr_t and port_field is a uint16_t. + * r is typically a routerinfo_t or routerstatus_t. + */ +#define SL_ADD_NEW_IPV6_AP(r, port_field, sl, valid) \ + STMT_BEGIN \ + if (tor_addr_port_is_valid(&(r)->ipv6_addr, (r)->port_field, 0)) { \ + valid = 1; \ + tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); \ + tor_addr_copy(&ap->addr, &(r)->ipv6_addr); \ + ap->port = (r)->port_field; \ + smartlist_add((sl), ap); \ + } \ + STMT_END + /** Return list of tor_addr_port_t with all OR ports (in the sense IP * addr + TCP port) for <b>node</b>. Caller must free all elements * using tor_free() and free the list using smartlist_free(). @@ -766,30 +800,38 @@ smartlist_t * node_get_all_orports(const node_t *node) { smartlist_t *sl = smartlist_new(); + int valid = 0; + /* Find a valid IPv4 address and port */ if (node->ri != NULL) { - if (node->ri->addr != 0) { - tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); - tor_addr_from_ipv4h(&ap->addr, node->ri->addr); - ap->port = node->ri->or_port; - smartlist_add(sl, ap); - } - if (!tor_addr_is_null(&node->ri->ipv6_addr)) { - tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); - tor_addr_copy(&ap->addr, &node->ri->ipv6_addr); - ap->port = node->ri->or_port; - smartlist_add(sl, ap); - } - } else if (node->rs != NULL) { - tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); - tor_addr_from_ipv4h(&ap->addr, node->rs->addr); - ap->port = node->rs->or_port; - smartlist_add(sl, ap); + SL_ADD_NEW_IPV4_AP(node->ri, or_port, sl, valid); + } + + /* If we didn't find a valid address/port in the ri, try the rs */ + if (!valid && node->rs != NULL) { + SL_ADD_NEW_IPV4_AP(node->rs, or_port, sl, valid); + } + + /* Find a valid IPv6 address and port */ + valid = 0; + if (node->ri != NULL) { + SL_ADD_NEW_IPV6_AP(node->ri, ipv6_orport, sl, valid); + } + + if (!valid && node->rs != NULL) { + SL_ADD_NEW_IPV6_AP(node->rs, ipv6_orport, sl, valid); + } + + if (!valid && node->md != NULL) { + SL_ADD_NEW_IPV6_AP(node->md, ipv6_orport, sl, valid); } return sl; } +#undef SL_ADD_NEW_IPV4_AP +#undef SL_ADD_NEW_IPV6_AP + /** Wrapper around node_get_prim_orport for backward compatibility. */ void |