aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-03-14 16:34:33 -0400
committerNick Mathewson <nickm@torproject.org>2011-03-14 16:34:33 -0400
commite91a8c5589be1f562563a73c6e866a3b84afee87 (patch)
tree98df41dbc7dfe797cf47c583c6869c8e7decdc0d /src/or
parentf1c365b032e058e7342b632006435ecc175475a3 (diff)
parent0588330c1d66960353c412812d1d073fdb37e310 (diff)
downloadtor-e91a8c5589be1f562563a73c6e866a3b84afee87.tar
tor-e91a8c5589be1f562563a73c6e866a3b84afee87.tar.gz
Merge remote branch 'origin/maint-0.2.2'
Resolved nontrivial conflict around rewrite_x_address_for_bridge and learned_bridge_descriptor. Now, since leanred_bridge_descriptor works on nodes, we must make sure that rewrite_node_address_for_bridge also works on nodes. Conflicts: src/or/circuitbuild.c
Diffstat (limited to 'src/or')
-rw-r--r--src/or/circuitbuild.c55
-rw-r--r--src/or/or.h1
-rw-r--r--src/or/routerlist.c17
3 files changed, 70 insertions, 3 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 7ad3b0750..e2b5f138d 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -4688,6 +4688,55 @@ fetch_bridge_descriptors(or_options_t *options, time_t now)
SMARTLIST_FOREACH_END(bridge);
}
+/** If our <b>bridge</b> is configured to be a different address than
+ * the bridge gives in <b>node</b>, rewrite the routerinfo
+ * we received to use the address we meant to use. Now we handle
+ * multihomed bridges better.
+ */
+static void
+rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node)
+{
+ /* XXXX move this function. */
+ /* XXXX overridden addresses should really live in the node_t, so that the
+ * routerinfo_t and the microdesc_t can be immutable. But we can only
+ * do that safely if
+ */
+ tor_addr_t addr;
+
+ if (node->ri) {
+ routerinfo_t *ri = node->ri;
+ tor_addr_from_ipv4h(&addr, ri->addr);
+
+ if (!tor_addr_compare(&bridge->addr, &addr, CMP_EXACT) &&
+ bridge->port == ri->or_port) {
+ /* they match, so no need to do anything */
+ } else {
+ ri->addr = tor_addr_to_ipv4h(&bridge->addr);
+ tor_free(ri->address);
+ ri->address = tor_dup_ip(ri->addr);
+ ri->or_port = bridge->port;
+ log_info(LD_DIR,
+ "Adjusted bridge '%s' to match configured address %s:%d.",
+ ri->nickname, ri->address, ri->or_port);
+ }
+ }
+ if (node->rs) {
+ routerstatus_t *rs = node->rs;
+ tor_addr_from_ipv4h(&addr, rs->addr);
+
+ if (!tor_addr_compare(&bridge->addr, &addr, CMP_EXACT) &&
+ bridge->port == rs->or_port) {
+ /* they match, so no need to do anything */
+ } else {
+ rs->addr = tor_addr_to_ipv4h(&bridge->addr);
+ rs->or_port = bridge->port;
+ log_info(LD_DIR,
+ "Adjusted bridge '%s' to match configured address %s:%d.",
+ rs->nickname, fmt_addr(&bridge->addr), rs->or_port);
+ }
+ }
+}
+
/** We just learned a descriptor for a bridge. See if that
* digest is in our entry guard list, and add it if not. */
void
@@ -4702,14 +4751,16 @@ learned_bridge_descriptor(routerinfo_t *ri, int from_cache)
router_set_status(ri->cache_info.identity_digest, 1);
if (bridge) { /* if we actually want to use this one */
- const node_t *node;
+ node_t *node;
/* it's here; schedule its re-fetch for a long time from now. */
if (!from_cache)
download_status_reset(&bridge->fetch_status);
- node = node_get_by_id(ri->cache_info.identity_digest);
+ node = node_get_mutable_by_id(ri->cache_info.identity_digest);
tor_assert(node);
+ rewrite_node_address_for_bridge(bridge, node);
add_an_entry_guard(node, 1);
+
log_notice(LD_DIR, "new bridge descriptor '%s' (%s)", ri->nickname,
from_cache ? "cached" : "fresh");
/* set entry->made_contact so if it goes down we don't drop it from
diff --git a/src/or/or.h b/src/or/or.h
index 323c472e4..553afbdb7 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3687,6 +3687,7 @@ typedef enum was_router_added_t {
ROUTER_NOT_IN_CONSENSUS = -3,
ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -4,
ROUTER_AUTHDIR_REJECTS = -5,
+ ROUTER_WAS_NOT_WANTED = -6
} was_router_added_t;
/********************************* routerparse.c ************************/
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 66066f68d..1205fd123 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -3233,7 +3233,8 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
int from_cache, int from_fetch)
{
const char *id_digest;
- int authdir = authdir_mode_handles_descs(get_options(), router->purpose);
+ or_options_t *options = get_options();
+ int authdir = authdir_mode_handles_descs(options, router->purpose);
int authdir_believes_valid = 0;
routerinfo_t *old_router;
networkstatus_t *consensus = networkstatus_get_latest_consensus();
@@ -3339,6 +3340,20 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
return ROUTER_NOT_IN_CONSENSUS;
}
+ /* If we're reading a bridge descriptor from our cache, and we don't
+ * recognize it as one of our currently configured bridges, drop the
+ * descriptor. Otherwise we could end up using it as one of our entry
+ * guards even if it isn't in our Bridge config lines. */
+ if (router->purpose == ROUTER_PURPOSE_BRIDGE && from_cache &&
+ !authdir_mode_bridge(options) &&
+ !routerinfo_is_a_configured_bridge(router)) {
+ log_info(LD_DIR, "Dropping bridge descriptor for '%s' because we have "
+ "no bridge configured at that address.", router->nickname);
+ *msg = "Router descriptor was not a configured bridge.";
+ routerinfo_free(router);
+ return ROUTER_WAS_NOT_WANTED;
+ }
+
/* If we have a router with the same identity key, choose the newer one. */
if (old_router) {
if (!in_consensus && (router->cache_info.published_on <=