|
@@ -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
|