summaryrefslogtreecommitdiff
path: root/src/or/nodelist.c
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordberg.se>2011-11-24 18:29:56 +0100
committerNick Mathewson <nickm@torproject.org>2011-11-30 11:55:45 -0500
commitf786307ab7f601a3cb41c46df0a09758671a0bcf (patch)
treef4176da46b8baf23f3055fc1240c0c1c4aca3ca6 /src/or/nodelist.c
parent5bee213d236943dac2e08e04c1525e96a62f13f7 (diff)
downloadtor-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/nodelist.c')
-rw-r--r--src/or/nodelist.c121
1 files changed, 107 insertions, 14 deletions
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index b93b919c13..08dcde6f02 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -646,24 +646,59 @@ node_exit_policy_rejects_all(const node_t *node)
return 1;
}
-/** Copy the address for <b>node</b> into *<b>addr_out</b>. */
-int
-node_get_addr(const node_t *node, tor_addr_t *addr_out)
+/** 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().
+ *
+ * XXX this is potentially a memory fragmentation hog -- if on
+ * critical path consider the option of having the caller allocate the
+ * memory
+ */
+smartlist_t *
+node_get_all_orports(const node_t *node)
+{
+ smartlist_t *sl = smartlist_create();
+
+ 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);
+ }
+
+ return sl;
+}
+
+/** Copy the primary, IPv4, address for <b>node</b> into
+ * *<b>addr_out</b>. */
+void
+node_get_prim_addr(const node_t *node, tor_addr_t *addr_out)
{
if (node->ri) {
- tor_addr_from_ipv4h(addr_out, node->ri->addr);
- return 0;
- } else if (node->rs) {
+ router_get_prim_addr_port(node->ri, addr_out, NULL);
+ }
+ else if (node->rs) {
tor_addr_from_ipv4h(addr_out, node->rs->addr);
- return 0;
}
- return -1;
}
/** Return the host-order IPv4 address for <b>node</b>, or 0 if it doesn't
* seem to have one. */
uint32_t
-node_get_addr_ipv4h(const node_t *node)
+node_get_prim_addr_ipv4h(const node_t *node)
{
if (node->ri) {
return node->ri->addr;
@@ -673,9 +708,45 @@ node_get_addr_ipv4h(const node_t *node)
return 0;
}
-/** Copy a string representation of the IP address for <b>node</b> into the
- * <b>len</b>-byte buffer at <b>buf</b>.
- */
+/** Return 1 if we prefer the IPv6 address of <b>node</b>, else 0. */
+static int
+node_ipv6_preferred(const node_t *node)
+{
+ if (node->ri != NULL)
+ return router_ipv6_preferred(node->ri);
+ return 0;
+}
+
+/** Copy the preferred address for <b>node</b> into
+ * <b>addr_out</b>. */
+void
+node_get_pref_addr(const node_t *node, tor_addr_t *addr_out)
+{
+ if (node->ri) {
+ router_get_pref_addr_port(node->ri, addr_out, NULL);
+ } else if (node->rs) {
+ /* No IPv6 in routerstatus_t yet. XXXprop186 ok for private
+ bridges but needs fixing */
+ tor_addr_from_ipv4h(addr_out, node->rs->addr);
+ }
+}
+
+/** Copy the preferred IPv6 address for <b>node</b> into
+ * *<b>addr_out</b>. */
+void
+node_get_pref_ipv6_addr(const node_t *node, tor_addr_t *addr_out)
+{
+ if (node->ri) {
+ tor_addr_copy(addr_out, &node->ri->ipv6_addr);
+ } else if (node->rs) {
+ /* No IPv6 in routerstatus_t yet. XXXprop186 ok for private
+ bridges but needs fixing */
+ tor_addr_make_unspec(addr_out);
+ }
+}
+
+/** Copy a string representation of an IP address for <b>node</b> into
+ * the <b>len</b>-byte buffer at <b>buf</b>. */
void
node_get_address_string(const node_t *node, char *buf, size_t len)
{
@@ -701,9 +772,9 @@ node_get_declared_uptime(const node_t *node)
return -1;
}
-/** Return <b>node</b>'s declared or_port */
+/** Return <b>node</b>'s declared primary (IPv4) or_port. */
uint16_t
-node_get_orport(const node_t *node)
+node_get_prim_orport(const node_t *node)
{
if (node->ri)
return node->ri->or_port;
@@ -713,6 +784,28 @@ node_get_orport(const node_t *node)
return 0;
}
+/** Return <b>node</b>'s preferred or_port. */
+uint16_t
+node_get_pref_orport(const node_t *node)
+{
+ if (node_ipv6_preferred(node))
+ return node_get_pref_ipv6_orport(node);
+ else
+ return node_get_prim_orport(node);
+}
+
+/** Return <b>node</b>'s preferred IPv6 or_port. */
+uint16_t
+node_get_pref_ipv6_orport(const node_t *node)
+{
+ if (node->ri)
+ return node->ri->ipv6_orport;
+ else if (node->rs)
+ return 0; /* No IPv6 in routerstatus_t yet. */
+ else
+ return 0;
+}
+
/** Return <b>node</b>'s platform string, or NULL if we don't know it. */
const char *
node_get_platform(const node_t *node)