mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
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.
This commit is contained in:
parent
b9714e1366
commit
4460feaf28
@ -908,6 +908,59 @@ tor_addr_is_loopback(const tor_addr_t *addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Is addr valid?
|
||||||
|
* Checks that addr is non-NULL and not tor_addr_is_null().
|
||||||
|
* If for_listening is true, IPv4 addr 0.0.0.0 is allowed.
|
||||||
|
* It means "bind to all addresses on the local machine". */
|
||||||
|
int
|
||||||
|
tor_addr_is_valid(const tor_addr_t *addr, int for_listening)
|
||||||
|
{
|
||||||
|
/* NULL addresses are invalid regardless of for_listening */
|
||||||
|
if (addr == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only allow IPv4 0.0.0.0 for_listening. */
|
||||||
|
if (for_listening && addr->family == AF_INET
|
||||||
|
&& tor_addr_to_ipv4h(addr) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, the address is valid if it's not tor_addr_is_null() */
|
||||||
|
return !tor_addr_is_null(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the network-order IPv4 address v4n_addr valid?
|
||||||
|
* Checks that addr is not zero.
|
||||||
|
* Except if for_listening is true, where IPv4 addr 0.0.0.0 is allowed. */
|
||||||
|
int
|
||||||
|
tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening)
|
||||||
|
{
|
||||||
|
/* Any IPv4 address is valid with for_listening. */
|
||||||
|
if (for_listening) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, zero addresses are invalid. */
|
||||||
|
return v4n_addr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is port valid?
|
||||||
|
* Checks that port is not 0.
|
||||||
|
* Except if for_listening is true, where port 0 is allowed.
|
||||||
|
* It means "OS chooses a port". */
|
||||||
|
int
|
||||||
|
tor_port_is_valid(uint16_t port, int for_listening)
|
||||||
|
{
|
||||||
|
/* Any port value is valid with for_listening. */
|
||||||
|
if (for_listening) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, zero ports are invalid. */
|
||||||
|
return port != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Set <b>dest</b> to equal the IPv4 address in <b>v4addr</b> (given in
|
/** Set <b>dest</b> to equal the IPv4 address in <b>v4addr</b> (given in
|
||||||
* network order). */
|
* network order). */
|
||||||
void
|
void
|
||||||
|
@ -267,6 +267,27 @@ void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6);
|
|||||||
int tor_addr_is_null(const tor_addr_t *addr);
|
int tor_addr_is_null(const tor_addr_t *addr);
|
||||||
int tor_addr_is_loopback(const tor_addr_t *addr);
|
int tor_addr_is_loopback(const tor_addr_t *addr);
|
||||||
|
|
||||||
|
int tor_addr_is_valid(const tor_addr_t *addr, int for_listening);
|
||||||
|
int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening);
|
||||||
|
#define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \
|
||||||
|
tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening))
|
||||||
|
int tor_port_is_valid(uint16_t port, int for_listening);
|
||||||
|
/* Are addr and port both valid? */
|
||||||
|
#define tor_addr_port_is_valid(addr, port, for_listening) \
|
||||||
|
(tor_addr_is_valid((addr), (for_listening)) && \
|
||||||
|
tor_port_is_valid((port), (for_listening)))
|
||||||
|
/* Are ap->addr and ap->port both valid? */
|
||||||
|
#define tor_addr_port_is_valid_ap(ap, for_listening) \
|
||||||
|
tor_addr_port_is_valid(&(ap)->addr, (ap)->port, (for_listening))
|
||||||
|
/* Are the network-order v4addr and port both valid? */
|
||||||
|
#define tor_addr_port_is_valid_ipv4n(v4n_addr, port, for_listening) \
|
||||||
|
(tor_addr_is_valid_ipv4n((v4n_addr), (for_listening)) && \
|
||||||
|
tor_port_is_valid((port), (for_listening)))
|
||||||
|
/* Are the host-order v4addr and port both valid? */
|
||||||
|
#define tor_addr_port_is_valid_ipv4h(v4h_addr, port, for_listening) \
|
||||||
|
(tor_addr_is_valid_ipv4h((v4h_addr), (for_listening)) && \
|
||||||
|
tor_port_is_valid((port), (for_listening)))
|
||||||
|
|
||||||
int tor_addr_port_split(int severity, const char *addrport,
|
int tor_addr_port_split(int severity, const char *addrport,
|
||||||
char **address_out, uint16_t *port_out);
|
char **address_out, uint16_t *port_out);
|
||||||
|
|
||||||
|
@ -754,6 +754,40 @@ node_exit_policy_is_exact(const node_t *node, sa_family_t family)
|
|||||||
return 1;
|
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
|
/** 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
|
* addr + TCP port) for <b>node</b>. Caller must free all elements
|
||||||
* using tor_free() and free the list using smartlist_free().
|
* using tor_free() and free the list using smartlist_free().
|
||||||
@ -766,30 +800,38 @@ smartlist_t *
|
|||||||
node_get_all_orports(const node_t *node)
|
node_get_all_orports(const node_t *node)
|
||||||
{
|
{
|
||||||
smartlist_t *sl = smartlist_new();
|
smartlist_t *sl = smartlist_new();
|
||||||
|
int valid = 0;
|
||||||
|
|
||||||
|
/* Find a valid IPv4 address and port */
|
||||||
if (node->ri != NULL) {
|
if (node->ri != NULL) {
|
||||||
if (node->ri->addr != 0) {
|
SL_ADD_NEW_IPV4_AP(node->ri, or_port, sl, valid);
|
||||||
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));
|
/* If we didn't find a valid address/port in the ri, try the rs */
|
||||||
tor_addr_copy(&ap->addr, &node->ri->ipv6_addr);
|
if (!valid && node->rs != NULL) {
|
||||||
ap->port = node->ri->or_port;
|
SL_ADD_NEW_IPV4_AP(node->rs, or_port, sl, valid);
|
||||||
smartlist_add(sl, ap);
|
|
||||||
}
|
}
|
||||||
} else if (node->rs != NULL) {
|
|
||||||
tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t));
|
/* Find a valid IPv6 address and port */
|
||||||
tor_addr_from_ipv4h(&ap->addr, node->rs->addr);
|
valid = 0;
|
||||||
ap->port = node->rs->or_port;
|
if (node->ri != NULL) {
|
||||||
smartlist_add(sl, ap);
|
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;
|
return sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef SL_ADD_NEW_IPV4_AP
|
||||||
|
#undef SL_ADD_NEW_IPV6_AP
|
||||||
|
|
||||||
/** Wrapper around node_get_prim_orport for backward
|
/** Wrapper around node_get_prim_orport for backward
|
||||||
compatibility. */
|
compatibility. */
|
||||||
void
|
void
|
||||||
|
@ -3350,28 +3350,16 @@ router_free_all(void)
|
|||||||
|
|
||||||
/** Return a smartlist of tor_addr_port_t's with all the OR ports of
|
/** Return a smartlist of tor_addr_port_t's with all the OR ports of
|
||||||
<b>ri</b>. Note that freeing of the items in the list as well as
|
<b>ri</b>. Note that freeing of the items in the list as well as
|
||||||
the smartlist itself is the callers responsibility.
|
the smartlist itself is the callers responsibility. */
|
||||||
|
|
||||||
XXX duplicating code from node_get_all_orports(). */
|
|
||||||
smartlist_t *
|
smartlist_t *
|
||||||
router_get_all_orports(const routerinfo_t *ri)
|
router_get_all_orports(const routerinfo_t *ri)
|
||||||
{
|
{
|
||||||
smartlist_t *sl = smartlist_new();
|
|
||||||
tor_assert(ri);
|
tor_assert(ri);
|
||||||
|
node_t fake_node;
|
||||||
if (ri->addr != 0) {
|
memset(&fake_node, 0, sizeof(fake_node));
|
||||||
tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t));
|
/* we don't modify ri, fake_node is passed as a const node_t *
|
||||||
tor_addr_from_ipv4h(&ap->addr, ri->addr);
|
*/
|
||||||
ap->port = ri->or_port;
|
fake_node.ri = (routerinfo_t *)ri;
|
||||||
smartlist_add(sl, ap);
|
return node_get_all_orports(&fake_node);
|
||||||
}
|
|
||||||
if (!tor_addr_is_null(&ri->ipv6_addr)) {
|
|
||||||
tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t));
|
|
||||||
tor_addr_copy(&ap->addr, &ri->ipv6_addr);
|
|
||||||
ap->port = ri->or_port;
|
|
||||||
smartlist_add(sl, ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user